Skip to content

Commit 9dec414

Browse files
Add mul_low and pow_trunc methods to fmpz_poly and fmpq_poly
1 parent c76120c commit 9dec414

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

src/flint/types/fmpq_poly.pyx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,53 @@ cdef class fmpq_poly(flint_poly):
502502
fmpq_poly_pow(res.val, self.val, <ulong>exp)
503503
return res
504504

505+
def mul_low(self, other, slong n):
506+
r"""
507+
Returns the lowest ``n`` coefficients of the multiplication of ``self`` with ``other``
508+
509+
Equivalent to computing `f(x) \cdot g(x) \mod x^n`
510+
511+
>>> f = fmpq_poly([2,3,5,7,11])
512+
>>> g = fmpq_poly([1,2,4,8,16])
513+
>>> f.mul_low(g, 5)
514+
101*x^4 + 45*x^3 + 19*x^2 + 7*x + 2
515+
>>> f.mul_low(g, 3)
516+
19*x^2 + 7*x + 2
517+
>>> f.mul_low(g, 1)
518+
2
519+
"""
520+
# Only allow multiplication with other fmpq_poly
521+
if not typecheck(other, fmpq_poly):
522+
raise TypeError("other polynomial must be of type fmpq_poly")
523+
524+
cdef fmpq_poly res
525+
res = fmpq_poly.__new__(fmpq_poly)
526+
fmpq_poly_mullow(res.val, self.val, (<fmpq_poly>other).val, n)
527+
return res
528+
529+
def pow_trunc(self, slong e, slong n):
530+
r"""
531+
Returns ``self`` raised to the power ``e`` modulo `x^n`:
532+
:math:`f^e \mod x^n`/
533+
534+
Note: For exponents larger that 2^63 (which do not fit inside a slong) use the
535+
method :meth:`~.pow_mod` with the explicit modulus `x^n`.
536+
537+
>>> f = fmpq_poly([1, 2, 3])
538+
>>> x = fmpq_poly([0, 1])
539+
>>> f.pow_trunc(2**20, 4)
540+
1537230871828889600*x^3 + 2199024304128*x^2 + 2097152*x + 1
541+
>>> f.pow_trunc(5**25, 3)
542+
177635683940025046765804290771484375*x^2 + 596046447753906250*x + 1
543+
"""
544+
if e < 0:
545+
raise ValueError("Exponent must be non-negative")
546+
547+
cdef fmpq_poly res
548+
res = fmpq_poly.__new__(fmpq_poly)
549+
fmpq_poly_pow_trunc(res.val, self.val, e, n)
550+
return res
551+
505552
def gcd(self, other):
506553
"""
507554
Returns the greatest common divisor of *self* and *other*.

src/flint/types/fmpz_poly.pyx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,53 @@ cdef class fmpz_poly(flint_poly):
483483
fmpz_poly_pow(res.val, self.val, <ulong>exp)
484484
return res
485485

486+
def mul_low(self, other, slong n):
487+
r"""
488+
Returns the lowest ``n`` coefficients of the multiplication of ``self`` with ``other``
489+
490+
Equivalent to computing `f(x) \cdot g(x) \mod x^n`
491+
492+
>>> f = fmpz_poly([2,3,5,7,11])
493+
>>> g = fmpz_poly([1,2,4,8,16])
494+
>>> f.mul_low(g, 5)
495+
101*x^4 + 45*x^3 + 19*x^2 + 7*x + 2
496+
>>> f.mul_low(g, 3)
497+
19*x^2 + 7*x + 2
498+
>>> f.mul_low(g, 1)
499+
2
500+
"""
501+
# Only allow multiplication with other fmpz_poly
502+
if not typecheck(other, fmpz_poly):
503+
raise TypeError("other polynomial must be of type fmpz_poly")
504+
505+
cdef fmpz_poly res
506+
res = fmpz_poly.__new__(fmpz_poly)
507+
fmpz_poly_mullow(res.val, self.val, (<fmpz_poly>other).val, n)
508+
return res
509+
510+
def pow_trunc(self, slong e, slong n):
511+
r"""
512+
Returns ``self`` raised to the power ``e`` modulo `x^n`:
513+
:math:`f^e \mod x^n`/
514+
515+
Note: For exponents larger that 2^63 (which do not fit inside a slong) use the
516+
method :meth:`~.pow_mod` with the explicit modulus `x^n`.
517+
518+
>>> f = fmpz_poly([1, 2, 3])
519+
>>> x = fmpz_poly([0, 1])
520+
>>> f.pow_trunc(2**20, 4)
521+
1537230871828889600*x^3 + 2199024304128*x^2 + 2097152*x + 1
522+
>>> f.pow_trunc(5**25, 3)
523+
177635683940025046765804290771484375*x^2 + 596046447753906250*x + 1
524+
"""
525+
if e < 0:
526+
raise ValueError("Exponent must be non-negative")
527+
528+
cdef fmpz_poly res
529+
res = fmpz_poly.__new__(fmpz_poly)
530+
fmpz_poly_pow_trunc(res.val, self.val, e, n)
531+
return res
532+
486533
def gcd(self, other):
487534
"""
488535
Returns the greatest common divisor of self and other.

0 commit comments

Comments
 (0)