Skip to content

Commit 86ffb15

Browse files
committed
Add resultant tests and nmod_poly implementation
1 parent fec8a10 commit 86ffb15

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

src/flint/test/test_all.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2834,6 +2834,36 @@ def setbad(obj, i, val):
28342834
if type(p) == flint.fq_default_poly:
28352835
assert raises(lambda: p.integral(), NotImplementedError)
28362836

2837+
# resultant checks.
2838+
2839+
if is_field and characteristic == 0:
2840+
# Check that the resultant of two cyclotomic polynomials is right.
2841+
# See Dresden's 2012 "Resultants of Cyclotomic Polynomials"
2842+
for m in range(1, 50):
2843+
for n in range(m + 1, 50):
2844+
a = flint.fmpz_poly.cyclotomic(m)
2845+
b = flint.fmpz_poly.cyclotomic(n)
2846+
q, r = divmod(flint.fmpz(n), flint.fmpz(m))
2847+
fs = q.factor()
2848+
if r != 0 or len(fs) > 1:
2849+
assert a.resultant(b) == 1
2850+
else:
2851+
prime = fs[0][0]
2852+
tot = flint.fmpz(m).euler_phi()
2853+
assert a.resultant(b) == prime**tot
2854+
2855+
x = P([0, 1])
2856+
# Flint does not implement resultants over GF(q) for nonprime q, so we
2857+
# there's nothing for us to check.
2858+
if composite_characteristic or type(x) == flint.fq_default_poly:
2859+
pass
2860+
else:
2861+
assert x.resultant(x) == 0
2862+
assert x.resultant(x**2 + x - x) == 0
2863+
2864+
for k in range(-10, 10):
2865+
assert x.resultant(x + S(k)) == S(k)
2866+
assert x.resultant(x**10 - x**5 + 1) == S(1)
28372867

28382868
def _all_mpolys():
28392869
return [
@@ -2869,7 +2899,6 @@ def _all_mpolys():
28692899
),
28702900
]
28712901

2872-
28732902
def test_mpolys():
28742903
for P, get_context, S, is_field, characteristic in _all_mpolys():
28752904

src/flint/types/fmpz_poly.pyx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ cdef class fmpz_poly(flint_poly):
450450
fmpz_poly_resultant_modular(res.val, self.val, (<fmpz_poly>other).val)
451451
return res
452452

453-
454453
def factor(self):
455454
"""
456455
Factors self into irreducible factors, returning a tuple

src/flint/types/nmod_poly.pyx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,26 @@ cdef class nmod_poly(flint_poly):
621621
nmod_poly_gcd(res.val, self.val, (<nmod_poly>other).val)
622622
return res
623623

624+
def resultant(self, other):
625+
"""
626+
Returns the resultant of *self* and *other*.
627+
628+
>>> f = nmod_poly([1, 2, 3], 3)
629+
>>> g = nmod_poly([1, 0, 1], 3)
630+
>>> f.resultant(f)
631+
0
632+
>>> f.resultant(g)
633+
2
634+
635+
"""
636+
cdef ulong res
637+
other = any_as_nmod_poly(other, (<nmod_poly>self).val.mod)
638+
if other is NotImplemented:
639+
raise TypeError("cannot convert input to nmod_poly")
640+
641+
res = nmod_poly_resultant(self.val, (<nmod_poly>other).val)
642+
return res
643+
624644
def xgcd(self, other):
625645
cdef nmod_poly res1, res2, res3
626646
other = any_as_nmod_poly(other, (<nmod_poly>self).val.mod)

0 commit comments

Comments
 (0)