Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Enabling GF(p^n) with no variable name given
Browse files Browse the repository at this point in the history
  • Loading branch information
roed314 authored and rharron committed Jan 22, 2016
1 parent 1961f94 commit a56ec74
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 48 deletions.
92 changes: 44 additions & 48 deletions src/sage/rings/finite_rings/constructor.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@
contains a database of Conway polynomials which also can be queried
independently of finite field construction.
A pseduo-Conway polynomial satisfies all of the conditions required
of a Conway polynomial except the condition that it is lexicographically
first. They are therefore not unique. If no variable name is
specified for an extension field, Sage will fit the finite field
into a compatible lattice of field extensions defined by pseduo-Conway
polynomials. This lattice is stored in an AlgebraicClosureFiniteField
object; different algebraic closure objects can be created by using
a different ``prefix`` keyword to the finite field constructor.
Note that the computation of pseudo-Conway polynomials is expensive
when the degree is large and highly composite. If a variable
name is specified then a random polynomial is used instead, which
will be much faster to find.
While Sage supports basic arithmetic in finite fields some more
advanced features for computing with finite fields are still not
implemented. For instance, Sage does not calculate embeddings of
Expand Down Expand Up @@ -181,15 +195,22 @@ class FiniteFieldFactory(UniqueFactory):
- ``order`` -- a prime power
- ``name`` -- string; must be specified unless ``order`` is prime.
- ``name`` -- string, optional. Note that there can be a
substantial speed penalty (in creating extension fields) when
omitting the variable name, since doing so triggers the
computation of pseudo-Conway polynomials in order to define a
coherent lattice of extensions of the prime field. The speed
penalty grows with the size of extension degree and with
the number of factors of the extension degree.
- ``modulus`` -- (optional) either a defining polynomial for the
field, or a string specifying an algorithm to use to generate
such a polynomial. If ``modulus`` is a string, it is passed to
:meth:`~sage.rings.polynomial.irreducible_element()` as the
parameter ``algorithm``; see there for the permissible values of
this parameter. In particular, you can specify
``modulus="primitive"`` to get a primitive polynomial.
``modulus="primitive"`` to get a primitive polynomial. You
may not specify a modulus if you do not specify a variable name.
- ``impl`` -- (optional) a string specifying the implementation of
the finite field. Possible values are:
Expand Down Expand Up @@ -374,15 +395,15 @@ class FiniteFieldFactory(UniqueFactory):
The following demonstrate coercions for finite fields using Conway
polynomials::
sage: k = GF(5^2, conway=True, prefix='z'); a = k.gen()
sage: l = GF(5^5, conway=True, prefix='z'); b = l.gen()
sage: k = GF(5^2); a = k.gen()
sage: l = GF(5^5); b = l.gen()
sage: a + b
3*z10^5 + z10^4 + z10^2 + 3*z10 + 1
Note that embeddings are compatible in lattices of such finite
fields::
sage: m = GF(5^3, conway=True, prefix='z'); c = m.gen()
sage: m = GF(5^3); c = m.gen()
sage: (a+b)+c == a+(b+c)
True
sage: (a*b)*c == a*(b*c)
Expand All @@ -396,11 +417,18 @@ class FiniteFieldFactory(UniqueFactory):
Another check that embeddings are defined properly::
sage: k = GF(3**10, conway=True, prefix='z')
sage: l = GF(3**20, conway=True, prefix='z')
sage: k = GF(3**10)
sage: l = GF(3**20)
sage: l(k.gen()**10) == l(k.gen())**10
True
Using pseudo-Conway polynomials is slow for highly
composite extension degrees::
sage: k = GF(3^120) # long time -- about 3 seconds
sage: GF(3^40).gen().minimal_polynomial()(k.gen()^((3^120-1)/(3^40-1))) # long time because of previous line
0
Check that :trac:`16934` has been fixed::
sage: k1.<a> = GF(17^14, impl="pari_ffelt")
Expand Down Expand Up @@ -444,51 +472,19 @@ def create_key_and_extra_args(self, order, name=None, modulus=None, names=None,
name = normalize_names(1, name)

p, n = order.factor()[0]

# The following is a temporary solution that allows us
# to construct compatible systems of finite fields
# until algebraic closures of finite fields are
# implemented in Sage. It requires the user to
# specify two parameters:
#
# - `conway` -- boolean; if True, this field is
# constructed to fit in a compatible system using
# a Conway polynomial.
# - `prefix` -- a string used to generate names for
# automatically constructed finite fields
#
# See the docstring of FiniteFieldFactory for examples.
#
# Once algebraic closures of finite fields are
# implemented, this syntax should be superseded by
# something like the following:
#
# sage: Fpbar = GF(5).algebraic_closure('z')
# sage: F, e = Fpbar.subfield(3) # e is the embedding into Fpbar
# sage: F
# Finite field in z3 of size 5^3
#
# This temporary solution only uses actual Conway
# polynomials (no pseudo-Conway polynomials), since
# pseudo-Conway polynomials are not unique, and until
# we have algebraic closures of finite fields, there
# is no good place to store a specific choice of
# pseudo-Conway polynomials.
if name is None:
if not ('conway' in kwds and kwds['conway']):
raise ValueError("parameter 'conway' is required if no name given")
if 'prefix' not in kwds:
raise ValueError("parameter 'prefix' is required if no name given")
kwds['prefix'] = 'z'
name = kwds['prefix'] + str(n)

if 'conway' in kwds and kwds['conway']:
from conway_polynomials import conway_polynomial
if 'prefix' not in kwds:
raise ValueError("a prefix must be specified if conway=True")
if modulus is not None:
raise ValueError("no modulus may be specified if conway=True")
# The following raises a RuntimeError if no polynomial is found.
modulus = conway_polynomial(p, n)
raise ValueError("no modulus may be specified if variable name not given")
# Fpbar will have a strong reference, since algebraic_closure caches its results,
# and the coefficients of modulus lie in GF(p)
Fpbar = GF(p).algebraic_closure(kwds.get('prefix','z'))
# This will give a Conway polynomial if p,n is small enough to be in the database
# and a pseudo-Conway polynomial if it's not.
modulus = Fpbar._get_polynomial(n)
check_irreducible = False

if impl is None:
if order < zech_log_bound:
Expand Down
2 changes: 2 additions & 0 deletions src/sage/rings/finite_rings/conway_polynomials.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from sage.misc.fast_methods import WithEqualityById
from sage.structure.sage_object import SageObject
from sage.rings.finite_rings.constructor import FiniteField
from sage.rings.integer import Integer
import sage.databases.conway

def conway_polynomial(p, n):
Expand Down Expand Up @@ -217,6 +218,7 @@ def polynomial(self, n):
return self.nodes[n]

p = self.p
n = Integer(n)

if n == 1:
f = self.ring.gen() - FiniteField(p).multiplicative_generator()
Expand Down

0 comments on commit a56ec74

Please sign in to comment.