Path: blob/master/src/sage/rings/finite_rings/finite_field_base.pyx
8820 views
"""1Base Classes for Finite Fields23TESTS::45sage: K.<a> = NumberField(x^2 + 1)6sage: F = K.factor(3)[0][0].residue_field()7sage: loads(dumps(F)) == F8True9"""10include "sage/ext/stdsage.pxi"1112from sage.structure.parent cimport Parent13from sage.misc.cachefunc import cached_method14from sage.misc.prandom import randrange1516cdef class FiniteFieldIterator:17r"""18An iterator over a finite field. This should only be used when the field19is an extension of a smaller field which already has a separate iterator20function.21"""22cdef object iter23cdef FiniteField parent2425def __init__(self,FiniteField parent):26r"""27Initialize ``self``.2829EXAMPLES::3031sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari32sage: k = iter(FiniteField_ext_pari(9, 'a')) # indirect doctest33sage: isinstance(k, sage.rings.finite_rings.finite_field_base.FiniteFieldIterator)34True35"""36self.parent = parent37self.iter =iter(self.parent.vector_space())3839def __next__(self):40r"""41Return the next element in the iterator.4243EXAMPLE::4445sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari46sage: k = iter(FiniteField_ext_pari(9, 'a'))47sage: k.next() # indirect doctest48049"""50return self.parent(self.iter.next())5152def __iter__(self):53"""54Return ``self`` since this is an interator class.5556EXAMPLES::5758sage: K.<a> = GF(7^4)59sage: K.list()[:7]60[0, a, a^2, a^3, 2*a^2 + 3*a + 4, 2*a^3 + 3*a^2 + 4*a, 3*a^3 + a^2 + 6*a + 1]61sage: K.<a> = GF(5^9)62sage: for x in K:63... if x == a+3: break64... print x65066167268369470a71a + 172a + 273"""74return self7576from sage.categories.finite_fields import FiniteFields77_FiniteFields = FiniteFields()78cdef class FiniteField(Field):79"""80Abstract base class for finite fields.81"""82def __init__(self, base, names, normalize):83"""84Initialize ``self``.8586EXAMPLES::8788sage: K = GF(7); K89Finite Field of size 790sage: loads(K.dumps()) == K91True92sage: GF(7^10, 'a')93Finite Field in a of size 7^1094sage: K = GF(7^10, 'a'); K95Finite Field in a of size 7^1096sage: loads(K.dumps()) == K97True98"""99Field.__init__(self, base, names, normalize, category=_FiniteFields)100101def __repr__(self):102"""103String representation of this finite field.104105EXAMPLES::106107sage: k = GF(127)108sage: k # indirect doctest109Finite Field of size 127110111sage: k.<b> = GF(2^8)112sage: k113Finite Field in b of size 2^8114115sage: k.<c> = GF(2^20)116sage: k117Finite Field in c of size 2^20118119sage: k.<d> = GF(7^20)120sage: k121Finite Field in d of size 7^20122"""123if self.degree()>1:124return "Finite Field in %s of size %s^%s"%(self.variable_name(),self.characteristic(),self.degree())125else:126return "Finite Field of size %s"%(self.characteristic())127128def _latex_(self):129r"""130Returns a string denoting the name of the field in LaTeX.131132The :func:`~sage.misc.latex.latex` function calls the133``_latex_`` attribute when available.134135EXAMPLES:136137The ``latex`` command parses the string::138139sage: GF(81, 'a')._latex_()140'\\Bold{F}_{3^{4}}'141sage: latex(GF(81, 'a'))142\Bold{F}_{3^{4}}143sage: GF(3)._latex_()144'\\Bold{F}_{3}'145sage: latex(GF(3))146\Bold{F}_{3}147"""148if self.degree() > 1:149e = "^{%s}"%self.degree()150else:151e = ""152return "\\Bold{F}_{%s%s}"%(self.characteristic(), e)153154def _gap_init_(self):155"""156Return string that initializes the GAP version of157this finite field.158159EXAMPLES::160161sage: GF(9,'a')._gap_init_()162'GF(9)'163"""164return 'GF(%s)'%self.order()165166def _magma_init_(self, magma):167"""168Return string representation of ``self`` that Magma can169understand.170171EXAMPLES::172173sage: GF(97,'a')._magma_init_(magma) # optional - magma174'GF(97)'175sage: GF(9,'a')._magma_init_(magma) # optional - magma176'SageCreateWithNames(ext<GF(3)|_sage_[...]![GF(3)!2,GF(3)!2,GF(3)!1]>,["a"])'177sage: magma(GF(9,'a')) # optional - magma178Finite field of size 3^2179sage: magma(GF(9,'a')).1 # optional - magma180a181"""182if self.degree() == 1:183return 'GF(%s)'%self.order()184B = self.base_ring()185p = self.polynomial()186s = "ext<%s|%s>"%(B._magma_init_(magma),p._magma_init_(magma))187return magma._with_names(s, self.variable_names())188189def _macaulay2_init_(self):190"""191Returns the string representation of ``self`` that Macaulay2 can192understand.193194EXAMPLES::195196sage: GF(97,'a')._macaulay2_init_()197'GF 97'198199sage: macaulay2(GF(97, 'a')) # optional - macaulay2200GF 97201sage: macaulay2(GF(49, 'a')) # optional - macaulay2202GF 49203"""204return "GF %s"%(self.order())205206def _sage_input_(self, sib, coerced):207r"""208Produce an expression which will reproduce this value when evaluated.209210EXAMPLES::211212sage: sage_input(GF(5), verify=True)213# Verified214GF(5)215sage: sage_input(GF(32, 'a'), verify=True)216# Verified217R.<x> = GF(2)[]218GF(2^5, 'a', x^5 + x^2 + 1)219sage: K = GF(125, 'b')220sage: sage_input((K, K), verify=True)221# Verified222R.<x> = GF(5)[]223GF_5_3 = GF(5^3, 'b', x^3 + 3*x + 3)224(GF_5_3, GF_5_3)225sage: from sage.misc.sage_input import SageInputBuilder226sage: GF(81, 'a')._sage_input_(SageInputBuilder(), False)227{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}})}228"""229if self.degree() == 1:230v = sib.name('GF')(sib.int(self.characteristic()))231name = 'GF_%d' % self.characteristic()232else:233v = sib.name('GF')(sib.int(self.characteristic()) ** sib.int(self.degree()),234self.variable_name(),235self.modulus())236name = 'GF_%d_%d' % (self.characteristic(), self.degree())237sib.cache(self, v, name)238return v239240def _cmp_(left, Parent right):241"""242Compares this finite field with other.243244.. WARNING::245246The notation of equality of finite fields in Sage is247currently not stable, i.e., it may change in a future version.248249EXAMPLES::250251sage: FiniteField(3**2, 'c') == FiniteField(3**3, 'c') # indirect doctest252False253sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'c')254True255256The variable name is (currently) relevant for comparison of finite257fields::258259sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'd')260False261"""262if not PY_TYPE_CHECK(right, FiniteField):263return cmp(type(left), type(right))264c = cmp(left.characteristic(), right.characteristic())265if c: return c266c = cmp(left.degree(), right.degree())267if c: return c268# TODO comparing the polynomials themselves would recursively call269# this cmp... Also, as mentioned above, we will get rid of this.270if left.degree() > 1:271c = cmp(str(left.polynomial()), str(right.polynomial()))272if c: return c273return 0274275def __iter__(self):276"""277Return an iterator over the elements of this finite field. This generic278implementation uses the fairly simple :class:`FiniteFieldIterator`279class; derived classes may implement their own more sophisticated280replacements.281282EXAMPLES::283284sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari285sage: k = FiniteField_ext_pari(8, 'a')286sage: i = iter(k); i # indirect doctest287<sage.rings.finite_rings.finite_field_base.FiniteFieldIterator object at ...>288sage: i.next()2890290sage: list(k) # indirect doctest291[0, 1, a, a + 1, a^2, a^2 + 1, a^2 + a, a^2 + a + 1]292"""293return FiniteFieldIterator(self)294295def _is_valid_homomorphism_(self, codomain, im_gens):296"""297Return ``True`` if the map from self to codomain sending298``self.0`` to the unique element of ``im_gens`` is a valid field299homomorphism. Otherwise, return ``False``.300301EXAMPLES::302303sage: k = FiniteField(73^2, 'a')304sage: K = FiniteField(73^3, 'b') ; b = K.0305sage: L = FiniteField(73^4, 'c') ; c = L.0306sage: k.hom([c]) # indirect doctest307Traceback (most recent call last):308...309TypeError: images do not define a valid homomorphism310311sage: k.hom([c^(73*73+1)])312Ring morphism:313From: Finite Field in a of size 73^2314To: Finite Field in c of size 73^4315Defn: a |--> 7*c^3 + 13*c^2 + 65*c + 71316317sage: k.hom([b])318Traceback (most recent call last):319...320TypeError: images do not define a valid homomorphism321"""322if (self.characteristic() != codomain.characteristic()):323raise ValueError, "no map from %s to %s"%(self, codomain)324if (len(im_gens) != 1):325raise ValueError, "only one generator for finite fields."326327return (im_gens[0].charpoly())(self.gen(0)).is_zero()328329def _Hom_(self, codomain, cat=None):330"""331Return homset of homomorphisms from ``self`` to the finite field332codomain. This function is implicitly called by the Hom method or333function.334335The ``cat`` option is currently ignored.336337EXAMPLES::338339sage: K.<a> = GF(25); K340Finite Field in a of size 5^2341sage: K.Hom(K) # indirect doctest342Automorphism group of Finite Field in a of size 5^2343"""344from sage.rings.finite_rings.homset import FiniteFieldHomset345return FiniteFieldHomset(self, codomain)346347def gen(self):348r"""349Return a generator of this field (over its prime field). As this is an350abstract base class, this just raises a ``NotImplementedError``.351352EXAMPLES::353354sage: K = GF(17)355sage: sage.rings.finite_rings.finite_field_base.FiniteField.gen(K)356Traceback (most recent call last):357...358NotImplementedError359"""360raise NotImplementedError361362def zeta_order(self):363"""364Return the order of the distinguished root of unity in ``self``.365366EXAMPLES::367368sage: GF(9,'a').zeta_order()3698370sage: GF(9,'a').zeta()371a372sage: GF(9,'a').zeta().multiplicative_order()3738374"""375return self.order() - 1376377def zeta(self, n=None):378"""379Returns an element of multiplicative order ``n`` in this380finite field, if there is one. Raises a ``ValueError`` if there381is not.382383EXAMPLES::384385sage: k = GF(7)386sage: k.zeta()3873388sage: k.zeta().multiplicative_order()3896390sage: k.zeta(3)3912392sage: k.zeta(3).multiplicative_order()3933394sage: k = GF(49, 'a')395sage: k.zeta().multiplicative_order()39648397sage: k.zeta(6)3983399400Even more examples::401402sage: GF(9,'a').zeta_order()4038404sage: GF(9,'a').zeta()405a406sage: GF(9,'a').zeta(4)407a + 1408sage: GF(9,'a').zeta()^2409a + 1410"""411z = self.multiplicative_generator()412if n is None:413return z414else:415import sage.rings.integer416n = sage.rings.integer.Integer(n)417m = z.multiplicative_order()418if m % n != 0:419raise ValueError, "No %sth root of unity in self"%n420return z**(m.__floordiv__(n))421422def multiplicative_generator(self):423"""424Return a primitive element of this finite field, i.e. a generator425of the multiplicative group.426427You can use :meth:`multiplicative_generator()` or428:meth:`primitive_element()`, these mean the same thing.429430.. WARNING::431432This generator might change from one version of Sage to another.433434EXAMPLES::435436sage: k = GF(997)437sage: k.multiplicative_generator()4387439sage: k.<a> = GF(11^3)440sage: k.primitive_element()441a442sage: k.<b> = GF(19^32)443sage: k.multiplicative_generator()444b + 4445446TESTS:447448Check that large characteristics work (:trac:`11946`)::449450sage: p = 10^20 + 39451sage: x = polygen(GF(p))452sage: K.<a> = GF(p^2, modulus=x^2+1)453sage: K.multiplicative_generator()454a + 12455"""456from sage.rings.arith import primitive_root457458if self.__multiplicative_generator is not None:459return self.__multiplicative_generator460if self.degree() == 1:461self.__multiplicative_generator = self(primitive_root(self.order()))462return self.__multiplicative_generator463n = self.order() - 1464g = self.gen(0)465# We check whether x+g is a multiplicative generator, where466# x runs through the finite field.467# This has the advantage that g is the first element we try,468# so we always get g as generator if possible. Second, the469# PARI finite field iterator gives all the constant elements470# first, so we try g+(constant) before anything else.471for x in self:472a = g+x473if a != 0 and a.multiplicative_order() == n:474self.__multiplicative_generator = a475return a476477primitive_element = multiplicative_generator478479def ngens(self):480"""481The number of generators of the finite field. Always 1.482483EXAMPLES::484485sage: k = FiniteField(3^4, 'b')486sage: k.ngens()4871488"""489return 1490491def is_field(self, proof = True):492"""493Returns whether or not the finite field is a field, i.e.,494always returns ``True``.495496EXAMPLES::497498sage: k.<a> = FiniteField(3^4)499sage: k.is_field()500True501"""502return True503504def is_finite(self):505"""506Return ``True`` since a finite field is finite.507508EXAMPLES::509510sage: GF(997).is_finite()511True512"""513return True514515def order(self):516"""517Return the order of this finite field.518519EXAMPLES::520521sage: GF(997).order()522997523"""524raise NotImplementedError525526# cached because constructing the Factorization is slow;527# see :trac:`11628`.528@cached_method529def factored_order(self):530"""531Returns the factored order of this field. For compatibility with532:mod:`~sage.rings.finite_rings.integer_mod_ring`.533534EXAMPLES::535536sage: GF(7^2,'a').factored_order()5377^2538"""539from sage.structure.factorization import Factorization540return Factorization([(self.characteristic(), self.degree())])541542def factored_unit_order(self):543"""544Returns the factorization of ``self.order()-1``, as a 1-element list.545546The format is for compatibility with547:mod:`~sage.rings.finite_rings.integer_mod_ring`.548549EXAMPLES::550551sage: GF(7^2,'a').factored_unit_order()552[2^4 * 3]553"""554if self.__factored_unit_order is None:555self.__factored_unit_order = [(self.order()-1).factor()]556return self.__factored_unit_order557558def cardinality(self):559"""560Return the cardinality of ``self``.561562Same as :meth:`order`.563564EXAMPLES::565566sage: GF(997).cardinality()567997568"""569return self.order()570571__len__ = cardinality572573def is_prime_field(self):574"""575Return ``True`` if ``self`` is a prime field, i.e., has degree 1.576577EXAMPLES::578579sage: GF(3^7, 'a').is_prime_field()580False581sage: GF(3, 'a').is_prime_field()582True583"""584return self.degree()==1585586def modulus(self):587r"""588Return the minimal polynomial of the generator of self (over an589appropriate base field).590591The minimal polynomial of an element `a` in a field is the unique592irreducible polynomial of smallest degree with coefficients in the base593field that has `a` as a root. In finite field extensions, `\GF{p^n}`,594the base field is `\GF{p}`. Here are several examples::595596sage: F.<a> = GF(7^2, 'a'); F597Finite Field in a of size 7^2598sage: F.polynomial_ring()599Univariate Polynomial Ring in a over Finite Field of size 7600sage: f = F.modulus(); f601x^2 + 6*x + 3602sage: f(a)6030604605Although `f` is irreducible over the base field, we can double-check606whether or not `f` factors in `F` as follows. The command607``F[x](f)`` coerces `f` as a polynomial with coefficients in `F`.608(Instead of a polynomial with coefficients over the base field.)609610::611612sage: f.factor()613x^2 + 6*x + 3614sage: F[x](f).factor()615(x + a + 6) * (x + 6*a)616617Here is an example with a degree 3 extension::618619sage: G.<b> = GF(7^3, 'b'); G620Finite Field in b of size 7^3621sage: g = G.modulus(); g622x^3 + 6*x^2 + 4623sage: g.degree(); G.degree()62436253626"""627return self.polynomial_ring("x")(self.polynomial().list())628629def unit_group_exponent(self):630"""631The exponent of the unit group of the finite field. For a632finite field, this is always the order minus 1.633634EXAMPLES::635636sage: k = GF(2^10, 'a')637sage: k.order()6381024639sage: k.unit_group_exponent()6401023641"""642return self.order() - 1643644645def random_element(self, *args, **kwds):646r"""647A random element of the finite field. Passes arguments to648``random_element()`` function of underlying vector space.649650EXAMPLES::651652sage: k = GF(19^4, 'a')653sage: k.random_element()654a^3 + 3*a^2 + 6*a + 9655656Passes extra positional or keyword arguments through::657658sage: k.random_element(prob=0)6590660661"""662if self.degree() == 1:663return self(randrange(self.order()))664v = self.vector_space().random_element(*args, **kwds)665return self(v)666667def some_elements(self):668"""669Returns a collection of elements of this finite field for use in unit670testing.671672EXAMPLES::673674sage: k = GF(2^8,'a')675sage: k.some_elements() # random output676[a^4 + a^3 + 1, a^6 + a^4 + a^3, a^5 + a^4 + a, a^2 + a]677"""678return [self.random_element() for i in range(4)]679680def polynomial(self):681"""682Return the defining polynomial of this finite field.683684EXAMPLES::685686sage: f = GF(27,'a').polynomial(); f687a^3 + 2*a + 1688sage: parent(f)689Univariate Polynomial Ring in a over Finite Field of size 3690"""691raise NotImplementedError692693def polynomial_ring(self, variable_name=None):694"""695Returns the polynomial ring over the prime subfield in the696same variable as this finite field.697698EXAMPLES::699700sage: k.<alpha> = FiniteField(3^4)701sage: k.polynomial_ring()702Univariate Polynomial Ring in alpha over Finite Field of size 3703"""704from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing705from sage.rings.finite_rings.constructor import FiniteField as GF706707if variable_name is None and self.__polynomial_ring is not None:708return self.__polynomial_ring709else:710if variable_name is None:711self.__polynomial_ring = PolynomialRing(GF(self.characteristic()), self.variable_name())712return self.__polynomial_ring713else:714return PolynomialRing(GF(self.characteristic()), variable_name)715716def vector_space(self):717"""718Return the vector space over the prime subfield isomorphic719to this finite field as a vector space.720721EXAMPLES::722723sage: GF(27,'a').vector_space()724Vector space of dimension 3 over Finite Field of size 3725"""726if self.__vector_space is not None:727return self.__vector_space728else:729import sage.modules.all730V = sage.modules.all.VectorSpace(self.prime_subfield(),self.degree())731self.__vector_space = V732return V733734def __hash__(self):735r"""736Return a hash of this finite field.737738EXAMPLES::739740sage: hash(GF(17))741-1709973406 # 32-bit7429088054599082082 # 64-bit743"""744return hash("GF") + hash(self.order())745746cpdef _coerce_map_from_(self, R):747r"""748Canonical coercion to ``self``.749750TESTS::751752sage: k.<a> = GF(2^8)753sage: a + 1754a + 1755sage: a + int(1)756a + 1757sage: a + GF(2)(1)758a + 1759760sage: k.<a> = GF(3^8)761sage: a + 1762a + 1763sage: a + int(1)764a + 1765sage: a + GF(3)(1)766a + 1767768sage: k = GF(4, 'a')769sage: k._coerce_(GF(2)(1))7701771sage: k._coerce_(k.0)772a773sage: k._coerce_(3)7741775sage: k._coerce_(2/3)776Traceback (most recent call last):777...778TypeError: no canonical coercion from Rational Field to Finite Field in a of size 2^2779780sage: FiniteField(16, 'a', conway=True, prefix='z')._coerce_(FiniteField(4, 'a', conway=True, prefix='z').0)781a^2 + a782783sage: FiniteField(8, 'a')._coerce_(FiniteField(4, 'a').0)784Traceback (most recent call last):785...786TypeError: no canonical coercion from Finite Field in a of size 2^2 to Finite Field in a of size 2^3787788sage: FiniteField(8, 'a')._coerce_(FiniteField(7, 'a')(2))789Traceback (most recent call last):790...791TypeError: no canonical coercion from Finite Field of size 7 to Finite Field in a of size 2^3792"""793from sage.rings.integer_ring import ZZ794from sage.rings.finite_rings.finite_field_base import is_FiniteField795from sage.rings.finite_rings.integer_mod_ring import is_IntegerModRing796if R is int or R is long or R is ZZ:797return True798if is_IntegerModRing(R) and self.characteristic().divides(R.characteristic()):799return True800if is_FiniteField(R):801if R is self:802return True803from sage.rings.residue_field import ResidueField_generic804if isinstance(R, ResidueField_generic):805return False806if R.characteristic() == self.characteristic():807if R.degree() == 1:808return True809if self.degree() % R.degree() == 0:810if hasattr(self, '_prefix') and hasattr(R, '_prefix'):811return R.hom((self.gen() ** ((self.order() - 1)//(R.order() - 1)),))812813def construction(self):814"""815Return the construction of this finite field, as a ``ConstructionFunctor``816and the base field.817818EXAMPLES::819820sage: v = GF(3^3, conway=True, prefix='z').construction(); v821(AlgebraicExtensionFunctor, Finite Field of size 3)822sage: v[0].polys[0]8233824sage: v = GF(2^1000, 'a').construction(); v[0].polys[0]825a^1000 + a^5 + a^4 + a^3 + 1826"""827from sage.categories.pushout import AlgebraicExtensionFunctor828if self.degree() == 1:829# this is not of type FiniteField_prime_modn830from sage.rings.integer import Integer831return AlgebraicExtensionFunctor([self.polynomial()], [None], [None], conway=1), self.base_ring()832elif hasattr(self, '_prefix'):833return (AlgebraicExtensionFunctor([self.degree()], [self.variable_name()], [None],834conway=True, prefix=self._prefix),835self.base_ring())836else:837return (AlgebraicExtensionFunctor([self.polynomial()], [self.variable_name()], [None]),838self.base_ring())839840def extension(self, modulus, name=None, names=None, map=False, embedding=None, **kwds):841"""842Return an extension of this finite field.843844INPUT:845846- ``modulus`` -- a polynomial with coefficients in ``self``,847or an integer.848849- ``name`` -- string: the name of the generator in the new850extension851852- ``map`` -- boolean (default: ``False``): if ``False``,853return just the extension `E`; if ``True``, return a pair854`(E, f)`, where `f` is an embedding of ``self`` into `E`.855856- ``embedding`` -- currently not used; for compatibility with857other ``AlgebraicExtensionFunctor`` calls.858859- ``**kwds``: further keywords, passed to the finite field860constructor.861862OUTPUT:863864An extension of the given modulus, or pseudo-Conway of the865given degree if ``modulus`` is an integer.866867EXAMPLES::868869sage: k = GF(2)870sage: R.<x> = k[]871sage: k.extension(x^1000 + x^5 + x^4 + x^3 + 1, 'a')872Finite Field in a of size 2^1000873sage: k = GF(3^4, conway=True, prefix='z')874sage: R.<x> = k[]875sage: k.extension(3, conway=True, prefix='z')876Finite Field in z12 of size 3^12877878An example using the ``map`` argument::879880sage: F = GF(5)881sage: E, f = F.extension(2, 'b', map=True)882sage: E883Finite Field in b of size 5^2884sage: f885Conversion map:886From: Finite Field of size 5887To: Finite Field in b of size 5^2888sage: f.parent()889Set of field embeddings from Finite Field of size 5 to Finite Field in b of size 5^2890891Extensions of non-prime finite fields by polynomials are not yet892supported: we fall back to generic code::893894sage: k.extension(x^5 + x^2 + x - 1)895Univariate Quotient Polynomial Ring in x over Finite Field in z4 of size 3^4 with modulus x^5 + x^2 + x + 2896"""897from constructor import GF898from sage.rings.polynomial.all import is_Polynomial899from sage.rings.integer import Integer900if name is None and names is not None:901name = names902if self.degree() == 1:903if isinstance(modulus, Integer):904E = GF(self.characteristic()**modulus, name=name, **kwds)905elif isinstance(modulus, (list, tuple)):906E = GF(self.characteristic()**(len(modulus) - 1), name=name, modulus=modulus, **kwds)907elif is_Polynomial(modulus):908if modulus.change_ring(self).is_irreducible():909E = GF(self.characteristic()**(modulus.degree()), name=name, modulus=modulus, **kwds)910else:911E = Field.extension(self, modulus, name=name, embedding=embedding)912elif isinstance(modulus, Integer):913E = GF(self.order()**modulus, name=name, **kwds)914else:915E = Field.extension(self, modulus, name=name, embedding=embedding)916if not map:917return E918# Use the canonical map if it exists.919f = E.coerce_map_from(self)920if f is None:921from sage.categories.homset import Hom922f = Hom(self, E).an_element()923return (E, f)924925def subfields(self, degree=0, name=None):926"""927Return all subfields of ``self`` of the given ``degree``,928or all possible degrees if ``degree`` is `0`.929930The subfields are returned as absolute fields together with931an embedding into ``self``.932933INPUT:934935- ``degree`` -- (default: `0`) an integer936937- ``name`` -- a string, a dictionary or ``None``:938939- If ``degree`` is nonzero, then ``name`` must be a string940(or ``None``, if this is a pseudo-Conway extension),941and will be the variable name of the returned field.942- If ``degree`` is zero, the dictionary should have keys the divisors943of the degree of this field, with the desired variable name for the944field of that degree as an entry.945- As a shortcut, you can provide a string and the degree of each946subfield will be appended for the variable name of that subfield.947- If ``None``, uses the prefix of this field.948949OUTPUT:950951A list of pairs ``(K, e)``, where ``K`` ranges over the subfields of952this field and ``e`` gives an embedding of ``K`` into ``self``.953954EXAMPLES::955956sage: k.<a> = GF(2^21, conway=True, prefix='z')957sage: k.subfields()958[(Finite Field of size 2,959Conversion map:960From: Finite Field of size 2961To: Finite Field in a of size 2^21),962(Finite Field in z3 of size 2^3,963Ring morphism:964From: Finite Field in z3 of size 2^3965To: Finite Field in a of size 2^21966Defn: z3 |--> a^20 + a^19 + a^17 + a^15 + a^11 + a^9 + a^8 + a^6 + a^2),967(Finite Field in z7 of size 2^7,968Ring morphism:969From: Finite Field in z7 of size 2^7970To: Finite Field in a of size 2^21971Defn: z7 |--> a^20 + a^19 + a^17 + a^15 + a^14 + a^6 + a^4 + a^3 + a),972(Finite Field in z21 of size 2^21,973Ring morphism:974From: Finite Field in z21 of size 2^21975To: Finite Field in a of size 2^21976Defn: z21 |--> a)]977"""978from sage.rings.integer import Integer979from constructor import GF980p = self.characteristic()981n = self.degree()982if degree != 0:983degree = Integer(degree)984if not degree.divides(n):985return []986elif hasattr(self, '_prefix'):987K = GF(p**degree, name=name, conway=True, prefix=self._prefix)988return [(K, self.coerce_map_from(K))]989elif degree == 1:990K = GF(p)991return [(K, self.coerce_map_from(K))]992else:993gen = self.gen()**((self.order() - 1)//(p**degree - 1))994K = GF(p**degree, modulus=gen.minimal_polynomial(), name=name)995return [(K, K.hom((gen,)))]996else:997divisors = n.divisors()998if name is None:999if hasattr(self, '_prefix'):1000name = self._prefix1001else:1002name = self.variable_name()1003if isinstance(name, str):1004name = {m: name + str(m) for m in divisors}1005elif not isinstance(name, dict):1006raise ValueError, "name must be None, a string or a dictionary indexed by divisors of the degree"1007return [self.subfields(m, name=name[m])[0] for m in divisors]10081009def algebraic_closure(self):1010"""1011Return the algebraic closure of ``self`` (not implemented).10121013.. NOTE::10141015This is not yet implemented for finite fields.10161017EXAMPLES::10181019sage: GF(5).algebraic_closure()1020Traceback (most recent call last):1021...1022NotImplementedError: Algebraic closures of finite fields not implemented.1023"""1024raise NotImplementedError, "Algebraic closures of finite fields not implemented."10251026@cached_method1027def is_conway(self):1028"""1029Return ``True`` if self is defined by a Conway polynomial.10301031EXAMPLES:10321033sage: GF(5^3, 'a').is_conway()1034True1035sage: GF(5^3, 'a', modulus='adleman-lenstra').is_conway()1036False1037sage: GF(next_prime(2^16, 2), 'a').is_conway()1038False1039"""1040from conway_polynomials import conway_polynomial, exists_conway_polynomial1041p = self.characteristic()1042n = self.degree()1043return (exists_conway_polynomial(p, n)1044and self.polynomial() == self.polynomial_ring()(conway_polynomial(p, n)))10451046def frobenius_endomorphism(self, n=1):1047"""1048INPUT:10491050- ``n`` -- an integer (default: 1)10511052OUTPUT:10531054The `n`-th power of the absolute arithmetic Frobenius1055endomorphism on this finite field.10561057EXAMPLES::10581059sage: k.<t> = GF(3^5)1060sage: Frob = k.frobenius_endomorphism(); Frob1061Frobenius endomorphism t |--> t^3 on Finite Field in t of size 3^510621063sage: a = k.random_element()1064sage: Frob(a) == a^31065True10661067We can specify a power::10681069sage: k.frobenius_endomorphism(2)1070Frobenius endomorphism t |--> t^(3^2) on Finite Field in t of size 3^510711072The result is simplified if possible::10731074sage: k.frobenius_endomorphism(6)1075Frobenius endomorphism t |--> t^3 on Finite Field in t of size 3^51076sage: k.frobenius_endomorphism(5)1077Identity endomorphism of Finite Field in t of size 3^510781079Comparisons work::10801081sage: k.frobenius_endomorphism(6) == Frob1082True1083sage: from sage.categories.morphism import IdentityMorphism1084sage: k.frobenius_endomorphism(5) == IdentityMorphism(k)1085True10861087AUTHOR:10881089- Xavier Caruso (2012-06-29)1090"""1091from sage.rings.finite_rings.hom_finite_field import FrobeniusEndomorphism_finite_field1092return FrobeniusEndomorphism_finite_field(self, n)109310941095def unpickle_FiniteField_ext(_type, order, variable_name, modulus, kwargs):1096r"""1097Used to unpickle extensions of finite fields. Now superseded (hence no1098doctest), but kept around for backward compatibility.10991100EXAMPLES::11011102sage: # not tested1103"""1104return _type(order, variable_name, modulus, **kwargs)11051106def unpickle_FiniteField_prm(_type, order, variable_name, kwargs):1107r"""1108Used to unpickle finite prime fields. Now superseded (hence no doctest),1109but kept around for backward compatibility.11101111EXAMPLE::11121113sage: # not tested1114"""1115return _type(order, variable_name, **kwargs)111611171118def is_FiniteField(x):1119"""1120Return ``True`` if ``x`` is of type finite field, and ``False`` otherwise.11211122EXAMPLES::11231124sage: from sage.rings.finite_rings.finite_field_base import is_FiniteField1125sage: is_FiniteField(GF(9,'a'))1126True1127sage: is_FiniteField(GF(next_prime(10^10)))1128True11291130Note that the integers modulo n are not of type finite field,1131so this function returns ``False``::11321133sage: is_FiniteField(Integers(7))1134False1135"""1136return IS_INSTANCE(x, FiniteField)113711381139