Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sage.rings.finite_rings: Modularization fixes, # needs #36056

Merged
merged 23 commits into from
Aug 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
bfc5cdf
src/sage/rings/finite_rings/integer_mod.pyx: Move import from sage.gr…
mkoeppe Feb 20, 2023
4c437cb
sage.rings: More # optional
mkoeppe Jun 4, 2023
97b5398
More # optional
mkoeppe Jun 9, 2023
d1f5704
sage.rings.finite_rings: More # optional
mkoeppe Jun 28, 2023
a1e4409
sage.rings.finite_rings: ./sage -fixdoctests --only-tags
mkoeppe Jun 28, 2023
a44af4d
sage.schemes: Update # needs
mkoeppe Jun 30, 2023
1f7e48a
Update # optional/needs
mkoeppe Jul 1, 2023
173d3c3
sage.rings: Update # optional / # needs
mkoeppe Jul 2, 2023
c0118ba
src/sage/rings/polynomial/polynomial_ring.py: Use '# needs sage.libs.…
mkoeppe Jul 8, 2023
19222fb
./sage -fixdoctests --distribution sagemath-categories --probe sage.r…
mkoeppe Jul 13, 2023
a04dbbc
src/sage/rings/finite_rings/conway_polynomials.py: Use lazy_import fo…
mkoeppe Jul 15, 2023
e78d4ea
sage.rings: Update # needs
mkoeppe Jul 16, 2023
6042ff7
sage.rings.{finite_rings,polynomial}: Modularization fixes for imports
mkoeppe Jul 17, 2023
1bc26c2
sage.rings.finite_rings: Update # needs
mkoeppe Jul 17, 2023
1b54228
src/sage/rings/finite_rings/conway_polynomials.py: Add # needs
mkoeppe Jul 22, 2023
baca60e
sage.rings: Update # needs
mkoeppe Jul 22, 2023
1810daf
sage.rings.finite_rings: Update # needs
mkoeppe Aug 6, 2023
a3ef387
sage.rings.finite_rings: Update # needs
mkoeppe Aug 7, 2023
a18e1ab
src/sage/rings: sage -fixdoctests --only-tags
mkoeppe Aug 8, 2023
e9630a6
pkgs/sagemath-categories/MANIFEST.in.m4: Add sage.rings.finite_rings.…
mkoeppe Jan 27, 2023
8a823ff
src/sage/rings/finite_rings: Use more block tags
mkoeppe Aug 10, 2023
98283ea
src/sage/rings/finite_rings/conway_polynomials.py: Fix # needs
mkoeppe Aug 11, 2023
744ddf8
src/sage/rings/finite_rings/residue_field.pyx: Make a doctest work wh…
mkoeppe Aug 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions src/sage/rings/finite_rings/conway_polynomials.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
"""

from sage.misc.fast_methods import WithEqualityById
from sage.misc.lazy_import import lazy_import
from sage.structure.sage_object import SageObject
from sage.rings.finite_rings.finite_field_constructor import FiniteField
from sage.rings.integer import Integer
import sage.databases.conway

lazy_import('sage.databases.conway', 'ConwayPolynomials')


def conway_polynomial(p, n):
"""
Expand Down Expand Up @@ -45,19 +48,19 @@ def conway_polynomial(p, n):

EXAMPLES::

sage: conway_polynomial(2,5)
sage: conway_polynomial(2,5) # needs conway_polynomials
x^5 + x^2 + 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the tag be file-scoped?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module also contains code for computing pseudo-Conway polynomials, which has to be used when the database is not available

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

sage: conway_polynomial(101,5)
sage: conway_polynomial(101,5) # needs conway_polynomials
x^5 + 2*x + 99
sage: conway_polynomial(97,101)
sage: conway_polynomial(97,101) # needs conway_polynomials
Traceback (most recent call last):
...
RuntimeError: requested Conway polynomial not in database.
"""
(p, n) = (int(p), int(n))
R = FiniteField(p)['x']
try:
return R(sage.databases.conway.ConwayPolynomials()[p][n])
return R(ConwayPolynomials()[p][n])
except KeyError:
raise RuntimeError("requested Conway polynomial not in database.")

Expand All @@ -82,7 +85,7 @@ def exists_conway_polynomial(p, n):

EXAMPLES::

sage: exists_conway_polynomial(2,3)
sage: exists_conway_polynomial(2,3) # needs conway_polynomials
True
sage: exists_conway_polynomial(2,-1)
False
Expand All @@ -91,7 +94,10 @@ def exists_conway_polynomial(p, n):
sage: exists_conway_polynomial(6,6)
False
"""
return sage.databases.conway.ConwayPolynomials().has_polynomial(p,n)
try:
return ConwayPolynomials().has_polynomial(p,n)
except ImportError:
return False
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it incorrect to return False when the database is not available? Why catch ImportError?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method is named exists_conway_polynomial, but it actually only tests whether it is known to Sage. When the database is not installed, nothing is known to Sage.
Return False here triggers the use of pseudo-Conway polynomials in the relevant code paths.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. That is reasonable. Thanks.


class PseudoConwayLattice(WithEqualityById, SageObject):
r"""
Expand Down Expand Up @@ -127,6 +133,7 @@ class PseudoConwayLattice(WithEqualityById, SageObject):

EXAMPLES::

sage: # needs sage.rings.finite_rings
sage: from sage.rings.finite_rings.conway_polynomials import PseudoConwayLattice
sage: PCL = PseudoConwayLattice(2, use_database=False)
sage: PCL.polynomial(3)
Expand Down Expand Up @@ -154,11 +161,13 @@ def __init__(self, p, use_database=True):
"""
TESTS::

sage: # needs sage.rings.finite_rings
sage: from sage.rings.finite_rings.conway_polynomials import PseudoConwayLattice
sage: PCL = PseudoConwayLattice(3)
sage: PCL.polynomial(3)
x^3 + 2*x + 1

sage: # needs sage.rings.finite_rings
sage: PCL = PseudoConwayLattice(5, use_database=False)
sage: PCL.polynomial(12)
x^12 + 4*x^11 + 2*x^10 + 4*x^9 + 2*x^8 + 2*x^7 + 4*x^6 + x^5 + 2*x^4 + 2*x^2 + x + 2
Expand All @@ -171,9 +180,13 @@ def __init__(self, p, use_database=True):
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
self.ring = PolynomialRing(FiniteField(p), 'x')
if use_database:
C = sage.databases.conway.ConwayPolynomials()
self.nodes = {n: self.ring(C.polynomial(p, n))
for n in C.degrees(p)}
try:
C = ConwayPolynomials()
except ImportError:
self.nodes = {}
else:
self.nodes = {n: self.ring(C.polynomial(p, n))
for n in C.degrees(p)}
else:
self.nodes = {}

Expand All @@ -199,6 +212,7 @@ def polynomial(self, n):

EXAMPLES::

sage: # needs sage.rings.finite_rings
sage: from sage.rings.finite_rings.conway_polynomials import PseudoConwayLattice
sage: PCL = PseudoConwayLattice(2, use_database=False)
sage: PCL.polynomial(3)
Expand Down Expand Up @@ -267,6 +281,7 @@ def check_consistency(self, n):

EXAMPLES::

sage: # needs sage.rings.finite_rings
sage: from sage.rings.finite_rings.conway_polynomials import PseudoConwayLattice
sage: PCL = PseudoConwayLattice(2, use_database=False)
sage: PCL.check_consistency(6)
Expand Down Expand Up @@ -301,6 +316,7 @@ def _find_pow_of_frobenius(p, n, x, y):

EXAMPLES::

sage: # needs sage.rings.finite_rings
sage: from sage.rings.finite_rings.conway_polynomials import _find_pow_of_frobenius
sage: K.<a> = GF(3^14)
sage: x = K.multiplicative_generator()
Expand Down Expand Up @@ -380,6 +396,7 @@ def _frobenius_shift(K, generators, check_only=False):

EXAMPLES::

sage: # needs sage.libs.ntl sage.rings.finite_rings
sage: R.<x> = GF(2)[]
sage: f30 = x^30 + x^28 + x^27 + x^25 + x^24 + x^20 + x^19 + x^18 + x^16 + x^15 + x^12 + x^10 + x^7 + x^2 + 1
sage: f20 = x^20 + x^19 + x^15 + x^13 + x^12 + x^11 + x^9 + x^8 + x^7 + x^4 + x^2 + x + 1
Expand Down
23 changes: 12 additions & 11 deletions src/sage/rings/finite_rings/element_base.pyx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# sage.doctest: optional - sage.rings.finite_rings
# sage.doctest: needs sage.rings.finite_rings
"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't all files in src/sage/rings/finite_rings installed by the distribution that provides the feature?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, sagemath-categories ships the basic modules of sage.rings.finite_rings - https://github.com/mkoeppe/sage/blob/t/32432/modularization_of_sagelib__break_out_a_separate_package_sagemath_polyhedra/pkgs/sagemath-categories/MANIFEST.in.m4#L109-L123

This makes the prime fields and the integer mod rings available.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I missed it.

Base class for finite field elements

Expand Down Expand Up @@ -711,23 +711,23 @@ cdef class FinitePolyExtElement(FiniteRingElement):

EXAMPLES::

sage: k.<a> = FiniteField(9, impl='givaro', modulus='primitive')
sage: a.is_square()
sage: k.<a> = FiniteField(9, impl='givaro', modulus='primitive') # needs sage.libs.linbox
sage: a.is_square() # needs sage.libs.linbox
False
sage: (a**2).is_square()
sage: (a**2).is_square() # needs sage.libs.linbox
True
sage: k.<a> = FiniteField(4, impl='ntl', modulus='primitive')
sage: (a**2).is_square()
sage: k.<a> = FiniteField(4, impl='ntl', modulus='primitive') # needs sage.libs.ntl
sage: (a**2).is_square() # needs sage.libs.ntl
True
sage: k.<a> = FiniteField(17^5, impl='pari_ffelt', modulus='primitive')
sage: a.is_square()
sage: k.<a> = FiniteField(17^5, impl='pari_ffelt', modulus='primitive') # needs sage.libs.pari
sage: a.is_square() # needs sage.libs.pari
False
sage: (a**2).is_square()
sage: (a**2).is_square() # needs sage.libs.pari
True

::

sage: k(0).is_square()
sage: k(0).is_square() # needs sage.libs.linbox
True
"""
K = self.parent()
Expand Down Expand Up @@ -1049,6 +1049,7 @@ cdef class FinitePolyExtElement(FiniteRingElement):

TESTS::

sage: # needs sage.modules
sage: p = random_prime(2^99)
sage: k = randrange(2,10)
sage: F.<t> = GF((p, k))
Expand Down Expand Up @@ -1086,7 +1087,7 @@ cdef class Cache_base(SageObject):
EXAMPLES::

sage: k.<a> = GF(2^48)
sage: k._cache.fetch_int(2^33 + 2 + 1)
sage: k._cache.fetch_int(2^33 + 2 + 1) # needs sage.libs.ntl
a^33 + a + 1
"""
raise NotImplementedError("this must be implemented by subclasses")
10 changes: 8 additions & 2 deletions src/sage/rings/finite_rings/element_pari_ffelt.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ from .element_base cimport FinitePolyExtElement
from .integer_mod import IntegerMod_abstract

import sage.rings.integer
from sage.modules.free_module_element import FreeModuleElement
from sage.rings.integer cimport Integer
from sage.rings.polynomial.polynomial_element import Polynomial
from sage.rings.polynomial.multi_polynomial_element import MPolynomial
from sage.rings.rational import Rational
from sage.structure.richcmp cimport rich_to_bool

try:
from sage.modules.free_module_element import FreeModuleElement
except ImportError:
FreeModuleElement = ()

from sage.interfaces.abc import GapElement

Expand Down Expand Up @@ -1330,9 +1333,10 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):

EXAMPLES::

sage: # needs sage.libs.gap
sage: F = FiniteField(2^3, 'aa', impl='pari_ffelt')
sage: aa = F.multiplicative_generator()
sage: gap(aa) # indirect doctest
sage: gap(aa) # indirect doctest
Z(2^3)
sage: b = F.multiplicative_generator()
sage: a = b^3
Expand All @@ -1347,6 +1351,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):

You can specify the instance of the Gap interpreter that is used::

sage: # needs sage.libs.gap
sage: F = FiniteField(next_prime(200)^2, 'a', impl='pari_ffelt')
sage: a = F.multiplicative_generator()
sage: a._gap_ (gap)
Expand All @@ -1356,6 +1361,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):

Gap only supports relatively small finite fields::

sage: # needs sage.libs.gap
sage: F = FiniteField(next_prime(1000)^2, 'a', impl='pari_ffelt')
sage: a = F.multiplicative_generator()
sage: a._gap_init_()
Expand Down
Loading