GF(q^m)
|
GF(q = p^s)
|
GF(p)
sage: k = GF(2)
sage: K = GF(2^2)
sage: L = GF(2^6)
sage: K.hom(L)
sage: K.hom(L)
Ring Coercion morphism:
From: Finite Field in z2 of size 2^2
To: Finite Field in z6 of size 2^6
sage: Hom(K,L)
Set of field embeddings from Finite Field in z2 of size 2^2 to Finite Field in z6 of size 2^6
sage: list(_)
[Ring morphism:
From: Finite Field in z2 of size 2^2
To: Finite Field in z6 of size 2^6
Defn: z2 |--> z6^3 + z6^2 + z6, Ring morphism:
From: Finite Field in z2 of size 2^2
To: Finite Field in z6 of size 2^6
Defn: z2 |--> z6^3 + z6^2 + z6 + 1]
sage: from sage.rings.finite_rings.hom_finite_field import FiniteFieldHomomorphism_generic
sage: phi = FiniteFieldHomomorphism_generic(Hom(K, L))
sage: phi.section()
Section of Ring morphism:
From: Finite Field in z2 of size 2^2
To: Finite Field in z6 of size 2^6
Defn: z2 |--> z6^3 + z6^2 + z6
sage: from sage.coding.relative_finite_field_extension import RelativeFiniteFieldExtension
sage: g = RelativeFiniteFieldExtension(L,K)
Relative field extension between Finite Field in z6 of size 2^6 and Finite Field in z2 of size 2^2
sage: g.relative_field_representation(L.random_element())
(1, z2 + 1, z2)
sage: type(_)
<type 'sage.modules.free_module_element.FreeModuleElement_generic_dense'>
sage: k.<z> = GF(2^3)
sage: K = GF(2^6)
sage: K == k.extension(2)
True
sage: A = K.algebra_over(k)
sage: A == k.extension_seen_as_a_very_large_algebra_with_nice_basis(2)
True
sage: B = K.view_as_algebra(base=k)
sage: A == B
True
sage: psi = B.defining_morphism()
sage: phi = k.hom(K)
sage: A == phi.induced_algebra(basis=[1, z-1])
True
sage: A == FieldExtension(k, K, embedding=None, basis=None) # ??
True
sage: A == Algebra(K, base=k, embedding=None, basis=None)
True
sage: A(K.gen())
(1) + (z-1)
sage: _ == K.gen() # coercion A → K
True
sage: A.is_galois()
True
sage: A.galois_group()
...
sage: A.normal_basis()
...
sage: A.scalar_restiction(GF(2)) # what basis do we pick here?
...
sage: P.<x,y> = GF(2)[]
sage: C = P.quo([x^3 + ..., y^2 + ...])
sage: A.hom(C)
...
- How to meld with existing APIs
sage.rings.algebraic_closure_finite_field.AlgebraicClosureFiniteField
,sage.rings.number_field.number_field_rel.NumberField_relative
? - Should any field be seen by default as an algebra over its base field, thus having all the functionalities of an algebra?
Proposed by Xavier. Johan dislikes RelativeRing
, Xavier suggests RingRelative
then.
class RelativeRing(Parent):
def __init__(self, base, ring, defining_morphism=None):
# check
# create defining_morphism if not given
# define coercion self -> L
pass
def defining_morphism(self):
return self._defining_morphism
def base_ring(self):
return self._K
def to_ring(self):
return self._L
def tensor_product(self, other):
raise NotImplementedError
def scalar_restriction(self, other):
raise NotImplementedError
def is_galois(self):
raise NotImplementedError
def galois_group(self):
if not self.is_galois():
raise ValueError("%s is not Galois over %s" % (self._L, self._K)
raise NotImplementedError
def normal_basis(self):
# Naive algorithm:
# 1. compute the Galois group
# 2. pick an element x at random in L
# 3. check whether the family (gx) (g in Galois) is a basis
# if it is, output it, otherwise go back to 2.
raise NotImplementedError
def is_finite(self):
raise NotImplementedError
def is_flat(self):
raise NotImplementedError
def is_etale(self):
raise NotImplementedError
def is_smooth(self):
raise NotImplementedError
class RelativeRingWithBasis(RelativeRing):
def __init__(self, K, L, defining_morphism=None, basis=None):
# check
# create defining_morphism if not given
# choose a basis if not given
# define coercion self -> L
pass
def basis(self):
return self._basis
def dimension(self):
return len(self._basis)
def multiplication_table(self):
raise NotImplementedError
def change_basis(self, basis, check=True):
if check:
# check basis
pass
return self.__class__(self._K, self._L, self._defining_morphism, basis)
def tensor_product(self, other):
# compute the basis of the tensor product
raise NotImplementedError
def scalar_restriction(self, other):
# compute the basis of the scalar restriction
raise NotImplementedError
def is_finite(self):
return True
def is_flat(self):
return True
class RelativeRingElement_generic(Element):
def __init__(self, parent, element):
# initialize
self._element = element
pass
def to_ring(self):
return self._element
def _add_(self, other):
return self.__class__(self.parent(), self.to_ring() + other.to_ring())
def _mul_(self, other):
return self.__class__(self.parent(), self.to_ring() * other.to_ring())
def _repr_(self):
return self._element._repr_()
class RelativeRingElement_basis_generic(RelativeRingElement_generic):
def decompose_on_basis(self):
raise NotImplementedError
def _repr_(self):
s = ""
d = self.parent().dimension()
basis = self.parent().basis()
v = self.decompose_on_basis()
for i in range(d):
if v[i].is_zero():
pass
elif v[i].is_one():
s += " + (%s)" % basis[i]
else:
s += " + (%s)*(%s)" % (v[i], basis[i])
return s[2:]