SageMath 多项式

archive time: 2024-09-06

代数运算好难啊

对于多项式,根据其中变量的个数,可以分为 单变量多项式(Univariate Polynomials)多变量多项式(Multivariate Polynomials)

单变量多项式

我们一般可以通过 PolynomialRing() 函数来构造多项式环

R = PolynomialRing(QQ, "t")
R
# => Univariate Polynomial Ring in t over Rational Field

获取生成元

多项式的 生成元1t,但是要注意,这里并没有定义符号 t,所以是不能够直接使用的

下面是一种等价写法:

R = QQ["t"]
R
# => Univariate Polynomial Ring in t over Rational Field

如果想要在定义多项式环的同时定义在这个环上的生成元 t,可以使用如下的方式:

R.<t> = QQ[]
(R, t)
# => (Univariate Polynomial Ring in t over Rational Field, t)

或者可以使用 R.0R.gen(0) 的方式得到

t1 = R.gen(0)
assert(t == t1)
assert(t1 in R)

还有其他的方式可以获取多项式环上的生成元,可以参考 这个文档

除了有理数,复数域 也有对应生成元,即虚数单位

assert(CC.gen(0) == I)

相关计算

对于多项式环 R 和获取到的生成元 t,我们可以当成一般的符号变量来运算,例如利用 t 来构造一个多项式:

R, t = QQ['t'].objgen()
f = 2*t^7 + 3*t^2 - 15/19
f^2
# =>
# 4*t^14 + 12*t^9 - 60/19*t^7 + 9*t^4 - 90/19*t^2 + 225/361

其中 objgen() 会返回多项式环以及对应的生成元

对于多项式环,我们还可以使用一些内置函数来构造多项式, 例如可以使用 cyclotomic_polynomial() 来构造循环多项式:

cyclo = R.cyclotomic_polynomial(7)
cyclo
# =>
# t^6 + t^5 + t^4 + t^3 + t^2 + t + 1

对于多项式本身,我们还可以进一步操作:

g = 7 * cyclo * t^5 * (t^5 + 10*t + 2)
g
# =>
# 7*t^16 + 7*t^15 + 7*t^14 + 7*t^13 + 77*t^12 + 91*t^11
#  + 91*t^10 + 84*t^9 + 84*t^8 + 84*t^7 + 84*t^6 + 14*t^5

对于多项式的常见操作,例如因式分解,SageMath 也是支持的:

F = factor(g)
F
# =>
# (7) * t^5 * (t^5 + 10*t + 2) * (t^6 + t^5 + t^4 + t^3 + t^2 + t + 1)

其中分解后的常数项被称为多项式的 unit,对于分解的结果,我们可以通过 list() 转换成列表,从而获取每一项的值:

(F.unit(), list(F))
# =>
# (7, [(t, 5), (t^5 + 10*t + 2, 1), (t^6 + t^5 + t^4 + t^3 + t^2 + t + 1, 1)])

不过要注意,SageMath 很多函数实际上是其他工具暴露出来的一个计算接口,我们可以通过 <object-name>?? 的方式查看实现, 例如 cyclotomic_polynomial() 函数,SageMath 内部就是调用 sage.rings.polynomial.cyclotomic.cyclotomic_coeffs(), 再进一步查看就会发现实际上调用的是 PARI/GPpari.polcyclo() 函数,这也说明了 SageMath 是一个基于各个开源计算社区的工具,是集大成者

对于多项式除法,默认情况下 SageMath 会把结果变成 分式域(Fractional Field)2,这样保证数学的准确和严谨性

x = QQ['x'].gen(0)
f = x^3 + 1
g = x^2 - 17
h = f/g
(h, f.parent(), g.parent(), h.parent())
# =>
# ((x^3 + 1)/(x^2 - 17),
#  Univariate Polynomial Ring in x over Rational Field,
#  Univariate Polynomial Ring in x over Rational Field,
#  Fraction Field of Univariate Polynomial Ring in x over Rational Field)

所谓分式域,是指对于一个 整环(integeral domain),最小的能够进行除法操作的一个域, 即 , 其中 就是整环,而 则是 中的所有非零元素构成的集合, 就是对应的分式域

而整环就是一个环,并且对于非零元素 满足对于任意两个元素 ,满足

通过使用洛朗级数,我们还可以在有理数系数的多项式环 的分式域中计算出幂级数展开:

R.<x> = LaurentSeriesRing(QQ)
(R, 1 / (1 - x) + O(x^8))
# =>
# (Laurent Series Ring in x over Rational Field,
#  1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + O(x^8))

洛朗级数环就是表示 这样的一个级数对应的多项式, 具体的使用可以参考 洛朗级数环洛朗级数 这两篇文档

一般函数展开都是使用泰勒展开,即 taylor() 或者 series() 函数

对于单变量的多项式环,不同的环和对应生成器,都是不同的:

A.<x> = QQ["x"]
B.<y> = QQ["y"]
assert(A != B)
assert(x != y)

通过对应的多项式环,可以将生成元变为环所对应的生成元:

(A(y), A(y^2 - 17))
# => (x, x^2 - 17)

实际上,环的区分是通过对应生成器的名称,也就是说对于两个生成器都是 x 的环,那么这两个环相等:

A = QQ["x"]
B = QQ["x"]
assert(A == B)
assert(A is B)

类似洛朗级数环,SageMath 中还有一个专门的幂级数环,对应泰勒展开, 与洛朗级数的不同之处在于洛朗级数的 是从 , 而幂级数的 是从

R.<t> = PowerSeriesRing(GF(7))
s = t + 3*t^2 + t^3 + O(t^4)
(R, 1/s, (1/s).parent())
# =>
# (Power Series Ring in t over Finite Field of size 7,
#  t^-1 + 4 + t + O(t^2),
#  Laurent Series Ring in t over Finite Field of size 7)

对于幂级数环,可以简单的使用两个方括号来构建:

GF(7)[["T"]]
# => Power Series Ring in T over Finite Field of size 7

多变量多项式

多变量多项式和单变量多项式最大的区别就是变量个数, 对于多变量多项式,可以通过指定多个变量来构建:

PolynomialRing(GF(5), 3, "z")
# => Multivariate Polynomial Ring in z0, z1, z2 over Finite Field of size 5

除了直接说有多少个变量,我们也可以通过类似 var() 函数的方式来构建:

R.<z0, z1, z2> = GF(5)[]
(GF(5)["z0, z1, z2"], R)
# =>
# (Multivariate Polynomial Ring in z0, z1, z2 over Finite Field of size 5,
#  Multivariate Polynomial Ring in z0, z1, z2 over Finite Field of size 5)

这些生成元可以通过类似单生成元的方式, 即使用 gens()objgens() 以及类似 R.<x, y, z> 的方式来获得

SageMath 中的多元多项式使用的是 Python 的字典以及使用了 分配表示 的方式, 其中键一般存储为对应变量的指数,例如 就可能表示为 (2, 4), 而对应的值一般是其系数,即 对应的就是 8

有些情况下,SageMath 会使用到 Singular 来计算, 例如 gcd()

R, (x, y) = PolynomialRing(RationalField(), 2, "x, y").objgens()
f = (x^3 + 2 * y^2 * x)^2
g = x^2 * y^2
f.gcd(g)
# => x^2

SageMath 还有许多例如交换代数的相关实现,具体的还需要仔细查看文档,了解函数的使用

后记

这算是最后一篇基础的 SageMath 内容笔记, 展现了 SageMath 对于代数中非常重要的内容,即多项式,的处理方法, 以及展现了 SageMath 在实现相关功能上的细节

SageMath 确实是一个不错的 CAS, 不过 SageMath 包含了太多工具,每个工具都是独立的开源项目, 这就导致了 SageMath 无法很好有效的管理其依赖,包括依赖的版本,以及依赖的依赖项, 这导致了 SageMath 中有可能会出现由于原项目版本更新修复的问题在 SageMath 中仍然存在, 其次就是编译安装时总是会有各种问题,提示依赖错误,或者由于编译器版本导致编译不通过

但是以上的问题都是小问题,基本都有对应的解决方法, 相信 SageMath 随着社区的完善和软件的迭代,越来越完善


1

Subring.Wikipedia [DB/OL].(2024-08-22)[2024-09-06]. https://en.wikipedia.org/wiki/Subring#Subring_generated_by_a_set

2

Field of fractions.Wikipedia [DB/OL].(2024-04-17)[2024-09-06]. https://en.wikipedia.org/wiki/Field_of_fractions

3

Integral domain.Wikipedia [DB\OL].(2024-06-23)[2024-09-06]. https://en.wikipedia.org/wiki/Integral_domain