diff --git a/src/flint/flint_base/flint_base.pxd b/src/flint/flint_base/flint_base.pxd index 239cab54..d9d31c73 100644 --- a/src/flint/flint_base/flint_base.pxd +++ b/src/flint/flint_base/flint_base.pxd @@ -14,7 +14,37 @@ cdef class flint_mpoly_context(flint_elem): cdef const char ** c_names cdef class flint_mpoly(flint_elem): - pass + cdef _add_scalar_(self, other) + cdef _sub_scalar_(self, other) + cdef _mul_scalar_(self, other) + + cdef _add_mpoly_(self, other) + cdef _sub_mpoly_(self, other) + cdef _mul_mpoly_(self, other) + + cdef _divmod_mpoly_(self, other) + cdef _floordiv_mpoly_(self, other) + cdef _truediv_mpoly_(self, other) + cdef _mod_mpoly_(self, other) + + cdef _rsub_scalar_(self, other) + cdef _rsub_mpoly_(self, other) + + cdef _rdivmod_mpoly_(self, other) + cdef _rfloordiv_mpoly_(self, other) + cdef _rtruediv_mpoly_(self, other) + cdef _rmod_mpoly_(self, other) + + cdef _pow_(self, other) + + cdef _iadd_scalar_(self, other) + cdef _isub_scalar_(self, other) + cdef _imul_scalar_(self, other) + + cdef _iadd_mpoly_(self, other) + cdef _isub_mpoly_(self, other) + cdef _imul_mpoly_(self, other) + cdef class flint_mat(flint_elem): pass diff --git a/src/flint/flint_base/flint_base.pyx b/src/flint/flint_base/flint_base.pyx index 4b9ab56d..e93e69ba 100644 --- a/src/flint/flint_base/flint_base.pyx +++ b/src/flint/flint_base/flint_base.pyx @@ -165,7 +165,6 @@ cdef class flint_scalar(flint_elem): return self._invert_() - cdef class flint_poly(flint_elem): """ Base class for polynomials. @@ -405,52 +404,73 @@ cdef class flint_mpoly(flint_elem): if not other: raise ZeroDivisionError("nmod_mpoly division by zero") - def _add_scalar_(self, other): + cdef _add_scalar_(self, other): + return NotImplemented + + cdef _sub_scalar_(self, other): + return NotImplemented + + cdef _mul_scalar_(self, other): + return NotImplemented + + cdef _add_mpoly_(self, other): + return NotImplemented + + cdef _sub_mpoly_(self, other): + return NotImplemented + + cdef _mul_mpoly_(self, other): return NotImplemented - def _add_mpoly_(self, other): + cdef _divmod_mpoly_(self, other): return NotImplemented - def _iadd_scalar_(self, other): + cdef _floordiv_mpoly_(self, other): return NotImplemented - def _iadd_mpoly_(self, other): + cdef _truediv_mpoly_(self, other): return NotImplemented - def _sub_scalar_(self, other): + cdef _mod_mpoly_(self, other): return NotImplemented - def _sub_mpoly_(self, other): + cdef _rsub_scalar_(self, other): return NotImplemented - def _isub_scalar_(self, other): + cdef _rsub_mpoly_(self, other): return NotImplemented - def _isub_mpoly_(self, other): + cdef _rdivmod_mpoly_(self, other): return NotImplemented - def _mul_scalar_(self, other): + cdef _rfloordiv_mpoly_(self, other): return NotImplemented - def _imul_mpoly_(self, other): + cdef _rtruediv_mpoly_(self, other): return NotImplemented - def _imul_scalar_(self, other): + cdef _rmod_mpoly_(self, other): return NotImplemented - def _mul_mpoly_(self, other): + cdef _pow_(self, other): return NotImplemented - def _pow_(self, other): + cdef _iadd_scalar_(self, other): return NotImplemented - def _divmod_mpoly_(self, other): + cdef _isub_scalar_(self, other): return NotImplemented - def _floordiv_mpoly_(self, other): + cdef _imul_scalar_(self, other): return NotImplemented - def _truediv_mpoly_(self, other): + cdef _iadd_mpoly_(self, other): + return NotImplemented + + cdef _isub_mpoly_(self, other): + return NotImplemented + + cdef _imul_mpoly_(self, other): return NotImplemented def __add__(self, other): @@ -465,32 +485,15 @@ cdef class flint_mpoly(flint_elem): return self._add_scalar_(other) def __radd__(self, other): - return self.__add__(other) - - def iadd(self, other): - """ - In-place addition, mutates self. - - >>> from flint import Ordering, fmpz_mpoly_ctx - >>> ctx = fmpz_mpoly_ctx.get_context(2, Ordering.lex, 'x') - >>> f = ctx.from_dict({(1, 0): 2, (0, 1): 3, (1, 1): 4}) - >>> f - 4*x0*x1 + 2*x0 + 3*x1 - >>> f.iadd(5) - >>> f - 4*x0*x1 + 2*x0 + 3*x1 + 5 - - """ if typecheck(other, type(self)): self.context().compatible_context_check(other.context()) - self._iadd_mpoly_(other) - return + return self._add_mpoly_(other) - other_scalar = self.context().any_as_scalar(other) - if other_scalar is NotImplemented: - raise NotImplementedError(f"cannot add {type(self)} and {type(other)}") + other = self.context().any_as_scalar(other) + if other is NotImplemented: + return NotImplemented - self._iadd_scalar_(other_scalar) + return self._add_scalar_(other) def __sub__(self, other): if typecheck(other, type(self)): @@ -504,32 +507,15 @@ cdef class flint_mpoly(flint_elem): return self._sub_scalar_(other) def __rsub__(self, other): - return -self.__sub__(other) - - def isub(self, other): - """ - In-place subtraction, mutates self. - - >>> from flint import Ordering, fmpz_mpoly_ctx - >>> ctx = fmpz_mpoly_ctx.get_context(2, Ordering.lex, 'x') - >>> f = ctx.from_dict({(1, 0): 2, (0, 1): 3, (1, 1): 4}) - >>> f - 4*x0*x1 + 2*x0 + 3*x1 - >>> f.isub(5) - >>> f - 4*x0*x1 + 2*x0 + 3*x1 - 5 - - """ if typecheck(other, type(self)): self.context().compatible_context_check(other.context()) - self._isub_mpoly_(other) - return + return self._rsub_mpoly_(other) - other_scalar = self.context().any_as_scalar(other) - if other_scalar is NotImplemented: - raise NotImplementedError(f"cannot subtract {type(self)} and {type(other)}") + other = self.context().any_as_scalar(other) + if other is NotImplemented: + return NotImplemented - self._isub_scalar_(other_scalar) + return self._rsub_scalar_(other) def __mul__(self, other): if typecheck(other, type(self)): @@ -543,32 +529,15 @@ cdef class flint_mpoly(flint_elem): return self._mul_scalar_(other) def __rmul__(self, other): - return self.__mul__(other) - - def imul(self, other): - """ - In-place multiplication, mutates self. - - >>> from flint import Ordering, fmpz_mpoly_ctx - >>> ctx = fmpz_mpoly_ctx.get_context(2, Ordering.lex, 'x') - >>> f = ctx.from_dict({(1, 0): 2, (0, 1): 3, (1, 1): 4}) - >>> f - 4*x0*x1 + 2*x0 + 3*x1 - >>> f.imul(2) - >>> f - 8*x0*x1 + 4*x0 + 6*x1 - - """ if typecheck(other, type(self)): self.context().compatible_context_check(other.context()) - self._imul_mpoly_(other) - return + return self._mul_mpoly_(other) - other_scalar = self.context().any_as_scalar(other) - if other_scalar is NotImplemented: - raise NotImplementedError(f"cannot multiply {type(self)} and {type(other)}") + other = self.context().any_as_scalar(other) + if other is NotImplemented: + return NotImplemented - self._imul_scalar_(other_scalar) + return self._mul_scalar_(other) def __pow__(self, other, modulus): if modulus is not None: @@ -605,7 +574,7 @@ cdef class flint_mpoly(flint_elem): other = self.context().scalar_as_mpoly(other) other._division_check(self) - return other._divmod_mpoly_(self) + return self._rdivmod_mpoly_(other) def __truediv__(self, other): if typecheck(other, type(self)): @@ -628,7 +597,7 @@ cdef class flint_mpoly(flint_elem): other = self.context().scalar_as_mpoly(other) other._division_check(self) - return other._truediv_mpoly_(self) + return self._rtruediv_mpoly_(other) def __floordiv__(self, other): if typecheck(other, type(self)): @@ -651,7 +620,7 @@ cdef class flint_mpoly(flint_elem): other = self.context().scalar_as_mpoly(other) other._division_check(self) - return other._floordiv_mpoly_(self) + return self._rfloordiv_mpoly_(other) def __mod__(self, other): if typecheck(other, type(self)): @@ -674,7 +643,82 @@ cdef class flint_mpoly(flint_elem): other = self.context().scalar_as_mpoly(other) other._division_check(self) - return other._mod_mpoly_(self) + return self._rmod_mpoly_(other) + + def iadd(self, other): + """ + In-place addition, mutates self. + + >>> from flint import Ordering, fmpz_mpoly_ctx + >>> ctx = fmpz_mpoly_ctx.get_context(2, Ordering.lex, 'x') + >>> f = ctx.from_dict({(1, 0): 2, (0, 1): 3, (1, 1): 4}) + >>> f + 4*x0*x1 + 2*x0 + 3*x1 + >>> f.iadd(5) + >>> f + 4*x0*x1 + 2*x0 + 3*x1 + 5 + + """ + if typecheck(other, type(self)): + self.context().compatible_context_check(other.context()) + self._iadd_mpoly_(other) + return + + other_scalar = self.context().any_as_scalar(other) + if other_scalar is NotImplemented: + raise NotImplementedError(f"cannot add {type(self)} and {type(other)}") + + self._iadd_scalar_(other_scalar) + + def isub(self, other): + """ + In-place subtraction, mutates self. + + >>> from flint import Ordering, fmpz_mpoly_ctx + >>> ctx = fmpz_mpoly_ctx.get_context(2, Ordering.lex, 'x') + >>> f = ctx.from_dict({(1, 0): 2, (0, 1): 3, (1, 1): 4}) + >>> f + 4*x0*x1 + 2*x0 + 3*x1 + >>> f.isub(5) + >>> f + 4*x0*x1 + 2*x0 + 3*x1 - 5 + + """ + if typecheck(other, type(self)): + self.context().compatible_context_check(other.context()) + self._isub_mpoly_(other) + return + + other_scalar = self.context().any_as_scalar(other) + if other_scalar is NotImplemented: + raise NotImplementedError(f"cannot subtract {type(self)} and {type(other)}") + + self._isub_scalar_(other_scalar) + + def imul(self, other): + """ + In-place multiplication, mutates self. + + >>> from flint import Ordering, fmpz_mpoly_ctx + >>> ctx = fmpz_mpoly_ctx.get_context(2, Ordering.lex, 'x') + >>> f = ctx.from_dict({(1, 0): 2, (0, 1): 3, (1, 1): 4}) + >>> f + 4*x0*x1 + 2*x0 + 3*x1 + >>> f.imul(2) + >>> f + 8*x0*x1 + 4*x0 + 6*x1 + + """ + if typecheck(other, type(self)): + self.context().compatible_context_check(other.context()) + self._imul_mpoly_(other) + return + + other_scalar = self.context().any_as_scalar(other) + if other_scalar is NotImplemented: + raise NotImplementedError(f"cannot multiply {type(self)} and {type(other)}") + + self._imul_scalar_(other_scalar) def __contains__(self, x): """ diff --git a/src/flint/types/fmpq_mpoly.pyx b/src/flint/types/fmpq_mpoly.pyx index 8e3ca9b0..2c8471e5 100644 --- a/src/flint/types/fmpq_mpoly.pyx +++ b/src/flint/types/fmpq_mpoly.pyx @@ -352,78 +352,128 @@ cdef class fmpq_mpoly(flint_mpoly): fmpq_mpoly_neg(res.val, (self).val, res.ctx.val) return res - - def _add_scalar_(self, other: fmpq): + cdef _add_scalar_(self, arg): cdef fmpq_mpoly res + cdef fmpq other = arg res = create_fmpq_mpoly(self.ctx) fmpq_mpoly_add_fmpq(res.val, self.val, other.val, self.ctx.val) return res - def _add_mpoly_(self, other: fmpq_mpoly): - cdef fmpq_mpoly res + cdef _add_mpoly_(self, arg): + cdef fmpq_mpoly res, other = arg res = create_fmpq_mpoly(self.ctx) fmpq_mpoly_add(res.val, self.val, other.val, res.ctx.val) return res - def _sub_scalar_(self, other: fmpq): + cdef _sub_scalar_(self, arg): cdef fmpq_mpoly res + cdef fmpq other = arg res = create_fmpq_mpoly(self.ctx) fmpq_mpoly_sub_fmpq(res.val, self.val, other.val, self.ctx.val) return res - def _sub_mpoly_(self, other: fmpq_mpoly): - cdef fmpq_mpoly res + cdef _sub_mpoly_(self, arg): + cdef fmpq_mpoly res, other = arg res = create_fmpq_mpoly(self.ctx) fmpq_mpoly_sub(res.val, self.val, other.val, res.ctx.val) return res - def _mul_scalar_(self, other: fmpq): + cdef _mul_scalar_(self, arg): cdef fmpq_mpoly res + cdef fmpq other = arg res = create_fmpq_mpoly(self.ctx) fmpq_mpoly_scalar_mul_fmpq(res.val, self.val, other.val, self.ctx.val) return res - def _mul_mpoly_(self, other: fmpq_mpoly): - cdef fmpq_mpoly res + cdef _mul_mpoly_(self, arg): + cdef fmpq_mpoly res, other = arg res = create_fmpq_mpoly(self.ctx) fmpq_mpoly_mul(res.val, self.val, other.val, res.ctx.val) return res - def _pow_(self, other: fmpz): + cdef _pow_(self, arg): cdef fmpq_mpoly res + cdef fmpz other = arg res = create_fmpq_mpoly(self.ctx) if fmpq_mpoly_pow_fmpz(res.val, self.val, other.val, res.ctx.val) == 0: raise ValueError("unreasonably large polynomial") # pragma: no cover return res - def _divmod_mpoly_(self, other: fmpq_mpoly): - cdef fmpq_mpoly quotient, remainder + cdef _divmod_mpoly_(self, arg): + cdef fmpq_mpoly quotient, remainder, other = arg quotient = create_fmpq_mpoly(self.ctx) remainder = create_fmpq_mpoly(self.ctx) fmpq_mpoly_divrem(quotient.val, remainder.val, self.val, other.val, self.ctx.val) return (quotient, remainder) - def _floordiv_mpoly_(self, other: fmpq_mpoly): - cdef fmpq_mpoly quotient + cdef _floordiv_mpoly_(self, arg): + cdef fmpq_mpoly quotient, other = arg quotient = create_fmpq_mpoly(self.ctx) fmpq_mpoly_div(quotient.val, self.val, other.val, self.ctx.val) return quotient - def _truediv_mpoly_(self, other: fmpq_mpoly): - cdef fmpq_mpoly quotient + cdef _truediv_mpoly_(self, arg): + cdef fmpq_mpoly quotient, other = arg quotient = create_fmpq_mpoly(self.ctx) if fmpq_mpoly_divides(quotient.val, self.val, other.val, self.ctx.val): return quotient else: raise DomainError("fmpq_mpoly division is not exact") - def _mod_mpoly_(self, other: fmpq_mpoly): - cdef fmpq_mpoly quotient, remainder + cdef _mod_mpoly_(self, arg): + cdef fmpq_mpoly quotient, remainder, other = arg quotient = create_fmpq_mpoly(self.ctx) remainder = create_fmpq_mpoly(self.ctx) fmpq_mpoly_divrem(quotient.val, remainder.val, self.val, other.val, self.ctx.val) return remainder + cdef _rsub_scalar_(self, arg): + cdef fmpq_mpoly res + cdef fmpq other = arg + res = create_fmpq_mpoly(self.ctx) + fmpq_mpoly_sub_fmpq(res.val, self.val, other.val, self.ctx.val) + fmpq_mpoly_neg(res.val, res.val, res.ctx.val) + return res + + cdef _rsub_mpoly_(self, arg): + return (arg)._sub_mpoly_(self) + + cdef _rdivmod_mpoly_(self, arg): + return (arg)._divmod_mpoly_(self) + + cdef _rfloordiv_mpoly_(self, arg): + return (arg)._floordiv_mpoly_(self) + + cdef _rtruediv_mpoly_(self, arg): + return (arg)._truediv_mpoly_(self) + + cdef _rmod_mpoly_(self, arg): + return (arg)._mod_mpoly_(self) + + cdef _iadd_scalar_(self, arg): + cdef fmpq other = arg + fmpq_mpoly_add_fmpq(self.val, self.val, other.val, self.ctx.val) + + cdef _isub_scalar_(self, arg): + cdef fmpq other = arg + fmpq_mpoly_sub_fmpq(self.val, self.val, other.val, self.ctx.val) + + cdef _imul_scalar_(self, arg): + cdef fmpq other = arg + fmpq_mpoly_scalar_mul_fmpq(self.val, self.val, other.val, self.ctx.val) + + cdef _iadd_mpoly_(self, arg): + cdef fmpq_mpoly other = arg + fmpq_mpoly_add(self.val, self.val, other.val, self.ctx.val) + + cdef _isub_mpoly_(self, arg): + cdef fmpq_mpoly other = arg + fmpq_mpoly_sub(self.val, self.val, other.val, self.ctx.val) + + cdef _imul_mpoly_(self, arg): + cdef fmpq_mpoly other = arg + fmpq_mpoly_mul(self.val, self.val, other.val, self.ctx.val) + def __call__(self, *args) -> fmpq: cdef: fmpq_vec V @@ -439,24 +489,6 @@ cdef class fmpq_mpoly(flint_mpoly): raise ValueError("unreasonably large polynomial") # pragma: no cover return vres - def _iadd_scalar_(self, other: fmpq): - fmpq_mpoly_add_fmpq(self.val, self.val, other.val, self.ctx.val) - - def _iadd_mpoly_(self, other: fmpq_mpoly): - fmpq_mpoly_add(self.val, self.val, other.val, self.ctx.val) - - def _isub_scalar_(self, other: fmpq): - fmpq_mpoly_sub_fmpq(self.val, self.val, other.val, self.ctx.val) - - def _isub_mpoly_(self, other: fmpq_mpoly): - fmpq_mpoly_sub(self.val, self.val, other.val, self.ctx.val) - - def _imul_scalar_(self, other: fmpq): - fmpq_mpoly_scalar_mul_fmpq(self.val, self.val, other.val, self.ctx.val) - - def _imul_mpoly_(self, other: fmpq_mpoly): - fmpq_mpoly_mul(self.val, self.val, other.val, self.ctx.val) - def monoms(self): """ Return the exponent vectors of each term as a tuple of fmpz. diff --git a/src/flint/types/fmpz_mod_mpoly.pyx b/src/flint/types/fmpz_mod_mpoly.pyx index cb7d5ef0..7018a2a0 100644 --- a/src/flint/types/fmpz_mod_mpoly.pyx +++ b/src/flint/types/fmpz_mod_mpoly.pyx @@ -430,77 +430,128 @@ cdef class fmpz_mod_mpoly(flint_mpoly): fmpz_mod_mpoly_neg(res.val, (self).val, res.ctx.val) return res - def _add_scalar_(self, other: fmpz): + cdef _add_scalar_(self, arg): cdef fmpz_mod_mpoly res + cdef fmpz other = arg res = create_fmpz_mod_mpoly(self.ctx) fmpz_mod_mpoly_add_fmpz(res.val, self.val, other.val, self.ctx.val) return res - def _add_mpoly_(self, other: fmpz_mod_mpoly): + cdef _sub_scalar_(self, arg): cdef fmpz_mod_mpoly res + cdef fmpz other = arg res = create_fmpz_mod_mpoly(self.ctx) - fmpz_mod_mpoly_add(res.val, self.val, other.val, res.ctx.val) + fmpz_mod_mpoly_sub_fmpz(res.val, self.val, other.val, self.ctx.val) return res - def _sub_scalar_(self, other: fmpz): + cdef _mul_scalar_(self, arg): cdef fmpz_mod_mpoly res + cdef fmpz other = arg res = create_fmpz_mod_mpoly(self.ctx) - fmpz_mod_mpoly_sub_fmpz(res.val, self.val, other.val, self.ctx.val) + fmpz_mod_mpoly_scalar_mul_fmpz(res.val, self.val, other.val, self.ctx.val) return res - def _sub_mpoly_(self, other: fmpz_mod_mpoly): + cdef _pow_(self, arg): cdef fmpz_mod_mpoly res + cdef fmpz other = arg res = create_fmpz_mod_mpoly(self.ctx) - fmpz_mod_mpoly_sub(res.val, self.val, other.val, res.ctx.val) + if fmpz_mod_mpoly_pow_fmpz(res.val, self.val, other.val, res.ctx.val) == 0: + raise ValueError("unreasonably large polynomial") # pragma: no cover return res - def _mul_scalar_(self, other: fmpz): - cdef fmpz_mod_mpoly res + cdef _add_mpoly_(self, arg): + cdef fmpz_mod_mpoly res, other = arg res = create_fmpz_mod_mpoly(self.ctx) - fmpz_mod_mpoly_scalar_mul_fmpz(res.val, self.val, other.val, self.ctx.val) + fmpz_mod_mpoly_add(res.val, self.val, other.val, res.ctx.val) return res - def _mul_mpoly_(self, other: fmpz_mod_mpoly): - cdef fmpz_mod_mpoly res + cdef _sub_mpoly_(self, arg): + cdef fmpz_mod_mpoly res, other = arg res = create_fmpz_mod_mpoly(self.ctx) - fmpz_mod_mpoly_mul(res.val, self.val, other.val, res.ctx.val) + fmpz_mod_mpoly_sub(res.val, self.val, other.val, res.ctx.val) return res - def _pow_(self, other: fmpz): - cdef fmpz_mod_mpoly res + cdef _mul_mpoly_(self, arg): + cdef fmpz_mod_mpoly res, other = arg res = create_fmpz_mod_mpoly(self.ctx) - if fmpz_mod_mpoly_pow_fmpz(res.val, self.val, other.val, res.ctx.val) == 0: - raise ValueError("unreasonably large polynomial") # pragma: no cover + fmpz_mod_mpoly_mul(res.val, self.val, other.val, res.ctx.val) return res - def _divmod_mpoly_(self, other: fmpz_mod_mpoly): - cdef fmpz_mod_mpoly quotient, remainder + cdef _divmod_mpoly_(self, arg): + cdef fmpz_mod_mpoly quotient, remainder, other = arg quotient = create_fmpz_mod_mpoly(self.ctx) remainder = create_fmpz_mod_mpoly(self.ctx) fmpz_mod_mpoly_divrem(quotient.val, remainder.val, self.val, other.val, self.ctx.val) return (quotient, remainder) - def _floordiv_mpoly_(self, other: fmpz_mod_mpoly): - cdef fmpz_mod_mpoly quotient + cdef _floordiv_mpoly_(self, arg): + cdef fmpz_mod_mpoly quotient, other = arg quotient = create_fmpz_mod_mpoly(self.ctx) fmpz_mod_mpoly_div(quotient.val, self.val, other.val, self.ctx.val) return quotient - def _truediv_mpoly_(self, other: fmpz_mod_mpoly): - cdef fmpz_mod_mpoly quotient + cdef _truediv_mpoly_(self, arg): + cdef fmpz_mod_mpoly quotient, other = arg quotient = create_fmpz_mod_mpoly(self.ctx) if fmpz_mod_mpoly_divides(quotient.val, self.val, other.val, self.ctx.val): return quotient else: raise DomainError("fmpz_mod_mpoly division is not exact") - def _mod_mpoly_(self, other: fmpz_mod_mpoly): - cdef fmpz_mod_mpoly quotient, remainder + cdef _mod_mpoly_(self, arg): + cdef fmpz_mod_mpoly quotient, remainder, other = arg quotient = create_fmpz_mod_mpoly(self.ctx) remainder = create_fmpz_mod_mpoly(self.ctx) fmpz_mod_mpoly_divrem(quotient.val, remainder.val, self.val, other.val, self.ctx.val) return remainder + cdef _rsub_scalar_(self, arg): + cdef fmpz_mod_mpoly res + cdef fmpz other = arg + res = create_fmpz_mod_mpoly(self.ctx) + fmpz_mod_mpoly_sub_fmpz(res.val, self.val, other.val, self.ctx.val) + fmpz_mod_mpoly_neg(res.val, res.val, res.ctx.val) + return res + + cdef _rsub_mpoly_(self, arg): + return (arg)._sub_mpoly_(self) + + cdef _rdivmod_mpoly_(self, arg): + return (arg)._divmod_mpoly_(self) + + cdef _rfloordiv_mpoly_(self, arg): + return (arg)._floordiv_mpoly_(self) + + cdef _rtruediv_mpoly_(self, arg): + return (arg)._truediv_mpoly_(self) + + cdef _rmod_mpoly_(self, arg): + return (arg)._mod_mpoly_(self) + + cdef _iadd_scalar_(self, arg): + cdef fmpz other = arg + fmpz_mod_mpoly_add_fmpz(self.val, self.val, other.val, self.ctx.val) + + cdef _isub_scalar_(self, arg): + cdef fmpz other = arg + fmpz_mod_mpoly_sub_fmpz(self.val, self.val, other.val, self.ctx.val) + + cdef _imul_scalar_(self, arg): + cdef fmpz other = arg + fmpz_mod_mpoly_scalar_mul_fmpz(self.val, self.val, other.val, self.ctx.val) + + cdef _iadd_mpoly_(self, arg): + cdef fmpz_mod_mpoly other = arg + fmpz_mod_mpoly_add(self.val, self.val, other.val, self.ctx.val) + + cdef _isub_mpoly_(self, arg): + cdef fmpz_mod_mpoly other = arg + fmpz_mod_mpoly_sub(self.val, self.val, other.val, self.ctx.val) + + cdef _imul_mpoly_(self, arg): + cdef fmpz_mod_mpoly other = arg + fmpz_mod_mpoly_mul(self.val, self.val, other.val, self.ctx.val) + def __call__(self, *args) -> fmpz: cdef: fmpz_vec V @@ -515,24 +566,6 @@ cdef class fmpz_mod_mpoly(flint_mpoly): fmpz_mod_mpoly_evaluate_all_fmpz(vres.val, self.val, V.double_indirect, self.ctx.val) return vres - def _iadd_scalar_(self, other: fmpz): - fmpz_mod_mpoly_add_fmpz(self.val, self.val, other.val, self.ctx.val) - - def _iadd_mpoly_(self, other: fmpz_mod_mpoly): - fmpz_mod_mpoly_add(self.val, self.val, other.val, self.ctx.val) - - def _isub_scalar_(self, other: fmpz): - fmpz_mod_mpoly_sub_fmpz(self.val, self.val, other.val, self.ctx.val) - - def _isub_mpoly_(self, other: fmpz_mod_mpoly): - fmpz_mod_mpoly_sub(self.val, self.val, other.val, self.ctx.val) - - def _imul_scalar_(self, other: fmpz): - fmpz_mod_mpoly_scalar_mul_fmpz(self.val, self.val, other.val, self.ctx.val) - - def _imul_mpoly_(self, other: fmpz_mod_mpoly): - fmpz_mod_mpoly_mul(self.val, self.val, other.val, self.ctx.val) - def monoms(self): """ Return the exponent vectors of each term as a tuple of fmpz. diff --git a/src/flint/types/fmpz_mpoly.pyx b/src/flint/types/fmpz_mpoly.pyx index 9d1d7696..37898114 100644 --- a/src/flint/types/fmpz_mpoly.pyx +++ b/src/flint/types/fmpz_mpoly.pyx @@ -326,77 +326,128 @@ cdef class fmpz_mpoly(flint_mpoly): fmpz_mpoly_neg(res.val, (self).val, res.ctx.val) return res - def _add_scalar_(self, other: fmpz): + cdef _add_scalar_(self, arg): cdef fmpz_mpoly res + cdef fmpz other = arg res = create_fmpz_mpoly(self.ctx) fmpz_mpoly_add_fmpz(res.val, self.val, other.val, self.ctx.val) return res - def _add_mpoly_(self, other: fmpz_mpoly): + cdef _sub_scalar_(self, arg): cdef fmpz_mpoly res + cdef fmpz other = arg res = create_fmpz_mpoly(self.ctx) - fmpz_mpoly_add(res.val, self.val, other.val, res.ctx.val) + fmpz_mpoly_sub_fmpz(res.val, self.val, other.val, self.ctx.val) return res - def _sub_scalar_(self, other: fmpz): + cdef _mul_scalar_(self, arg): cdef fmpz_mpoly res + cdef fmpz other = arg res = create_fmpz_mpoly(self.ctx) - fmpz_mpoly_sub_fmpz(res.val, self.val, other.val, self.ctx.val) + fmpz_mpoly_scalar_mul_fmpz(res.val, self.val, other.val, self.ctx.val) return res - def _sub_mpoly_(self, other: fmpz_mpoly): + cdef _pow_(self, arg): cdef fmpz_mpoly res + cdef fmpz other = arg res = create_fmpz_mpoly(self.ctx) - fmpz_mpoly_sub(res.val, self.val, other.val, res.ctx.val) + if fmpz_mpoly_pow_fmpz(res.val, self.val, other.val, res.ctx.val) == 0: + raise ValueError("unreasonably large polynomial") # pragma: no cover return res - def _mul_scalar_(self, other: fmpz): - cdef fmpz_mpoly res + cdef _add_mpoly_(self, arg): + cdef fmpz_mpoly res, other = arg res = create_fmpz_mpoly(self.ctx) - fmpz_mpoly_scalar_mul_fmpz(res.val, self.val, other.val, self.ctx.val) + fmpz_mpoly_add(res.val, self.val, other.val, res.ctx.val) return res - def _mul_mpoly_(self, other: fmpz_mpoly): - cdef fmpz_mpoly res + cdef _sub_mpoly_(self, arg): + cdef fmpz_mpoly res, other = arg res = create_fmpz_mpoly(self.ctx) - fmpz_mpoly_mul(res.val, self.val, other.val, res.ctx.val) + fmpz_mpoly_sub(res.val, self.val, other.val, res.ctx.val) return res - def _pow_(self, other: fmpz): - cdef fmpz_mpoly res + cdef _mul_mpoly_(self, arg): + cdef fmpz_mpoly res, other = arg res = create_fmpz_mpoly(self.ctx) - if fmpz_mpoly_pow_fmpz(res.val, self.val, other.val, res.ctx.val) == 0: - raise ValueError("unreasonably large polynomial") # pragma: no cover + fmpz_mpoly_mul(res.val, self.val, other.val, res.ctx.val) return res - def _divmod_mpoly_(self, other: fmpz_mpoly): - cdef fmpz_mpoly quotient, remainder + cdef _divmod_mpoly_(self, arg): + cdef fmpz_mpoly quotient, remainder, other = arg quotient = create_fmpz_mpoly(self.ctx) remainder = create_fmpz_mpoly(self.ctx) fmpz_mpoly_divrem(quotient.val, remainder.val, self.val, other.val, self.ctx.val) return (quotient, remainder) - def _floordiv_mpoly_(self, other: fmpz_mpoly): - cdef fmpz_mpoly quotient + cdef _floordiv_mpoly_(self, arg): + cdef fmpz_mpoly quotient, other = arg quotient = create_fmpz_mpoly(self.ctx) fmpz_mpoly_div(quotient.val, self.val, other.val, self.ctx.val) return quotient - def _truediv_mpoly_(self, other: fmpz_mpoly): - cdef fmpz_mpoly quotient + cdef _truediv_mpoly_(self, arg): + cdef fmpz_mpoly quotient, other = arg quotient = create_fmpz_mpoly(self.ctx) if fmpz_mpoly_divides(quotient.val, self.val, other.val, self.ctx.val): return quotient else: raise DomainError("fmpz_mpoly division is not exact") - def _mod_mpoly_(self, other: fmpz_mpoly): - cdef fmpz_mpoly quotient, remainder + cdef _mod_mpoly_(self, arg): + cdef fmpz_mpoly quotient, remainder, other = arg quotient = create_fmpz_mpoly(self.ctx) remainder = create_fmpz_mpoly(self.ctx) fmpz_mpoly_divrem(quotient.val, remainder.val, self.val, other.val, self.ctx.val) return remainder + cdef _rsub_scalar_(self, arg): + cdef fmpz_mpoly res + cdef fmpz other = arg + res = create_fmpz_mpoly(self.ctx) + fmpz_mpoly_sub_fmpz(res.val, self.val, other.val, self.ctx.val) + fmpz_mpoly_neg(res.val, res.val, res.ctx.val) + return res + + cdef _rsub_mpoly_(self, arg): + return (arg)._sub_mpoly_(self) + + cdef _rdivmod_mpoly_(self, arg): + return (arg)._divmod_mpoly_(self) + + cdef _rfloordiv_mpoly_(self, arg): + return (arg)._floordiv_mpoly_(self) + + cdef _rtruediv_mpoly_(self, arg): + return (arg)._truediv_mpoly_(self) + + cdef _rmod_mpoly_(self, arg): + return (arg)._mod_mpoly_(self) + + cdef _iadd_scalar_(self, arg): + cdef fmpz other = arg + fmpz_mpoly_add_fmpz(self.val, self.val, other.val, self.ctx.val) + + cdef _isub_scalar_(self, arg): + cdef fmpz other = arg + fmpz_mpoly_sub_fmpz(self.val, self.val, other.val, self.ctx.val) + + cdef _imul_scalar_(self, arg): + cdef fmpz other = arg + fmpz_mpoly_scalar_mul_fmpz(self.val, self.val, other.val, self.ctx.val) + + cdef _iadd_mpoly_(self, arg): + cdef fmpz_mpoly other = arg + fmpz_mpoly_add(self.val, self.val, other.val, self.ctx.val) + + cdef _isub_mpoly_(self, arg): + cdef fmpz_mpoly other = arg + fmpz_mpoly_sub(self.val, self.val, other.val, self.ctx.val) + + cdef _imul_mpoly_(self, arg): + cdef fmpz_mpoly other = arg + fmpz_mpoly_mul(self.val, self.val, other.val, self.ctx.val) + def __call__(self, *args) -> fmpz: cdef: fmpz_vec V @@ -412,24 +463,6 @@ cdef class fmpz_mpoly(flint_mpoly): raise ValueError("unreasonably large polynomial") # pragma: no cover return vres - def _iadd_scalar_(self, other: fmpz): - fmpz_mpoly_add_fmpz(self.val, self.val, other.val, self.ctx.val) - - def _iadd_mpoly_(self, other: fmpz_mpoly): - fmpz_mpoly_add(self.val, self.val, other.val, self.ctx.val) - - def _isub_scalar_(self, other: fmpz): - fmpz_mpoly_sub_fmpz(self.val, self.val, other.val, self.ctx.val) - - def _isub_mpoly_(self, other: fmpz_mpoly): - fmpz_mpoly_sub(self.val, self.val, other.val, self.ctx.val) - - def _imul_scalar_(self, other: fmpz): - fmpz_mpoly_scalar_mul_fmpz(self.val, self.val, other.val, self.ctx.val) - - def _imul_mpoly_(self, other: fmpz_mpoly): - fmpz_mpoly_mul(self.val, self.val, other.val, self.ctx.val) - def monoms(self): """ Return the exponent vectors of each term as a tuple of fmpz. diff --git a/src/flint/types/nmod_mpoly.pyx b/src/flint/types/nmod_mpoly.pyx index 1d6e6f75..a29b58d6 100644 --- a/src/flint/types/nmod_mpoly.pyx +++ b/src/flint/types/nmod_mpoly.pyx @@ -406,77 +406,128 @@ cdef class nmod_mpoly(flint_mpoly): nmod_mpoly_neg(res.val, (self).val, res.ctx.val) return res - def _add_scalar_(self, other: ulong): + cdef _add_scalar_(self, arg): cdef nmod_mpoly res + cdef ulong other = arg res = create_nmod_mpoly(self.ctx) nmod_mpoly_add_ui(res.val, self.val, other, self.ctx.val) return res - def _add_mpoly_(self, other: nmod_mpoly): + cdef _sub_scalar_(self, arg): cdef nmod_mpoly res + cdef ulong other = arg res = create_nmod_mpoly(self.ctx) - nmod_mpoly_add(res.val, self.val, other.val, res.ctx.val) + nmod_mpoly_sub_ui(res.val, self.val, other, self.ctx.val) return res - def _sub_scalar_(self, other: ulong): + cdef _mul_scalar_(self, arg): cdef nmod_mpoly res + cdef ulong other = arg res = create_nmod_mpoly(self.ctx) - nmod_mpoly_sub_ui(res.val, self.val, other, self.ctx.val) + nmod_mpoly_scalar_mul_ui(res.val, self.val, other, self.ctx.val) return res - def _sub_mpoly_(self, other: nmod_mpoly): + cdef _pow_(self, arg): cdef nmod_mpoly res + cdef fmpz other = arg res = create_nmod_mpoly(self.ctx) - nmod_mpoly_sub(res.val, self.val, other.val, res.ctx.val) + if nmod_mpoly_pow_fmpz(res.val, self.val, other.val, res.ctx.val) == 0: + raise ValueError("unreasonably large polynomial") # pragma: no cover return res - def _mul_scalar_(self, other: ulong): - cdef nmod_mpoly res + cdef _add_mpoly_(self, arg): + cdef nmod_mpoly res, other = arg res = create_nmod_mpoly(self.ctx) - nmod_mpoly_scalar_mul_ui(res.val, self.val, other, self.ctx.val) + nmod_mpoly_add(res.val, self.val, other.val, res.ctx.val) return res - def _mul_mpoly_(self, other: nmod_mpoly): - cdef nmod_mpoly res + cdef _sub_mpoly_(self, arg): + cdef nmod_mpoly res, other = arg res = create_nmod_mpoly(self.ctx) - nmod_mpoly_mul(res.val, self.val, other.val, res.ctx.val) + nmod_mpoly_sub(res.val, self.val, other.val, res.ctx.val) return res - def _pow_(self, other: fmpz): - cdef nmod_mpoly res + cdef _mul_mpoly_(self, arg): + cdef nmod_mpoly res, other = arg res = create_nmod_mpoly(self.ctx) - if nmod_mpoly_pow_fmpz(res.val, self.val, (other).val, res.ctx.val) == 0: - raise ValueError("unreasonably large polynomial") # pragma: no cover + nmod_mpoly_mul(res.val, self.val, other.val, res.ctx.val) return res - def _divmod_mpoly_(self, other: nmod_mpoly): - cdef nmod_mpoly quotient, remainder + cdef _divmod_mpoly_(self, arg): + cdef nmod_mpoly quotient, remainder, other = arg quotient = create_nmod_mpoly(self.ctx) remainder = create_nmod_mpoly(self.ctx) nmod_mpoly_divrem(quotient.val, remainder.val, self.val, other.val, self.ctx.val) return (quotient, remainder) - def _floordiv_mpoly_(self, other: nmod_mpoly): - cdef nmod_mpoly quotient + cdef _floordiv_mpoly_(self, arg): + cdef nmod_mpoly quotient, other = arg quotient = create_nmod_mpoly(self.ctx) nmod_mpoly_div(quotient.val, self.val, other.val, self.ctx.val) return quotient - def _truediv_mpoly_(self, other: nmod_mpoly): - cdef nmod_mpoly quotient + cdef _truediv_mpoly_(self, arg): + cdef nmod_mpoly quotient, other = arg quotient = create_nmod_mpoly(self.ctx) if nmod_mpoly_divides(quotient.val, self.val, other.val, self.ctx.val): return quotient else: raise DomainError("nmod_mpoly division is not exact") - def _mod_mpoly_(self, other: nmod_mpoly): - cdef nmod_mpoly quotient, remainder + cdef _mod_mpoly_(self, arg): + cdef nmod_mpoly quotient, remainder, other = arg quotient = create_nmod_mpoly(self.ctx) remainder = create_nmod_mpoly(self.ctx) nmod_mpoly_divrem(quotient.val, remainder.val, self.val, other.val, self.ctx.val) return remainder + cdef _rsub_scalar_(self, arg): + cdef nmod_mpoly res + cdef ulong other = arg + res = create_nmod_mpoly(self.ctx) + nmod_mpoly_sub_ui(res.val, self.val, other, self.ctx.val) + nmod_mpoly_neg(res.val, res.val, res.ctx.val) + return res + + cdef _rsub_mpoly_(self, arg): + return (arg)._sub_mpoly_(self) + + cdef _rdivmod_mpoly_(self, arg): + return (arg)._divmod_mpoly_(self) + + cdef _rfloordiv_mpoly_(self, arg): + return (arg)._floordiv_mpoly_(self) + + cdef _rtruediv_mpoly_(self, arg): + return (arg)._truediv_mpoly_(self) + + cdef _rmod_mpoly_(self, arg): + return (arg)._mod_mpoly_(self) + + cdef _iadd_scalar_(self, arg): + cdef ulong other = arg + nmod_mpoly_add_ui(self.val, self.val, other, self.ctx.val) + + cdef _isub_scalar_(self, arg): + cdef ulong other = arg + nmod_mpoly_sub_ui(self.val, self.val, other, self.ctx.val) + + cdef _imul_scalar_(self, arg): + cdef ulong other = arg + nmod_mpoly_scalar_mul_ui(self.val, self.val, other, self.ctx.val) + + cdef _iadd_mpoly_(self, arg): + cdef nmod_mpoly other = arg + nmod_mpoly_add(self.val, self.val, other.val, self.ctx.val) + + cdef _isub_mpoly_(self, arg): + cdef nmod_mpoly other = arg + nmod_mpoly_sub(self.val, self.val, other.val, self.ctx.val) + + cdef _imul_mpoly_(self, arg): + cdef nmod_mpoly other = arg + nmod_mpoly_mul(self.val, self.val, other.val, self.ctx.val) + def __call__(self, *args) -> ulong: cdef: slong nvars = self.ctx.nvars(), nargs = len(args) @@ -502,24 +553,6 @@ cdef class nmod_mpoly(flint_mpoly): return res - def _iadd_scalar_(self, other: ulong): - nmod_mpoly_add_ui(self.val, self.val, other, self.ctx.val) - - def _iadd_mpoly_(self, other: nmod_mpoly): - nmod_mpoly_add(self.val, self.val, other.val, self.ctx.val) - - def _isub_scalar_(self, other: ulong): - nmod_mpoly_sub_ui(self.val, self.val, other, self.ctx.val) - - def _isub_mpoly_(self, other: nmod_mpoly): - nmod_mpoly_sub(self.val, self.val, other.val, self.ctx.val) - - def _imul_scalar_(self, other: ulong): - nmod_mpoly_scalar_mul_ui(self.val, self.val, other, self.ctx.val) - - def _imul_mpoly_(self, other: nmod_mpoly): - nmod_mpoly_mul(self.val, self.val, other.val, self.ctx.val) - def monoms(self): """ Return the exponent vectors of each term as a tuple of fmpz.