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

Commit

Permalink
Use general ring extension framework for finite fields
Browse files Browse the repository at this point in the history
  • Loading branch information
saraedum committed Sep 12, 2019
1 parent 544f4dd commit 9cc9805
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 17 deletions.
12 changes: 6 additions & 6 deletions src/sage/rings/finite_rings/element_relative.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
# http://www.gnu.org/licenses/
#*****************************************************************************
from sage.structure.element import CommutativeRingElement
from sage.rings.ring_extension_element import RingExtensionElement

class FiniteField_relativeElement(CommutativeRingElement):
class FiniteField_relativeElement(RingExtensionElement):
r"""
Element of a
:class:`sage.rings.finite_rings.finite_field_relative.FiniteField_relative`.
Expand All @@ -33,7 +34,7 @@ class FiniteField_relativeElement(CommutativeRingElement):
sage: a = k.gen(); a
"""
def __init__(self, parent, backend):
def __init__(self, parent, x):
r"""
TESTS::
Expand All @@ -42,9 +43,8 @@ def __init__(self, parent, backend):
sage: isinstance(k.gen(), FiniteField_relativeElement)
"""
if backend.parent() is not parent:
raise ValueError("parent must be %s but it is %s"%(parent, backend.parent()))
self._backend = backend
CommutativeRingElement.__init__(self, parent)
# if x.parent() is not parent:
# raise ValueError("parent must be %s but it is %s"%(parent, x.parent()))
RingExtensionElement.__init__(self, parent, x)


25 changes: 25 additions & 0 deletions src/sage/rings/finite_rings/finite_field_base.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,31 @@ cdef class FiniteField(Field):
"""
raise NotImplementedError("subclasses must implement gen()")

def _any_embedding(self, codomain):
r"""
Return an embedding of this field into ``codomain``.
EXAMPLES::
sage: GF(2)._any_embedding(GF(2^2))
Ring morphism:
From: Finite Field of size 2
To: Finite Field in z2 of size 2^2
Defn: 1 |--> 1
sage: GF(2^2)._any_embedding(GF(2^4))
Ring morphism:
From: Finite Field in z2 of size 2^2
To: Finite Field in z4 of size 2^4
Defn: z2 |--> z4^2 + z4
sage: GF(3^2).extension(3, absolute=False)._any_embedding(GF(3^12))
"""
if codomain.has_coerce_map_from(self):
return codomain.coerce_map_from(self)

base_hom = self.base_ring()._any_embedding(codomain)
minpoly = self.gen().minpoly().change_ring(base_hom)
return self.hom(codomain, [minpoly.any_root()], base_map=base_hom)

def zeta_order(self):
"""
Return the order of the distinguished root of unity in ``self``.
Expand Down
28 changes: 18 additions & 10 deletions src/sage/rings/finite_rings/finite_field_relative.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@

from __future__ import absolute_import

from sage.misc.cachefunc import cached_method

from .finite_field_base import FiniteField
from .element_relative import FiniteField_relativeElement
from sage.rings.ring_extension import RingExtensionWithGen

# TODO: Make sure that we run TestSuite for all the constellations that I can
# imagine. TestSuite should test something for every method that I touched in
# finite_field_base.pyx.
class FiniteField_relative(FiniteField):
class FiniteField_relative(FiniteField, RingExtensionWithGen):
r"""
A finite field extension which delegates all the computations to an
absolute finite field, the ``_backend``. This is used for relative
Expand Down Expand Up @@ -81,17 +84,18 @@ def __init__(self, base, modulus, names, category=None, **kwds):
"""
order = base.order() ** modulus.degree()

from sage.all import GF, FiniteFields
self._backend = GF(order, **kwds)
from sage.all import GF, FiniteFields, Hom
backend = GF(order, names=["b%s"%(order,)], **kwds)

assert modulus.base_ring() is base
self._modulus = modulus
assert len(names) == 1
self._name = names[0]

FiniteField.__init__(self, base, names, normalize=False, category=category or FiniteFields())
# TODO: Register coercion map from base
# TODO: Register conversions from and to the backend

defining_embedding = self.base_ring()._any_embedding(backend)
gen = modulus.map_coefficients(defining_embedding).any_root()
RingExtensionWithGen.__init__(self, defining_morphism=defining_embedding, gen=gen, name=names[0], coerce=False)

def __reduce__(self):
r"""
Expand All @@ -117,11 +121,15 @@ def absolute_field(self, map=False, **kwds):
sage: k.absolute_field(map=True)
"""
E = self._backend.absolute_field(**kwds)
backend = self._backend()
absolute = backend.absolute_field(map=map, **kwds)
if map:
return (E, self._from_backend, self._to_backend)
(absolute, absolute_to_backend, backend_to_absolute) = absolute
return (absolute,
backend.hom(self) * absolute_to_backend,
backend_to_absolute * self.hom(backend))
else:
return E
return absolute

def characteristic(self):
r"""
Expand All @@ -134,6 +142,6 @@ def characteristic(self):
3
"""
return self._backend.characteristic()
return self._backend().characteristic()

Element = FiniteField_relativeElement
2 changes: 1 addition & 1 deletion src/sage/rings/ring_extension_morphism.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ cdef class RingExtensionHomomorphism(RingHomomorphism):
sage: E2 = RingExtension(L,K)
"""
def __init__(self, parent, backend):
def __init__(self, parent, backend, check=None):
RingHomomorphism.__init__(self, parent)
backend_domain = self.domain()
if isinstance(backend_domain, RingExtension_class):
Expand Down

0 comments on commit 9cc9805

Please sign in to comment.