Repository: flintlib/python-flint (language: python)

Issue:
fmpz_mod_poly has mulmod and mul_mod
It's my mistake but making an issue so we can decide on which name of the two to keep


Discussion / hints:
I think we discussed this recently and most methods were `meth_mod` like `pow_mod`, etc. Not sure how consistent it is:
```console
$ git grep 'def .*mod(' src/flint/types/
src/flint/types/fmpz.pyx:    def sqrtmod(self, m):
src/flint/types/fmpz_mod.pxd:    cdef set_any_as_fmpz_mod(self, fmpz_t val, obj)
src/flint/types/fmpz_mod.pxd:    cdef any_as_fmpz_mod(self, obj)
src/flint/types/fmpz_mod.pxd:cdef class fmpz_mod(flint_scalar):
src/flint/types/fmpz_mod.pyx:    cdef set_any_as_fmpz_mod(self, fmpz_t val, obj):
src/flint/types/fmpz_mod.pyx:    cdef any_as_fmpz_mod(self, obj):
src/flint/types/fmpz_mod.pyx:cdef class fmpz_mod(flint_scalar):
src/flint/types/fmpz_mod_poly.pyx:    def compose_mod(self, other, modulus):
src/flint/types/fmpz_mod_poly.pyx:    def mulmod(self, other, modulus):
src/flint/types/fmpz_mod_poly.pyx:    def pow_mod(self, e, modulus, mod_rev_inv=None):
src/flint/types/fmpz_mod_poly.pyx:    def divmod(self, other):
src/flint/types/fmpz_mod_poly.pyx:    def inverse_mod(self, other):
src/flint/types/fmpz_mod_poly.pyx:    def mul_mod(self, other, modulus):
src/flint/types/nmod.pxd:cdef int any_as_nmod(mp_limb_t * val, obj, nmod_t mod) except -1
src/flint/types/nmod.pxd:cdef class nmod(flint_scalar):
src/flint/types/nmod.pyx:cdef int any_as_nmod(mp_limb_t * val, obj, nmod_t mod) except -1:
src/flint/types/nmod.pyx:cdef class nmod(flint_scalar):
src/flint/types/nmod_mat.pxd:    cdef __mul_nmod(self, mp_limb_t c)
src/flint/types/nmod_mat.pyx:    cdef __mul_nmod(self, mp_limb_t c):
src/flint/types/nmod_poly.pyx:    def compose_mod(self, other, modulus):
src/flint/types/nmod_poly.pyx:    def pow_mod(self, e, modulus, mod_rev_inv=None):
```

Fix patch:
diff --git a/src/flint/types/fmpz_mod_poly.pyx b/src/flint/types/fmpz_mod_poly.pyx
index 5830da03..a3884ac9 100644
--- a/src/flint/types/fmpz_mod_poly.pyx
+++ b/src/flint/types/fmpz_mod_poly.pyx
@@ -1106,7 +1106,7 @@ cdef class fmpz_mod_poly(flint_poly):
         )
         return res
 
-    def mulmod(self, other, modulus):
+    def mul_mod(self, other, modulus):
         """
         Computes the multiplication of ``self`` with ``other``
         modulo the polynomial ``modulus``
@@ -1117,7 +1117,7 @@ cdef class fmpz_mod_poly(flint_poly):
             >>> 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.mulmod(g, mod)
+            >>> f.mul_mod(g, mod)
             106*x^3 + 44*x^2 + 53*x + 77
         """
         cdef fmpz_mod_poly res
@@ -1504,7 +1504,7 @@ cdef class fmpz_mod_poly(flint_poly):
             >>> h = f.sqrt_trunc(5)
             >>> h
             82*x^4 + 162*x^3 + x^2 + x + 1
-            >>> h.mulmod(h, x**5) == f
+            >>> h.mul_mod(h, x**5) == f
             True
 
         """
@@ -1647,38 +1647,6 @@ cdef class fmpz_mod_poly(flint_poly):
         )
         return res
 
-    def mul_mod(self, other, modulus):
-        r"""
-        Returns remainder of the product of ``self`` with ``other`` after reduction by ``modulus``
-
-        Equivalent 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])
-        >>> h = R([1,0,1])
-        >>> f.mul_mod(g, h) == (f * g) % h
-        True
-        >>> f.mul_mod(g, h)
-        63*x + 80
-        """
-        # Only allow multiplication and reduction with other fmpz_mod_poly
-        if not typecheck(other, fmpz_mod_poly) or not typecheck(modulus, fmpz_mod_poly):
-            raise TypeError("input polynomials must be of type fmpz_mod_poly")
-
-        # Ensure the contexts match
-        other_c = <fmpz_mod_poly>other
-        modulus_c = <fmpz_mod_poly>modulus
-        if (self.ctx != other_c.ctx) or (self.ctx != modulus_c.ctx):
-            raise ValueError("other polynomial's context does not match")
-
-        cdef fmpz_mod_poly res
-        res = self.ctx.new_ctype_poly()
-        fmpz_mod_poly_mulmod(
-            res.val, self.val, other_c.val, modulus_c.val, res.ctx.mod.val
-        )
-        return res
-
     def pow_trunc(self, slong e, slong n):
         """
         Returns ``self`` raised to the power ``e`` modulo `x^n`:


Test patch:
diff --git a/src/flint/test/test_all.py b/src/flint/test/test_all.py
index 991c0291..200a0f84 100644
--- a/src/flint/test/test_all.py
+++ b/src/flint/test/test_all.py
@@ -2158,9 +2158,9 @@ def test_fmpz_mod_poly():
         assert f*f == f**2 == f.square()
 
         # mulmod
-        assert f.mulmod(f, g) == (f*f) % g
-        assert raises(lambda: f.mulmod(f, "AAA"), TypeError)
-        assert raises(lambda: f.mulmod("AAA", g), TypeError)
+        assert f.mul_mod(f, g) == (f*f) % g
+        assert raises(lambda: f.mul_mod(f, "AAA"), TypeError)
+        assert raises(lambda: f.mul_mod("AAA", g), TypeError)
 
         # pow_mod
         assert f.pow_mod(2, g) == (f*f) % g
@@ -2272,10 +2272,6 @@ def test_fmpz_mod_poly():
         assert raises(lambda: f.mul_low(g, "A"), TypeError)
         assert f.mul_low(g, 3) == (f * g) % x**3
 
-        assert raises(lambda: f.mul_mod(f_cmp, h), ValueError)
-        assert raises(lambda: f.mul_mod(g, f_cmp), ValueError)
-        assert f.mul_mod(g, h) == (f * g) % h
-
         assert raises(lambda: f.pow_trunc(-1, 5), ValueError)