Skip to content

Commit

Permalink
Add @cython.no_gc to nmod_poly and nmod_mat
Browse files Browse the repository at this point in the history
  • Loading branch information
oscarbenjamin committed Aug 29, 2024
1 parent 6546f12 commit 2c6aa95
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 16 deletions.
3 changes: 2 additions & 1 deletion src/flint/types/nmod_mat.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ cdef class nmod_mat_ctx:
return nmod_mat(*args, self)


@cython.no_gc
cdef class nmod_mat(flint_mat):
"""
The nmod_mat type represents dense matrices over Z/nZ for word-size n (see
Expand Down Expand Up @@ -475,7 +476,7 @@ cdef class nmod_mat(flint_mat):
cdef nmod_mat_struct *sv
cdef nmod_mat_struct *tv
cdef mp_limb_t c
sv = &(<nmod_mat>s).val[0]
sv = &s.val[0]
u = s.ctx.any_as_nmod_mat(t)
if u is NotImplemented:
if s.ctx.any_as_nmod(&c, t):
Expand Down
33 changes: 18 additions & 15 deletions src/flint/types/nmod_poly.pyx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
cimport cython

from cpython.list cimport PyList_GET_SIZE
from flint.flint_base.flint_base cimport flint_poly
from flint.utils.typecheck cimport typecheck
Expand All @@ -18,9 +20,10 @@ from flint.utils.flint_exceptions import DomainError
cdef dict _nmod_poly_ctx_cache = {}


@cython.no_gc
cdef class nmod_poly_ctx:
"""
Context object for creating :class:`~.nmod_poly` initalised
Context object for creating :class:`~.nmod_poly` initalised
with modulus :math:`N`.
>>> nmod_poly_ctx.new(17)
Expand Down Expand Up @@ -170,6 +173,7 @@ cdef class nmod_poly_ctx:
return nmod_poly(arg, self)


@cython.no_gc
cdef class nmod_poly(flint_poly):
"""
The nmod_poly type represents dense univariate polynomials
Expand Down Expand Up @@ -337,7 +341,7 @@ cdef class nmod_poly(flint_poly):
"""
cdef nmod_poly res
cdef slong d

if degree is not None:
d = degree
if d != degree or d < 0:
Expand Down Expand Up @@ -387,7 +391,7 @@ cdef class nmod_poly(flint_poly):
"""
if n <= 0:
raise ValueError(f"{n = } must be positive")

if nmod_poly_get_coeff_ui(self.val, 0) == 0:
raise ZeroDivisionError(f"nmod_poly inverse_series_trunc: leading coefficient is zero")

Expand All @@ -402,7 +406,7 @@ cdef class nmod_poly(flint_poly):
"""
Returns the composition of two polynomials
To be precise about the order of composition, given ``self``, and ``other``
To be precise about the order of composition, given ``self``, and ``other``
by `f(x)`, `g(x)`, returns `f(g(x))`.
>>> f = nmod_poly([1,2,3], 163)
Expand All @@ -417,15 +421,15 @@ cdef class nmod_poly(flint_poly):
if other is NotImplemented:
raise TypeError("cannot convert input to nmod_poly")
res = self.ctx.new_nmod_poly()
nmod_poly_compose(res.val, self.val, (<nmod_poly>other).val)
return res
nmod_poly_compose(res.val, self.val, (<nmod_poly>other).val)
return res

def compose_mod(self, other, modulus):
"""
Returns the composition of two polynomials modulo a third.
To be precise about the order of composition, given ``self``, and ``other``
and ``modulus`` by `f(x)`, `g(x)` and `h(x)`, returns `f(g(x)) \mod h(x)`.
To be precise about the order of composition, given ``self``, and ``other``
and ``modulus`` by `f(x)`, `g(x)` and `h(x)`, returns `f(g(x)) \mod h(x)`.
We require that `h(x)` is non-zero.
>>> f = nmod_poly([1,2,3,4,5], 163)
Expand All @@ -440,17 +444,17 @@ cdef class nmod_poly(flint_poly):
g = self.ctx.any_as_nmod_poly(other)
if g is NotImplemented:
raise TypeError(f"cannot convert {other = } to nmod_poly")

h = self.ctx.any_as_nmod_poly(modulus)
if h is NotImplemented:
raise TypeError(f"cannot convert {modulus = } to nmod_poly")

if modulus.is_zero():
raise ZeroDivisionError("cannot reduce modulo zero")

res = self.ctx.new_nmod_poly()
nmod_poly_compose_mod(res.val, self.val, (<nmod_poly>other).val, (<nmod_poly>modulus).val)
return res
nmod_poly_compose_mod(res.val, self.val, (<nmod_poly>other).val, (<nmod_poly>modulus).val)
return res

def __call__(self, other):
cdef nmod_poly r
Expand Down Expand Up @@ -638,8 +642,7 @@ cdef class nmod_poly(flint_poly):
>>> 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)
>>> 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
Expand All @@ -663,7 +666,7 @@ cdef class nmod_poly(flint_poly):

# Output polynomial
res = self.ctx.new_nmod_poly()

# For small exponents, use a simple binary exponentiation method
if e.bit_length() < 32:
nmod_poly_powmod_ui_binexp(
Expand Down

0 comments on commit 2c6aa95

Please sign in to comment.