Polynomial multiplication is very fast, and is implemented using one of 4 different algorithms:
The choice of algorithm is somewhat heuristic, and may not always be perfect.
Many thanks to Juergen Gerhard <jngerhar@plato.uni-paderborn.de> for pointing out the deficiency in the NTL-1.0 ZZX arithmetic, and for contributing the Schoenhage/Strassen code.
Extensive use is made of modular algorithms to enhance performance (e.g., the GCD algorithm and many others).
charpoly_mod,
clear,
constant_term,
content,
copy,
degree,
derivative,
discriminant,
gcd,
invert_and_truncate,
is_monic,
is_one,
is_x,
is_zero,
leading_coefficient,
left_shift,
minpoly_mod_noproof,
multiply_and_truncate,
multiply_mod,
norm_mod,
preallocate_space,
primitive_part,
pseudo_quo_rem,
quo_rem,
resultant,
reverse,
right_shift,
set_x,
square,
square_and_truncate,
trace_list,
trace_mod,
truncate,
xgcd
Further documentation:
) |
Return the characteristic polynomial of this polynomial modulo
the modulus. The modulus must be monic of degree bigger than
self. If proof=False (the default is True), then this function
may use a randomized strategy that errors with probability no
more than
.
sage: f = ntl.ZZX([1,2,0,3]) sage: mod = ntl.ZZX([-5,2,0,0,1]) sage: f.charpoly_mod(mod) [-8846 -594 -60 14 1]
) |
Reset this polynomial to 0. Changes this polynomial in place.
sage: f = ntl.ZZX([1,2,3]) sage: f [1 2 3] sage: f.clear() sage: f []
) |
Return the constant coefficient of this polynomial.
sage: f = ntl.ZZX([3,6,9]) sage: f.constant_term() 3 sage: f = ntl.ZZX() sage: f.constant_term() 0
) |
Return the content of f, which has sign the same as the leading coefficient of f. Also, our convention is that the content of 0 is 0.
sage: f = ntl.ZZX([2,0,0,2]) sage: f.content() 2 sage: f = ntl.ZZX([2,0,0,-2]) sage: f.content() -2 sage: f = ntl.ZZX([6,12,3,9]) sage: f.content() 3 sage: f = ntl.ZZX([]) sage: f.content() 0
) |
Return the degree of this polynomial. The degree of the 0 polynomial is -1.
sage: f = ntl.ZZX([5,0,1]) sage: f.degree() 2 sage: f = ntl.ZZX(range(100)) sage: f.degree() 99 sage: f = ntl.ZZX() sage: f.degree() -1 sage: f = ntl.ZZX([1]) sage: f.degree() 0
) |
Return the derivative of this polynomial.
sage: f = ntl.ZZX([1,7,0,13]) sage: f.derivative() [7 0 39]
) |
Return the discriminant of self, which is by definition
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
sage: f = ntl.ZZX([1,2,0,3]) sage: f.discriminant() -339 sage: f.discriminant(proof=False) -339
) |
Return the gcd d = gcd(a, b), where by convention the leading coefficient of d is >= 0. We uses a multi-modular algorithm.
sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2 sage: g = ntl.ZZX([1,1,1])**3 * ntl.ZZX([1,2,3]) sage: f.gcd(g) [1 2 3] sage: g.gcd(f) [1 2 3]
) |
Compute and return the inverse of self modulo
.
The constant term of self must be 1 or -1.
sage: f = ntl.ZZX([1,2,3,4,5,6,7]) sage: f.invert_and_truncate(20) [1 -2 1 0 0 0 0 8 -23 22 -7 0 0 0 64 -240 337 -210 49] sage: g = f.invert_and_truncate(20) sage: g * f [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -512 1344 -1176 343]
) |
Return True exactly if this polynomial is monic.
sage: f = ntl.ZZX([2,0,0,1]) sage: f.is_monic() True sage: g = f.reverse() sage: g.is_monic() False sage: g [1 0 0 2]
) |
Return True exactly if this polynomial is 1.
sage: f = ntl.ZZX([1,1]) sage: f.is_one() False sage: f = ntl.ZZX([1]) sage: f.is_one() True
) |
True if this is the polynomial "x".
sage: f = ntl.ZZX() sage: f.set_x() sage: f.is_x() True sage: f = ntl.ZZX([0,1]) sage: f.is_x() True sage: f = ntl.ZZX([1]) sage: f.is_x() False
) |
Return True exactly if this polynomial is 0.
sage: f = ntl.ZZX([0,0,0,0]) sage: f.is_zero() True sage: f = ntl.ZZX([0,0,1]) sage: f [0 0 1] sage: f.is_zero() False
) |
Return the leading coefficient of this polynomial.
sage: f = ntl.ZZX([3,6,9]) sage: f.leading_coefficient() 9 sage: f = ntl.ZZX() sage: f.leading_coefficient() 0
) |
Return the polynomial obtained by shifting all coefficients of this polynomial to the left n positions.
sage: f = ntl.ZZX([2,0,0,1]) sage: f [2 0 0 1] sage: f.left_shift(2) [0 0 2 0 0 1] sage: f.left_shift(5) [0 0 0 0 0 2 0 0 1]
A negative left shift is a right shift.
sage: f.left_shift(-2) [0 1]
) |
Return the minimal polynomial of this polynomial modulo the
modulus. The modulus must be monic of degree bigger than
self. In all cases, this function may use a randomized
strategy that errors with probability no more than
.
sage: f = ntl.ZZX([0,0,1]) sage: g = f*f sage: f.charpoly_mod(g) [0 0 0 0 1]
However, since
moduluo
, its minimal polynomial
is of degree
.
sage: f.minpoly_mod_noproof(g) [0 0 1]
) |
Return self*other but with terms of degree >= m removed.
sage: f = ntl.ZZX([1,2,3,4,5]) sage: g = ntl.ZZX([10]) sage: f.multiply_and_truncate(g, 2) [10 20] sage: g.multiply_and_truncate(f, 2) [10 20]
) |
Return self*other deg(modulus) > 0, and self and other must have smaller degree.
sage: modulus = ntl.ZZX([1,2,0,1]) # must be monic sage: g = ntl.ZZX([-1,0,1]) sage: h = ntl.ZZX([3,7,13]) sage: h.multiply_mod(g, modulus) [-10 -34 -36]
) |
Return the norm of this polynomial modulo the modulus. The
modulus must be monic, and of positive degree strictly greater
than the degree of self. If proof=False (the default is
proof=True) then it may use a randomized strategy that errors
with probability no more than
.
EXAMPLE:
sage: f = ntl.ZZX([1,2,0,3]) sage: mod = ntl.ZZX([-5,2,0,0,1]) sage: f.norm_mod(mod) -8846
The norm is the constant term of the characteristic polynomial.
sage: f.charpoly_mod(mod) [-8846 -594 -60 14 1]
) |
Pre-allocate spaces for n coefficients. The polynomial that f represents is unchanged. This is useful if you know you'll be setting coefficients up to n, so memory isn't re-allocated as the polynomial grows. (You might save a millisecond with this function.)
sage: f = ntl.ZZX([1,2,3]) sage: f.preallocate_space(20) sage: f [1 2 3] sage: f[10]=5 # no new memory is allocated sage: f [1 2 3 0 0 0 0 0 0 0 5]
) |
Return the primitive part of f. Our convention is that the leading coefficient of the primitive part is nonnegegative, and the primitive part of 0 is 0.
sage: f = ntl.ZZX([6,12,3,9]) sage: f.primitive_part() [2 4 1 3] sage: f [6 12 3 9] sage: f = ntl.ZZX([6,12,3,-9]) sage: f [6 12 3 -9] sage: f.primitive_part() [-2 -4 -1 3] sage: f = ntl.ZZX() sage: f.primitive_part() []
) |
Performs pseudo-division: computes q and r with deg(r) <
deg(b), and LeadCoeff(b)(deg(a)-deg(b)+1) a = b q + r
.
Only the classical algorithm is used.
sage: f = ntl.ZZX([0,1]) sage: g = ntl.ZZX([1,2,3]) sage: g.pseudo_quo_rem(f) ([1], [2 3]) sage: f = ntl.ZZX([1,1]) sage: g.pseudo_quo_rem(f) ([2], [-1 3])
) |
Returns the unique integral q and r such that self = q*other + r, if they exist. Otherwise raises an Exception.
sage: f = ntl.ZZX(range(10)); g = ntl.ZZX([-1,0,1]) sage: q, r = f.quo_rem(g) sage: q, r ([20 24 18 21 14 16 8 9], [20 25]) sage: q*g + r == f True
) |
Return the resultant of self and other. If proof = False (the
default is proof=True), then this function may use a
randomized strategy that errors with probability no more than
.
sage: f = ntl.ZZX([17,0,1,1]) sage: g = ntl.ZZX([34,-17,18,2]) sage: f.resultant(g) 1345873 sage: f.resultant(g, proof=False) 1345873
) |
Return the polynomial obtained by reversing the coefficients of this polynomial. If hi is set then this function behaves as if this polynomial has degree hi.
sage: f = ntl.ZZX([1,2,3,4,5]) sage: f.reverse() [5 4 3 2 1] sage: f.reverse(hi=10) [0 0 0 0 0 0 5 4 3 2 1] sage: f.reverse(hi=2) [3 2 1] sage: f.reverse(hi=-2) []
) |
Return the polynomial obtained by shifting all coefficients of this polynomial to the right n positions.
sage: f = ntl.ZZX([2,0,0,1]) sage: f [2 0 0 1] sage: f.right_shift(2) [0 1] sage: f.right_shift(5) [] sage: f.right_shift(-2) [0 0 2 0 0 1]
) |
Set this polynomial to the monomial "x".
sage: f = ntl.ZZX() sage: f.set_x() sage: f [0 1] sage: g = ntl.ZZX([0,1]) sage: f == g True
Though f and g are equal, they are not the same objects in memory:
sage: f is g False
) |
Return f*f.
sage: f = ntl.ZZX([-1,0,1]) sage: f*f [1 0 -2 0 1]
) |
Return self*self but with terms of degree >= m removed.
sage: f = ntl.ZZX([1,2,3,4,5]) sage: f.square_and_truncate(4) [1 4 10 20] sage: (f*f).truncate(4) [1 4 10 20]
) |
Return the list of traces of the powers
of the
monomial x modulo this polynomial for i = 0, ..., deg(f)-1.
This polynomial must be monic.
sage: f = ntl.ZZX([1,2,0,3,0,1]) sage: f.trace_list() [5, 0, -6, 0, 10]
The input polynomial must be monic or a ValueError is raised:
sage: f = ntl.ZZX([1,2,0,3,0,2]) sage: f.trace_list() Traceback (most recent call last): ... ValueError: polynomial must be monic.
) |
Return the trace of this polynomial modulus the modulus. The modulus must be monic, and of positive degree degree bigger than the the degree of self.
sage: f = ntl.ZZX([1,2,0,3]) sage: mod = ntl.ZZX([5,3,-1,1,1]) sage: f.trace_mod(mod) -37
) |
Return the truncation of this polynomial obtained by removing all terms of degree >= m.
sage: f = ntl.ZZX([1,2,3,4,5]) sage: f.truncate(3) [1 2 3] sage: f.truncate(8) [1 2 3 4 5] sage: f.truncate(1) [1] sage: f.truncate(0) [] sage: f.truncate(-1) [] sage: f.truncate(-5) []
) |
Returns r,s,t such that r = s*self + t*other.
Here r is the resultant of a and b; if r != 0, then this
function computes s and t such that: a*s + b*t = r; otherwise
s and t are both 0. If proof = False (*not* the default),
then resultant computation may use a randomized strategy that
errs with probability no more than
.
sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2 sage: g = ntl.ZZX([1,1,1])**3 * ntl.ZZX([1,2,3]) sage: f.xgcd(g) # nothing since they are not coprime (0, [], [])
In this example the input quadratic polynomials have a common root modulo 13.
sage: f = ntl.ZZX([5,0,1]) sage: g = ntl.ZZX([18,0,1]) sage: f.xgcd(g) (169, [-13], [13])
Instances of class ZZX_class also have the following special functions:
__add__,
__cmp__,
__delitem__,
__div__,
__getitem__,
__mod__,
__mul__,
__neg__,
__pow__,
__radd__,
__rdiv__,
__rmod__,
__rmul__,
__rpow__,
__rsub__,
__setitem__,
__sub__
See About this document... for information on suggesting changes.