diff --git a/src/flint/test/test_all.py b/src/flint/test/test_all.py index a10f867e..08e59218 100644 --- a/src/flint/test/test_all.py +++ b/src/flint/test/test_all.py @@ -1604,7 +1604,7 @@ def test_pickling(): def test_fmpz_mod(): from flint import fmpz_mod_ctx, fmpz, fmpz_mod - + p_sml = 163 p_med = 2**127 - 1 p_big = 2**255 - 19 @@ -1754,7 +1754,7 @@ def test_fmpz_mod(): assert raises(lambda: F_test(test_x) * "AAA", TypeError) assert raises(lambda: F_test(test_x) * F_other(test_x), ValueError) - # Exponentiation + # Exponentiation assert F_test(0)**0 == pow(0, 0, test_mod) assert F_test(0)**1 == pow(0, 1, test_mod) @@ -1804,7 +1804,7 @@ def test_fmpz_mod(): assert fmpz(test_y) / F_test(test_x) == (test_y * pow(test_x, -1, test_mod)) % test_mod assert test_y / F_test(test_x) == (test_y * pow(test_x, -1, test_mod)) % test_mod - + def test_fmpz_mod_dlog(): from flint import fmpz, fmpz_mod_ctx @@ -1826,7 +1826,7 @@ def test_fmpz_mod_dlog(): F = fmpz_mod_ctx(163) g = F(2) a = g**123 - + assert 123 == g.discrete_log(a) a_int = pow(2, 123, 163) @@ -1877,7 +1877,7 @@ def test_fmpz_mod_poly(): assert repr(R3) == "fmpz_mod_poly_ctx(13)" assert R1.modulus() == 11 - + assert R1.is_prime() assert R1.zero() == 0 assert R1.one() == 1 @@ -1946,7 +1946,7 @@ def test_fmpz_mod_poly(): assert str(f) == "8*x^3 + 7*x^2 + 6*x + 7" # TODO: currently repr does pretty printing - # just like str, we should address this. Mainly, + # just like str, we should address this. Mainly, # the issue is we want nice `repr` behaviour in # interactive shells, which currently is why this # choice has been made @@ -1992,7 +1992,7 @@ def test_fmpz_mod_poly(): F_sml = fmpz_mod_ctx(p_sml) F_med = fmpz_mod_ctx(p_med) F_big = fmpz_mod_ctx(p_big) - + R_sml = fmpz_mod_poly_ctx(F_sml) R_med = fmpz_mod_poly_ctx(F_med) R_big = fmpz_mod_poly_ctx(F_big) @@ -2003,14 +2003,14 @@ def test_fmpz_mod_poly(): f_bad = R_cmp([2,2,2,2,2]) for (F_test, R_test) in [(F_sml, R_sml), (F_med, R_med), (F_big, R_big)]: - + f = R_test([-1,-2]) g = R_test([-3,-4]) # pos, neg assert f is +f assert -f == R_test([1,2]) - + # add assert raises(lambda: f + f_cmp, ValueError) assert raises(lambda: f + "AAA", TypeError) @@ -2063,7 +2063,7 @@ def test_fmpz_mod_poly(): assert raises(lambda: f / "AAA", TypeError) assert raises(lambda: f / 0, ZeroDivisionError) assert raises(lambda: f_cmp / 2, ZeroDivisionError) - + assert (f + f) / 2 == f assert (f + f) / fmpz(2) == f assert (f + f) / F_test(2) == f @@ -2077,7 +2077,7 @@ def test_fmpz_mod_poly(): assert (f + f) // 2 == f assert (f + f) // fmpz(2) == f assert (f + f) // F_test(2) == f - assert 2 // R_test(2) == 1 + assert 2 // R_test(2) == 1 assert (f + 1) // f == 1 # pow @@ -2171,7 +2171,7 @@ def test_fmpz_mod_poly(): f1 = R_test([-3, 1]) f2 = R_test([-5, 1]) assert f1.resultant(f2) == (3 - 5) - assert raises(lambda: f.resultant("AAA"), TypeError) + assert raises(lambda: f.resultant("AAA"), TypeError) # sqrt f1 = R_test.random_element(irreducible=True) @@ -2428,14 +2428,14 @@ def _all_polys(): (flint.fmpz_poly, flint.fmpz, False), (flint.fmpq_poly, flint.fmpq, True), (lambda *a: flint.nmod_poly(*a, 17), lambda x: flint.nmod(x, 17), True), - (lambda *a: flint.fmpz_mod_poly(*a, flint.fmpz_mod_poly_ctx(163)), - lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(163)), + (lambda *a: flint.fmpz_mod_poly(*a, flint.fmpz_mod_poly_ctx(163)), + lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(163)), True), - (lambda *a: flint.fmpz_mod_poly(*a, flint.fmpz_mod_poly_ctx(2**127 - 1)), - lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(2**127 - 1)), + (lambda *a: flint.fmpz_mod_poly(*a, flint.fmpz_mod_poly_ctx(2**127 - 1)), + lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(2**127 - 1)), True), - (lambda *a: flint.fmpz_mod_poly(*a, flint.fmpz_mod_poly_ctx(2**255 - 19)), - lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(2**255 - 19)), + (lambda *a: flint.fmpz_mod_poly(*a, flint.fmpz_mod_poly_ctx(2**255 - 19)), + lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(2**255 - 19)), True), ] @@ -2467,6 +2467,28 @@ def test_polys(): assert (P([1]) == P([2])) is False assert (P([1]) != P([2])) is True + assert (P([1]) == 1) is True + assert (P([1]) != 1) is False + assert (P([1]) == 2) is False + assert (P([1]) != 2) is True + + assert (1 == P([1])) is True + assert (1 != P([1])) is False + assert (2 == P([1])) is False + assert (2 != P([1])) is True + + s1, s2 = S(1), S(2) + + assert (P([s1]) == s1) is True + assert (P([s1]) != s1) is False + assert (P([s1]) == s2) is False + assert (P([s1]) != s2) is True + + assert (s1 == P([s1])) is True + assert (s1 != P([s1])) is False + assert (s1 == P([s2])) is False + assert (s1 != P([s2])) is True + assert (P([1]) == None) is False assert (P([1]) != None) is True assert (None == P([1])) is False @@ -2500,12 +2522,17 @@ def setbad(obj, i, val): assert raises(lambda: setbad(p, -1, 1), ValueError) for v in [], [1], [1, 2]: - if P == flint.fmpz_poly: + p = P(v) + if type(p) == flint.fmpz_poly: assert P(v).repr() == f'fmpz_poly({v!r})' - elif P == flint.fmpq_poly: + elif type(p) == flint.fmpq_poly: assert P(v).repr() == f'fmpq_poly({v!r})' - elif P == flint.nmod_poly: + elif type(p) == flint.nmod_poly: assert P(v).repr() == f'nmod_poly({v!r}, 17)' + elif type(p) == flint.fmpz_mod_poly: + pass # fmpz_mod_poly does not have .repr() ... + else: + assert False assert repr(P([])) == '0' assert repr(P([1])) == '1' @@ -2521,6 +2548,12 @@ def setbad(obj, i, val): assert bool(P([])) is False assert bool(P([1])) is True + assert P([]).is_zero() is True + assert P([1]).is_zero() is False + + assert P([]).is_one() is False + assert P([1]).is_one() is True + assert +P([1, 2, 3]) == P([1, 2, 3]) assert -P([1, 2, 3]) == P([-1, -2, -3]) @@ -2600,7 +2633,7 @@ def setbad(obj, i, val): assert P([1, 1]) ** 2 == P([1, 2, 1]) assert raises(lambda: P([1, 1]) ** -1, ValueError) assert raises(lambda: P([1, 1]) ** None, TypeError) - + # # XXX: Not sure what this should do in general: assert raises(lambda: pow(P([1, 1]), 2, 3), NotImplementedError) @@ -2825,6 +2858,12 @@ def quick_poly(): assert bool(P(ctx=ctx)) is False assert bool(P(1, ctx=ctx)) is True + assert P(ctx=ctx).is_zero() is True + assert P(1, ctx=ctx).is_zero() is False + + assert P(ctx=ctx).is_one() is False + assert P(1, ctx=ctx).is_one() is True + assert +quick_poly() \ == quick_poly() assert -quick_poly() \ diff --git a/src/flint/types/acb_mat.pyx b/src/flint/types/acb_mat.pyx index d33a65f1..2d4cd41e 100644 --- a/src/flint/types/acb_mat.pyx +++ b/src/flint/types/acb_mat.pyx @@ -150,7 +150,7 @@ cdef class acb_mat(flint_mat): else: raise ValueError("acb_mat: expected 1-3 arguments") - def __nonzero__(self): + def __bool__(self): raise NotImplementedError cpdef long nrows(s): diff --git a/src/flint/types/arb_mat.pyx b/src/flint/types/arb_mat.pyx index d7507969..d3bd310a 100644 --- a/src/flint/types/arb_mat.pyx +++ b/src/flint/types/arb_mat.pyx @@ -148,7 +148,7 @@ cdef class arb_mat(flint_mat): else: raise ValueError("arb_mat: expected 1-3 arguments") - def __nonzero__(self): + def __bool__(self): raise NotImplementedError cpdef long nrows(s): diff --git a/src/flint/types/fmpq.pyx b/src/flint/types/fmpq.pyx index 49c008b5..d359080a 100644 --- a/src/flint/types/fmpq.pyx +++ b/src/flint/types/fmpq.pyx @@ -186,7 +186,7 @@ cdef class fmpq(flint_scalar): def __trunc__(self): return self.trunc() - def __nonzero__(self): + def __bool__(self): return not fmpq_is_zero(self.val) def __round__(self, ndigits=None): diff --git a/src/flint/types/fmpq_mat.pyx b/src/flint/types/fmpq_mat.pyx index 35d32ff3..59959789 100644 --- a/src/flint/types/fmpq_mat.pyx +++ b/src/flint/types/fmpq_mat.pyx @@ -92,7 +92,7 @@ cdef class fmpq_mat(flint_mat): else: raise TypeError("fmpq_mat: expected 1-3 arguments") - def __nonzero__(self): + def __bool__(self): return not fmpq_mat_is_zero(self.val) def __richcmp__(s, t, int op): diff --git a/src/flint/types/fmpq_mpoly.pyx b/src/flint/types/fmpq_mpoly.pyx index 234d7f63..bcb3ea20 100644 --- a/src/flint/types/fmpq_mpoly.pyx +++ b/src/flint/types/fmpq_mpoly.pyx @@ -243,6 +243,12 @@ cdef class fmpq_mpoly(flint_mpoly): def __bool__(self): return not fmpq_mpoly_is_zero(self.val, self.ctx.val) + def is_zero(self): + return fmpq_mpoly_is_zero(self.val, self.ctx.val) + + def is_one(self): + return fmpq_mpoly_is_one(self.val, self.ctx.val) + def __richcmp__(self, other, int op): if not (op == Py_EQ or op == Py_NE): return NotImplemented @@ -782,9 +788,6 @@ cdef class fmpq_mpoly(flint_mpoly): """ return self.ctx - def is_one(self): - return fmpq_mpoly_is_one(self.val, self.ctx.val) - def coefficient(self, slong i): """ Return the coefficient at index `i`. diff --git a/src/flint/types/fmpq_poly.pyx b/src/flint/types/fmpq_poly.pyx index dddac1d8..f83f471b 100644 --- a/src/flint/types/fmpq_poly.pyx +++ b/src/flint/types/fmpq_poly.pyx @@ -167,9 +167,15 @@ cdef class fmpq_poly(flint_poly): else: return "fmpq_poly(%s, %s)" % ([int(c) for c in n.coeffs()], d) - def __nonzero__(self): + def __bool__(self): return not fmpq_poly_is_zero(self.val) + def is_zero(self): + return fmpq_poly_is_zero(self.val) + + def is_one(self): + return fmpq_poly_is_one(self.val) + def __call__(self, other): t = any_as_fmpz(other) if t is not NotImplemented: diff --git a/src/flint/types/fmpz.pyx b/src/flint/types/fmpz.pyx index a1aa7e05..4f01eb80 100644 --- a/src/flint/types/fmpz.pyx +++ b/src/flint/types/fmpz.pyx @@ -168,7 +168,7 @@ cdef class fmpz(flint_scalar): def repr(self): return "fmpz(%s)" % self.str() - def __nonzero__(self): + def __bool__(self): return not fmpz_is_zero(self.val) def __pos__(self): diff --git a/src/flint/types/fmpz_mat.pyx b/src/flint/types/fmpz_mat.pyx index 4012f8ca..69b05a87 100644 --- a/src/flint/types/fmpz_mat.pyx +++ b/src/flint/types/fmpz_mat.pyx @@ -131,7 +131,7 @@ cdef class fmpz_mat(flint_mat): else: raise TypeError("fmpz_mat: expected 1-3 arguments") - def __nonzero__(self): + def __bool__(self): return not fmpz_mat_is_zero(self.val) def __richcmp__(fmpz_mat s, t, int op): diff --git a/src/flint/types/fmpz_mod_mat.pyx b/src/flint/types/fmpz_mod_mat.pyx index 0049ad39..923fa6fd 100644 --- a/src/flint/types/fmpz_mod_mat.pyx +++ b/src/flint/types/fmpz_mod_mat.pyx @@ -303,7 +303,7 @@ cdef class fmpz_mod_mat(flint_mat): e = self.ctx.any_as_fmpz_mod(value) self._setitem(i, j, e.val) - def __nonzero__(self): + def __bool__(self): """Return ``True`` if the matrix has any nonzero entries.""" cdef bint zero zero = compat_fmpz_mod_mat_is_zero(self.val, self.ctx.val) diff --git a/src/flint/types/fmpz_mpoly.pyx b/src/flint/types/fmpz_mpoly.pyx index 28c6bf76..d8e2d869 100644 --- a/src/flint/types/fmpz_mpoly.pyx +++ b/src/flint/types/fmpz_mpoly.pyx @@ -223,6 +223,12 @@ cdef class fmpz_mpoly(flint_mpoly): def __bool__(self): return not fmpz_mpoly_is_zero(self.val, self.ctx.val) + def is_zero(self): + return fmpz_mpoly_is_zero(self.val, self.ctx.val) + + def is_one(self): + return fmpz_mpoly_is_one(self.val, self.ctx.val) + def __richcmp__(self, other, int op): if not (op == Py_EQ or op == Py_NE): return NotImplemented @@ -764,9 +770,6 @@ cdef class fmpz_mpoly(flint_mpoly): """ return self.ctx - def is_one(self): - return fmpz_mpoly_is_one(self.val, self.ctx.val) - def coefficient(self, slong i): """ Return the coefficient at index `i`. diff --git a/src/flint/types/fmpz_poly.pyx b/src/flint/types/fmpz_poly.pyx index 52314404..14d5631e 100644 --- a/src/flint/types/fmpz_poly.pyx +++ b/src/flint/types/fmpz_poly.pyx @@ -137,9 +137,15 @@ cdef class fmpz_poly(flint_poly): def repr(self): return "fmpz_poly([%s])" % (", ".join(map(str, self.coeffs()))) - def __nonzero__(self): + def __bool__(self): return not fmpz_poly_is_zero(self.val) + def is_zero(self): + return fmpz_poly_is_zero(self.val) + + def is_one(self): + return fmpz_poly_is_one(self.val) + def __call__(self, other): t = any_as_fmpz(other) if t is not NotImplemented: diff --git a/src/flint/types/nmod.pyx b/src/flint/types/nmod.pyx index 53bee07b..7bcab98a 100644 --- a/src/flint/types/nmod.pyx +++ b/src/flint/types/nmod.pyx @@ -89,7 +89,7 @@ cdef class nmod(flint_scalar): def __hash__(self): return hash((int(self.val), self.modulus)) - def __nonzero__(self): + def __bool__(self): return self.val != 0 def __pos__(self): diff --git a/src/flint/types/nmod_mat.pyx b/src/flint/types/nmod_mat.pyx index 35e016cb..8c99e2ef 100644 --- a/src/flint/types/nmod_mat.pyx +++ b/src/flint/types/nmod_mat.pyx @@ -136,7 +136,7 @@ cdef class nmod_mat(flint_mat): else: raise TypeError("nmod_mat: expected 1-3 arguments plus modulus") - def __nonzero__(self): + def __bool__(self): return not nmod_mat_is_zero(self.val) def __richcmp__(s, t, int op): diff --git a/src/flint/types/nmod_poly.pyx b/src/flint/types/nmod_poly.pyx index 637001af..ca5421dd 100644 --- a/src/flint/types/nmod_poly.pyx +++ b/src/flint/types/nmod_poly.pyx @@ -117,7 +117,7 @@ cdef class nmod_poly(flint_poly): cdef mp_limb_t v cdef bint res if op != 2 and op != 3: - raise TypeError("nmod_polyss cannot be ordered") + raise TypeError("nmod_polys cannot be ordered") if typecheck(s, nmod_poly) and typecheck(t, nmod_poly): if (s).val.mod.n != (t).val.mod.n: res = False @@ -127,6 +127,22 @@ cdef class nmod_poly(flint_poly): return res if op == 3: return not res + else: + if not typecheck(s, nmod_poly): + s, t = t, s + try: + t = nmod_poly([t], (s).val.mod.n) + except TypeError: + pass + if typecheck(s, nmod_poly) and typecheck(t, nmod_poly): + if (s).val.mod.n != (t).val.mod.n: + res = False + else: + res = nmod_poly_equal((s).val, (t).val) + if op == 2: + return res + if op == 3: + return not res return NotImplemented def __iter__(self): @@ -166,9 +182,15 @@ cdef class nmod_poly(flint_poly): else: raise TypeError("cannot set element of type %s" % type(x)) - def __nonzero__(self): + def __bool__(self): return not nmod_poly_is_zero(self.val) + def is_zero(self): + return nmod_poly_is_zero(self.val) + + def is_one(self): + return nmod_poly_is_one(self.val) + def __call__(self, other): cdef mp_limb_t c if any_as_nmod(&c, other, self.val.mod):