In [73]:
Copied!
R1 = PolynomialRing(QQ, 'r')
R2 = QQ['r']
R1 == R2
# 这只是表示打印时使用'r',但此时不能够使用 'r' 作为变量名
# f = r ** 2 - 1 # NameError: name 'r' is not defined
# f, f.roots(), f.parent()
R1 = PolynomialRing(QQ, 'r')
R2 = QQ['r']
R1 == R2
# 这只是表示打印时使用'r',但此时不能够使用 'r' 作为变量名
# f = r ** 2 - 1 # NameError: name 'r' is not defined
# f, f.roots(), f.parent()
Out[73]:
True
In [74]:
Copied!
# 下面三行定义了 r1/r2/r3 变量,可以直接使用
R1.<r1> = PolynomialRing(QQ)
R2.<r2> = QQ['r2']
R3.<r3> = QQ[]
f1, f2, f3 = r1 ** 2 - 1, r2 ** 2 - 1, r3 ** 2 - 1
R2 == R3, R1.0, R2.0, R3.0, R1.gen(), R1.objgen()
# 只能够在 sagemath 中使用,python 使用如下
# 下面三行定义了 r1/r2/r3 变量,可以直接使用
R1. = PolynomialRing(QQ)
R2. = QQ['r2']
R3. = QQ[]
f1, f2, f3 = r1 ** 2 - 1, r2 ** 2 - 1, r3 ** 2 - 1
R2 == R3, R1.0, R2.0, R3.0, R1.gen(), R1.objgen()
# 只能够在 sagemath 中使用,python 使用如下
Out[74]:
(False, r1, r2, r3, r1, (Univariate Polynomial Ring in r1 over Rational Field, r1))
In [75]:
Copied!
from sage.all import *
S1 = PolynomialRing(QQ, 's1'); s1 = S1.gen(0) # 对于单变量多项式环,可以省略 0
S2 = QQ['s2']; s2 = S2.gen(0)
S3, s3 = QQ['s3'].objgen()
g2 = s2 ** 2 + s2 + 1
S1 == S2
from sage.all import *
S1 = PolynomialRing(QQ, 's1'); s1 = S1.gen(0) # 对于单变量多项式环,可以省略 0
S2 = QQ['s2']; s2 = S2.gen(0)
S3, s3 = QQ['s3'].objgen()
g2 = s2 ** 2 + s2 + 1
S1 == S2
Out[75]:
False
In [76]:
Copied!
# 随后就可创建多项式了
poly = (r1 - 1) * (r1 + 1)
poly, poly.roots(), poly.factor(), poly.parent(), poly in R1, poly in R2
# 随后就可创建多项式了
poly = (r1 - 1) * (r1 + 1)
poly, poly.roots(), poly.factor(), poly.parent(), poly in R1, poly in R2
Out[76]:
(r1^2 - 1, [(1, 1), (-1, 1)], (r1 - 1) * (r1 + 1), Univariate Polynomial Ring in r1 over Rational Field, True, False)
In [77]:
Copied!
# 常用来解多项式方程
X, x = ZZ['x'].objgen()
f = 2 * (x - 1) ** 2 * (x - 2) * (x - 3)
fac = f.factor()
f"{fac.unit()}, {list(fac)}", f"roots:{f.roots()}" # 返回一个元组列表,元组为(根,重数)
# 常用来解多项式方程
X, x = ZZ['x'].objgen()
f = 2 * (x - 1) ** 2 * (x - 2) * (x - 3)
fac = f.factor()
f"{fac.unit()}, {list(fac)}", f"roots:{f.roots()}" # 返回一个元组列表,元组为(根,重数)
Out[77]:
('1, [(2, 1), (x - 3, 1), (x - 2, 1), (x - 1, 2)]', 'roots:[(3, 1), (2, 1), (1, 2)]')
In [80]:
Copied!
g = (x - 1) * (x - 2) * (x - 3)
h = f/g
h, h.parent(), gcd(f, g)# h.roots() # AttributeError: 'sage.rings.fraction_field_element.FractionFieldElement' object has no attribute 'roots'
g = (x - 1) * (x - 2) * (x - 3)
h = f/g
h, h.parent(), gcd(f, g)# h.roots() # AttributeError: 'sage.rings.fraction_field_element.FractionFieldElement' object has no attribute 'roots'
Out[80]:
(2*(x^4 - 7*x^3 + 17*x^2 - 17*x + 6)/((x - 1)*(x - 2)*(x - 3)), Symbolic Ring, (x - 1)*(x - 2)*(x - 3))
In [92]:
Copied!
# 在密码学中常用 GF() 有限域;或者说 Zmod n 有限域
p = 2
n = 3
F, x = GF(p**n)['x'].objgen() # 或者直接 x = GF(p**n)['x'].gen()
f = (x - 6) * (x - 7) * (x - 8) * (x - 9) # = x^4 - 30*x^3 + 335*x^2 - 1650*x + 3024
f, f.factor(), f.roots()
# 在密码学中常用 GF() 有限域;或者说 Zmod n 有限域
p = 2
n = 3
F, x = GF(p**n)['x'].objgen() # 或者直接 x = GF(p**n)['x'].gen()
f = (x - 6) * (x - 7) * (x - 8) * (x - 9) # = x^4 - 30*x^3 + 335*x^2 - 1650*x + 3024
f, f.factor(), f.roots()
Out[92]:
(x^4 + x^2, x^2 * (x + 1)^2, [(0, 2), (1, 2)])
In [ ]:
Copied!
# 寻找小根,使用 coppersmith & LLL 算法
N = 10001
K = Zmod(10001)
P.<x> = PolynomialRing(K, implementation='NTL')
f = x^3 + 10*x^2 + 5000*x - 222
f.small_roots() # 返回最小的根
# 寻找小根,使用 coppersmith & LLL 算法
N = 10001
K = Zmod(10001)
P. = PolynomialRing(K, implementation='NTL')
f = x^3 + 10*x^2 + 5000*x - 222
f.small_roots() # 返回最小的根
Out[ ]:
[4]
In [2]:
Copied!
# 发现新的创建多项式生成元的写法
x = polygen(GF(7))
f = (x**3 + x - 2).monic()
f.roots()
# 发现新的创建多项式生成元的写法
x = polygen(GF(7))
f = (x**3 + x - 2).monic()
f.roots()
Out[2]:
[(1, 1), (3, 2)]
Multivariate Polynomials¶
多元多项式的创建与单元多项式基本一致,只是需要指定变量的个数。
In [71]:
Copied!
# 在 sage / python 中可以
R = PolynomialRing(GF(2), 3, 'a')
S = PolynomialRing(GF(2), 3, 'abc') # 这样只能够创建单字母变量,字母数与变量数要相同
T= PolynomialRing(GF(2), 3, 'ab')# 否则会当作一整个变量名
R.gens(), S.gens(), T.gens()
# 在 sage / python 中可以
R = PolynomialRing(GF(2), 3, 'a')
S = PolynomialRing(GF(2), 3, 'abc') # 这样只能够创建单字母变量,字母数与变量数要相同
T= PolynomialRing(GF(2), 3, 'ab')# 否则会当作一整个变量名
R.gens(), S.gens(), T.gens()
Out[71]:
((a0, a1, a2), (a, b, c), (ab0, ab1, ab2))
In [ ]:
Copied!
# 或者在 sage 中
F.<r1, r2, r3> = GF(2)[]
assert (r1, r2, r3) == F.gens()
# 或者在 sage 中
F. = GF(2)[]
assert (r1, r2, r3) == F.gens()
In [66]:
Copied!
# 在 python 中只能
G, s = GF(7)['s0, s1, s2'].objgens()
assert s == G.gens() == (s[0], s[1], s[2]) # == (s0, s1, s2) # NameError: name 'S0' is not defined
# 在 python 中只能
G, s = GF(7)['s0, s1, s2'].objgens()
assert s == G.gens() == (s[0], s[1], s[2]) # == (s0, s1, s2) # NameError: name 'S0' is not defined
Normal polynomials solver¶
In [88]:
Copied!
var('x y z') # Declare symbolic variables
poly = x^2 + y^2 + z^2 - 1
poly.roots(), solve(poly, x, y, z)
var('x y z') # Declare symbolic variables
poly = x^2 + y^2 + z^2 - 1
poly.roots(), solve(poly, x, y, z)
Out[88]:
([(-sqrt(-y^2 - z^2 + 1), 1), (sqrt(-y^2 - z^2 + 1), 1)], [[x == r21, y == r22, z == sqrt(-r21^2 - r22^2 + 1)], [x == r23, y == r24, z == -sqrt(-r23^2 - r24^2 + 1)]])