保存和读取个人的对象
假设你正在计算一个矩阵,或是模块化的符号空间,你想保存下来以后再用。 应该怎么做?计算机代数系统有以下几种方法保存个人的对象。
- 保存游戏: 仅仅支持保存和读取完整的会话(如,GAP,Magma)
- 统一的输入/输出:每一个对象都以可以读回来的方式打印(GP/PARI)。
- Eval: 在解释器中将它变成容易执行的代码(如,Singular, PARI)。
因为Sage使用的是Python,它用一种不同的方式实现,每一个对象都可以序列化,即,转换为字符串以便将来进行恢复。这跟PARI中统一I/O的想法是类似的,只是在屏幕输出时不那么复杂。保存和读取(在多数情况下)是自动进行的,不需要额外编程。这是Python从开始就支持的一个简单特性。
几乎所有的Sage对象x,都能用save(x, filename)
以压缩格式保存到磁盘上(或x.save(filename)
)。读取时使用load(filename)
。
sage: A = MatrixSpace(QQ,3)(range(9))^2
sage: A
[ 15 18 21]
[ 42 54 66]
[ 69 90 111]
sage: save(A, 'A')
你现在可以退出Sage并重启。然后可以把A
找回来:
sage: A = load('A')
sage: A
[ 15 18 21]
[ 42 54 66]
[ 69 90 111]
对于其他更复杂的对象,如椭圆曲线,也可以这么做。所有与对象有关的数据都会保存下来。
sage: E = EllipticCurve('11a')
sage: v = E.anlist(100000) # 这里需要花点时间
sage: save(E, 'E')
sage: quit
保存下来的E
有153KB,因为它保存了前100000个$a_n$.
~/tmp$ls -l E.sobj
-rw-r--r-- 1 was was 153500 2006-01-28 19:23 E.sobj
~/tmp$sage[...]
sage: E = load('E')
sage: v = E.anlist(100000) # 很快!
(在Python中,保存和读取是使用cPickle
模块实现的。特别的,一个Sage对象x
可以通过cPickle.dumps(x, 2)
保存。 注意2
!)
Sage不能保存和读取其他计算机代数系统创建的个人对象,如,GAP,Singular,Maxima等。它们重载时标记为”无效”状态。在GAP中,虽然很多对象的输出是一种可重构的形式,但是很多却不行,所以不能用它们的输出结果重构。
sage: a = gap(2)
sage: a.save('a')
sage: load('a')
Traceback (most recent call last):
...
ValueError: The session in which this object was defined is no longer
running.
GP/PARI的对象可以保存和读取,因为他们的输出形式足以重构。
sage: a = gp(2)
sage: a.save('a')
sage: load('a')
2
已保存的对象可以被不同的架构或操作系统的计算机读取,如,你可以在32位的OS X机上保存一个大的矩阵,并在64位的Linux机上重新读入,转为阶梯矩阵再移回去。多数情况下,你甚至可以使用不同版本的Sage读取已保存的对象,只要那个对象的代码差别不大。所有的属性与定义对象的类一起被保存下来(但不是源码)。如果那个类在新版的Sage中不存在,那么这个对象就不能在新版中被重新读取。但是你可以在老版本中读取,连同对象的字典(x.__dict__
)一起保存,再在新版中打开。
保存为纯文本
你可以把对象保存为ASCII文本格式,只需简单的打开一个文件并将字符串写入(很多对象都可以这么做)。写完之后再关闭文件。
sage: R.<x,y> = PolynomialRing(QQ,2)
sage: f = (x+y)^7
sage: o = open('file.txt','w')
sage: o.write(str(f))
sage: o.close()