Skip to content

Commit 9a86d4e

Browse files
Merge pull request #78 from oscarbenjamin/pr_nmod
Minor fixes for nmod
2 parents 1bbde28 + 7b49ebe commit 9a86d4e

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

src/flint/test/test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,7 @@ def test_nmod():
12791279
assert G(1,2) != G(0,2)
12801280
assert G(0,2) != G(0,3)
12811281
assert G(3,5) == G(8,5)
1282+
assert isinstance(hash(G(3, 5)), int)
12821283
assert raises(lambda: G([], 3), TypeError)
12831284
#assert G(3,5) == 8 # do we want this?
12841285
#assert 8 == G(3,5)
@@ -1300,9 +1301,14 @@ def test_nmod():
13001301
assert G(3,17) / G(2,17) == G(10,17)
13011302
assert G(3,17) / 2 == G(10,17)
13021303
assert 3 / G(2,17) == G(10,17)
1304+
assert G(0,3) / G(1,3) == G(0,3)
13031305
assert G(3,17) * flint.fmpq(11,5) == G(10,17)
13041306
assert G(3,17) / flint.fmpq(11,5) == G(6,17)
1307+
assert G(1,3) ** 2 == G(1,3)
1308+
assert G(2,3) ** flint.fmpz(2) == G(1,3)
13051309
assert G(flint.fmpq(2, 3), 5) == G(4,5)
1310+
assert raises(lambda: G(2,5) ** G(2,5), TypeError)
1311+
assert raises(lambda: flint.fmpz(2) ** G(2,5), TypeError)
13061312
assert raises(lambda: G(flint.fmpq(2, 3), 3), ZeroDivisionError)
13071313
assert raises(lambda: G(2,5) / G(0,5), ZeroDivisionError)
13081314
assert raises(lambda: G(2,5) / 0, ZeroDivisionError)
@@ -1314,10 +1320,12 @@ def test_nmod():
13141320
assert raises(lambda: G(2,5) - [], TypeError)
13151321
assert raises(lambda: G(2,5) * [], TypeError)
13161322
assert raises(lambda: G(2,5) / [], TypeError)
1323+
assert raises(lambda: G(2,5) ** [], TypeError)
13171324
assert raises(lambda: [] + G(2,5), TypeError)
13181325
assert raises(lambda: [] - G(2,5), TypeError)
13191326
assert raises(lambda: [] * G(2,5), TypeError)
13201327
assert raises(lambda: [] / G(2,5), TypeError)
1328+
assert raises(lambda: [] ** G(2,5), TypeError)
13211329
assert G(3,17).modulus() == 17
13221330
assert str(G(3,5)) == "3"
13231331
assert G(3,5).repr() == "nmod(3, 5)"

src/flint/types/nmod.pyx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ from flint.types.fmpz cimport fmpz
66
from flint.types.fmpq cimport fmpq
77

88
from flint.flintlib.fmpz cimport fmpz_t
9+
from flint.flintlib.nmod cimport nmod_pow_fmpz, nmod_inv
910
from flint.flintlib.nmod_vec cimport *
1011
from flint.flintlib.fmpz cimport fmpz_fdiv_ui, fmpz_init, fmpz_clear
1112
from flint.flintlib.fmpz cimport fmpz_set_ui, fmpz_get_ui
@@ -89,6 +90,9 @@ cdef class nmod(flint_scalar):
8990
return not res
9091
return NotImplemented
9192

93+
def __hash__(self):
94+
return hash((int(self.val), self.modulus))
95+
9296
def __nonzero__(self):
9397
return self.val != 0
9498

@@ -178,6 +182,8 @@ cdef class nmod(flint_scalar):
178182
return NotImplemented
179183
if tval == 0:
180184
raise ZeroDivisionError("%s is not invertible mod %s" % (tval, mod.n))
185+
if not s:
186+
return s
181187
# XXX: check invertibility?
182188
x = nmod_div(sval, tval, mod)
183189
if x == 0:
@@ -195,3 +201,17 @@ cdef class nmod(flint_scalar):
195201

196202
def __invert__(self):
197203
return (1 / self) # XXX: speed up
204+
205+
def __pow__(self, exp):
206+
cdef nmod r
207+
e = any_as_fmpz(exp)
208+
if e is NotImplemented:
209+
return NotImplemented
210+
r = nmod.__new__(nmod)
211+
r.mod = self.mod
212+
r.val = self.val
213+
if e < 0:
214+
r.val = nmod_inv(r.val, self.mod)
215+
e = -e
216+
r.val = nmod_pow_fmpz(r.val, (<fmpz>e).val, self.mod)
217+
return r

0 commit comments

Comments
 (0)