Path: blob/master/src/sage/rings/finite_rings/hom_finite_field_givaro.pyx
8820 views
"""1Special implementation for givaro finite fields of:23- embeddings between finite fields45- frobenius endomorphisms67SEEALSO::89:mod:`sage.rings.finite_rings.hom_finite_field`1011AUTHOR:1213- Xavier Caruso (2012-06-29)14"""1516#############################################################################17# Copyright (C) 2012 Xavier Caruso <[email protected]>18#19# Distributed under the terms of the GNU General Public License (GPL)20#21# http://www.gnu.org/licenses/22#****************************************************************************2324include "../../ext/stdsage.pxi"2526from sage.rings.finite_rings.constructor import FiniteField2728from hom_finite_field cimport SectionFiniteFieldHomomorphism_generic29from hom_finite_field cimport FiniteFieldHomomorphism_generic30from hom_finite_field cimport FrobeniusEndomorphism_finite_field3132from hom_prime_finite_field cimport FiniteFieldHomomorphism_prime3334from sage.categories.homset import Hom35from sage.structure.element cimport Element36from sage.rings.morphism cimport RingHomomorphism_im_gens3738from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro39from element_givaro cimport FiniteField_givaroElement40#from element_givaro cimport make_FiniteField_givaroElement4142from sage.structure.parent cimport Parent43from element_givaro cimport Cache_givaro444546cdef class SectionFiniteFieldHomomorphism_givaro(SectionFiniteFieldHomomorphism_generic):47def __init__(self, inverse):48"""49TESTS::5051sage: from sage.rings.finite_rings.hom_finite_field_givaro import FiniteFieldHomomorphism_givaro52sage: k.<t> = GF(3^2)53sage: K.<T> = GF(3^4)54sage: f = FiniteFieldHomomorphism_givaro(Hom(k, K))55sage: g = f.section(); g56Section of Ring morphism:57From: Finite Field in t of size 3^258To: Finite Field in T of size 3^459Defn: t |--> 2*T^3 + 2*T^2 + 160"""61if not isinstance(inverse, FiniteFieldHomomorphism_givaro):62raise TypeError("The given map is not an instance of FiniteFieldHomomorphism_givaro")63SectionFiniteFieldHomomorphism_generic.__init__(self, inverse)6465cdef long inverse_power = (<FiniteFieldHomomorphism_givaro>inverse)._power66cdef long order = self.domain().cardinality() - 167self._order_codomain = self.codomain().cardinality() - 16869# Compute a = gcd(inverse_power, order)70# and solve inverse_power*x = a (mod order)71cdef long a = inverse_power, b = order72cdef unsigned long q73cdef long x = 1, y = 074cdef long sb, sy75while b != 0:76q = a // b77sb = b; b = a-q*b; a = sb78sy = y; y = x-q*y; x = sy7980self._gcd = a81if x < 0:82x += order83self._power = x % self._order_codomain8485self._codomain_cache = (<FiniteField_givaroElement>(self._codomain.gen()))._cache868788cpdef Element _call_(self, x):89"""90TESTS::9192sage: from sage.rings.finite_rings.hom_finite_field_givaro import FiniteFieldHomomorphism_givaro93sage: k.<t> = GF(3^2)94sage: K.<T> = GF(3^4)95sage: f = FiniteFieldHomomorphism_givaro(Hom(k, K))96sage: g = f.section()97sage: g(f(t+1))98t + 199100sage: g(T)101Traceback (most recent call last):102...103ValueError: T is not in the image of Ring morphism:104From: Finite Field in t of size 3^2105To: Finite Field in T of size 3^4106Defn: t |--> 2*T^3 + 2*T^2 + 1107"""108if x.parent() != self.domain():109raise TypeError("%s is not in %s" % (x, self.domain()))110cdef FiniteField_givaroElement y = <FiniteField_givaroElement?>x111if y._cache.objectptr.isZero(y.element):112return make_FiniteField_givaroElement(self._codomain_cache, self._codomain_cache.objectptr.zero)113if y._cache.objectptr.isOne(y.element):114return make_FiniteField_givaroElement(self._codomain_cache, self._codomain_cache.objectptr.one)115cdef int log = y.element116cdef int q = log / self._gcd117if log == q*self._gcd:118q = (q*self._power) % self._order_codomain119return make_FiniteField_givaroElement(self._codomain_cache, q)120else:121raise ValueError("%s is not in the image of %s" % (x, self._inverse))122123124cdef class FiniteFieldHomomorphism_givaro(FiniteFieldHomomorphism_generic):125def __init__(self, parent, im_gens=None, check=False):126"""127TESTS::128129sage: from sage.rings.finite_rings.hom_finite_field_givaro import FiniteFieldHomomorphism_givaro130sage: k.<t> = GF(3^2)131sage: K.<T> = GF(3^4)132sage: f = FiniteFieldHomomorphism_givaro(Hom(k, K)); f133Ring morphism:134From: Finite Field in t of size 3^2135To: Finite Field in T of size 3^4136Defn: t |--> 2*T^3 + 2*T^2 + 1137138sage: k.<t> = GF(3^10)139sage: K.<T> = GF(3^20)140sage: f = FiniteFieldHomomorphism_givaro(Hom(k, K)); f141Traceback (most recent call last):142...143TypeError: The codomain is not an instance of FiniteField_givaro144"""145domain = parent.domain()146codomain = parent.codomain()147if not isinstance(domain, FiniteField_givaro):148raise TypeError("The domain is not an instance of FiniteField_givaro")149if not isinstance(codomain, FiniteField_givaro):150raise TypeError("The codomain is not an instance of FiniteField_givaro")151152FiniteFieldHomomorphism_generic.__init__(self, parent, im_gens, check,153section_class=SectionFiniteFieldHomomorphism_givaro)154155cdef Cache_givaro domain_cache = (<FiniteField_givaroElement>(domain.gen()))._cache156self._codomain_cache = (<FiniteField_givaroElement>(codomain.gen()))._cache157158cdef FiniteField_givaroElement g = make_FiniteField_givaroElement(domain_cache, 1)159cdef FiniteField_givaroElement G = FiniteFieldHomomorphism_generic._call_(self, g)160self._power = G.element161162self._order_domain = domain.cardinality() - 1163self._order_codomain = codomain.cardinality() - 1164165166cpdef Element _call_(self, x):167"""168TESTS::169170sage: from sage.rings.finite_rings.hom_finite_field_givaro import FiniteFieldHomomorphism_givaro171sage: k.<t> = GF(3^2)172sage: K.<T> = GF(3^4)173sage: f = FiniteFieldHomomorphism_givaro(Hom(k, K))174sage: f(t)1752*T^3 + 2*T^2 + 1176"""177if x.parent() != self.domain():178raise TypeError("%s is not in %s" % (x, self.domain()))179cdef FiniteField_givaroElement y = <FiniteField_givaroElement?>x180if y._cache.objectptr.isZero(y.element):181return make_FiniteField_givaroElement(self._codomain_cache, self._codomain_cache.objectptr.zero)182if y._cache.objectptr.isOne(y.element):183return make_FiniteField_givaroElement(self._codomain_cache, self._codomain_cache.objectptr.one)184cdef int log = y.element185log = (log*self._power) % self._order_codomain186return make_FiniteField_givaroElement(self._codomain_cache, log)187188189190cdef class FrobeniusEndomorphism_givaro(FrobeniusEndomorphism_finite_field):191def __init__(self, domain, power=1):192"""193TESTS::194195sage: k.<t> = GF(5^3)196sage: Frob = k.frobenius_endomorphism(); Frob197Frobenius endomorphism t |--> t^5 on Finite Field in t of size 5^3198sage: type(Frob)199<type 'sage.rings.finite_rings.hom_finite_field_givaro.FrobeniusEndomorphism_givaro'>200201sage: k.<t> = GF(5^20)202sage: Frob = k.frobenius_endomorphism(); Frob203Frobenius endomorphism t |--> t^5 on Finite Field in t of size 5^20204sage: type(Frob)205<type 'sage.rings.finite_rings.hom_finite_field.FrobeniusEndomorphism_finite_field'>206"""207if not isinstance(domain, FiniteField_givaro):208raise TypeError("The domain is not an instance of FiniteField_givaro")209FrobeniusEndomorphism_finite_field.__init__(self, domain, power)210211212def fixed_field(self):213"""214Return the fixed field of ``self``.215216OUTPUT:217218- a tuple `(K, e)`, where `K` is the subfield of the domain219consisting of elements fixed by ``self`` and `e` is an220embedding of `K` into the domain.221222.. NOTE::223224The name of the variable used for the subfield (if it225is not a prime subfield) is suffixed by ``_fixed``.226227EXAMPLES::228229sage: k.<t> = GF(5^6)230sage: f = k.frobenius_endomorphism(2)231sage: kfixed, embed = f.fixed_field()232sage: kfixed233Finite Field in t_fixed of size 5^2234sage: embed235Ring morphism:236From: Finite Field in t_fixed of size 5^2237To: Finite Field in t of size 5^6238Defn: t_fixed |--> 4*t^5 + 2*t^4 + 4*t^2 + t239240sage: tfixed = kfixed.gen()241sage: embed(tfixed)2424*t^5 + 2*t^4 + 4*t^2 + t243"""244if self._degree_fixed == 1:245k = FiniteField(self.domain().characteristic())246f = FiniteFieldHomomorphism_prime(Hom(k, self.domain()))247else:248k = FiniteField(self.domain().characteristic()**self._degree_fixed,249name=self.domain().variable_name() + "_fixed")250f = FiniteFieldHomomorphism_givaro(Hom(k, self.domain()))251return k, f252253254# copied from element_givaro.pyx255cdef inline FiniteField_givaroElement make_FiniteField_givaroElement(Cache_givaro cache, int x):256cdef FiniteField_givaroElement y257258if cache._has_array:259return <FiniteField_givaroElement>cache._array[x]260else:261y = PY_NEW(FiniteField_givaroElement)262y._parent = <Parent> cache.parent263y._cache = cache264y.element = x265return y266267268