Dense univariate polynomials over \(\ZZ\), implemented using NTL.¶
AUTHORS:
David Harvey: split off from polynomial_element_generic.py (2007-09)
David Harvey: rewrote to talk to NTL directly, instead of via ntl.pyx (2007-09); a lot of this was based on Joel Mohler’s recent rewrite of the NTL wrapper
Sage includes two implementations of dense univariate polynomials over \(\ZZ\);
this file contains the implementation based on NTL, but there is also an
implementation based on FLINT in
sage.rings.polynomial.polynomial_integer_dense_flint
.
The FLINT implementation is preferred (FLINT’s arithmetic operations are generally faster), so it is the default; to use the NTL implementation, you can do:
sage: K.<x> = PolynomialRing(ZZ, implementation='NTL')
sage: K
Univariate Polynomial Ring in x over Integer Ring (using NTL)
>>> from sage.all import *
>>> K = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = K._first_ngens(1)
>>> K
Univariate Polynomial Ring in x over Integer Ring (using NTL)
- class sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl[source]¶
Bases:
Polynomial
A dense polynomial over the integers, implemented via NTL.
- content()[source]¶
Return the greatest common divisor of the coefficients of this polynomial. The sign is the sign of the leading coefficient. The content of the zero polynomial is zero.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL') sage: (2*x^2 - 4*x^4 + 14*x^7).content() 2 sage: (2*x^2 - 4*x^4 - 14*x^7).content() -2 sage: x.content() 1 sage: R(1).content() 1 sage: R(0).content() 0
>>> from sage.all import * >>> R = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> (Integer(2)*x**Integer(2) - Integer(4)*x**Integer(4) + Integer(14)*x**Integer(7)).content() 2 >>> (Integer(2)*x**Integer(2) - Integer(4)*x**Integer(4) - Integer(14)*x**Integer(7)).content() -2 >>> x.content() 1 >>> R(Integer(1)).content() 1 >>> R(Integer(0)).content() 0
- degree(gen=None)[source]¶
Return the degree of this polynomial. The zero polynomial has degree \(-1\).
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL') sage: x.degree() 1 sage: (x^2).degree() 2 sage: R(1).degree() 0 sage: R(0).degree() -1
>>> from sage.all import * >>> R = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> x.degree() 1 >>> (x**Integer(2)).degree() 2 >>> R(Integer(1)).degree() 0 >>> R(Integer(0)).degree() -1
- discriminant(proof=True)[source]¶
Return the discriminant of
self
, which is by definition\[(-1)^{m(m-1)/2} \text{resultant}(a, a')/lc(a),\]where \(m = deg(a)\), and \(lc(a)\) is the leading coefficient of a. If
proof
is False (the default is True), then this function may use a randomized strategy that errors with probability no more than \(2^{-80}\).EXAMPLES:
sage: f = ntl.ZZX([1,2,0,3]) sage: f.discriminant() -339 sage: f.discriminant(proof=False) -339
>>> from sage.all import * >>> f = ntl.ZZX([Integer(1),Integer(2),Integer(0),Integer(3)]) >>> f.discriminant() -339 >>> f.discriminant(proof=False) -339
- factor()[source]¶
This function overrides the generic polynomial factorization to make a somewhat intelligent decision to use PARI or NTL based on some benchmarking.
Note: This function factors the content of the polynomial, which can take very long if it’s a really big integer. If you do not need the content factored, divide it out of your polynomial before calling this function.
EXAMPLES:
sage: R.<x> = ZZ[] sage: f = x^4 - 1 sage: f.factor() (x - 1) * (x + 1) * (x^2 + 1) sage: f = 1 - x sage: f.factor() (-1) * (x - 1) sage: f.factor().unit() -1 sage: f = -30*x; f.factor() (-1) * 2 * 3 * 5 * x
>>> from sage.all import * >>> R = ZZ['x']; (x,) = R._first_ngens(1) >>> f = x**Integer(4) - Integer(1) >>> f.factor() (x - 1) * (x + 1) * (x^2 + 1) >>> f = Integer(1) - x >>> f.factor() (-1) * (x - 1) >>> f.factor().unit() -1 >>> f = -Integer(30)*x; f.factor() (-1) * 2 * 3 * 5 * x
- factor_mod(p)[source]¶
Return the factorization of
self
modulo the prime \(p\).INPUT:
p
– prime
OUTPUT: factorization of
self
reduced modulo \(p\)EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, 'x', implementation='NTL') sage: f = -3*x*(x-2)*(x-9) + x sage: f.factor_mod(3) x sage: f = -3*x*(x-2)*(x-9) sage: f.factor_mod(3) Traceback (most recent call last): ... ArithmeticError: factorization of 0 is not defined sage: f = 2*x*(x-2)*(x-9) sage: f.factor_mod(7) (2) * x * (x + 5)^2
>>> from sage.all import * >>> R = PolynomialRing(ZZ, 'x', implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> f = -Integer(3)*x*(x-Integer(2))*(x-Integer(9)) + x >>> f.factor_mod(Integer(3)) x >>> f = -Integer(3)*x*(x-Integer(2))*(x-Integer(9)) >>> f.factor_mod(Integer(3)) Traceback (most recent call last): ... ArithmeticError: factorization of 0 is not defined >>> f = Integer(2)*x*(x-Integer(2))*(x-Integer(9)) >>> f.factor_mod(Integer(7)) (2) * x * (x + 5)^2
- factor_padic(p, prec=10)[source]¶
Return \(p\)-adic factorization of
self
to given precision.INPUT:
p
– primeprec
– integer; the precision
OUTPUT: factorization of
self
over the completion at \(p\)EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL') sage: f = x^2 + 1 sage: f.factor_padic(5, 4) ((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4)) * ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4))
>>> from sage.all import * >>> R = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> f = x**Integer(2) + Integer(1) >>> f.factor_padic(Integer(5), Integer(4)) ((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4)) * ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4))
A more difficult example:
sage: f = 100 * (5*x + 1)^2 * (x + 5)^2 sage: f.factor_padic(5, 10) (4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2 * ((5 + O(5^10))*x + 1 + O(5^10))^2
>>> from sage.all import * >>> f = Integer(100) * (Integer(5)*x + Integer(1))**Integer(2) * (x + Integer(5))**Integer(2) >>> f.factor_padic(Integer(5), Integer(10)) (4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2 * ((5 + O(5^10))*x + 1 + O(5^10))^2
- gcd(right)[source]¶
Return the GCD of
self
andright
. The leading coefficient need not be 1.EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL') sage: f = (6*x + 47) * (7*x^2 - 2*x + 38) sage: g = (6*x + 47) * (3*x^3 + 2*x + 1) sage: f.gcd(g) 6*x + 47
>>> from sage.all import * >>> R = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> f = (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) - Integer(2)*x + Integer(38)) >>> g = (Integer(6)*x + Integer(47)) * (Integer(3)*x**Integer(3) + Integer(2)*x + Integer(1)) >>> f.gcd(g) 6*x + 47
- lcm(right)[source]¶
Return the LCM of
self
andright
.EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL') sage: f = (6*x + 47) * (7*x^2 - 2*x + 38) sage: g = (6*x + 47) * (3*x^3 + 2*x + 1) sage: h = f.lcm(g); h 126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786 sage: h == (6*x + 47) * (7*x^2 - 2*x + 38) * (3*x^3 + 2*x + 1) True
>>> from sage.all import * >>> R = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> f = (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) - Integer(2)*x + Integer(38)) >>> g = (Integer(6)*x + Integer(47)) * (Integer(3)*x**Integer(3) + Integer(2)*x + Integer(1)) >>> h = f.lcm(g); h 126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786 >>> h == (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) - Integer(2)*x + Integer(38)) * (Integer(3)*x**Integer(3) + Integer(2)*x + Integer(1)) True
- list(copy=True)[source]¶
Return a new copy of the list of the underlying elements of
self
.EXAMPLES:
sage: x = PolynomialRing(ZZ, 'x', implementation='NTL').0 sage: f = x^3 + 3*x - 17 sage: f.list() [-17, 3, 0, 1] sage: f = PolynomialRing(ZZ, 'x', implementation='NTL')(0) sage: f.list() []
>>> from sage.all import * >>> x = PolynomialRing(ZZ, 'x', implementation='NTL').gen(0) >>> f = x**Integer(3) + Integer(3)*x - Integer(17) >>> f.list() [-17, 3, 0, 1] >>> f = PolynomialRing(ZZ, 'x', implementation='NTL')(Integer(0)) >>> f.list() []
- quo_rem(right)[source]¶
Attempt to divide
self
byright
, and return a quotient and remainder.If right is monic, then it returns
(q, r)
whereself = q * right + r
anddeg(r) < deg(right)
.If right is not monic, then it returns \((q, 0)\) where
q = self/right
ifright
exactly dividesself
, otherwise it raises an exception.EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL') sage: f = R(range(10)); g = R([-1, 0, 1]) sage: q, r = f.quo_rem(g) sage: q, r (9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 25*x + 20) sage: q*g + r == f True sage: 0//(2*x) 0 sage: f = x^2 sage: f.quo_rem(0) Traceback (most recent call last): ... ArithmeticError: division by zero polynomial sage: f = (x^2 + 3) * (2*x - 1) sage: f.quo_rem(2*x - 1) (x^2 + 3, 0) sage: f = x^2 sage: f.quo_rem(2*x - 1) Traceback (most recent call last): ... ArithmeticError: division not exact in Z[x] (consider coercing to Q[x] first)
>>> from sage.all import * >>> R = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> f = R(range(Integer(10))); g = R([-Integer(1), Integer(0), Integer(1)]) >>> q, r = f.quo_rem(g) >>> q, r (9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 25*x + 20) >>> q*g + r == f True >>> Integer(0)//(Integer(2)*x) 0 >>> f = x**Integer(2) >>> f.quo_rem(Integer(0)) Traceback (most recent call last): ... ArithmeticError: division by zero polynomial >>> f = (x**Integer(2) + Integer(3)) * (Integer(2)*x - Integer(1)) >>> f.quo_rem(Integer(2)*x - Integer(1)) (x^2 + 3, 0) >>> f = x**Integer(2) >>> f.quo_rem(Integer(2)*x - Integer(1)) Traceback (most recent call last): ... ArithmeticError: division not exact in Z[x] (consider coercing to Q[x] first)
- real_root_intervals()[source]¶
Return isolating intervals for the real roots of this polynomial.
EXAMPLES: We compute the roots of the characteristic polynomial of some Salem numbers:
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL') sage: f = 1 - x^2 - x^3 - x^4 + x^6 sage: f.real_root_intervals() # needs sage.libs.linbox [((1/2, 3/4), 1), ((1, 3/2), 1)]
>>> from sage.all import * >>> R = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> f = Integer(1) - x**Integer(2) - x**Integer(3) - x**Integer(4) + x**Integer(6) >>> f.real_root_intervals() # needs sage.libs.linbox [((1/2, 3/4), 1), ((1, 3/2), 1)]
- resultant(other, proof=True)[source]¶
Return the resultant of
self
andother
, which must lie in the same polynomial ring.If
proof=False
(the default isproof=True
), then this function may use a randomized strategy that errors with probability no more than \(2^{-80}\).INPUT:
other
– a polynomial
OUTPUT: an element of the base ring of the polynomial ring
EXAMPLES:
sage: x = PolynomialRing(ZZ, 'x', implementation='NTL').0 sage: f = x^3 + x + 1; g = x^3 - x - 1 sage: r = f.resultant(g); r -8 sage: r.parent() is ZZ True
>>> from sage.all import * >>> x = PolynomialRing(ZZ, 'x', implementation='NTL').gen(0) >>> f = x**Integer(3) + x + Integer(1); g = x**Integer(3) - x - Integer(1) >>> r = f.resultant(g); r -8 >>> r.parent() is ZZ True
- squarefree_decomposition()[source]¶
Return the square-free decomposition of
self
. This is a partial factorization ofself
into square-free, relatively prime polynomials.This is a wrapper for the NTL function
SquareFreeDecomp
.EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL') sage: p = 37 * (x-1)^2 * (x-2)^2 * (x-3)^3 * (x-4) sage: p.squarefree_decomposition() (37) * (x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3
>>> from sage.all import * >>> R = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = R._first_ngens(1) >>> p = Integer(37) * (x-Integer(1))**Integer(2) * (x-Integer(2))**Integer(2) * (x-Integer(3))**Integer(3) * (x-Integer(4)) >>> p.squarefree_decomposition() (37) * (x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3
- xgcd(right)[source]¶
This function can’t in general return \((g,s,t)\) as above, since they need not exist. Instead, over the integers, we first multiply \(g\) by a divisor of the resultant of \(a/g\) and \(b/g\), up to sign, and return
g, u, v
such thatg = s*self + s*right
. But note that this \(g\) may be a multiple of the gcd.If
self
andright
are coprime as polynomials over the rationals, theng
is guaranteed to be the resultant ofself
andright
, as a constant polynomial.EXAMPLES:
sage: P.<x> = PolynomialRing(ZZ, implementation='NTL') sage: F = (x^2 + 2)*x^3; G = (x^2+2)*(x-3) sage: g, u, v = F.xgcd(G) sage: g, u, v (27*x^2 + 54, 1, -x^2 - 3*x - 9) sage: u*F + v*G 27*x^2 + 54 sage: x.xgcd(P(0)) (x, 1, 0) sage: f = P(0) sage: f.xgcd(x) (x, 0, 1) sage: F = (x-3)^3; G = (x-15)^2 sage: g, u, v = F.xgcd(G) sage: g, u, v (2985984, -432*x + 8208, 432*x^2 + 864*x + 14256) sage: u*F + v*G 2985984
>>> from sage.all import * >>> P = PolynomialRing(ZZ, implementation='NTL', names=('x',)); (x,) = P._first_ngens(1) >>> F = (x**Integer(2) + Integer(2))*x**Integer(3); G = (x**Integer(2)+Integer(2))*(x-Integer(3)) >>> g, u, v = F.xgcd(G) >>> g, u, v (27*x^2 + 54, 1, -x^2 - 3*x - 9) >>> u*F + v*G 27*x^2 + 54 >>> x.xgcd(P(Integer(0))) (x, 1, 0) >>> f = P(Integer(0)) >>> f.xgcd(x) (x, 0, 1) >>> F = (x-Integer(3))**Integer(3); G = (x-Integer(15))**Integer(2) >>> g, u, v = F.xgcd(G) >>> g, u, v (2985984, -432*x + 8208, 432*x^2 + 864*x + 14256) >>> u*F + v*G 2985984