本网站由以下捐款支持:OEIS基金会.

用户:Peter Luschny/SageForOEIS

来自OeisWiki
跳转到:航行,搜索

使用工具、提示和技巧
OEIS背景下的SAGE

获取软件

http://www.sagemath.org/

浏览文档

搜索文档,参考,oeis模块

修剪序列。

历史上,OEIS条目有3个术语行,总字符数(包括符号)。今天,在提交给OEIS的文件中,建议“DATA”字段的长度为260个字符。功能下面将给定的列表修剪到这个长度。

定义OEIStrim(L):n=0长度=0T=[]对于l中的l:s=1,如果l<0,否则为0leng=leng+s+len(str(l))如果长度>260:断开长度+=2T附加(l)n+=1打印n,“术语”返回T

示例用法:OEIStrim([(-n)^n代表n in(0..100)])

使用OEIS界面

在Sage中,您可以使用内置斯隆。Axxxxx的功能。例如,快速实现A102467号

定义为_A102467(n):return bool(斯隆)。A001221号(n) <>1和斯隆。A001222号(n) <>2)定义A102467_列表(n):如果是_A102467(k),则返回[(1..n)中k的k

Sage计算的“sloane”序列的功能已记录在案在这里. 如果您想知道这些函数是如何实现的,请查看github在这里(Jaap Spies编写了大部分序列)。

备忘录

在Sage中,通过应用记忆装饰器激活记忆将“CachedFunction”添加到函数。我们的第一个示例是lame:阶乘函数。

@缓存函数定义f(x):如果x>1,则返回x*f(x-1),否则返回1对于(0..9)中的i:打印f(i)

现在如果你计算f(1000),你不仅执行了1000乘法,但也会建立一个缓存,可容纳1000个左右的大小整数。如果随后不在进一步计算中使用这些值这是对资源的巨大浪费。因此,这是一个潜在的误导示例(摘自维基). 动态编程技术不能替代好的算法。如果你想知道如何高效计算阶乘函数在这里.

如果只需要对值进行循环,那么经济的方法是使用生成器(这不需要内部记忆表)。

定义F(最大值):n=0f=1当n<=最大值时:产量fn+=1f*=n对于f(9)中的f:打印f

一个比阶乘更有意义的记忆用法示例函数由指数变换提供:

def-exptrans(s):@缓存函数定义g(n):如果n>0,则返回加法(二项式(n-1,k-1)*s(k)*g(n-k)for k in(1..n)),否则为1返回g

指数变换将序列s映射到序列t。例如s是常数序列1。

定义s(n):返回1t=出口[(0..9)中n的t(n)]
输出>[1、1、2、5、15、52、203、877、4140、21147]

或者让s是常数序列-1。

定义s(n):返回-1t=出口[(0..9)中n的t(n)]
输出>[1,-1,0,1,1,-2,-9,-9、50、267]

表达这一点的一种更简洁的形式是使用lambda表示法,它创建一个可调用的Python函数,将m发送到1。

A000110号=exptrans(λm:1)[A000110号(n) 对于n in(0..9)]
输出>[1、1、2、5、15、52、203、877、4140、21147]

或更短:

[(0..9)中n的exptrans(λm:1)(n)]

可以找到更多指数变换的例子在这里.

展平迭代

一个经常需要的实用函数是“扁平化”。

def展平(I):L=[]对于i中的i:如果hasattr(i,“iter_”):L.extend(展平(i))其他:L.附录(i)返回L

示例用途是压平按类型给定的标尺(请参见威克曼统治者).

科学的格式

任意精度(MPFR)实数的打印例程。

定义SciFormat(f,n):s=f.str()t=“”计数=0w=真对于c in s:如果c<>‘e’和w:如果计数<n+2:t+=c计数+=1其他:t+=cw=假返回t#例如:b=2.2379923576571269975e4767529对于(0..20)中的i:打印SciFormat(b,i)

示例用法见伯努利数的渐近性其中仅显示渐近近似值的有效位数。

标杆管理

让我们用它们的生成函数来计算贝尔数。。。

定义A000110_list(n):R.<t>=PowerSeriesRing(QQ,default_prec=n+1)G=exp(exp(t)-1)return G.ogf().padded_list()

…以及数据库中给出的实现,A000110号 :

定义A000110_列表(m):A=[0,i在范围(0,m)内]A[0]=1R=[1,1]对于范围(1,m)内的n:A[n]=A[0]对于范围(n,0,-1)中的k:A[k-1]+=A[k]R追加(A[0])返回R

时间安排:

时间a=A000110_列表(1000)

时间:CPU 4.31秒,墙:5.56秒(在生成函数的情况下)
时间:CPU 0.99秒,墙壁:1.35秒(在OEIS实施的情况下)

因此,OEIS的实施速度是实施速度的4倍基于生成函数;-)

弗雷德里克·约翰逊在mpmath中实现了贝尔数。他写在他的博客:“我为计算大贝尔数B做了一些基准测试n个, 而且这种方法似乎比其他系统使用的速度快得多。“所以让我们看看他的实现。

从mpmath导入*定义bellexact(n,x=1):mp.prec=20大小=int(log(bell(n,x),2))+10mp.prec=大小返回int(钟形(n,x)+0.5)定义A000110_list(n):return[(0..n)中k的bellexact(k)]时间a=A000110_列表(1000)

时间:CPU 19.69秒,墙壁:27.72秒

当然,约翰逊的算法针对单个评估进行了优化,而不是用于计算值列表。然而,该示例显示了Phython是多么容易库可以在Sage中使用,如本例所示mpmath(数学).

我们还有另一种方法用Sage计算Bell数:expnums!(E·T·贝尔的论文标题是“指数”。)

时间a=扩展(1001,1)

时间:CPU 0.10秒,墙壁:0.19秒

这位圣人班(作家尼克·亚历山大)无疑是赢家。另一方面,我们的实现是普通的Python脚本,而“expnums”函数是基于代码编译的论超高速MPIR公司(前GMP)库。

还有另一个计算贝尔数的功能,在类sage.combinat.combinet,称为bell_number,用于包装间隙是贝尔。

定义A000110_list(n):return[(0..n)中k的bell_number(k)]时间a=A000110_列表(1000)

这次我们得等三分钟以上!秒表上说
时间:CPU 5.25秒,墙壁:182.39秒
好吧,与我们花了大约一秒钟才闪亮的小10字线相比

总之,这些示例表明Sage是一个提供执行任务的多种方法。其次OEIS应该有两种实现:一种是计算序列和另一个序列来计算值列表[a0,a1,a2,…,an]高效。

在本地使用数据库

函数SloaneEncyclopedia.install()安装本地数据库。这些文件是stripped.gz和names.gz. 每隔一段时间只调用此函数一次就足以更新它。为此,请以SloaneEncyclopedia.install(overwrite=True)的形式使用它。更多信息在这里.

斯隆百科全书安装()

出于各种原因,我发现包装库函数SloaneEncyclopedia.find()如下:

定义OEIS_ID(T,num):#T是以列表形式给出的序列,以供识别。#num是要返回的可能匹配项的数量。如果长度(T)<3:返回[]S=T[1:分钟(len(T),20)]R=SloaneEncyclopedia.find(S,num)如果R==[]:U=过滤器(λz:z!=0,S)删除U[0]R=SloaneEncyclopedia.find(U,num)A=[r[0]代表r中的r]s=[]对于a中的a:sa=str(a)L=“0万“[0:7-len(sa)]s.append(L+sa)返回s

示例调用:

OEIS_ID([1,2,3,4,5,6,7,8,9,10],4)
输出>['A000027号', 'A000401号', 'A000926号', 'A001477号']

例如,我在计算正定二次型.

使用Pari

在Sage中使用已发布的Pari脚本很容易。例如,考虑计算阿贝尔群(C_2)^n的子群个数。

在>gp.read(get_remote_file('http://www.cse.sc.edu/~maxal/gpscripts/nsg.gp'))
out>尝试加载远程文件:http://www.cse.sc.edu/~maxal/gpscripts/nsg.gp正在加载:[.]
in>[gp('numsubgrp(2,向量(%d,i,1))'%(n))for n in(0..9)]
输出>[1、2、5、16、67、374、2825、29212、417199、8283458]

这是A006116号。您无需安装Pari即可完成此操作。Pari安装自动与Sage一起工作,无需再做任何事。

我们还可以为此编写一个小包装器函数:

定义A006116号(n) :""" 交换群子群个数公式的实现鉴于G.A Miller的论文“关于阿贝尔群的子群”,数学年鉴,第二辑。,第6卷,第1期(1904年10月),第1-6页(c) 2007年Max Alekseyev"""gp.read(获取远程文件('http://home.gwu.edu/~maxal/gpscripts/nsg.gp'))返回gp('numsubgrp(2,向量(%d,i,1))'%(n))

此方法的一个缺点是您必须联机才能使用此功能。然而,您可以进一步推进,并将代码直接合并到包装纸&只要你不侵犯版权。下一个示例演示了如何操作。

在>gp.read(get_remote_file('http://luschny.de/hacking/gp/A094348号.gp'))
out>尝试加载远程文件:http://luschny.de/hacking/gp/A094348号.gp(加仑)正在加载:[.]
in>gp('A094348号')
输出>(lim)->本地(n,i,R,A,len,count,change,high);R=矢量(500);A=矢量(50\);A[1]=1;A[2]=2;A[3]=4;A[4]=6;A[5]=12;计数=5;高=0;n=12;而(n<=li\m、 d=除数(n);len=长度(d);变化=0;对于(i=1,min(len,high),如果(R[i]>\d[i],R[i]=d[i]:;变化=1);如果(len>high,对于(i=high+1,len,R[i]=d[i]);高(hig)\h=长度);if(更改,计数++;A[计数]=n);n+=12;);向量(count,i,A[i])

现在可以将代码复制到包装器中。只需替换代码依据“A094348号(lim)=“。

定义A094348号(限制):gp('A094348号(lim)=局部(n,i,R,A,len,count,change,high)\R=矢量(500);A=矢量(50);A[1]=1;A[2]=2;A[3]=4;A[4]=6;A[5]=12\计数=5;高=0;n=12;而(n<=lim,d=除数(n);len=长度(d)\变化=0;对于(i=1,min(len,high),如果(R[i]>d[i],R[i]=d[i]:变化=1)\如果(len>high,对于(i=high+1,len,R[i]=d[i]);高=长度)\if(更改,计数++;A[计数]=n);n+=12;);向量(count,i,A[i])')返回gp('A094348号(%d)“%(lim)”)

打电话A094348号(7207200)稍后返回

[1、2、4、6、12、24、36、48、60、72、120、180、240、360、420、720、840,1260, 1680, 2520, 5040, 7560, 10080, 15120, 20160, 25200, 27720, 30240,45360, 50400, 55440, 83160, 110880, 166320, 221760, 277200, 332640,360360, 498960, 554400, 665280, 720720, 1081080, 1441440, 2162160,2882880, 3603600, 4324320, 6486480, 7207200]

严格地说,包装是没有必要的。“gp.read(…)”之后例如,您可以调用gp('A094348号(2000)’)。但封装调用是一种良好的软件实践。圣人说话Python和Sage所依赖的所有层都应该封装。所以,当你决定有一天实施A094348号在Python中或基于不同的库,只有一个位置您必须更改内容,而不是在整个代码中进行更改。

附带说明:马修·范德马斯特A094348号是一个非常有趣的序列。请参见David Wasserman的评论。可以在上找到更复杂的Pari脚本seqcomp系列还有一个讨论A094348的一个好算法?.

在云中计算,在网络上发布。

SMC公司(圣人数学云)创建一个帐户(免费),您可以立即开始计算没有安装任何软件。SMC上预装了许多不同的格式。因此,您不仅可以使用Sage笔记本,还可以使用IPython笔记本我最近更喜欢这样。要在IPython笔记本中使用Sage,您只需在IP-notebook的开头包含命令“%load_ext-sage”一次。例如,我在上的博客帖子完美和最佳的标尺只不过是一个导出到Html的Sage笔记本,相应的IP笔记本可以浏览在这里和已下载在这里.

更多信息和帮助可在此处找到山艾素-云-帮助在这里:云朵.