Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b24ec90
test: use cython==3.0.0a11 to build in CI
oscarbenjamin Dec 14, 2022
5fe55f3
fix: add __radd__ etc to fmpz
oscarbenjamin Dec 14, 2022
12885b6
test: also use cython 3 on Windows
oscarbenjamin Dec 14, 2022
3bacb07
fix: remove redundant paths in dunder methods
oscarbenjamin Apr 20, 2023
978696a
fix: add __rdunder__ methods for fmpq and nmod
oscarbenjamin Apr 20, 2023
1556939
fix: add __rdunder__ fmpz_mat, fmpq_mat and nmp_mat
oscarbenjamin Aug 3, 2023
19d7526
fix: add __rdunder__ fmpz_poly, fmpq_poly and nmp_poly
oscarbenjamin Apr 21, 2023
4d9175b
fix: add __rdunder__ methods fmpz_series, fmpq_series
oscarbenjamin Apr 21, 2023
3c03077
fix: add __rdunder__ methods for arb and acb
oscarbenjamin Apr 21, 2023
fcda89f
Use cython 3.0.0b2
oscarbenjamin Apr 21, 2023
5082c78
fix: add modulus arg to acb.__rpow__
oscarbenjamin Apr 21, 2023
5a4a2aa
fix: __rdunder__ acb_poly, acb_series, arb_poly, arb_series
oscarbenjamin Apr 21, 2023
d3c2519
Use cython==3.0.0b2 in Cirruc CI as well
oscarbenjamin Apr 21, 2023
0a8bf5c
fix: add __rdunder__ methods for acb_mat and arb_mat
oscarbenjamin Apr 21, 2023
913f69c
Add redundant type casts for older Cython
oscarbenjamin Apr 21, 2023
a390bdc
fix: fmpz_mat * nmod_mat -> nmod_mat
oscarbenjamin Aug 3, 2023
12bc215
Use GMP mirror from GitHub in CI
oscarbenjamin Aug 3, 2023
e1c0c70
Update Cython -> 3.0.0, GMP -> 6.3.0
oscarbenjamin Aug 3, 2023
d4db446
Do not apply GMP macos_arm64 patch
oscarbenjamin Aug 3, 2023
0370688
Remove version constraints for Cython
oscarbenjamin Aug 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: add __radd__ etc to fmpz
This is needed for Cython 3.x compatibility:

https://cython.readthedocs.io/en/latest/src/userguide/special_methods.html#arithmetic-methods

Similar methods should be added to all python-flint types that have
arithmetic operations.
  • Loading branch information
oscarbenjamin committed Aug 3, 2023
commit 5fe55f3817be07d723c08ebe141b82fc182d7cd5
95 changes: 95 additions & 0 deletions src/flint/fmpz.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,17 @@ cdef class fmpz(flint_scalar):
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __radd__(s, t):
cdef fmpz_struct tval[1]
cdef int ttype = FMPZ_UNKNOWN
u = NotImplemented
ttype = fmpz_set_any_ref(tval, t)
if ttype != FMPZ_UNKNOWN:
u = fmpz.__new__(fmpz)
fmpz_add((<fmpz>u).val, tval, (<fmpz>s).val)
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __sub__(s, t):
cdef fmpz_struct sval[1]
cdef fmpz_struct tval[1]
Expand All @@ -205,6 +216,17 @@ cdef class fmpz(flint_scalar):
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __rsub__(s, t):
cdef fmpz_struct tval[1]
cdef int ttype = FMPZ_UNKNOWN
u = NotImplemented
ttype = fmpz_set_any_ref(tval, t)
if ttype != FMPZ_UNKNOWN:
u = fmpz.__new__(fmpz)
fmpz_sub((<fmpz>u).val, tval, (<fmpz>s).val)
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __mul__(s, t):
cdef fmpz_struct sval[1]
cdef fmpz_struct tval[1]
Expand All @@ -221,6 +243,17 @@ cdef class fmpz(flint_scalar):
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __rmul__(s, t):
cdef fmpz_struct tval[1]
cdef int ttype = FMPZ_UNKNOWN
u = NotImplemented
ttype = fmpz_set_any_ref(tval, t)
if ttype != FMPZ_UNKNOWN:
u = fmpz.__new__(fmpz)
fmpz_mul((<fmpz>u).val, tval, (<fmpz>s).val)
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __floordiv__(s, t):
cdef fmpz_struct sval[1]
cdef fmpz_struct tval[1]
Expand All @@ -241,6 +274,21 @@ cdef class fmpz(flint_scalar):
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __rfloordiv__(s, t):
cdef fmpz_struct tval[1]
cdef int ttype = FMPZ_UNKNOWN
u = NotImplemented
ttype = fmpz_set_any_ref(tval, t)
if ttype != FMPZ_UNKNOWN:
if fmpz_is_zero((<fmpz>s).val):
if ttype == FMPZ_TMP:
fmpz_clear(tval)
raise ZeroDivisionError("fmpz division by zero")
u = fmpz.__new__(fmpz)
fmpz_fdiv_q((<fmpz>u).val, tval, (<fmpz>s).val)
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __mod__(s, t):
cdef fmpz_struct sval[1]
cdef fmpz_struct tval[1]
Expand All @@ -261,6 +309,21 @@ cdef class fmpz(flint_scalar):
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __rmod__(s, t):
cdef fmpz_struct tval[1]
cdef int ttype = FMPZ_UNKNOWN
u = NotImplemented
ttype = fmpz_set_any_ref(tval, t)
if ttype != FMPZ_UNKNOWN:
if fmpz_is_zero((<fmpz>s).val):
if ttype == FMPZ_TMP:
fmpz_clear(tval)
raise ZeroDivisionError("fmpz division by zero")
u = fmpz.__new__(fmpz)
fmpz_fdiv_r((<fmpz>u).val, tval, (<fmpz>s).val)
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __divmod__(s, t):
cdef fmpz_struct sval[1]
cdef fmpz_struct tval[1]
Expand All @@ -283,6 +346,23 @@ cdef class fmpz(flint_scalar):
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __rdivmod__(s, t):
cdef fmpz_struct tval[1]
cdef int ttype = FMPZ_UNKNOWN
u = NotImplemented
ttype = fmpz_set_any_ref(tval, t)
if ttype != FMPZ_UNKNOWN:
if fmpz_is_zero((<fmpz>s).val):
if ttype == FMPZ_TMP:
fmpz_clear(tval)
raise ZeroDivisionError("fmpz division by zero")
u1 = fmpz.__new__(fmpz)
u2 = fmpz.__new__(fmpz)
fmpz_fdiv_qr((<fmpz>u1).val, (<fmpz>u2).val, tval, (<fmpz>s).val)
u = u1, u2
if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def __pow__(s, t, m):
cdef fmpz_struct sval[1]
cdef int stype = FMPZ_UNKNOWN
Expand All @@ -298,6 +378,21 @@ cdef class fmpz(flint_scalar):
if stype == FMPZ_TMP: fmpz_clear(sval)
return u

def __rpow__(s, t, m):
cdef fmpz_struct tval[1]
cdef int stype = FMPZ_UNKNOWN
cdef ulong exp
u = NotImplemented
if m is not None:
raise NotImplementedError("modular exponentiation")
ttype = fmpz_set_any_ref(tval, t)
if ttype != FMPZ_UNKNOWN:
u = fmpz.__new__(fmpz)
s_ulong = fmpz_get_ui(s.val)
fmpz_pow_ui((<fmpz>u).val, tval, s_ulong)
Comment on lines 381 to 357
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this.

Actually I see that with current master and Cython 0.29 we have:

>>> import flint
>>> flint.fmpz(2) ** flint.fmpz(-2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "src/flint/fmpz.pyx", line 297, in flint._flint.fmpz.__pow__
    fmpz_pow_ui((<fmpz>u).val, sval, c)
OverflowError: can't convert negative value to ulong

So I guess the existing __pow__ method should be changed. At least OverflowError is not the right exception to raise.

Python itself gives:

>>> 2 ** -2
0.25
>>> 1 ** -1
1.0
>>> 2 ** 2
4

In principle an fmpq could be returned but I'm not sure if that's better than an error.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gmpy2 returns mpfr:

In [3]: gmpy2.mpz(2) ** -2
Out[3]: mpfr('0.25')

In [4]: gmpy2.mpz(2) ** 2
Out[4]: mpz(4)

It's probably good to maintain compatibility with gmpy2.mpz and int itself if possible so that mpz can be used interchangeably with those. I'm not sure what type that really means in the python-flint context though.

if ttype == FMPZ_TMP: fmpz_clear(tval)
return u

def gcd(self, other):
"""
Returns the greatest common divisor of self and other.
Expand Down