fmpz_mod_poly – polynomials over integers mod n¶
- class flint.fmpz_mod_poly_ctx(mod)¶
Context object for creating
fmpz_mod_polyinitialised with a modulus \(N\).>>> fmpz_mod_poly_ctx(2**127 - 1) fmpz_mod_poly_ctx(170141183460469231731687303715884105727)
- gen(self)¶
Return the generator of the polynomial: \(x\)
>>> R = fmpz_mod_poly_ctx(163) >>> R.gen() x
- is_prime(self)¶
Return whether the modulus is prime
>>> fmpz_mod_poly_ctx(2**127).is_prime() False >>> fmpz_mod_poly_ctx(2**127 - 1).is_prime() True
- minpoly(self, vals)¶
Returns a minimal generating polynomial for sequence \(vals\).
A minimal generating polynomial is a monic polynomial, of minimal degree \(d\), that annihilates any consecutive \(d+1\) terms in seq.
Assumes that the modulus is prime.
>>> R = fmpz_mod_poly_ctx(163) >>> R.minpoly([1,1,2,3,5,8]) x^2 + 162*x + 162 >>> R.minpoly([2,4,6,8,10]) x^2 + 161*x + 1
- modulus(self)¶
Return the modulus from the context as an
fmpztype>>> R = fmpz_mod_poly_ctx(2**127 - 1) >>> R.modulus() 170141183460469231731687303715884105727
- one(self)¶
Return the one element of this polynomial ring
>>> R = fmpz_mod_poly_ctx(163) >>> R.one() 1
- random_element(self, degree=3, monic=False, irreducible=False)¶
Return a random element of degree
degree. IfmonicisTrue, ensures the output is monic. IfirreducibleisTrue, ensures that the output is irreducible.>>> R = fmpz_mod_poly_ctx(163) >>> f = R.random_element() >>> f.degree() 3 >>> f = R.random_element(degree=123) >>> f.degree() 123 >>> f = R.random_element(monic=True) >>> f.is_monic() True >>> f = R.random_element(degree=13, monic=True, irreducible=True) >>> f.degree() 13 >>> f.is_monic() True >>> f.is_irreducible() True
- zero(self)¶
Return the zero element of this polynomial ring
>>> R = fmpz_mod_poly_ctx(163) >>> R.zero() 0
- class flint.fmpz_mod_poly(val, ctx)¶
The fmpz_mod_poly type represents univariate polynomials over integer modulo an arbitrary-size modulus. For wordsize modulus, see
nmod_poly.An fmpz_mod_poly element is constructed from an
fmpz_mod_poly_ctxeither by passing it as an argument to the type, or by directly calling the context:>>> fmpz_mod_poly([1,-2,3], fmpz_mod_poly_ctx(2**127 - 1)) 3*x^2 + 170141183460469231731687303715884105725*x + 1 >>> R = fmpz_mod_poly_ctx(2**127 - 1) >>> R([4,5,6]) 6*x^2 + 5*x + 4
- add_trunc(self, other, slong n)¶
Truncate
selfandotherto polynomials of lengthnand return their sum>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3,4,5]) >>> h = R([1,2,3]) >>> f.add_trunc(h, 2) 4*x + 2 >>> f.add_trunc(h, 3) 6*x^2 + 4*x + 2
- coeffs(self)¶
Returns the coefficients of
selfas a list>>> from flint import fmpz_poly >>> f = fmpz_poly([1,2,3,4,5]) >>> f.coeffs() [1, 2, 3, 4, 5]
- complex_roots(self)¶
This method is not implemented for polynomials in \((\mathbb{Z}/N\mathbb{Z})[X]\)
- compose(self, other)¶
Returns the composition of two polynomials
To be precise about the order of composition, given
self, andotherby \(f(x)\), \(g(x)\), returns \(f(g(x))\).>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> g = R([0,0,1]) >>> f.compose(g) 3*x^4 + 2*x^2 + 1 >>> g.compose(f) 9*x^4 + 12*x^3 + 10*x^2 + 4*x + 1
- compose_mod(self, other, modulus)¶
Returns the composition of two polynomials modulo a third.
To be precise about the order of composition, given
self, andotherandmodulusby \(f(x)\), \(g(x)\) and \(h(x)\), returns \(f(g(x)) \mod h(x)\). We require that \(h(x)\) is non-zero.>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3,4,5]) >>> g = R([3,2,1]) >>> h = R([1,0,1,0,1]) >>> f.compose_mod(g, h) 63*x^3 + 100*x^2 + 17*x + 63 >>> g.compose_mod(f, h) 147*x^3 + 159*x^2 + 4*x + 7
- constant_coefficient(self)¶
Return the constant coefficient of this polynomial.
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.constant_coefficient() fmpz_mod(1, 163)
- context(self)¶
- deflate(self, ulong n)¶
Returns the result of the polynomial \(f = \textrm{self}\) to \(f(x^{1/n})\)
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,0,2,0,3]) >>> f 3*x^4 + 2*x^2 + 1 >>> f.deflate(2) 3*x^2 + 2*x + 1
- deflation(self)¶
Returns the tuple (g, n) where for \(f = \textrm{self}\) to \(g = f(x^{1/n})\) where n is the largest allowed integer
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,0,2,0,3]) >>> f 3*x^4 + 2*x^2 + 1 >>> f.deflate(2) 3*x^2 + 2*x + 1
- degree(self) long¶
Return the degree of the polynomial
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.degree() 2
- derivative(self)¶
The formal derivative of this polynomial
>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = 111*x**4 + 58*x**3 + 98*x**2 + 117*x + 7 >>> f.derivative() 118*x^3 + 11*x^2 + 33*x + 117
- discriminant(self)¶
Return the discriminant of
self.>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = 6*x**4 + 7*x**3 + 7*x**2 + 8*x + 6 >>> f.discriminant() fmpz_mod(50, 163)
- divmod(self, other)¶
Return \(Q\), \(R\) such that for
self= \(F\) andother= \(G\), \(F = Q*G + R\)>>> R = fmpz_mod_poly_ctx(163) >>> f = R([123, 129, 63, 14, 51, 76, 133]) >>> g = R([106, 134, 32, 41, 158, 115, 115]) >>> f.divmod(g) (21, 106*x^5 + 156*x^4 + 131*x^3 + 43*x^2 + 86*x + 16)
- equal_trunc(self, other, slong n)¶
Returns if two polynomials are equal when truncated to the first
nterms>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3,4,5]) >>> h = R([1,2,3]) >>> f.equal_trunc(h, 3) True >>> f.equal_trunc(h, 4) False
- evaluate(self, input)¶
Evaluate
selfat a point in the base ring. This is the same as calling the polynomial directly. To evaluate a list of points, usemultiploint_evaluate.>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3,4,5,6]) >>> f.evaluate(-1) fmpz_mod(160, 163) >>> f.evaluate(-1) == f(-1) True
- exact_division(self, right)¶
Attempt to compute the exact quotient of self with other Raises a value error if division without remainder is not possible.
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,1]) >>> g = R([1,1]) >>> f.exact_division(g) x + 1
- factor(self, algorithm=None)¶
Factors self into irreducible factors, returning a tuple
(c, factors)where \(c\) is the content of the coefficients and factors is a list of(poly, exp)pairs.>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = 6*x**4 + 7*x**3 + 7*x**2 + 8*x + 6 >>> f.factor() (fmpz_mod(6, 163), [(x^4 + 137*x^3 + 137*x^2 + 110*x + 1, 1)]) >>> f = (x + 1)**3 * (x + 2) >>> f.factor() (fmpz_mod(1, 163), [(x + 1, 3), (x + 2, 1)])
- factor_squarefree(self)¶
Factors self into irreducible, squarefree factors, returning a tuple
(c, factors)where \(c\) is the content of the coefficients and factors is a list of(poly, exp)pairs.>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = (x + 1) * (x + 2) >>> f.factor_squarefree() (fmpz_mod(1, 163), [(x^2 + 3*x + 2, 1)]) >>> f = (x + 1) * (x + 2)**5 >>> f.factor_squarefree() (fmpz_mod(1, 163), [(x + 1, 1), (x + 2, 5)])
- gcd(self, other)¶
Return the greatest common divisor of self and other.
>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = x*(x + 1) >>> f.gcd(x+1) x + 1 >>> f.gcd(x*x) x
- inflate(self, ulong n)¶
Returns the result of the polynomial \(f = \textrm{self}\) to \(f(x^n)\)
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.inflate(10) 3*x^20 + 2*x^10 + 1
- integral(self)¶
The formal integral of this polynomial. The constant term from boundary conditions is picked to be zero.
>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = 118*x**3 + 11*x**2 + 33*x + 117 >>> f.integral() 111*x^4 + 58*x^3 + 98*x^2 + 117*x
- inverse_mod(self, other)¶
Returns the inverse of
selfmoduloother>>> R = fmpz_mod_poly_ctx(163) >>> f = f = R([123, 129, 63, 14, 51, 76, 133]) >>> f = R([123, 129, 63, 14, 51, 76, 133]) >>> g = R([139, 9, 35, 154, 87, 120, 24]) >>> f.inverse_mod(g) 41*x^5 + 121*x^4 + 47*x^3 + 41*x^2 + 6*x + 5
- inverse_series_trunc(self, slong n)¶
Returns the inverse of
selfmodulo \(x^n\).>>> R = fmpz_mod_poly_ctx(163) >>> f = R([123, 129, 63, 14, 51, 76, 133]) >>> f.inverse_series_trunc(3) 159*x^2 + 151*x + 110 >>> f.inverse_series_trunc(4) 23*x^3 + 159*x^2 + 151*x + 110 >>> f.inverse_series_trunc(5) 45*x^4 + 23*x^3 + 159*x^2 + 151*x + 110
- inverse_sqrt_trunc(self, slong n)¶
Returns the inverse squareroot of
selfmodulo \(x^n\).>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> h = f.inverse_sqrt_trunc(5) >>> h 78*x^4 + 2*x^3 + 162*x + 1 >>> (h*h).inverse_series_trunc(5) == f True
- is_constant(self)¶
Return
Trueif this is a constant polynomial.>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> x.is_constant() False >>> R(123).is_constant() True
- is_gen(self)¶
Return
Trueif the polynomial is the generator of the polynomial, \(x\), andFalseotherwise>>> R = fmpz_mod_poly_ctx(163) >>> f = R([0,1]) >>> f.is_gen() True
- is_irreducible(self)¶
Return whether this polynomial is irreducible.
>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = x**2 + 5*x + 3 >>> f.is_irreducible() True >>> f = x**2 + x + 3 >>> f.is_irreducible() False
- is_monic(self)¶
Return whether this polynomial is monic.
>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = x**2 + 5*x + 3 >>> f.is_monic() True >>> f = 5*x**2 + x + 3 >>> f.is_monic() False
- is_one(self)¶
Return
Trueif the polynomial is equal to one andFalseotherwise>>> R = fmpz_mod_poly_ctx(163) >>> f = R(1) >>> f.is_one() True
- is_squarefree(self)¶
Return whether this polynomial is squarefree.
>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = (x + 1)**2 * (x + 3) >>> f.is_squarefree() False >>> f = (x + 1) * (x + 3) >>> f.is_squarefree() True
- is_zero(self)¶
Return
Trueif the polynomial is the zero polynomial andFalseotherwise>>> R = fmpz_mod_poly_ctx(163) >>> f = R(0) >>> f.is_zero() True
- leading_coefficient(self)¶
Return the leading coefficient of this polynomial.
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.leading_coefficient() fmpz_mod(3, 163)
- left_shift(self, slong n)¶
Returns
selfshifted left byncoefficients by inserting zero coefficients. This is equivalent to multiplying the polynomial by x^n>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.left_shift(0) 3*x^2 + 2*x + 1 >>> f.left_shift(1) 3*x^3 + 2*x^2 + x >>> f.left_shift(4) 3*x^6 + 2*x^5 + x^4
- length(self) long¶
Return the length of the polynomial
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.length() 3
- modulus(self)¶
- monic(self, check=True)¶
Return this polynomial divided by its leading coefficient.
If
checkis True, raises ValueError if the leading coefficient is not invertible modulo N. Ifcheckis False and the leading coefficient is not invertible, the output is undefined.>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.monic() x^2 + 55*x + 109
- mul_low(self, other, slong n)¶
Returns the lowest
ncoefficients of the multiplication ofselfwithotherEquivalent to computing \(f(x) \cdot g(x) \mod x^n\)
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([2,3,5,7,11]) >>> g = R([1,2,4,8,16]) >>> f.mul_low(g, 5) 101*x^4 + 45*x^3 + 19*x^2 + 7*x + 2 >>> f.mul_low(g, 3) 19*x^2 + 7*x + 2 >>> f.mul_low(g, 1) 2
- mul_mod(self, other, modulus)¶
Computes the multiplication of
selfwithothermodulo the polynomialmodulus>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = 30*x**6 + 104*x**5 + 76*x**4 + 33*x**3 + 70*x**2 + 44*x + 65 >>> g = 43*x**6 + 91*x**5 + 77*x**4 + 113*x**3 + 71*x**2 + 132*x + 60 >>> mod = x**4 + 93*x**3 + 78*x**2 + 72*x + 149 >>> >>> f.mul_mod(g, mod) 106*x^3 + 44*x^2 + 53*x + 77
- multipoint_evaluate(self, vals)¶
Returns a list of values computed from evaluating
selfat thenvalues given in the vectorvalTODO: We could allow passing as an optional input the subproduct tree, which would allow for faster, repeated multipoint evaluations
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3,4,5]) >>> [f(x) for x in [-1,-2,-3]] [fmpz_mod(3, 163), fmpz_mod(57, 163), fmpz_mod(156, 163)] >>> f.multipoint_evaluate([-1,-2,-3]) [fmpz_mod(3, 163), fmpz_mod(57, 163), fmpz_mod(156, 163)]
- pow_mod(self, e, modulus, mod_rev_inv=None)¶
Returns
selfraised to the poweremodulomodulus: \(f^e \mod g\)/mod_rev_invis the inverse of the reverse of the modulus, precomputing it and passing it topow_mod()can optimise powering of polynomials with large exponents.>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = 30*x**6 + 104*x**5 + 76*x**4 + 33*x**3 + 70*x**2 + 44*x + 65 >>> g = 43*x**6 + 91*x**5 + 77*x**4 + 113*x**3 + 71*x**2 + 132*x + 60 >>> mod = x**4 + 93*x**3 + 78*x**2 + 72*x + 149 >>> >>> f.pow_mod(123, mod) 3*x^3 + 25*x^2 + 115*x + 161 >>> f.pow_mod(2**64, mod) 52*x^3 + 96*x^2 + 136*x + 9 >>> mod_rev_inv = mod.reverse().inverse_series_trunc(4) >>> f.pow_mod(2**64, mod, mod_rev_inv) 52*x^3 + 96*x^2 + 136*x + 9
- pow_trunc(self, slong e, slong n)¶
Returns
selfraised to the poweremodulo \(x^n\): \(f^e \mod x^n\)/Note: For exponents larger that 2^31 (which do not fit inside a ulong) use the method
pow_mod()with the explicit modulus \(x^n\).>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = 30*x**6 + 104*x**5 + 76*x**4 + 33*x**3 + 70*x**2 + 44*x + 65 >>> f.pow_trunc(2**20, 30) == pow(f, 2**20, x**30) True >>> f.pow_trunc(2**20, 5) 132*x^4 + 113*x^3 + 36*x^2 + 48*x + 6
- radical(self)¶
Return the radical of
self, the product of the irreducible factors of the polynomial. This is also referred to as the square-free part of the polynomial.>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = (x + 1)**3 * (x + 2) >>> f.radical() x^2 + 3*x + 2
- real_roots(self)¶
This method is not implemented for polynomials in \((\mathbb{Z}/N\mathbb{Z})[X]\)
- repr(self)¶
- resultant(self, other)¶
Returns the resultant of
selfwithother.>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3,4,5]) >>> g = R([9,8,7]) >>> f.resultant(g) fmpz_mod(57, 163)
- reverse(self, degree=None)¶
Return a polynomial with the coefficients of this polynomial reversed.
If
degreeis not None, the output polynomial will be zero-padded or truncated before being reversed. NOTE: degree must be non-negative.>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3,4,5]) >>> f.reverse() x^4 + 2*x^3 + 3*x^2 + 4*x + 5 >>> f.reverse(degree=1) x + 2 >>> f.reverse(degree=100) x^100 + 2*x^99 + 3*x^98 + 4*x^97 + 5*x^96
- right_shift(self, slong n)¶
Returns
selfshifted right byncoefficients. This is equivalent to the floor division of the polynomial by x^n>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.right_shift(0) 3*x^2 + 2*x + 1 >>> f.right_shift(1) 3*x + 2 >>> f.right_shift(4) 0
- roots(self, multiplicities=True)¶
Return the roots of the polynomial in \((\mathbb{Z}/N\mathbb{Z})^*\) Requires that the modulus \(N\) is prime.
>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = (x - 1) * (x - 2)**3 * (x - 3)**5 >>> f.roots() [(fmpz_mod(1, 163), 1), (fmpz_mod(2, 163), 3), (fmpz_mod(3, 163), 5)] >>> f.roots(multiplicities=False) [fmpz_mod(1, 163), fmpz_mod(2, 163), fmpz_mod(3, 163)]
- scalar_mul(self, other)¶
Returns the polynomial equal to
selfscaled by the inputother
- sqrt(self)¶
If
selfis a perfect square, compute the square root>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,1]) >>> (f*f).sqrt() x + 1
- sqrt_trunc(self, slong n)¶
Returns the squareroot of
selfmodulo \(x^n\).>>> R = fmpz_mod_poly_ctx(163) >>> x = R.gen() >>> f = R([1,2,3]) >>> h = f.sqrt_trunc(5) >>> h 82*x^4 + 162*x^3 + x^2 + x + 1 >>> h.mul_mod(h, x**5) == f True
- square(self)¶
Returns the square of
self>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.square() 9*x^4 + 12*x^3 + 10*x^2 + 4*x + 1
- str(self, bool ascending=False, var='x', *args, **kwargs)¶
Convert to a human-readable string (generic implementation for all polynomial types).
If ascending is True, the monomials are output from low degree to high, otherwise from high to low.
- sub_trunc(self, other, slong n)¶
Truncate
selfandotherto polynomials of lengthnand return their difference>>> R = fmpz_mod_poly_ctx(163) >>> f = R([2,3,5,7,11]) >>> h = R([1,2,4,8,16]) >>> f.sub_trunc(h, 2) x + 1 >>> f.sub_trunc(h, 4) 162*x^3 + x^2 + x + 1
- truncate(self, slong n)¶
Notionally truncate the polynomial to have length
n. Ifnis larger than the length of the input, then a copy ofselfis returned. Ifnis not positive, then the zero polynomial is returned.Effectively returns this polynomial \(\mod x^n\).
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([1,2,3]) >>> f.truncate(3) == f True >>> f.truncate(2) 2*x + 1 >>> f.truncate(1) 1 >>> f.truncate(0) 0 >>> f.truncate(-1) 0
- xgcd(self, other)¶
Computes the extended gcd of self and other: (\(G\), \(S\), \(T\)) where \(G\) is the
gcd(self, other)and \(S\), \(T\) are such that:\(G = \textrm{self}*S + \textrm{other}*T\)
>>> R = fmpz_mod_poly_ctx(163) >>> f = R([143, 19, 37, 138, 102, 127, 95]) >>> g = R([139, 9, 35, 154, 87, 120, 24]) >>> f.xgcd(g) (x^3 + 128*x^2 + 123*x + 91, 17*x^2 + 49*x + 104, 21*x^2 + 5*x + 25)