Skip to content

Commit 8235eb4

Browse files
Merge pull request #312 from remyoudompheng/discriminant
Add discriminant method to fmpz_poly, fmpq_poly, nmod_poly
2 parents 4920921 + d26eb2c commit 8235eb4

File tree

8 files changed

+78
-1
lines changed

8 files changed

+78
-1
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ CHANGELOG
162162
Next release (0.9.0)...
163163
-----------------------
164164

165+
Contributors (0.9.0):
166+
167+
- Rémy Oudompheng (RO)
168+
169+
Changes (0.9.0):
170+
171+
- [gh-312](https://github.com/flintlib/python-flint/pull/312),
172+
Add `discriminant` method to `fmpz_poly`, `fmpq_poly` and
173+
`nmod_poly`. (RO)
174+
165175
0.8.0
166176
-----
167177

src/flint/test/test_all.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3045,6 +3045,9 @@ def setbad(obj, i, val):
30453045
assert x.resultant(x**10 - x**5 + 1) == S(1)
30463046
assert (x - 1).resultant(x**5 + 1) == S(2)
30473047

3048+
assert (x**5 + 1).discriminant() == S(3125)
3049+
assert (x**5 + 1).resultant(5 * x**4) == S(3125)
3050+
30483051
for k in range(-10, 10):
30493052
assert x.resultant(x + S(k)) == S(k)
30503053

src/flint/types/fmpq_poly.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class fmpq_poly(flint_poly[fmpq]):
7373
def truncate(self, n: int, /) -> fmpq_poly: ...
7474

7575
def gcd(self, other: ifmpq_poly, /) -> fmpq_poly: ...
76+
def discriminant(self) -> fmpq: ...
7677
def resultant(self, other: ifmpq_poly, /) -> fmpq: ...
7778
def xgcd(self, other: ifmpq_poly, /) -> tuple[fmpq_poly, fmpq_poly, fmpq_poly]: ...
7879

src/flint/types/fmpq_poly.pyx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ from flint.types.fmpz cimport any_as_fmpz
1010

1111
from flint.flintlib.functions.fmpz cimport fmpz_is_zero
1212
from flint.flintlib.functions.fmpz cimport fmpz_set
13-
from flint.flintlib.functions.fmpq cimport fmpq_is_zero
13+
from flint.flintlib.functions.fmpz_poly cimport fmpz_poly_discriminant
14+
from flint.flintlib.functions.fmpq cimport fmpq_is_zero, fmpq_set_fmpz_frac
1415
from flint.flintlib.functions.fmpq_poly cimport *
1516
from flint.flintlib.functions.arith cimport arith_bernoulli_polynomial
1617
from flint.flintlib.functions.arith cimport arith_euler_polynomial
@@ -518,6 +519,34 @@ cdef class fmpq_poly(flint_poly):
518519
fmpq_poly_gcd(res.val, self.val, (<fmpq_poly>other).val)
519520
return res
520521

522+
def discriminant(self):
523+
"""
524+
Return the discriminant of ``self``.
525+
526+
>>> f = fmpq_poly([1, 2, 3, 4, 5, 6])
527+
>>> f.discriminant()
528+
1037232
529+
>>> f = fmpq_poly([1, 3, 5, 7, 9, 11, 13])
530+
>>> f.discriminant()
531+
-2238305839
532+
>>> f = fmpq_poly([1, 3, 5, 7, 9, 11, 13], 10)
533+
>>> f.discriminant()
534+
-2238305839/10000000000
535+
536+
"""
537+
# There is no FLINT function for the discriminant of a fmpq_poly,
538+
# we use the fact that disc(f/q) = disc(f)/q^(2d-2)
539+
cdef fmpq res = fmpq.__new__(fmpq)
540+
cdef fmpz rnum = fmpz.__new__(fmpz)
541+
cdef fmpz rden = self.denom()**(2 * self.degree() - 2)
542+
543+
cdef fmpz_poly x = fmpz_poly.__new__(fmpz_poly)
544+
fmpq_poly_get_numerator(x.val, self.val)
545+
fmpz_poly_discriminant(rnum.val, x.val)
546+
fmpq_set_fmpz_frac(res.val, rnum.val, rden.val)
547+
548+
return res
549+
521550
def resultant(self, other):
522551
"""
523552
Returns the resultant of *self* and *other*.

src/flint/types/fmpz_poly.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class fmpz_poly(flint_poly[fmpz]):
6262

6363
def gcd(self, other: ifmpz_poly, /) -> fmpz_poly: ...
6464
def content(self) -> fmpz: ...
65+
def discriminant(self) -> fmpz: ...
6566
def resultant(self, other: ifmpz_poly, /) -> fmpz: ...
6667
def factor(self) -> tuple[fmpz, list[tuple[fmpz_poly, int]]]: ...
6768
def factor_squarefree(self) -> tuple[fmpz, list[tuple[fmpz_poly, int]]]: ...

src/flint/types/fmpz_poly.pyx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,22 @@ cdef class fmpz_poly(flint_poly):
500500
fmpz_poly_gcd(res.val, self.val, (<fmpz_poly>other).val)
501501
return res
502502

503+
def discriminant(self):
504+
"""
505+
Return the discriminant of ``self``.
506+
507+
>>> f = fmpz_poly([1, 2, 3, 4, 5, 6])
508+
>>> f.discriminant()
509+
1037232
510+
>>> f = fmpz_poly([1, 3, 5, 7, 9, 11, 13])
511+
>>> f.discriminant()
512+
-2238305839
513+
514+
"""
515+
cdef fmpz res = fmpz.__new__(fmpz)
516+
fmpz_poly_discriminant(res.val, self.val)
517+
return res
518+
503519
def resultant(self, other):
504520
"""
505521
Returns the resultant of *self* and *other*.

src/flint/types/nmod_poly.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class nmod_poly(flint_poly[nmod]):
6161
self, e: int, modulus: inmod_poly, mod_rev_inv: inmod_poly | None = None
6262
) -> nmod_poly: ...
6363
def gcd(self, other: inmod_poly) -> nmod_poly: ...
64+
def discriminant(self) -> nmod: ...
6465
def resultant(self, other: inmod_poly) -> nmod: ...
6566
def xgcd(self, other: inmod_poly) -> tuple[nmod_poly, nmod_poly, nmod_poly]: ...
6667
def factor(

src/flint/types/nmod_poly.pyx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,22 @@ cdef class nmod_poly(flint_poly):
712712
nmod_poly_gcd(res.val, self.val, (<nmod_poly>other).val)
713713
return res
714714

715+
def discriminant(self):
716+
"""
717+
Return the discriminant of ``self``.
718+
719+
>>> f = nmod_poly([1, 2, 3, 4, 5, 6], 65537)
720+
>>> f.discriminant()
721+
54177
722+
>>> f = nmod_poly([1, 3, 5, 7, 9, 11, 13], 65537)
723+
>>> f.discriminant()
724+
44859
725+
726+
"""
727+
cdef nmod res = nmod(0, self.modulus())
728+
res.val = nmod_poly_discriminant(self.val)
729+
return res
730+
715731
def resultant(self, other):
716732
"""
717733
Returns the resultant of *self* and *other*.

0 commit comments

Comments
 (0)