Skip to content

Commit a85b98f

Browse files
author
Release Manager
committed
gh-37377: fix bad Frac(sparse polynomial ring over finite field) In passing, add support for fraction fields of polynomial rings over prime fields based on NTL. Fixes #37374 URL: #37377 Reported by: Marc Mezzarobba Reviewer(s): Travis Scrimshaw
2 parents 17a8ebd + d75e9af commit a85b98f

File tree

3 files changed

+63
-24
lines changed

3 files changed

+63
-24
lines changed

src/sage/rings/fraction_field_FpT.pyx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,27 @@ class FpT(FractionField_1poly_field):
4444
"""
4545
INPUT:
4646
47-
- ``R`` -- A polynomial ring over a finite field of prime order `p` with `2 < p < 2^16`
47+
- ``R`` -- a dense polynomial ring over a finite field of prime order
48+
`p` with `2 < p < 2^{16}`
4849
4950
EXAMPLES::
5051
5152
sage: R.<x> = GF(31)[]
5253
sage: K = R.fraction_field(); K
5354
Fraction Field of Univariate Polynomial Ring in x over Finite Field of size 31
55+
56+
TESTS::
57+
58+
sage: from sage.rings.fraction_field_FpT import FpT
59+
sage: FpT(PolynomialRing(GF(37), ['x'], sparse=True))
60+
Traceback (most recent call last):
61+
...
62+
TypeError: unsupported polynomial ring
5463
"""
5564
cdef long p = R.base_ring().characteristic()
5665
assert 2 < p < FpT.INTEGER_LIMIT
66+
if not issubclass(R.element_class, Polynomial_zmod_flint):
67+
raise TypeError("unsupported polynomial ring")
5768
self.p = p
5869
self.poly_ring = R
5970
FractionField_1poly_field.__init__(self, R, element_class=FpTElement)

src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -852,14 +852,6 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n):
852852
sage: (x-1)^5
853853
x^5 + 95*x^4 + 10*x^3 + 90*x^2 + 5*x + 99
854854
855-
Negative powers will not work::
856-
857-
sage: R.<x> = PolynomialRing(Integers(101), implementation='NTL')
858-
sage: (x-1)^(-5)
859-
Traceback (most recent call last):
860-
...
861-
NotImplementedError: Fraction fields not implemented for this type.
862-
863855
We define ``0^0`` to be unity, :issue:`13895`::
864856
865857
sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
@@ -872,6 +864,21 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n):
872864
sage: type(R(0)^0) == type(R(0))
873865
True
874866
867+
Negative powers work (over prime fields) but use the generic
868+
implementation of fraction fields::
869+
870+
sage: R.<x> = PolynomialRing(Integers(101), implementation='NTL')
871+
sage: f = (x-1)^(-5)
872+
sage: type(f)
873+
<class 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'>
874+
sage: (f + 2).numerator()
875+
2*x^5 + 91*x^4 + 20*x^3 + 81*x^2 + 10*x + 100
876+
877+
sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
878+
sage: (x-1)^(-5)
879+
Traceback (most recent call last):
880+
...
881+
TypeError: ...
875882
"""
876883
cdef bint recip = 0, do_sig
877884
cdef long e = ee

src/sage/rings/polynomial/polynomial_ring.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2529,14 +2529,13 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r
25292529
@cached_method
25302530
def fraction_field(self):
25312531
"""
2532-
Returns the fraction field of self.
2532+
Return the fraction field of ``self``.
25332533
25342534
EXAMPLES::
25352535
2536-
sage: R.<t> = GF(5)[]
2537-
sage: R.fraction_field()
2538-
Fraction Field of Univariate Polynomial Ring in t
2539-
over Finite Field of size 5
2536+
sage: QQbar['x'].fraction_field()
2537+
Fraction Field of Univariate Polynomial Ring in x over Algebraic
2538+
Field
25402539
25412540
TESTS:
25422541
@@ -2556,17 +2555,14 @@ def fraction_field(self):
25562555
sage: t(x)
25572556
x
25582557
2558+
Fixed :issue:`37374`::
2559+
2560+
sage: x = PolynomialRing(GF(37), ['x'], sparse=True).fraction_field().gen()
2561+
sage: type(x.numerator())
2562+
<class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.element_class'>
2563+
sage: (x^8 + 16*x^6 + 4*x^4 + x^2 + 12).numerator() - 1
2564+
x^8 + 16*x^6 + 4*x^4 + x^2 + 11
25592565
"""
2560-
R = self.base_ring()
2561-
p = R.characteristic()
2562-
if p != 0 and R.is_prime_field():
2563-
try:
2564-
from sage.rings.fraction_field_FpT import FpT
2565-
except ImportError:
2566-
pass
2567-
else:
2568-
if 2 < p and p < FpT.INTEGER_LIMIT:
2569-
return FpT(self)
25702566
from sage.rings.fraction_field import FractionField_1poly_field
25712567
return FractionField_1poly_field(self)
25722568

@@ -3639,6 +3635,31 @@ def irreducible_element(self, n, algorithm=None):
36393635
# No suitable algorithm found, try algorithms from the base class.
36403636
return PolynomialRing_dense_finite_field.irreducible_element(self, n, algorithm)
36413637

3638+
@cached_method
3639+
def fraction_field(self):
3640+
"""
3641+
Return the fraction field of ``self``.
3642+
3643+
EXAMPLES::
3644+
3645+
sage: R.<t> = GF(5)[]
3646+
sage: R.fraction_field()
3647+
Fraction Field of Univariate Polynomial Ring in t
3648+
over Finite Field of size 5
3649+
"""
3650+
try:
3651+
from sage.rings.fraction_field_FpT import FpT
3652+
from sage.rings.polynomial.polynomial_zmod_flint import Polynomial_zmod_flint
3653+
except ImportError:
3654+
pass
3655+
else:
3656+
p = self.base_ring().characteristic()
3657+
if (issubclass(self.element_class, Polynomial_zmod_flint)
3658+
and 2 < p < FpT.INTEGER_LIMIT):
3659+
return FpT(self)
3660+
return super().fraction_field()
3661+
3662+
36423663
def polygen(ring_or_element, name="x"):
36433664
"""
36443665
Return a polynomial indeterminate.

0 commit comments

Comments
 (0)