Path: blob/master/sage/rings/finite_rings/finite_field_base.pyx
4108 views
"""1TESTS::23sage: K.<a> = NumberField(x^2 + 1)4sage: F = K.factor(3)[0][0].residue_field()5sage: loads(dumps(F)) == F6True7"""8include "../../ext/stdsage.pxi"910from sage.structure.parent cimport Parent11from sage.misc.prandom import randrange12from sage.rings.finite_rings.homset import FiniteFieldHomset1314cdef class FiniteFieldIterator:15r"""16An iterator over a finite field. This should only be used when the field is17an extension of a smaller field which already has a separate iterator function.18"""19cdef object iter20cdef FiniteField parent2122def __init__(self,FiniteField parent):23r"""24Standard init function.2526EXAMPLE::2728sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari29sage: k = iter(FiniteField_ext_pari(9, 'a')) # indirect doctest30sage: isinstance(k, sage.rings.finite_rings.finite_field_base.FiniteFieldIterator)31True32"""33self.parent = parent34self.iter =iter(self.parent.vector_space())3536def __next__(self):37r"""38Return the next element in the iterator.3940EXAMPLE::4142sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari43sage: k = iter(FiniteField_ext_pari(9, 'a'))44sage: k.next() # indirect doctest45046"""47return self.parent(self.iter.next())4849def __iter__(self):50"""5152EXAMPLES::5354sage: K.<a> = GF(7^4)55sage: K.list()[:7]56[0, 6*a, a^2, 6*a^3, 2*a^2 + 3*a + 4, 5*a^3 + 4*a^2 + 3*a, 3*a^3 + a^2 + 6*a + 1]57sage: K.<a> = GF(5^9)58sage: for x in K:59... if x == a+3: break60... print x61062163264365466a67a + 168a + 269"""70return self7172from sage.categories.finite_fields import FiniteFields73_FiniteFields = FiniteFields()74cdef class FiniteField(Field):75def __init__(self, base, names, normalize):76"""77EXAMPLES::7879sage: K = GF(7); K80Finite Field of size 781sage: loads(K.dumps()) == K82True83sage: GF(7^10, 'a')84Finite Field in a of size 7^1085sage: K = GF(7^10, 'a'); K86Finite Field in a of size 7^1087sage: loads(K.dumps()) == K88True89"""90Field.__init__(self, base, names, normalize, category=_FiniteFields)9192def __repr__(self):93"""94String representation of this finite field.9596EXAMPLES::9798sage: k = GF(127)99sage: k # indirect doctest100Finite Field of size 127101102sage: k.<b> = GF(2^8)103sage: k104Finite Field in b of size 2^8105106sage: k.<c> = GF(2^20)107sage: k108Finite Field in c of size 2^20109110sage: k.<d> = GF(7^20)111sage: k112Finite Field in d of size 7^20113"""114if self.degree()>1:115return "Finite Field in %s of size %s^%s"%(self.variable_name(),self.characteristic(),self.degree())116else:117return "Finite Field of size %s"%(self.characteristic())118119def _latex_(self):120r"""121Returns a string denoting the name of the field in LaTeX.122123The :func:`sage.misc.latex.latex` function calls the124``_latex_`` attribute when available.125126EXAMPLES:127128The ``latex`` command parses the string::129130sage: GF(81, 'a')._latex_()131'\\Bold{F}_{3^{4}}'132sage: latex(GF(81, 'a'))133\Bold{F}_{3^{4}}134sage: GF(3)._latex_()135'\\Bold{F}_{3}'136sage: latex(GF(3))137\Bold{F}_{3}138"""139if self.degree() > 1:140e = "^{%s}"%self.degree()141else:142e = ""143return "\\Bold{F}_{%s%s}"%(self.characteristic(), e)144145def _gap_init_(self):146"""147Return string that initializes the GAP version of148this finite field.149150EXAMPLES::151152sage: GF(9,'a')._gap_init_()153'GF(9)'154"""155return 'GF(%s)'%self.order()156157def _magma_init_(self, magma):158"""159Return string representation of self that Magma can160understand.161162EXAMPLES::163164sage: GF(97,'a')._magma_init_(magma) # optional - magma165'GF(97)'166sage: GF(9,'a')._magma_init_(magma) # optional - magma167'SageCreateWithNames(ext<GF(3)|_sage_[...]![GF(3)!2,GF(3)!2,GF(3)!1]>,["a"])'168sage: magma(GF(9,'a')) # optional - magma169Finite field of size 3^2170sage: magma(GF(9,'a')).1 # optional - magma171a172"""173if self.degree() == 1:174return 'GF(%s)'%self.order()175B = self.base_ring()176p = self.polynomial()177s = "ext<%s|%s>"%(B._magma_init_(magma),p._magma_init_(magma))178return magma._with_names(s, self.variable_names())179180def _macaulay2_init_(self):181"""182Returns the string representation of self that Macaulay2 can183understand.184185EXAMPLES::186187sage: GF(97,'a')._macaulay2_init_()188'GF 97'189190sage: macaulay2(GF(97, 'a')) # optional - macaulay2191ZZ192--19397194sage: macaulay2(GF(49, 'a')) # optional - macaulay2195GF 49196"""197return "GF %s"%(self.order())198199def _sage_input_(self, sib, coerced):200r"""201Produce an expression which will reproduce this value when evaluated.202203EXAMPLES::204205sage: sage_input(GF(5), verify=True)206# Verified207GF(5)208sage: sage_input(GF(32, 'a'), verify=True)209# Verified210R.<x> = GF(2)[]211GF(2^5, 'a', x^5 + x^2 + 1)212sage: K = GF(125, 'b')213sage: sage_input((K, K), verify=True)214# Verified215R.<x> = GF(5)[]216GF_5_3 = GF(5^3, 'b', x^3 + 3*x + 3)217(GF_5_3, GF_5_3)218sage: from sage.misc.sage_input import SageInputBuilder219sage: GF(81, 'a')._sage_input_(SageInputBuilder(), False)220{call: {atomic:GF}({binop:** {atomic:3} {atomic:4}}, {atomic:'a'}, {binop:+ {binop:+ {binop:** {gen:x {constr_parent: {subscr: {call: {atomic:GF}({atomic:3})}[{atomic:'x'}]} with gens: ('x',)}} {atomic:4}} {binop:* {atomic:2} {binop:** {gen:x {constr_parent: {subscr: {call: {atomic:GF}({atomic:3})}[{atomic:'x'}]} with gens: ('x',)}} {atomic:3}}}} {atomic:2}})}221"""222if self.degree() == 1:223v = sib.name('GF')(sib.int(self.characteristic()))224name = 'GF_%d' % self.characteristic()225else:226v = sib.name('GF')(sib.int(self.characteristic()) ** sib.int(self.degree()),227self.variable_name(),228self.modulus())229name = 'GF_%d_%d' % (self.characteristic(), self.degree())230sib.cache(self, v, name)231return v232233def _cmp_(left, Parent right):234"""235Compares this finite field with other.236237.. warning::238239The notation of equality of finite fields in Sage is240currently not stable, i.e., it may change in a future version.241242EXAMPLES::243244sage: FiniteField(3**2, 'c') == FiniteField(3**3, 'c') # indirect doctest245False246sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'c')247True248249The variable name is (currently) relevant for comparison of finite fields::250251sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'd')252False253"""254if not PY_TYPE_CHECK(right, FiniteField):255return cmp(type(left), type(right))256c = cmp(left.characteristic(), right.characteristic())257if c: return c258c = cmp(left.degree(), right.degree())259if c: return c260# TODO comparing the polynomials themselves would recursively call261# this cmp... Also, as mentioned above, we will get rid of this.262if left.degree() > 1:263c = cmp(str(left.polynomial()), str(right.polynomial()))264if c: return c265return 0266267def __iter__(self):268"""269Return an iterator over the elements of this finite field. This generic270implementation uses the fairly simple :class:`FiniteFieldIterator`271class; derived classes may implement their own more sophisticated272replacements.273274EXAMPLE::275276sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari277sage: k = FiniteField_ext_pari(8, 'a')278sage: i = iter(k); i # indirect doctest279<sage.rings.finite_rings.finite_field_base.FiniteFieldIterator object at ...>280sage: i.next()2810282sage: list(k) # indirect doctest283[0, 1, a, a + 1, a^2, a^2 + 1, a^2 + a, a^2 + a + 1]284"""285return FiniteFieldIterator(self)286287def _is_valid_homomorphism_(self, codomain, im_gens):288"""289Return True if the map from self to codomain sending290self.0 to the unique element of im_gens is a valid field291homomorphism. Otherwise, return False.292293EXAMPLES::294295sage: k = FiniteField(73^2, 'a')296sage: K = FiniteField(73^3, 'b') ; b = K.0297sage: L = FiniteField(73^4, 'c') ; c = L.0298sage: k.hom([c]) # indirect doctest299Traceback (most recent call last):300...301TypeError: images do not define a valid homomorphism302303sage: k.hom([c^(73*73+1)])304Ring morphism:305From: Finite Field in a of size 73^2306To: Finite Field in c of size 73^4307Defn: a |--> 7*c^3 + 13*c^2 + 65*c + 71308309sage: k.hom([b])310Traceback (most recent call last):311...312TypeError: images do not define a valid homomorphism313"""314315if (self.characteristic() != codomain.characteristic()):316raise ValueError, "no map from %s to %s"%(self, codomain)317if (len(im_gens) != 1):318raise ValueError, "only one generator for finite fields."319320return (im_gens[0].charpoly())(self.gen(0)).is_zero()321322def _Hom_(self, codomain, cat=None):323"""324Return homset of homomorphisms from self to the finite field codomain.325This function is implicitly called by the Hom method or function.326327The cat option is currently ignored.328329EXAMPLES::330331sage: K.<a> = GF(25); K332Finite Field in a of size 5^2333sage: K.Hom(K) # indirect doctest334Automorphism group of Finite Field in a of size 5^2335"""336return FiniteFieldHomset(self, codomain)337338def gen(self):339r"""340Return a generator of this field (over its prime field). As this is an abstract base class,341this just raises a NotImplementedError.342343EXAMPLE::344345sage: K = GF(17)346sage: sage.rings.finite_rings.finite_field_base.FiniteField.gen(K)347Traceback (most recent call last):348...349NotImplementedError350"""351raise NotImplementedError352353def zeta_order(self):354"""355Return the order of the distinguished root of unity in self.356357EXAMPLES::358359sage: GF(9,'a').zeta_order()3608361sage: GF(9,'a').zeta()362a363sage: GF(9,'a').zeta().multiplicative_order()3648365"""366return self.order() - 1367368def zeta(self, n=None):369"""370Returns an element of multiplicative order n in this371finite field, if there is one. Raises a ValueError if there372is not.373374EXAMPLES::375376sage: k = GF(7)377sage: k.zeta()3783379sage: k.zeta().multiplicative_order()3806381sage: k.zeta(3)3822383sage: k.zeta(3).multiplicative_order()3843385sage: k = GF(49, 'a')386sage: k.zeta().multiplicative_order()38748388sage: k.zeta(6)3893390391Even more examples::392393sage: GF(9,'a').zeta_order()3948395sage: GF(9,'a').zeta()396a397sage: GF(9,'a').zeta(4)398a + 1399sage: GF(9,'a').zeta()^2400a + 1401"""402z = self.multiplicative_generator()403if n is None:404return z405else:406import sage.rings.integer407n = sage.rings.integer.Integer(n)408m = z.multiplicative_order()409if m % n != 0:410raise ValueError, "No %sth root of unity in self"%n411return z**(m.__floordiv__(n))412413def multiplicative_generator(self):414"""415Return a primitive element of this finite field, i.e. a generator416of the multiplicative group.417418You can use ``self.multiplicative_generator()`` or419``self.primitive_element()``, these mean the same thing.420421.. WARNING::422423This generator might change from one version of Sage to another.424425EXAMPLES::426427sage: k = GF(997)428sage: k.multiplicative_generator()4297430sage: k.<a> = GF(11^3)431sage: k.primitive_element()432a433sage: k.<b> = GF(19^32)434sage: k.multiplicative_generator()435b + 5436437TESTS:438439Check that large characteristics work (Trac #11946)::440441sage: p = 10^20 + 39442sage: x = polygen(GF(p))443sage: K.<a> = GF(p^2, modulus=x^2+1)444sage: K.multiplicative_generator()445a + 12446"""447from sage.rings.arith import primitive_root448449if self.__multiplicative_generator is not None:450return self.__multiplicative_generator451if self.degree() == 1:452self.__multiplicative_generator = self(primitive_root(self.order()))453return self.__multiplicative_generator454n = self.order() - 1455g = self.gen(0)456# We check whether x+g is a multiplicative generator, where457# x runs through the finite field.458# This has the advantage that g is the first element we try,459# so we always get g as generator if possible. Second, the460# PARI finite field iterator gives all the constant elements461# first, so we try g+(constant) before anything else.462for x in self:463a = g+x464if a != 0 and a.multiplicative_order() == n:465self.__multiplicative_generator = a466return a467468primitive_element = multiplicative_generator469470def ngens(self):471"""472The number of generators of the finite field. Always 1.473474EXAMPLES::475476sage: k = FiniteField(3^4, 'b')477sage: k.ngens()4781479"""480return 1481482def is_field(self, proof = True):483"""484Returns whether or not the finite field is a field, i.e.,485always returns True.486487EXAMPLES::488489sage: k.<a> = FiniteField(3^4)490sage: k.is_field()491True492"""493return True494495def is_finite(self):496"""497Return True since a finite field is finite.498499EXAMPLES::500501sage: GF(997).is_finite()502True503"""504return True505506def order(self):507"""508Return the order of this finite field.509510EXAMPLES::511512sage: GF(997).order()513997514"""515raise NotImplementedError516517def factored_order(self):518"""519Returns the factored order of this field. For compatibility with IntegerModRing.520521EXAMPLES::522523sage: GF(7^2,'a').factored_order()5247^2525"""526from sage.structure.factorization import Factorization527return Factorization([(self.characteristic(), self.degree())])528529def factored_unit_order(self):530"""531Returns the factorization of ``self.order()-1``, as a 1-element list. The format is for compatibility with IntegerModRing.532533EXAMPLES::534535sage: GF(7^2,'a').factored_unit_order()536[2^4 * 3]537"""538if self.__factored_unit_order is None:539if self.characteristic() in []: # want to be [2,3,5,7,11] once #7240 is finished.540self.__factored_unit_order = [(self.order()-1)._factor_cunningham()]541else:542self.__factored_unit_order = [(self.order()-1).factor()]543return self.__factored_unit_order544545def cardinality(self):546"""547Return the order of this finite field (same as self.order()).548549EXAMPLES::550551sage: GF(997).cardinality()552997553"""554return self.order()555556def __len__(self):557"""558len(k) returns the cardinality of k, i.e., the number of elements in k.559560EXAMPLE::561562sage: len(GF(8,'a'))5638564"""565return self.order()566567def is_prime_field(self):568"""569Return True if self is a prime field, i.e., has degree 1.570571EXAMPLES::572573sage: GF(3^7, 'a').is_prime_field()574False575sage: GF(3, 'a').is_prime_field()576True577"""578return self.degree()==1579580def modulus(self):581r"""582Return the minimal polynomial of the generator of self (over an583appropriate base field).584585The minimal polynomial of an element `a` in a field is the unique586irreducible polynomial of smallest degree with coefficients in the base587field that has `a` as a root. In finite field extensions, `\GF{p^n}`,588the base field is `\GF{p}`. Here are several examples::589590sage: F.<a> = GF(7^2, 'a'); F591Finite Field in a of size 7^2592sage: F.polynomial_ring()593Univariate Polynomial Ring in a over Finite Field of size 7594sage: f = F.modulus(); f595x^2 + 6*x + 3596sage: f(a)5970598599Although `f` is irreducible over the base field, we can double-check600whether or not `f` factors in `F` as follows. The command601`F[x](f)` coerces `f` as a polynomial with coefficients in `F`.602(Instead of a polynomial with coefficients over the base field.)603604::605606sage: f.factor()607x^2 + 6*x + 3608sage: F[x](f).factor()609(x + a + 6) * (x + 6*a)610611Here is an example with a degree 3 extension::612613sage: G.<b> = GF(7^3, 'b'); G614Finite Field in b of size 7^3615sage: g = G.modulus(); g616x^3 + 6*x^2 + 4617sage: g.degree(); G.degree()61836193620"""621return self.polynomial_ring("x")(self.polynomial().list())622623def unit_group_exponent(self):624"""625The exponent of the unit group of the finite field. For a626finite field, this is always the order minus 1.627628EXAMPLES::629630sage: k = GF(2^10, 'a')631sage: k.order()6321024633sage: k.unit_group_exponent()6341023635"""636return self.order() - 1637638639def random_element(self, *args, **kwds):640r"""641A random element of the finite field. Passes arguments to642``random_element()`` function of underlying vector space.643644EXAMPLES::645646sage: k = GF(19^4, 'a')647sage: k.random_element()648a^3 + 3*a^2 + 6*a + 9649650Passes extra positional or keyword arguments through::651652sage: k.random_element(prob=0)6530654655"""656if self.degree() == 1:657return self(randrange(self.order()))658v = self.vector_space().random_element(*args, **kwds)659return self(v)660661def some_elements(self):662"""663Returns a collection of elements of this finite field for use in unit testing.664665EXAMPLES::666667sage: k = GF(2^8,'a')668sage: k.some_elements() # random output669[a^4 + a^3 + 1, a^6 + a^4 + a^3, a^5 + a^4 + a, a^2 + a]670"""671return [self.random_element() for i in range(4)]672673def polynomial(self):674"""675Return the defining polynomial of this finite field.676677EXAMPLES::678679sage: f = GF(27,'a').polynomial(); f680a^3 + 2*a + 1681sage: parent(f)682Univariate Polynomial Ring in a over Finite Field of size 3683"""684raise NotImplementedError685686def polynomial_ring(self, variable_name=None):687"""688Returns the polynomial ring over the prime subfield in the689same variable as this finite field.690691EXAMPLES::692693sage: k.<alpha> = FiniteField(3^4)694sage: k.polynomial_ring()695Univariate Polynomial Ring in alpha over Finite Field of size 3696"""697from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing698from sage.rings.finite_rings.constructor import FiniteField as GF699700if variable_name is None and self.__polynomial_ring is not None:701return self.__polynomial_ring702else:703if variable_name is None:704self.__polynomial_ring = PolynomialRing(GF(self.characteristic()), self.variable_name())705return self.__polynomial_ring706else:707return PolynomialRing(GF(self.characteristic()), variable_name)708709def vector_space(self):710"""711Return the vector space over the prime subfield isomorphic712to this finite field as a vector space.713714EXAMPLES::715716sage: GF(27,'a').vector_space()717Vector space of dimension 3 over Finite Field of size 3718"""719if self.__vector_space is not None:720return self.__vector_space721else:722import sage.modules.all723V = sage.modules.all.VectorSpace(self.prime_subfield(),self.degree())724self.__vector_space = V725return V726727def __hash__(self):728r"""729Return a hash of this finite field.730731EXAMPLES::732733sage: hash(GF(17))734-1709973406 # 32-bit7359088054599082082 # 64-bit736"""737return hash("GF") + hash(self.order())738739def algebraic_closure(self):740"""741Return the algebraic closure of self (not implemented).742743.. note::744745This is not yet implemented for finite fields.746747EXAMPLES::748749sage: GF(5).algebraic_closure()750Traceback (most recent call last):751...752NotImplementedError: Algebraic closures of finite fields not implemented.753"""754raise NotImplementedError, "Algebraic closures of finite fields not implemented."755756757def unpickle_FiniteField_ext(_type, order, variable_name, modulus, kwargs):758r"""759Used to unpickle extensions of finite fields. Now superseded (hence no760doctest), but kept around for backward compatibility.761762EXAMPLE::763764sage: # not tested765"""766return _type(order, variable_name, modulus, **kwargs)767768def unpickle_FiniteField_prm(_type, order, variable_name, kwargs):769r"""770Used to unpickle finite prime fields. Now superseded (hence no doctest),771but kept around for backward compatibility.772773EXAMPLE::774775sage: # not tested776"""777return _type(order, variable_name, **kwargs)778779780def is_FiniteField(x):781"""782Return True if x is of type finite field, and False otherwise.783784EXAMPLES::785786sage: from sage.rings.finite_rings.finite_field_base import is_FiniteField787sage: is_FiniteField(GF(9,'a'))788True789sage: is_FiniteField(GF(next_prime(10^10)))790True791792Note that the integers modulo n are not of type finite field,793so this function returns False::794795sage: is_FiniteField(Integers(7))796False797"""798return IS_INSTANCE(x, FiniteField)799800801802