Field extensions
Messages
Example 1, splitting field over Q
# Polynomial in Q[x]
var('x')
R.<x> = QQ[]
f = R(x^3 -7*x +7)
Messages
f.factor()
x^3 - 7*x + 7
Messages
# E = field simple field extension
E = R.quotient_by_principal_ideal(ideal(f))
E
Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^3 - 7*x + 7
Messages
E.is_field()
True
Messages
alpha = E(x)
alpha
xbar
Messages
alpha.minpoly()
x^3 - 7*x + 7
Messages
F = f.change_ring(E)
F
x^3 - 7*x + 7
Messages
# S = E[x]
S=F.parent()
S
Univariate Polynomial Ring in x over Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^3 - 7*x + 7
Messages
F.factor()
(x - xbar) * (x - 3*xbar^2 - 4*xbar + 14) * (x + 3*xbar^2 + 5*xbar - 14)
Messages
# So f(x) splits over E
Messages
E.degree()
3
Messages
f.discriminant()
49
Messages
Messages
Messages
Messages
Example 2, another splitting field over Q
# Change the example slightly
var('x')
R.<x> = QQ[]
f = R(x^3 -7*x +8)
f.discriminant()
-356
Messages
# E = field simple field extension
E = R.quotient_by_principal_ideal(ideal(f))
E
Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^3 - 7*x + 8
Messages
alpha = E(x)
alpha
xbar
Messages
Messages
alpha.minpoly()
x^3 - 7*x + 8
Messages
Messages
F = f.change_ring(E)
F
x^3 - 7*x + 8
Messages
Messages
# S = E[x]
S=F.parent()
S
Univariate Polynomial Ring in x over Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^3 - 7*x + 8
Messages
Messages
F.factor()
(x - xbar) * (x^2 + xbar*x + xbar^2 - 7)
Messages
Messages
# So f does not split over E
Messages
g = F.factor()[1][0]
g
x^2 + xbar*x + xbar^2 - 7
Messages
Messages
Messages
K = S.quotient_by_principal_ideal(ideal(g))
K
Univariate Quotient Polynomial Ring in xbar over Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^3 - 7*x + 8 with modulus x^2 + xbar*x + xbar^2 - 7
Messages
K.is_field()
True
Messages
Messages
F2 = f.change_ring(K)
F2
G = g.change_ring(K)
F2, G
(x^3 - 7*x + 8, x^2 + xbar*x + xbar^2 - 7)
Messages
# does not work
F2.factor()
--------------------------------------------------------------------------- NotImplementedError Traceback (most recent call last) /tmp/ipykernel_1906302/2714016358.py in <cell line: 2>() 1 # does not work ----> 2 F2.factor() ~/.conda/envs/sage/lib/python3.9/site-packages/sage/rings/polynomial/polynomial_element.pyx in sage.rings.polynomial.polynomial_element.Polynomial.factor (build/cythonized/sage/rings/polynomial/polynomial_element.c:35912)() 4348 R = self._parent.base_ring() 4349 if hasattr(R, '_factor_univariate_polynomial'): -> 4350 return R._factor_univariate_polynomial(self, **kwargs) 4351 4352 G = None ~/.conda/envs/sage/lib/python3.9/site-packages/sage/rings/polynomial/polynomial_quotient_ring.py in _factor_univariate_polynomial(self, f) 1800 return Factorization([(f,1)], unit=unit) 1801 else: -> 1802 from_isomorphic_ring, to_isomorphic_ring, isomorphic_ring = self._isomorphic_ring() 1803 g = f.map_coefficients(to_isomorphic_ring) 1804 F = g.factor() ~/.conda/envs/sage/lib/python3.9/site-packages/sage/misc/cachefunc.pyx in sage.misc.cachefunc.CachedMethodCallerNoArgs.__call__ (build/cythonized/sage/misc/cachefunc.c:12999)() 2308 if self.cache is None: 2309 f = self.f -> 2310 self.cache = f(self._instance) 2311 return self.cache 2312 ~/.conda/envs/sage/lib/python3.9/site-packages/sage/rings/polynomial/polynomial_quotient_ring.py in _isomorphic_ring(self) 1862 1863 # recursively try to rewrite the isomorphic_quotient -> 1864 isomorphic_ring_to_isomorphic_quotient, isomorphic_quotient_to_isomorphic_ring, isomorphic_ring = isomorphic_quotient._isomorphic_ring() 1865 1866 # the process has likely refined the category of ~/.conda/envs/sage/lib/python3.9/site-packages/sage/misc/cachefunc.pyx in sage.misc.cachefunc.CachedMethodCallerNoArgs.__call__ (build/cythonized/sage/misc/cachefunc.c:12999)() 2308 if self.cache is None: 2309 f = self.f -> 2310 self.cache = f(self._instance) 2311 return self.cache 2312 ~/.conda/envs/sage/lib/python3.9/site-packages/sage/rings/polynomial/polynomial_quotient_ring.py in _isomorphic_ring(self) 1955 return from_isomorphic_ring, to_isomorphic_ring, isomorphic_ring 1956 -> 1957 raise NotImplementedError("cannot rewrite %r as an isomorphic ring"%(self,)) 1958 1959 def _test_isomorphic_ring(self, **options): NotImplementedError: cannot rewrite Univariate Quotient Polynomial Ring in xbar over Number Field in xbar with defining polynomial x^3 - 7*x + 8 with modulus x^2 + xbar*x + xbar^2 - 7 as an isomorphic ring
Messages
Messages
# This works:
L.<y> = NumberField(f)
L
Number Field in y with defining polynomial x^3 - 7*x + 8
Messages
L.degree()
3
Messages
Messages
F = f.change_ring(L)
F.factor()
(x - y) * (x^2 + y*x + y^2 - 7)
Messages
Messages
g = F.factor()[1][0]
g
x^2 + y*x + y^2 - 7
Messages
Messages
K.<z> = L.extension(g)
K
Number Field in z with defining polynomial x^2 + y*x + y^2 - 7 over its base field
Messages
Messages
K.relative_degree()
2
Messages
Messages
K.absolute_degree()
6
Messages
Messages
FF = f.change_ring(K)
FF
x^3 - 7*x + 8
Messages
Messages
Messages
FF.factor()
(x - z) * (x - y) * (x + z + y)
Messages
# Cheat:
SF.<u> = f.splitting_field()
SF
Number Field in u with defining polynomial x^6 + 253*x^4 + 16*x^3 + 23812*x^2 - 4384*x + 820288
Messages
Messages
f.change_ring(SF).factor()
(x - 5/14952*u^5 + 1/3738*u^4 - 279/4984*u^3 + 517/3738*u^2 - 5374/1869*u + 3232/267) * (x + 121/2810976*u^5 + 1/702744*u^4 + 11495/936992*u^3 + 769/702744*u^2 + 527713/702744*u - 3007/25098) * (x + 39/133856*u^5 - 9/33464*u^4 + 5851/133856*u^3 - 4665/33464*u^2 + 71091/33464*u - 100267/8366)
Messages
Messages
Messages
Messages
Messages
Messages
Messages
Messages
Extensions of finite fields
Z2 = GF(2)
R.<x> = Z2[]
f=x^3+x+1
f.factor()
x^3 + x + 1
Messages
F = GF(2^3,name='a',modulus=f)
F
Finite Field in a of size 2^3
Messages
for b in F:
print(b)
0 a a^2 a + 1 a^2 + a a^2 + a + 1 a^2 + 1 1
Messages
fl = f.change_ring(F)
fl
x^3 + x + 1
Messages
# f splits in F
fl.factor()
(x + a) * (x + a^2) * (x + a^2 + a)
Messages
# We study the difference eqn s(n+3) = s(n+1)+s(n), s(0)=1, s(1)=s(2)=0
Messages
# method 1, direct
def s(n):
if (n==0):
return Z2(1)
elif(n==1):
return Z2(0)
elif(n==2):
return Z2(0)
else:
return(Z2(s(n-2)+s(n-3)))
Messages
[(n,s(n)) for n in range(20)]
[(0, 1), (1, 0), (2, 0), (3, 1), (4, 0), (5, 1), (6, 1), (7, 1), (8, 0), (9, 0), (10, 1), (11, 0), (12, 1), (13, 1), (14, 1), (15, 0), (16, 0), (17, 1), (18, 0), (19, 1)]
Messages
# Periodic with period 2^3-1, as expected
Messages
# Method 2: images in the quotient
a=F.gen()
a,a^12
(a, a^2 + a + 1)
Messages
[(n,a^n) for n in range(20)]
[(0, 1), (1, a), (2, a^2), (3, a + 1), (4, a^2 + a), (5, a^2 + a + 1), (6, a^2 + 1), (7, 1), (8, a), (9, a^2), (10, a + 1), (11, a^2 + a), (12, a^2 + a + 1), (13, a^2 + 1), (14, 1), (15, a), (16, a^2), (17, a + 1), (18, a^2 + a), (19, a^2 + a + 1)]
Messages
# What are the constant terms?
R.<a> = Z2[]
R(F.gen()^10)
a + 1
Messages
R(F.gen()^10).subs(a=0)
1
Messages
[(n,R(F.gen()^n).subs(a=0)) for n in range(20)]
[(0, 1), (1, 0), (2, 0), (3, 1), (4, 0), (5, 1), (6, 1), (7, 1), (8, 0), (9, 0), (10, 1), (11, 0), (12, 1), (13, 1), (14, 1), (15, 0), (16, 0), (17, 1), (18, 0), (19, 1)]
Messages
# Method 3: mult with a is a linear map, find its matrix
A = companion_matrix(f)
A
[0 0 1] [1 0 1] [0 1 0]
Messages
v = vector([Z2(1),Z2(0),Z2(0)])
v
(1, 0, 0)
Messages
# read first component
[(n,A^n*v) for n in range(20)]
[(0, (1, 0, 0)), (1, (0, 1, 0)), (2, (0, 0, 1)), (3, (1, 1, 0)), (4, (0, 1, 1)), (5, (1, 1, 1)), (6, (1, 0, 1)), (7, (1, 0, 0)), (8, (0, 1, 0)), (9, (0, 0, 1)), (10, (1, 1, 0)), (11, (0, 1, 1)), (12, (1, 1, 1)), (13, (1, 0, 1)), (14, (1, 0, 0)), (15, (0, 1, 0)), (16, (0, 0, 1)), (17, (1, 1, 0)), (18, (0, 1, 1)), (19, (1, 1, 1))]
Messages
# method 4: general formula
# s(n) = c0*r0^n + c1*r1^n + c2*r2^n
Messages
r=fl.roots()
r
[(a, 1), (a^2, 1), (a^2 + a, 1)]
Messages
r0 = r[0][0]
r1=r[1][0]
r2 = r[2][0]
r0,r1,r2
(a, a^2, a^2 + a)
Messages
R.<c0,c1,c2> = F[]
Messages
R
Multivariate Polynomial Ring in c0, c1, c2 over Finite Field in a of size 2^3
Messages
I = ideal(c0*1+ c1*1+c2*1-1, c0*r0 + c1*r1+c2*r2-0, c0*r0^2 + c1*r1^2 + c2*r2^2-0)
I
Ideal (c0 + c1 + c2 + 1, a*c0 + (a^2)*c1 + (a^2 + a)*c2, (a^2)*c0 + (a^2 + a)*c1 + a*c2) of Multivariate Polynomial Ring in c0, c1, c2 over Finite Field in a of size 2^3
Messages
I.variety()
[{c2: 1, c1: 1, c0: 1}]
Messages
[(n,1*r0^n+1*r1^n + 1*r2^n) for n in range(20)]
[(0, 1), (1, 0), (2, 0), (3, 1), (4, 0), (5, 1), (6, 1), (7, 1), (8, 0), (9, 0), (10, 1), (11, 0), (12, 1), (13, 1), (14, 1), (15, 0), (16, 0), (17, 1), (18, 0), (19, 1)]
Messages
# Method 4: formal power series
fl
x^3 + x + 1
Messages
R=fl.parent()
R
Univariate Polynomial Ring in x over Finite Field in a of size 2^3
Messages
fr = (x-1/r0)*(x-1/r1)*(x-1/r2)
fr
x^3 + x^2 + 1
Messages
S.<x> = PowerSeriesRing(F)
S
Power Series Ring in x over Finite Field in a of size 2^3
Messages
S(1/fr)
1 + x^2 + x^3 + x^4 + x^7 + x^9 + x^10 + x^11 + x^14 + x^16 + x^17 + x^18 + O(x^20)
Messages
# s(n) is one for 0,3,5,6,7,10,12,13,14,17,19...
Messages
G=fr.parent()((1+x^2))/fr
G
(x^2 + 1)/(x^3 + x^2 + 1)
Messages
S(G)
1 + x^3 + x^5 + x^6 + x^7 + x^10 + x^12 + x^13 + x^14 + x^17 + x^19 + O(x^20)
Messages
G.partial_fraction_decomposition()
(0, [(a + 1)/(x + a + 1), (a^2 + 1)/(x + a^2 + 1), (a^2 + a + 1)/(x + a^2 + a + 1)])
Messages
# Explicit formula for generating function
Messages
# Given initial segment, we can guess general sequence
Messages
def partialseries(n):
return(add(s(k)*S(x^k) for k in range(n)))
Messages
partialseries(10)
1 + x^3 + x^5 + x^6 + x^7
Messages
# now we guess...
p10=partialseries(10)
p10.pade(3,3)
(x^2 + 1)/(x^3 + x^2 + 1)
Messages
#already correct!
Messages
Messages
Messages
Messages
Messages
Messages
Messages
Messages
Messages
Messages
Messages
Messages
# Larger example, mod 3
Z3 = GF(3)
R.<t> = Z3[]
f = t^5+2*t+1
f.factor()
t^5 + 2*t + 1
Messages
F = GF(3^5,name='a',modulus=f)
F
Finite Field in a of size 3^5
Messages
A = companion_matrix(f)
A
[0 0 0 0 2] [1 0 0 0 1] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0]
Messages
#initial conditions
v = vector([Z3(1),Z3(0),Z3(0),Z3(1),Z3(1)])
v
(1, 0, 0, 1, 1)
Messages
# probably periodic with period 3^5 -1, to large to list
[(A^n*v)[0] for n in range(20)]
[1, 2, 2, 0, 0, 1, 0, 1, 0, 1, 2, 1, 2, 1, 1, 2, 1, 2, 0, 1]
Messages
S.<x> = PowerSeriesRing(F)
Messages
partial20 = add([x^n*(A^n*v)[0] for n in range(20)])
partial20
1 + 2*x + 2*x^2 + x^5 + x^7 + x^9 + 2*x^10 + x^11 + 2*x^12 + x^13 + x^14 + 2*x^15 + x^16 + 2*x^17 + x^19
Messages
S(partial20).pade(3,3)
(2*x^3 + x^2 + 2*x + 1)/(x^3 + 2*x^2 + 1)
Messages
f
t^5 + 2*t + 1
Messages
S(add([x^n*(A^n*v)[0] for n in range(40)])).pade(3,3)
(2*x^3 + x^2 + 2*x + 1)/(x^3 + 2*x^2 + 1)
Messages
S(add([x^n*(A^n*v)[0] for n in range(40)])).pade(4,4)
(2*x^3 + x^2 + 2*x + 1)/(x^3 + 2*x^2 + 1)
Messages
probablytrueres = S(add([x^n*(A^n*v)[0] for n in range(40)])).pade(4,4)
probablytrueres.partial_fraction_decomposition()
(2, [(2*x + 2)/(x^3 + 2*x^2 + 1)])
Messages
pfn=probablytrueres.numerator().change_ring(F)
pfn
2*x^3 + x^2 + 2*x + 1
Messages
pfd=probablytrueres.denominator().change_ring(F)
pfd
x^3 + 2*x^2 + 1
Messages
pfn.change_ring(F)
2*x^3 + x^2 + 2*x + 1
Messages
(pfn.change_ring(F)/pfd.change_ring(F)).partial_fraction_decomposition()
(2, [(2*x + 2)/(x^3 + 2*x^2 + 1)])
Messages
F
Finite Field in a of size 3^5
Messages
pfd.change_ring(F).factor()
x^3 + 2*x^2 + 1
Messages
G.<c> = pfd.splitting_field()
G
Finite Field in c of size 3^15
Messages
(pfn.change_ring(G)/pfd.change_ring(G)).partial_fraction_decomposition()
(2, [(2*c^14 + c^13 + c^12 + 2*c^11 + c^10 + 2*c^9 + 2*c^8 + 2*c^7 + 2*c^4 + 2*c + 2)/(x + c^13 + 2*c^12 + c^9 + c^8 + 2*c^6 + 2*c^5 + c^3 + 2*c + 2), (2*c^14 + c^13 + c^12 + 2*c^11 + c^10 + 2*c^9 + 2*c^8 + 2*c^7 + 2*c^4 + 2*c)/(x + c^14 + c^12 + c^11 + 2*c^10 + 2*c^9 + 2*c^8 + c^7 + 2*c^6 + 2*c^5 + c^4 + c^3), (2*c^14 + c^13 + c^12 + 2*c^11 + c^10 + 2*c^9 + 2*c^8 + 2*c^7 + 2*c^4 + 2*c + 1)/(x + 2*c^14 + 2*c^13 + 2*c^11 + c^10 + 2*c^7 + 2*c^6 + 2*c^5 + 2*c^4 + c^3 + c)])
Messages
# This is your "explicit" formula...
Messages
Messages
Messages
Messages
Messages
Messages
Messages
Messages
Messages