Univariate Polynomials over GF(p^e) via NTL’s ZZ_pEX¶
AUTHOR:
- Yann Laigle-Chapuy (2010-01) initial implementation 
- Lorenz Panny (2023-01): - minpoly_mod()
- Giacomo Pope (2023-08): - reverse(),- inverse_series_trunc()
- class sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX[source]¶
- Bases: - Polynomial_template- Univariate Polynomials over \(\GF{p^n}\) via NTL’s - ZZ_pEX.- EXAMPLES: - sage: K.<a> = GF(next_prime(2**60)**3) sage: R.<x> = PolynomialRing(K, implementation='NTL') sage: (x^3 + a*x^2 + 1) * (x + a) x^4 + 2*a*x^3 + a^2*x^2 + x + a - >>> from sage.all import * >>> K = GF(next_prime(Integer(2)**Integer(60))**Integer(3), names=('a',)); (a,) = K._first_ngens(1) >>> R = PolynomialRing(K, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> (x**Integer(3) + a*x**Integer(2) + Integer(1)) * (x + a) x^4 + 2*a*x^3 + a^2*x^2 + x + a - compose_mod(other, modulus)[source]¶
- Compute \(f(g) \bmod h\). - To be precise about the order fo compostion, given - self,- otherand- modulusas \(f(x)\), \(g(x)\) and \(h(x)\) compute \(f(g(x)) \bmod h(x)\).- INPUT: - other– a polynomial \(g(x)\)
- modulus– a polynomial \(h(x)\)
 - EXAMPLES: - sage: R.<x> = GF(3**6)[] sage: f = R.random_element() sage: g = R.random_element() sage: g.compose_mod(g, f) == g(g) % f True sage: F.<z3> = GF(3**6) sage: R.<x> = F[] sage: f = 2*z3^2*x^2 + (z3 + 1)*x + z3^2 + 2 sage: g = (z3^2 + 2*z3)*x^2 + (2*z3 + 2)*x + 2*z3^2 + z3 + 2 sage: h = (2*z3 + 2)*x^2 + (2*z3^2 + 1)*x + 2*z3^2 + z3 + 2 sage: f.compose_mod(g, h) (z3^5 + z3^4 + z3^3 + z3^2 + z3)*x + z3^5 + z3^3 + 2*z3 + 2 sage: f.compose_mod(g, h) == f(g) % h True - >>> from sage.all import * >>> R = GF(Integer(3)**Integer(6))['x']; (x,) = R._first_ngens(1) >>> f = R.random_element() >>> g = R.random_element() >>> g.compose_mod(g, f) == g(g) % f True >>> F = GF(Integer(3)**Integer(6), names=('z3',)); (z3,) = F._first_ngens(1) >>> R = F['x']; (x,) = R._first_ngens(1) >>> f = Integer(2)*z3**Integer(2)*x**Integer(2) + (z3 + Integer(1))*x + z3**Integer(2) + Integer(2) >>> g = (z3**Integer(2) + Integer(2)*z3)*x**Integer(2) + (Integer(2)*z3 + Integer(2))*x + Integer(2)*z3**Integer(2) + z3 + Integer(2) >>> h = (Integer(2)*z3 + Integer(2))*x**Integer(2) + (Integer(2)*z3**Integer(2) + Integer(1))*x + Integer(2)*z3**Integer(2) + z3 + Integer(2) >>> f.compose_mod(g, h) (z3^5 + z3^4 + z3^3 + z3^2 + z3)*x + z3^5 + z3^3 + 2*z3 + 2 >>> f.compose_mod(g, h) == f(g) % h True - AUTHORS: - Giacomo Pope (2024-08) initial implementation 
 
 - inverse_series_trunc(prec)[source]¶
- Compute and return the inverse of - selfmodulo \(x^{prec}\).- The constant term of - selfmust be invertible.- EXAMPLES: - sage: R.<x> = GF(101^2)[] sage: z2 = R.base_ring().gen() sage: f = (3*z2 + 57)*x^3 + (13*z2 + 94)*x^2 + (7*z2 + 2)*x + 66*z2 + 15 sage: f.inverse_series_trunc(1) 51*z2 + 92 sage: f.inverse_series_trunc(2) (30*z2 + 30)*x + 51*z2 + 92 sage: f.inverse_series_trunc(3) (42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92 sage: f.inverse_series_trunc(4) (99*z2 + 96)*x^3 + (42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92 - >>> from sage.all import * >>> R = GF(Integer(101)**Integer(2))['x']; (x,) = R._first_ngens(1) >>> z2 = R.base_ring().gen() >>> f = (Integer(3)*z2 + Integer(57))*x**Integer(3) + (Integer(13)*z2 + Integer(94))*x**Integer(2) + (Integer(7)*z2 + Integer(2))*x + Integer(66)*z2 + Integer(15) >>> f.inverse_series_trunc(Integer(1)) 51*z2 + 92 >>> f.inverse_series_trunc(Integer(2)) (30*z2 + 30)*x + 51*z2 + 92 >>> f.inverse_series_trunc(Integer(3)) (42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92 >>> f.inverse_series_trunc(Integer(4)) (99*z2 + 96)*x^3 + (42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92 
 - is_irreducible(algorithm='fast_when_false', iter=1)[source]¶
- Return - Trueprecisely when- selfis irreducible over its base ring.- INPUT: - algorithm– string (default:- 'fast_when_false'); there are 3 available algorithms:- 'fast_when_true',- 'fast_when_false', and- 'probabilistic'
- iter– (default: 1) if the algorithm is- 'probabilistic', defines the number of iterations. The error probability is bounded by \(q^{\text{-iter}}\) for polynomials in \(\GF{q}[x]\).
 - EXAMPLES: - sage: K.<a> = GF(next_prime(2**60)**3) sage: R.<x> = PolynomialRing(K, implementation='NTL') sage: P = x^3 + (2-a)*x + 1 sage: P.is_irreducible(algorithm='fast_when_false') True sage: P.is_irreducible(algorithm='fast_when_true') True sage: P.is_irreducible(algorithm='probabilistic') True sage: Q = (x^2+a)*(x+a^3) sage: Q.is_irreducible(algorithm='fast_when_false') False sage: Q.is_irreducible(algorithm='fast_when_true') False sage: Q.is_irreducible(algorithm='probabilistic') False - >>> from sage.all import * >>> K = GF(next_prime(Integer(2)**Integer(60))**Integer(3), names=('a',)); (a,) = K._first_ngens(1) >>> R = PolynomialRing(K, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> P = x**Integer(3) + (Integer(2)-a)*x + Integer(1) >>> P.is_irreducible(algorithm='fast_when_false') True >>> P.is_irreducible(algorithm='fast_when_true') True >>> P.is_irreducible(algorithm='probabilistic') True >>> Q = (x**Integer(2)+a)*(x+a**Integer(3)) >>> Q.is_irreducible(algorithm='fast_when_false') False >>> Q.is_irreducible(algorithm='fast_when_true') False >>> Q.is_irreducible(algorithm='probabilistic') False 
 - list(copy=True)[source]¶
- Return the list of coefficients. - EXAMPLES: - sage: K.<a> = GF(5^3) sage: P = PolynomialRing(K, 'x') sage: f = P.random_element(100) sage: f.list() == [f[i] for i in range(f.degree()+1)] True sage: P.0.list() [0, 1] - >>> from sage.all import * >>> K = GF(Integer(5)**Integer(3), names=('a',)); (a,) = K._first_ngens(1) >>> P = PolynomialRing(K, 'x') >>> f = P.random_element(Integer(100)) >>> f.list() == [f[i] for i in range(f.degree()+Integer(1))] True >>> P.gen(0).list() [0, 1] 
 - minpoly_mod(other)[source]¶
- Compute the minimal polynomial of this polynomial modulo another polynomial in the same ring. - ALGORITHM: - NTL’s - MinPolyMod(), which uses Shoup’s algorithm [Sho1999].- EXAMPLES: - sage: R.<x> = GF(101^2)[] sage: f = x^17 + x^2 - 1 sage: (x^2).minpoly_mod(f) x^17 + 100*x^2 + 2*x + 100 - >>> from sage.all import * >>> R = GF(Integer(101)**Integer(2))['x']; (x,) = R._first_ngens(1) >>> f = x**Integer(17) + x**Integer(2) - Integer(1) >>> (x**Integer(2)).minpoly_mod(f) x^17 + 100*x^2 + 2*x + 100 
 - modular_composition(other, modulus)[source]¶
- Compute \(f(g) \bmod h\). - To be precise about the order fo compostion, given - self,- otherand- modulusas \(f(x)\), \(g(x)\) and \(h(x)\) compute \(f(g(x)) \bmod h(x)\).- INPUT: - other– a polynomial \(g(x)\)
- modulus– a polynomial \(h(x)\)
 - EXAMPLES: - sage: R.<x> = GF(3**6)[] sage: f = R.random_element() sage: g = R.random_element() sage: g.compose_mod(g, f) == g(g) % f True sage: F.<z3> = GF(3**6) sage: R.<x> = F[] sage: f = 2*z3^2*x^2 + (z3 + 1)*x + z3^2 + 2 sage: g = (z3^2 + 2*z3)*x^2 + (2*z3 + 2)*x + 2*z3^2 + z3 + 2 sage: h = (2*z3 + 2)*x^2 + (2*z3^2 + 1)*x + 2*z3^2 + z3 + 2 sage: f.compose_mod(g, h) (z3^5 + z3^4 + z3^3 + z3^2 + z3)*x + z3^5 + z3^3 + 2*z3 + 2 sage: f.compose_mod(g, h) == f(g) % h True - >>> from sage.all import * >>> R = GF(Integer(3)**Integer(6))['x']; (x,) = R._first_ngens(1) >>> f = R.random_element() >>> g = R.random_element() >>> g.compose_mod(g, f) == g(g) % f True >>> F = GF(Integer(3)**Integer(6), names=('z3',)); (z3,) = F._first_ngens(1) >>> R = F['x']; (x,) = R._first_ngens(1) >>> f = Integer(2)*z3**Integer(2)*x**Integer(2) + (z3 + Integer(1))*x + z3**Integer(2) + Integer(2) >>> g = (z3**Integer(2) + Integer(2)*z3)*x**Integer(2) + (Integer(2)*z3 + Integer(2))*x + Integer(2)*z3**Integer(2) + z3 + Integer(2) >>> h = (Integer(2)*z3 + Integer(2))*x**Integer(2) + (Integer(2)*z3**Integer(2) + Integer(1))*x + Integer(2)*z3**Integer(2) + z3 + Integer(2) >>> f.compose_mod(g, h) (z3^5 + z3^4 + z3^3 + z3^2 + z3)*x + z3^5 + z3^3 + 2*z3 + 2 >>> f.compose_mod(g, h) == f(g) % h True - AUTHORS: - Giacomo Pope (2024-08) initial implementation 
 
 - resultant(other)[source]¶
- Return the resultant of - selfand- other, which must lie in the same polynomial ring.- INPUT: - other– a polynomial
 - OUTPUT: an element of the base ring of the polynomial ring - EXAMPLES: - sage: K.<a> = GF(next_prime(2**60)**3) sage: R.<x> = PolynomialRing(K, implementation='NTL') sage: f = (x-a)*(x-a**2)*(x+1) sage: g = (x-a**3)*(x-a**4)*(x+a) sage: r = f.resultant(g) sage: r == prod(u - v for (u,eu) in f.roots() for (v,ev) in g.roots()) True - >>> from sage.all import * >>> K = GF(next_prime(Integer(2)**Integer(60))**Integer(3), names=('a',)); (a,) = K._first_ngens(1) >>> R = PolynomialRing(K, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> f = (x-a)*(x-a**Integer(2))*(x+Integer(1)) >>> g = (x-a**Integer(3))*(x-a**Integer(4))*(x+a) >>> r = f.resultant(g) >>> r == prod(u - v for (u,eu) in f.roots() for (v,ev) in g.roots()) True 
 - reverse(degree=None)[source]¶
- Return the polynomial obtained by reversing the coefficients of this polynomial. If degree is set then this function behaves as if this polynomial has degree - degree.- EXAMPLES: - sage: R.<x> = GF(101^2)[] sage: f = x^13 + 11*x^10 + 32*x^6 + 4 sage: f.reverse() 4*x^13 + 32*x^7 + 11*x^3 + 1 sage: f.reverse(degree=15) 4*x^15 + 32*x^9 + 11*x^5 + x^2 sage: f.reverse(degree=2) 4*x^2 - >>> from sage.all import * >>> R = GF(Integer(101)**Integer(2))['x']; (x,) = R._first_ngens(1) >>> f = x**Integer(13) + Integer(11)*x**Integer(10) + Integer(32)*x**Integer(6) + Integer(4) >>> f.reverse() 4*x^13 + 32*x^7 + 11*x^3 + 1 >>> f.reverse(degree=Integer(15)) 4*x^15 + 32*x^9 + 11*x^5 + x^2 >>> f.reverse(degree=Integer(2)) 4*x^2 
 - shift(n)[source]¶
- EXAMPLES: - sage: K.<a> = GF(next_prime(2**60)**3) sage: R.<x> = PolynomialRing(K, implementation='NTL') sage: f = x^3 + x^2 + 1 sage: f.shift(1) x^4 + x^3 + x sage: f.shift(-1) x^2 + x - >>> from sage.all import * >>> K = GF(next_prime(Integer(2)**Integer(60))**Integer(3), names=('a',)); (a,) = K._first_ngens(1) >>> R = PolynomialRing(K, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(3) + x**Integer(2) + Integer(1) >>> f.shift(Integer(1)) x^4 + x^3 + x >>> f.shift(-Integer(1)) x^2 + x 
 
- class sage.rings.polynomial.polynomial_zz_pex.Polynomial_template[source]¶
- Bases: - Polynomial- Template for interfacing to external C / C++ libraries for implementations of polynomials. - AUTHORS: - Robert Bradshaw (2008-10): original idea for templating 
- Martin Albrecht (2008-10): initial implementation 
 - This file implements a simple templating engine for linking univariate polynomials to their C/C++ library implementations. It requires a ‘linkage’ file which implements the - celement_functions (see- sage.libs.ntl.ntl_GF2X_linkagefor an example). Both parts are then plugged together by inclusion of the linkage file when inheriting from this class. See- sage.rings.polynomial.polynomial_gf2xfor an example.- We illustrate the generic glueing using univariate polynomials over \(\mathop{\mathrm{GF}}(2)\). - Note - Implementations using this template MUST implement coercion from base ring elements and - get_unsafe(). See- Polynomial_GF2Xfor an example.- degree()[source]¶
- EXAMPLES: - sage: P.<x> = GF(2)[] sage: x.degree() 1 sage: P(1).degree() 0 sage: P(0).degree() -1 - >>> from sage.all import * >>> P = GF(Integer(2))['x']; (x,) = P._first_ngens(1) >>> x.degree() 1 >>> P(Integer(1)).degree() 0 >>> P(Integer(0)).degree() -1 
 - gcd(other)[source]¶
- Return the greatest common divisor of - selfand- other.- EXAMPLES: - sage: P.<x> = GF(2)[] sage: f = x*(x+1) sage: f.gcd(x+1) x + 1 sage: f.gcd(x^2) x - >>> from sage.all import * >>> P = GF(Integer(2))['x']; (x,) = P._first_ngens(1) >>> f = x*(x+Integer(1)) >>> f.gcd(x+Integer(1)) x + 1 >>> f.gcd(x**Integer(2)) x 
 - is_gen()[source]¶
- EXAMPLES: - sage: P.<x> = GF(2)[] sage: x.is_gen() True sage: (x+1).is_gen() False - >>> from sage.all import * >>> P = GF(Integer(2))['x']; (x,) = P._first_ngens(1) >>> x.is_gen() True >>> (x+Integer(1)).is_gen() False 
 - is_one()[source]¶
- EXAMPLES: - sage: P.<x> = GF(2)[] sage: P(1).is_one() True - >>> from sage.all import * >>> P = GF(Integer(2))['x']; (x,) = P._first_ngens(1) >>> P(Integer(1)).is_one() True 
 - is_zero()[source]¶
- EXAMPLES: - sage: P.<x> = GF(2)[] sage: x.is_zero() False - >>> from sage.all import * >>> P = GF(Integer(2))['x']; (x,) = P._first_ngens(1) >>> x.is_zero() False 
 - list(copy=True)[source]¶
- EXAMPLES: - sage: P.<x> = GF(2)[] sage: x.list() [0, 1] sage: list(x) [0, 1] - >>> from sage.all import * >>> P = GF(Integer(2))['x']; (x,) = P._first_ngens(1) >>> x.list() [0, 1] >>> list(x) [0, 1] 
 - quo_rem(right)[source]¶
- EXAMPLES: - sage: P.<x> = GF(2)[] sage: f = x^2 + x + 1 sage: f.quo_rem(x + 1) (x, 1) - >>> from sage.all import * >>> P = GF(Integer(2))['x']; (x,) = P._first_ngens(1) >>> f = x**Integer(2) + x + Integer(1) >>> f.quo_rem(x + Integer(1)) (x, 1) 
 - shift(n)[source]¶
- EXAMPLES: - sage: P.<x> = GF(2)[] sage: f = x^3 + x^2 + 1 sage: f.shift(1) x^4 + x^3 + x sage: f.shift(-1) x^2 + x - >>> from sage.all import * >>> P = GF(Integer(2))['x']; (x,) = P._first_ngens(1) >>> f = x**Integer(3) + x**Integer(2) + Integer(1) >>> f.shift(Integer(1)) x^4 + x^3 + x >>> f.shift(-Integer(1)) x^2 + x 
 - truncate(n)[source]¶
- Return this polynomial mod \(x^n\). - EXAMPLES: - sage: R.<x> =GF(2)[] sage: f = sum(x^n for n in range(10)); f x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 sage: f.truncate(6) x^5 + x^4 + x^3 + x^2 + x + 1 - >>> from sage.all import * >>> R = GF(Integer(2))['x']; (x,) = R._first_ngens(1) >>> f = sum(x**n for n in range(Integer(10))); f x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 >>> f.truncate(Integer(6)) x^5 + x^4 + x^3 + x^2 + x + 1 - If the precision is higher than the degree of the polynomial then the polynomial itself is returned: - sage: f.truncate(10) is f True - >>> from sage.all import * >>> f.truncate(Integer(10)) is f True - If the precision is negative, the zero polynomial is returned: - sage: f.truncate(-1) 0 - >>> from sage.all import * >>> f.truncate(-Integer(1)) 0 
 - xgcd(other)[source]¶
- Compute extended gcd of - selfand- other.- EXAMPLES: - sage: P.<x> = GF(7)[] sage: f = x*(x+1) sage: f.xgcd(x+1) (x + 1, 0, 1) sage: f.xgcd(x^2) (x, 1, 6) - >>> from sage.all import * >>> P = GF(Integer(7))['x']; (x,) = P._first_ngens(1) >>> f = x*(x+Integer(1)) >>> f.xgcd(x+Integer(1)) (x + 1, 0, 1) >>> f.xgcd(x**Integer(2)) (x, 1, 6)