Path: blob/master/src/sage/rings/finite_rings/element_ext_pari.py
8820 views
"""1Elements of Finite Fields23EXAMPLES::45sage: K = FiniteField(2)6sage: V = VectorSpace(K,3)7sage: w = V([0,1,2])8sage: K(1)*w9(0, 1, 0)1011We do some arithmetic involving a bigger field and a Conway12polynomial, i.e., we verify compatibility condition.1314::1516sage: f = conway_polynomial(2,63)17sage: K.<a> = GF(2**63, name='a', modulus=f, impl='pari_mod')18sage: n = f.degree()19sage: m = 3;20sage: e = (2^n - 1) / (2^m - 1)21sage: c = a^e22sage: conway = conway_polynomial(2,m)23sage: conway(c) == 024True25"""262728import operator2930import sage.structure.element as element31import sage.rings.arith as arith32import sage.rings.integer_ring as integer_ring33from sage.rings.integer import Integer34import sage.rings.rational as rational35from sage.libs.pari.all import pari, pari_gen36from sage.rings.finite_rings.element_base import FinitePolyExtElement37import sage.rings.field_element as field_element38import sage.rings.finite_rings.integer_mod as integer_mod39from element_base import is_FiniteFieldElement40from sage.modules.free_module_element import FreeModuleElement41from sage.structure.dynamic_class import dynamic_class42from sage.categories.finite_fields import FiniteFields4344class FiniteField_ext_pariElement(FinitePolyExtElement):45"""46An element of a finite field.4748Create elements by first defining the finite field ``F``, then use the49notation ``F(n)``, for ``n`` an integer, or let ``a = F.gen()`` and50write the element in terms of ``a``.5152EXAMPLES::5354sage: K = FiniteField(10007^10, 'a', impl='pari_mod')55sage: a = K.gen(); a56a57sage: loads(a.dumps()) == a58True59sage: K = GF(10007)60sage: a = K(938); a6193862sage: loads(a.dumps()) == a63True6465TESTS::6667sage: K.<a> = GF(2^16, impl='pari_mod')68sage: K(0).is_zero()69True70sage: (a - a).is_zero()71True72sage: a - a73074sage: a == a75True76sage: a - a == 077True78sage: a - a == K(0)79True80sage: TestSuite(a).run()81"""82def __init__(self, parent, value, value_from_pari=False):83"""84Create element of a finite field.8586INPUT:8788- ``parent`` -- A finite field, the parent of this element.8990- ``value`` -- Anything that can be converted into the PARI91interface and can be interpreted as an element of ``parent``.9293- ``value_from_pari`` -- optional bool, default ``False``. If it94evaluates as ``True``, then ``value`` *must* be an element of the95PARI interface, and there will be no conversion.9697.. NOTE::9899If the given value is a list or an element of the vector space100associated with the given parent, then it is interpreted as101the list of coefficients of a polynomial over the prime subfield,102and that polynomial is interpreted as an element of the given103parent. The empty list results in zero.104105If ``value_from_pari`` is ``True`` then it is assumed that the106given value is a suitable representation of the element in PARI,107and there is no conversion. Hence, it is very fast, but must be108used with care.109110EXAMPLES::111112sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari113sage: k = FiniteField_ext_pari(9,'a')114sage: a = k(11); a1152116sage: a.parent()117Finite Field in a of size 3^2118sage: V = k.vector_space(); v = V((1,2))119sage: k(v)1202*a + 1121122We create elements using a list and verify that :trac:`10486` has123been fixed::124125sage: k = FiniteField_ext_pari(3^11, 't')126sage: x = k([1,0,2,1]); x127t^3 + 2*t^2 + 1128sage: x + x + x1290130sage: pari(x)131Mod(Mod(1, 3)*a^3 + Mod(2, 3)*a^2 + Mod(1, 3), Mod(1, 3)*a^11 + Mod(2, 3)*a^2 + Mod(1, 3))132133If the list is longer than the degree, we just get the result134modulo the modulus::135136sage: R.<a> = PolynomialRing(GF(5))137sage: k = FiniteField_ext_pari(5^2, 't', modulus=a^2-2)138sage: x = k([0,0,0,1]); x1392*t140sage: pari(x)141Mod(Mod(2, 5)*a, Mod(1, 5)*a^2 + Mod(3, 5))142143When initializing from a list, the elements are first coerced144to the prime field (:trac:`11685`)::145146sage: k = FiniteField_ext_pari(3^11, 't')147sage: k([ 0, 1/2 ])1482*t149sage: k([ k(0), k(1) ])150t151sage: k([ GF(3)(2), GF(3^5,'u')(1) ])152t + 2153sage: R.<x> = PolynomialRing(k)154sage: k([ R(-1), x/x ])155t + 2156157We demonstrate the creation of an element via polynomials::158159sage: k.polynomial()160t^11 + 2*t^2 + 1161sage: P = k.polynomial_ring()162sage: k(P.0^11)163t^2 + 2164165We demonstrate the creation of an element via a vector::166167sage: V = k.vector_space()168sage: V169Vector space of dimension 11 over Finite Field of size 3170sage: v = V([0,1,2,0,1,2,0,1,2,0,1])171sage: k(v)172t^10 + 2*t^8 + t^7 + 2*t^5 + t^4 + 2*t^2 + t173174TESTS:175176Check that zeros are created correctly (:trac:`11685`)::177178sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari179sage: K = FiniteField_ext_pari(3^11, 't'); a = K.0180sage: v = 0; pari(K(v)).lift()181Mod(0, 3)182sage: v = Mod(0,3); pari(K(v)).lift()183Mod(0, 3)184sage: v = pari(0); pari(K(v)).lift()185Mod(0, 3)186sage: v = pari("Mod(0,3)"); pari(K(v)).lift()187Mod(0, 3)188sage: v = []; pari(K(v)).lift()189Mod(0, 3)190sage: v = [0]; pari(K(v)).lift()191Mod(0, 3)192sage: v = [0,0]; pari(K(v)).lift()193Mod(0, 3)194sage: v = pari("Pol(0)"); pari(K(v)).lift()195Mod(0, 3)196sage: v = pari("Mod(0, %s)"%K._pari_modulus()); pari(K(v)).lift()197Mod(0, 3)198sage: v = pari("Mod(Pol(0), %s)"%K._pari_modulus()); pari(K(v)).lift()199Mod(0, 3)200sage: v = K(1) - K(1); pari(K(v)).lift()201Mod(0, 3)202sage: v = K([1]) - K([1]); pari(K(v)).lift()203Mod(0, 3)204sage: v = a - a; pari(K(v)).lift()205Mod(0, 3)206sage: v = K(1)*0; pari(K(v)).lift()207Mod(0, 3)208sage: v = K([1])*K([0]); pari(K(v)).lift()209Mod(0, 3)210sage: v = a*0; pari(K(v)).lift()211Mod(0, 3)212213The following test documents the optional argument ``value_from_pari``.214It is for internal use only and greatly improves the speed in215arithmetic operations. However, the example shows why it must only be216used carefully::217218sage: from sage.rings.finite_rings.element_ext_pari import FiniteField_ext_pariElement219sage: a = FiniteField_ext_pariElement(K,pari(0),value_from_pari=True)220sage: a2210222sage: a == K(0)223False224225The reason is that the pari elements representing ``a`` and ``K(0)``226are different::227228sage: pari(a).lift()2290230sage: pari(K(0)).lift()231Mod(0, 3)232233"""234field_element.FieldElement.__init__(self, parent)235self.__class__ = dynamic_FiniteField_ext_pariElement236237# If value_from_pari is True, directly set self.__value to value.238# This assumes that value is a POLMOD with the correct modulus239# whose lift is either an INTMOD or a POL with INTMOD240# coefficients. In practice, this means that value comes from a241# PARI calculation with other elements of this finite field.242# This assumption is not checked.243if value_from_pari:244self.__value = value245return246247try:248if isinstance(value, pari_gen):249try:250# In some cases we get two different versions of251# the 0 element of a finite field. This has to do252# with how PARI's Mod() function works -- it treats253# polynomials different from integers.254# Also, we need to fix things like ``1/Mod(3,5)`` when255# we want ``Mod(2,5)``.256# These issues are solved by first simplifying the257# given value.258value = value.simplify()259if value.type() != "t_POLMOD":260value = value.Mod(parent._pari_modulus())261self.__value = value * parent._pari_one()262except RuntimeError:263raise TypeError, "no possible coercion implemented"264elif isinstance(value, FiniteField_ext_pariElement):265if parent != value.parent():266raise TypeError, "no coercion implemented"267else:268self.__value = value.__value269elif isinstance(value, FreeModuleElement):270if parent.vector_space() != value.parent():271raise TypeError, "e.parent must match self.vector_space"272self.__value = pari(0).Mod(parent._pari_modulus())*parent._pari_one()273for i in range(len(value)):274self.__value = self.__value + pari(int(value[i])).Mod(parent._pari_modulus())*pari("a^%s"%i)275elif isinstance(value, list):276# AUTHOR: Jeroen Demeyer277# See Trac #10486 and #11685 for comments about this278# implementation279280# We need a special case for the empty list because281# PARI's ``Pol([])`` returns an exact 0 while we want282# ``Mod(0,3)``.283if not value:284value = [0]285try:286# First, try the conversion directly in PARI. This287# should cover the most common cases, like converting288# from integers or intmods.289# Convert the list to PARI, then mod out the290# characteristic (PARI can do this directly for lists),291# convert to a polynomial with variable "a" and finally292# mod out the field modulus.293self.__value = pari(value).Mod(parent.characteristic()).Polrev("a").Mod(parent._pari_modulus())294except RuntimeError:295# That didn't work, do it in a more general but also296# slower way: first convert all list elements to the297# prime field.298GFp = parent.prime_subfield()299self.__value = pari([GFp(c) for c in value]).Polrev("a").Mod(parent._pari_modulus())300elif isinstance(value, str):301raise TypeError, "value must not be a string"302else:303try:304self.__value = pari(value).Mod(parent._pari_modulus())*parent._pari_one()305except RuntimeError:306raise TypeError, "no coercion implemented"307308except (AttributeError, TypeError):309raise TypeError, "unable to coerce"310311def __hash__(self):312"""313The hash of this element is the hash of the underlying polynomial.314315EXAMPLES::316317sage: k.<a> = GF(3^15, impl='pari_mod')318sage: R = GF(3)['a']; aa = R.gen()319sage: hash(a^2 + 1) == hash(aa^2 + 1)320True321"""322return hash(self.polynomial())323324def polynomial(self):325"""326Elements of a finite field are represented as a polynomial modulo a327modulus. This function returns the representing polynomial as an328element of the polynomial ring over the prime finite field, with329the same variable as the finite field.330331EXAMPLES:332333The default variable is ``a``::334335sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari336sage: k = FiniteField_ext_pari(3**2,'a')337sage: k.gen().polynomial()338a339340The variable can be any string::341342sage: k = FiniteField(3**4, "alpha", impl='pari_mod')343sage: a = k.gen()344sage: a.polynomial()345alpha346sage: (a**2 + 1).polynomial()347alpha^2 + 1348sage: (a**2 + 1).polynomial().parent()349Univariate Polynomial Ring in alpha over Finite Field of size 3350"""351return self.parent().polynomial_ring()(self.__value.lift())352353def is_square(self):354"""355Returns ``True`` if and only if this element is a perfect square.356357EXAMPLES::358359sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari360sage: k = FiniteField_ext_pari(3**2, 'a')361sage: a = k.gen()362sage: a.is_square()363False364sage: (a**2).is_square()365True366sage: k = FiniteField_ext_pari(2**2,'a')367sage: a = k.gen()368sage: (a**2).is_square()369True370sage: k = FiniteField_ext_pari(17**5,'a'); a = k.gen()371sage: (a**2).is_square()372True373sage: a.is_square()374False375376::377378sage: k(0).is_square()379True380"""381K = self.parent()382if K.characteristic() == 2:383return True384n = K.order() - 1385a = self**(n // 2)386return a == 1 or a == 0387388def square_root(self, extend=False, all=False):389"""390The square root function.391392INPUT:393394395- ``extend`` -- bool (default: ``True``); if ``True``, return a396square root in an extension ring, if necessary. Otherwise, raise a397ValueError if the root is not in the base ring.398399.. WARNING::400401This option is not implemented!402403- ``all`` - bool (default: ``False``); if ``True``, return all404square roots of ``self``, instead of just one.405406.. WARNING::407408The ``'extend'`` option is not implemented (yet).409410EXAMPLES::411412sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari413sage: F = FiniteField_ext_pari(7^2, 'a')414sage: F(2).square_root()4154416sage: F(3).square_root()4175*a + 1418sage: F(3).square_root()**24193420sage: F(4).square_root()4215422sage: K = FiniteField_ext_pari(7^3, 'alpha')423sage: K(3).square_root()424Traceback (most recent call last):425...426ValueError: must be a perfect square.427"""428if extend:429raise NotImplementedError430R = self.parent()['x']431f = R([-self, 0, 1])432g = f.factor()433if len(g) == 2 or g[0][1] == 2:434if all:435return [-g[0][0][0], g[0][0][0]]436else:437return -g[0][0][0]438if all:439return []440else:441raise ValueError, "must be a perfect square."442443def sqrt(self, extend=False, all = False):444"""445See :meth:square_root().446447EXAMPLES::448449sage: k.<a> = GF(3^17, impl='pari_mod')450sage: (a^3 - a - 1).sqrt()4512*a^16 + a^15 + 2*a^13 + a^12 + 2*a^10 + a^9 + a^8 + 2*a^7 + 2*a^6 + a^5 + 2*a^4 + a^2 + a + 1452"""453return self.square_root(extend=extend, all=all)454455def rational_reconstruction(self):456"""457If the parent field is a prime field, uses rational reconstruction458to try to find a lift of this element to the rational numbers.459460EXAMPLES::461462sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari463sage: k = GF(97)464sage: a = k(RationalField()('2/3'))465sage: a46633467sage: a.rational_reconstruction()4682/3469"""470if self.parent().degree() != 1:471raise ArithmeticError, "finite field must be prime"472t = arith.rational_reconstruction(int(self), self.parent().characteristic())473if t == None or t[1] == 0:474raise ZeroDivisionError, "unable to compute rational reconstruction"475return rational.Rational((t[0],t[1]))476477def multiplicative_order(self):478r"""479Returns the *multiplicative* order of this element, which must be480nonzero.481482EXAMPLES::483484sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari485sage: a = FiniteField_ext_pari(5**3, 'a').0486sage: a.multiplicative_order()487124488sage: a**1244891490"""491try:492return self.__multiplicative_order493except AttributeError:494if self.is_zero():495raise ArithmeticError("Multiplicative order of 0 not defined.")496n = self.parent().order() - 1497order = 1498for p, e in arith.factor(n):499# Determine the power of p that divides the order.500a = self**(n//(p**e))501while a != 1:502order *= p503a = a**p504self.__multiplicative_order = order505return order506507def __copy__(self):508"""509Return a copy of this element.510511EXAMPLES::512513sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari514sage: k = FiniteField_ext_pari(3**3,'a')515sage: a = k(5)516sage: a5172518sage: copy(a)5192520sage: b = copy(a)521sage: a == b522True523sage: a is b524False525sage: a is a526True527"""528return FiniteField_ext_pariElement(self.parent(), self.__value, value_from_pari=True)529530def _pari_(self, var=None):531"""532Return PARI object corresponding to this finite field element.533534EXAMPLES::535536sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari537sage: k = FiniteField_ext_pari(3**3, 'a')538sage: a = k.gen()539sage: b = a**2 + 2*a + 1540sage: b._pari_()541Mod(Mod(1, 3)*a^2 + Mod(2, 3)*a + Mod(1, 3), Mod(1, 3)*a^3 + Mod(2, 3)*a + Mod(1, 3))542543Looking at the PARI representation of a finite field element, it's544no wonder people find PARI difficult to work with directly. Compare545our representation::546547sage: b548a^2 + 2*a + 1549sage: b.parent()550Finite Field in a of size 3^3551"""552if var is None:553var = self.parent().variable_name()554if var == 'a':555return self.__value556else:557return self.__value.subst('a', var)558559def _pari_init_(self):560"""561The string producing this finite field element in PARI.562563EXAMPLES::564565sage: k.<a> = GF(3^17, impl='pari_mod')566sage: a._pari_init_()567'Mod(Mod(1, 3)*a, Mod(1, 3)*a^17 + Mod(2, 3)*a + Mod(1, 3))'568"""569return str(self.__value)570571def _magma_init_(self, magma):572"""573Return a string representation of self that Magma can understand.574575EXAMPLES::576577sage: GF(7)(3)._magma_init_(magma) # optional - magma578'GF(7)!3'579"""580km = magma(self.parent())581vn = km.gen(1).name()582return ("%s"%(self.__value.lift().lift())).replace('a',vn)583584def _gap_init_(self):585r"""586Supports returning corresponding GAP object. This can be slow since587non-prime GAP finite field elements are represented as powers of a588generator for the multiplicative group, so the discrete log problem589must be solved.590591.. NOTE::592593The order of the parent field must be `\leq 65536`.594595EXAMPLES::596597sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari598sage: F = FiniteField_ext_pari(8,'a')599sage: a = F.multiplicative_generator()600sage: gap(a) # indirect doctest601Z(2^3)602sage: b = F.multiplicative_generator()603sage: a = b^3604sage: gap(a)605Z(2^3)^3606sage: gap(a^3)607Z(2^3)^2608609You can specify the instance of the Gap interpreter that is used::610611sage: F = FiniteField_ext_pari(next_prime(200)^2, 'a')612sage: a = F.multiplicative_generator ()613sage: a._gap_ (gap)614Z(211^2)615sage: (a^20)._gap_(gap)616Z(211^2)^20617618Gap only supports relatively small finite fields.619620::621622sage: F = FiniteField_ext_pari(next_prime(1000)^2, 'a')623sage: a = F.multiplicative_generator ()624sage: gap._coerce_(a)625Traceback (most recent call last):626...627TypeError: order must be at most 65536628"""629F = self.parent()630if F.order() > 65536:631raise TypeError, "order must be at most 65536"632633if self == 0:634return '0*Z(%s)'%F.order()635assert F.degree() > 1636g = F.multiplicative_generator()637n = self.log(g)638return 'Z(%s)^%s'%(F.order(), n)639640def _repr_(self):641"""642String representation of this element.643644EXAMPLES::645646sage: k.<c> = GF(3^17, impl='pari_mod')647sage: c^20 # indirect doctest648c^4 + 2*c^3649"""650return ("%s"%(self.__value.lift().lift())).replace('a',self.parent().variable_name())651652def _add_(self, right):653"""654Addition.655656EXAMPLES::657658sage: k.<a> = GF(3^17, impl='pari_mod')659sage: a + a^2 # indirect doctest660a^2 + a661"""662return FiniteField_ext_pariElement(self.parent(), self.__value + right.__value, value_from_pari=True)663664def _sub_(self, right):665"""666Subtraction.667668EXAMPLES::669670sage: k.<a> = GF(3^17, impl='pari_mod')671sage: a - a # indirect doctest6720673"""674return FiniteField_ext_pariElement(self.parent(), self.__value - right.__value, value_from_pari=True)675676def _mul_(self, right):677"""678Multiplication.679680EXAMPLES::681682sage: k.<a> = GF(3^17, impl='pari_mod')683sage: (a^12 + 1)*(a^15 - 1) # indirect doctest684a^15 + 2*a^12 + a^11 + 2*a^10 + 2685"""686return FiniteField_ext_pariElement(self.parent(), self.__value * right.__value, value_from_pari=True)687688def _div_(self, right):689"""690Division.691692EXAMPLES::693694sage: k.<a> = GF(3^17, impl='pari_mod')695sage: (a - 1) / (a + 1) # indirect doctest6962*a^16 + a^15 + 2*a^14 + a^13 + 2*a^12 + a^11 + 2*a^10 + a^9 + 2*a^8 + a^7 + 2*a^6 + a^5 + 2*a^4 + a^3 + 2*a^2 + a + 1697"""698if right.__value == 0:699raise ZeroDivisionError700return FiniteField_ext_pariElement(self.parent(), self.__value / right.__value, value_from_pari=True)701702def __int__(self):703"""704Lifting to a python int, if possible.705706EXAMPLES::707708sage: k.<a> = GF(3^17, impl='pari_mod'); b = k(2)709sage: int(b)7102711sage: int(a)712Traceback (most recent call last):713...714TypeError: Unable to coerce PARI a to an Integer715"""716try:717return int(self.__value.lift().lift())718except ValueError:719raise TypeError, "cannot coerce to int"720721def _integer_(self, ZZ=None):722"""723Lifting to a sage integer if possible.724725EXAMPLES::726727sage: k.<a> = GF(3^17, impl='pari_mod'); b = k(2)728sage: b._integer_()7292730sage: a._integer_()731Traceback (most recent call last):732...733TypeError: Unable to coerce PARI a to an Integer734"""735return self.lift()736737def __long__(self):738"""739Lifting to a python long, if possible.740741EXAMPLES::742743sage: k.<a> = GF(3^17, impl='pari_mod'); b = k(2)744sage: long(b)7452L746"""747try:748return long(self.__value.lift().lift())749except ValueError:750raise TypeError, "cannot coerce to long"751752def __float__(self):753"""754Lifting to a python float, if possible.755756EXAMPLES::757758sage: k.<a> = GF(3^17, impl='pari_mod'); b = k(2)759sage: float(b)7602.0761"""762try:763return float(self.__value.lift().lift())764except ValueError:765raise TypeError, "cannot coerce to float"766767def __pow__(self, _right):768"""769TESTS::770771sage: K.<a> = GF(5^10, impl='pari_mod')772sage: n = (2*a)/a773774Naively compute `n^{-15}` in PARI, note that the result is `1/3`.775This is mathematically correct (modulo 5), but not what we want.776In particular, comparisons will fail::777778sage: pari(n)^-15779Mod(1/Mod(3, 5), Mod(1, 5)*a^10 + Mod(3, 5)*a^5 + Mod(3, 5)*a^4 + Mod(2, 5)*a^3 + Mod(4, 5)*a^2 + Mod(1, 5)*a + Mod(2, 5))780781We need to :meth:`simplify()` the result (which is done in the782:class:`FiniteField_ext_pariElement` constructor::783784sage: n^-157852786787Large exponents are not a problem::788789sage: e = 3^10000790sage: a^e7912*a^9 + a^5 + 4*a^4 + 4*a^3 + a^2 + 3*a792sage: a^(e % (5^10 - 1))7932*a^9 + a^5 + 4*a^4 + 4*a^3 + a^2 + 3*a794"""795right = int(_right)796if right != _right:797raise ValueError798# It is important to set value_from_pari=False, see doctest above!799return FiniteField_ext_pariElement(self.parent(), self.__value**right, value_from_pari=False)800801def __neg__(self):802"""803Negation.804805EXAMPLES::806807sage: k.<a> = GF(3^17, impl='pari_mod')808sage: -a8092*a810"""811return FiniteField_ext_pariElement(self.parent(), -self.__value, value_from_pari=True)812813def __pos__(self):814"""815Unitary positive operator...816817EXAMPLES::818819sage: k.<a> = GF(3^17, impl='pari_mod')820sage: +a821a822"""823return self824825def __abs__(self):826"""827Absolute value, which is not defined.828829EXAMPLES::830831sage: k.<a> = GF(3^17, impl='pari_mod')832sage: abs(a)833Traceback (most recent call last):834...835ArithmeticError: absolute value not defined836"""837raise ArithmeticError, "absolute value not defined"838839def __invert__(self):840"""841EXAMPLES::842843sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari844sage: a = FiniteField_ext_pari(9, 'a').gen()845sage: ~a846a + 2847sage: (a+1)*a8482*a + 1849sage: ~((2*a)/a)8502851"""852853if self.__value == 0:854raise ZeroDivisionError, "Cannot invert 0"855return FiniteField_ext_pariElement(self.parent(), ~self.__value, value_from_pari=True)856857def lift(self):858"""859If this element lies in a prime finite field, return a lift of this860element to an integer.861862EXAMPLES::863864sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari865sage: k = GF(next_prime(10**10))866sage: a = k(17)/k(19)867sage: b = a.lift(); b8687894736858869sage: b.parent()870Integer Ring871"""872return integer_ring.IntegerRing()(self.__value.lift().lift())873874875def __cmp__(self, other):876"""877Compare an element of a finite field with other. If other is not an878element of a finite field, an attempt is made to coerce it so it is879one.880881EXAMPLES::882883sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari884sage: a = FiniteField_ext_pari(3**3, 'a').gen()885sage: a == 1886False887sage: a**0 == 1888True889sage: a == a890True891sage: a < a**2892True893sage: a > a**2894False895"""896return cmp(self.__value, other.__value)897898def log(self, base):899"""900Return `x` such that `b^x = a`, where `x`901is `a` and `b` is the base.902903INPUT:904905- ``b`` -- finite field element that generates the906multiplicative group.907908OUTPUT:909910Integer `x` such that `a^x = b`, if it exists. Raises a911``ValueError`` exception if no such `x` exists.912913EXAMPLES::914915sage: F = GF(17)916sage: F(3^11).log(F(3))91711918sage: F = GF(113)919sage: F(3^19).log(F(3))92019921sage: F = GF(next_prime(10000))922sage: F(23^997).log(F(23))923997924925::926927sage: F = FiniteField(2^10, 'a', impl='pari_mod')928sage: g = F.gen()929sage: b = g; a = g^37930sage: a.log(b)93137932sage: b^37; a933a^8 + a^7 + a^4 + a + 1934a^8 + a^7 + a^4 + a + 1935936AUTHORS:937938- David Joyner and William Stein (2005-11)939"""940from sage.groups.generic import discrete_log941942b = self.parent()(base)943# TODO: This function is TERRIBLE!944return discrete_log(self, b)945946dynamic_FiniteField_ext_pariElement = None947def _late_import():948"""949Used to reset the class of PARI finite field elements in their initialization.950951EXAMPLES::952953sage: from sage.rings.finite_rings.element_ext_pari import FiniteField_ext_pariElement954sage: k.<a> = GF(3^17, impl='pari_mod')955sage: a.__class__ is FiniteField_ext_pariElement # indirect doctest956False957"""958global dynamic_FiniteField_ext_pariElement959dynamic_FiniteField_ext_pariElement = dynamic_class("%s_with_category"%FiniteField_ext_pariElement.__name__, (FiniteField_ext_pariElement, FiniteFields().element_class), doccls=FiniteField_ext_pariElement)960961from sage.structure.sage_object import register_unpickle_override962register_unpickle_override('sage.rings.finite_field_element', 'FiniteField_ext_pariElement', FiniteField_ext_pariElement)963964965