Skip to content

Instantly share code, notes, and snippets.

@defeo
Last active August 28, 2016 09:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save defeo/cabab27ea93aeb9e0deb0ba8c5bc745b to your computer and use it in GitHub Desktop.
Save defeo/cabab27ea93aeb9e0deb0ba8c5bc745b to your computer and use it in GitHub Desktop.
Pimp my Algebra

Field Embeddings

What we need

GF(q^m)
  |
GF(q = p^s)
  |
GF(p)

Examples

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'>

Planned API

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)
...

Questions

  • 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 API

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:]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment