Skip to content

Commit c76120c

Browse files
Add mul_low and pow_trunc methods to nmod_poly
1 parent d5c40a4 commit c76120c

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

src/flint/types/nmod_poly.pyx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,60 @@ cdef class nmod_poly(flint_poly):
724724
)
725725
return res
726726

727+
def mul_low(self, other, slong n):
728+
r"""
729+
Returns the lowest ``n`` coefficients of the multiplication of ``self`` with ``other``
730+
731+
Equivalent to computing `f(x) \cdot g(x) \mod x^n`
732+
733+
>>> f = nmod_poly([2,3,5,7,11], 163)
734+
>>> g = nmod_poly([1,2,4,8,16], 163)
735+
>>> f.mul_low(g, 5)
736+
101*x^4 + 45*x^3 + 19*x^2 + 7*x + 2
737+
>>> f.mul_low(g, 3)
738+
19*x^2 + 7*x + 2
739+
>>> f.mul_low(g, 1)
740+
2
741+
"""
742+
# Only allow multiplication with other nmod_poly
743+
if not typecheck(other, nmod_poly):
744+
raise TypeError("other polynomial must be of type nmod_poly")
745+
746+
if (<nmod_poly>self).val.mod.n != (<nmod_poly>other).val.mod.n:
747+
raise ValueError("cannot multiply nmod_polys with different moduli")
748+
749+
cdef nmod_poly res = nmod_poly.__new__(nmod_poly)
750+
res = nmod_poly.__new__(nmod_poly)
751+
nmod_poly_init_preinv(res.val, self.val.mod.n, self.val.mod.ninv)
752+
nmod_poly_mullow(res.val, self.val, (<nmod_poly>other).val, n)
753+
return res
754+
755+
def pow_trunc(self, slong e, slong n):
756+
r"""
757+
Returns ``self`` raised to the power ``e`` modulo `x^n`:
758+
:math:`f^e \mod x^n`/
759+
760+
Note: For exponents larger that 2^63 (which do not fit inside a slong) use the
761+
method :meth:`~.pow_mod` with the explicit modulus `x^n`.
762+
763+
>>> f = nmod_poly([65, 44, 70, 33, 76, 104, 30], 163)
764+
>>> x = nmod_poly([0, 1], 163)
765+
>>> f.pow_trunc(2**20, 30) == pow(f, 2**20, x**30)
766+
True
767+
>>> f.pow_trunc(2**20, 5)
768+
132*x^4 + 113*x^3 + 36*x^2 + 48*x + 6
769+
>>> f.pow_trunc(5**25, 5)
770+
147*x^4 + 98*x^3 + 95*x^2 + 33*x + 126
771+
"""
772+
if e < 0:
773+
raise ValueError("Exponent must be non-negative")
774+
775+
cdef nmod_poly res = nmod_poly.__new__(nmod_poly)
776+
res = nmod_poly.__new__(nmod_poly)
777+
nmod_poly_init_preinv(res.val, self.val.mod.n, self.val.mod.ninv)
778+
nmod_poly_pow_trunc(res.val, self.val, e, n)
779+
return res
780+
727781
def gcd(self, other):
728782
"""
729783
Returns the monic greatest common divisor of self and other.

0 commit comments

Comments
 (0)