Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow comparison with nmod to fmpz and fmpz_mod #178

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions src/flint/test/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,24 @@ def test_nmod():
assert str(G(3,5)) == "3"
assert G(3,5).repr() == "nmod(3, 5)"

# We can compare to int and fmpz types
assert G(1, 5) == int(1)
assert G(4, 5) == int(-1)
assert G(1, 5) == flint.fmpz(1)
assert G(4, 5) == flint.fmpz(-1)

# When the modulus matches, we can compare fmpz_mod
R = flint.fmpz_mod_ctx(5)
assert G(1, 5) == R(1)
assert G(1, 5) != R(-1)
assert G(4, 5) == R(4)
assert G(4, 5) == R(-1)
# when the modulus doesnt match, everything fails
assert G(1, 7) != R(1)
assert G(1, 7) != R(-1)
assert G(4, 7) != R(4)
assert G(4, 7) != R(-1)

def test_nmod_poly():
N = flint.nmod
P = flint.nmod_poly
Expand Down
36 changes: 20 additions & 16 deletions src/flint/types/nmod.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ from flint.utils.typecheck cimport typecheck
from flint.types.fmpq cimport any_as_fmpq
from flint.types.fmpz cimport any_as_fmpz
from flint.types.fmpz cimport fmpz
from flint.types.fmpz_mod cimport fmpz_mod
from flint.types.fmpq cimport fmpq

from flint.flintlib.flint cimport ulong
Expand Down Expand Up @@ -66,25 +67,28 @@ cdef class nmod(flint_scalar):
def modulus(self):
return self.mod.n

def __richcmp__(s, t, int op):
cdef mp_limb_t v
def __richcmp__(self, other, int op):
cdef bint res

if op != 2 and op != 3:
raise TypeError("nmods cannot be ordered")
if typecheck(s, nmod) and typecheck(t, nmod):
res = ((<nmod>s).val == (<nmod>t).val) and \
((<nmod>s).mod.n == (<nmod>t).mod.n)
if op == 2:
return res
else:
return not res
elif typecheck(s, nmod) and typecheck(t, int):
res = s.val == (t % s.mod.n)
if op == 2:
return res
else:
return not res
return NotImplemented

if typecheck(other, nmod):
res = self.val == (<nmod>other).val and \
self.mod.n == (<nmod>other).mod.n
elif typecheck(other, int):
res = self.val == (other % self.mod.n)
elif typecheck(other, fmpz):
res = self.val == (int(other) % self.mod.n)
elif typecheck(other, fmpz_mod):
res = self.mod.n == (<fmpz_mod>other).ctx.modulus() and \
self.val == int(other)
else:
return NotImplemented

if op == 2:
return res
return not res

def __hash__(self):
return hash((int(self.val), self.modulus))
Expand Down
Loading