source: sage/rings/finite_field_givaro.pyx @ 6024:aee0bd1defa8

Revision 6024:aee0bd1defa8, 65.5 KB checked in by boothby@…, 6 years ago (diff)

merge

Line 
1r"""
2Finite Non-prime Fields of cardinality up to $2^{16}$
3
4SAGE includes the Givaro finite field library, for highly optimized
5arithmetic in finite fields.
6
7NOTES: The arithmetic is performed by the Givaro C++ library which
8uses Zech logs internally to represent finite field elements. This
9implementation is the default finite extension field implementation in
10SAGE for the cardinality $< 2^{16}$, as it is vastly faster than the
11PARI implementation which uses polynomials to represent finite field
12elements. Some functionality in this class however is implemented
13using the PARI implementation.
14
15EXAMPLES:
16    sage: k = GF(5); type(k)
17    <class 'sage.rings.finite_field.FiniteField_prime_modn'>
18    sage: k = GF(5^2,'c'); type(k)
19    <type 'sage.rings.finite_field_givaro.FiniteField_givaro'>
20    sage: k = GF(2^16,'c'); type(k)
21    <class 'sage.rings.finite_field.FiniteField_ext_pari'>
22
23    sage: n = previous_prime_power(2^16 - 1)
24    sage: while is_prime(n):
25    ...    n = previous_prime_power(n)
26    sage: factor(n)
27    251^2
28    sage: k = GF(n,'c'); type(k)
29    <type 'sage.rings.finite_field_givaro.FiniteField_givaro'>
30
31AUTHORS:
32     -- Martin Albrecht <malb@informatik.uni-bremen.de> (2006-06-05)
33     -- William Stein (2006-12-07): editing, lots of docs, etc.
34     -- Robert Bradshaw (2007-05-23): is_square/sqrt, pow.
35"""
36
37
38#*****************************************************************************
39#
40#   SAGE: System for Algebra and Geometry Experimentation   
41#
42#       Copyright (C) 2006 William Stein <wstein@gmail.com>
43#
44#  Distributed under the terms of the GNU General Public License (GPL)
45#
46#    This code is distributed in the hope that it will be useful,
47#    but WITHOUT ANY WARRANTY; without even the implied warranty of
48#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
49#    General Public License for more details.
50#
51#  The full text of the GPL is available at:
52#
53#                  http://www.gnu.org/licenses/
54#*****************************************************************************
55
56include "../ext/interrupt.pxi"
57
58# this fails with a scoping error:
59#   AttributeError: CVoidType instance has no attribute 'scope'
60#include "../ext/stdsage.pxi"
61
62cdef extern from "stdsage.h":
63    ctypedef void PyObject
64    object PY_NEW(object t)
65    int PY_TYPE_CHECK(object o, object t)
66    void init_csage()
67#init_csage()
68
69from sage.rings.ring cimport FiniteField
70from sage.rings.ring cimport Ring
71from sage.structure.element cimport FiniteFieldElement, Element, RingElement, ModuleElement
72from sage.rings.finite_field_element import FiniteField_ext_pariElement
73from sage.structure.sage_object cimport SageObject
74import operator
75import sage.rings.arith
76import finite_field
77
78import sage.interfaces.gap
79from sage.libs.pari.all import pari
80from sage.libs.pari.gen import gen
81
82from sage.structure.parent  cimport Parent
83from sage.structure.parent_base cimport ParentWithBase
84from sage.structure.parent_gens cimport ParentWithGens
85
86
87
88
89
90
91cdef object is_IntegerMod
92cdef object IntegerModRing_generic
93cdef object Integer
94cdef object Rational
95cdef object is_Polynomial
96cdef object ConwayPolynomials
97cdef object conway_polynomial
98cdef object MPolynomial
99cdef object Polynomial
100cdef object FreeModuleElement
101
102cdef void late_import():
103    """
104    """
105    global is_IntegerMod, \
106           IntegerModRing_generic, \
107           Integer, \
108           Rational, \
109           is_Polynomial, \
110           ConwayPolynomials, \
111           conway_polynomial, \
112           MPolynomial, \
113           Polynomial, \
114           FreeModuleElement
115
116    if is_IntegerMod is not None:
117        return
118
119    import sage.rings.integer_mod
120    is_IntegerMod = sage.rings.integer_mod.is_IntegerMod
121
122    import sage.rings.integer_mod_ring
123    IntegerModRing_generic = sage.rings.integer_mod_ring.IntegerModRing_generic
124
125    import sage.rings.integer
126    Integer = sage.rings.integer.Integer
127
128    import sage.rings.rational
129    Rational = sage.rings.rational.Rational
130
131    import sage.rings.polynomial.polynomial_element
132    is_Polynomial = sage.rings.polynomial.polynomial_element.is_Polynomial
133   
134    import sage.databases.conway
135    ConwayPolynomials = sage.databases.conway.ConwayPolynomials
136   
137    import sage.rings.finite_field
138    conway_polynomial = sage.rings.finite_field.conway_polynomial
139
140    import sage.rings.polynomial.multi_polynomial_element
141    MPolynomial = sage.rings.polynomial.multi_polynomial_element.MPolynomial
142
143    import sage.rings.polynomial.polynomial_element
144    Polynomial = sage.rings.polynomial.polynomial_element.Polynomial
145
146    import sage.modules.free_module_element
147    FreeModuleElement = sage.modules.free_module_element.FreeModuleElement
148
149def get_mpol():
150    return MPolynomial
151
152
153cdef FiniteField_givaro parent_object(Element o):
154    return <FiniteField_givaro>(o._parent)
155
156cdef class FiniteField_givaro(FiniteField):
157    """
158    Fnite Field. These are implemented using Zech logs and the
159    cardinality must be < 2^16. See FiniteField_ext_pari for larger
160    cardinalities.
161    """
162
163    def __init__(FiniteField_givaro self, q, name="a",  modulus=None, repr="poly", cache=False):
164        """
165        Finite Field. These are implemented using Zech logs and the
166        cardinality must be < 2^16. By default conway polynomials are
167        used as minimal polynomial.
168
169        INPUT:
170            q     -- p^n (must be prime power)
171            name  -- variable used for poly_repr (default: 'a')
172            modulus -- you may provide a minimal polynomial to use for
173                     reduction or 'random' to force a random
174                     irreducible polynomial. (default: None, a conway
175                     polynomial is used if found. Otherwise a random
176                     polynomial is used)
177            repr  -- controls the way elements are printed to the user:
178                     (default: 'poly')
179                     'log': repr is element.log_repr()
180                     'int': repr is element.int_repr()
181                     'poly': repr is element.poly_repr()
182            cache -- if True a cache of all elements of this field is
183                     created. Thus, arithmetic does not create new
184                     elements which speeds calculations up. Also, if
185                     many elements are needed during a calculation
186                     this cache reduces the memory requirement as at
187                     most self.order() elements are created. (default: False)
188
189        OUTPUT:
190            Givaro finite field with characteristic p and cardinality p^n.
191
192        EXAMPLES:
193
194            By default conway polynomials are used:
195       
196            sage: k.<a> = GF(2**8)
197            sage: -a ^ k.degree()
198            a^4 + a^3 + a^2 + 1
199            sage: f = k.modulus(); f
200            x^8 + x^4 + x^3 + x^2 + 1
201
202
203            You may enforce a modulus:
204           
205            sage: P.<x> = PolynomialRing(GF(2))
206            sage: f = x^8 + x^4 + x^3 + x + 1 # Rijndael Polynomial
207            sage: k.<a> = GF(2^8, modulus=f)
208            sage: k.modulus()
209            x^8 + x^4 + x^3 + x + 1
210            sage: a^(2^8)
211            a
212
213            You may enforce a random modulus:
214
215            sage: k = GF(3**5, 'a', modulus='random')
216            sage: k.modulus() # random polynomial
217            x^5 + 2*x^4 + 2*x^3 + x^2 + 2
218
219            Three different representations are possible:
220           
221            sage: sage.rings.finite_field_givaro.FiniteField_givaro(9,repr='poly').gen()
222            a
223            sage: sage.rings.finite_field_givaro.FiniteField_givaro(9,repr='int').gen()
224            3
225            sage: sage.rings.finite_field_givaro.FiniteField_givaro(9,repr='log').gen()
226            5
227        """
228
229        # we are calling late_import here because this constructor is
230        # called at least once before any arithmetic is perfored.
231        late_import()
232
233        cdef intvec cPoly
234
235        if repr=='poly':
236            self.repr = 0
237        elif repr=='log':
238            self.repr = 1
239        elif repr=='int':
240            self.repr = 2
241        else:
242            raise ValueError, "Unknown representation %s"%repr
243
244        if q >= 1<<16:
245            raise ArithmeticError, "q must be < 2^16"
246
247        q = Integer(q)
248        if q < 2:
249            raise ArithmeticError, "q  must be a prime power"
250        F = q.factor()
251        if len(F) > 1:
252            raise ArithmeticError, "q must be a prime power"
253        p = F[0][0]
254        k = F[0][1]
255
256        ParentWithGens.__init__(self, finite_field.FiniteField(p), name, normalize=False)
257
258        self._is_conway = False
259        if modulus is None or modulus=="random":
260            if k>1 and ConwayPolynomials().has_polynomial(p, k) and modulus!="random":
261                modulus = conway_polynomial(p, k)
262                self._is_conway = True
263            else:
264                _sig_on
265                self.objectptr = gfq_factorypk(p,k)
266                self._zero_element = make_FiniteField_givaroElement(self,self.objectptr.zero)
267                self._one_element = make_FiniteField_givaroElement(self,self.objectptr.one)
268                _sig_off
269                if cache:
270                    self._array = self.gen_array()
271                return
272           
273        if is_Polynomial(modulus):
274            modulus = modulus.list()
275
276        if PY_TYPE_CHECK(modulus, list) or PY_TYPE_CHECK(modulus, tuple):
277
278            for i from 0 <= i < len(modulus):
279                cPoly.push_back(int( modulus[i] % p ))
280
281            _sig_on
282            self.objectptr = gfq_factorypkp(p, k,cPoly)
283            _sig_off
284            self._zero_element = make_FiniteField_givaroElement(self,self.objectptr.zero)
285            self._one_element = make_FiniteField_givaroElement(self,self.objectptr.one)
286
287            if cache:
288                self._array = self.gen_array()
289            return
290
291        raise TypeError, "Cannot understand modulus"
292
293    cdef gen_array(FiniteField_givaro self):
294        """
295        Generates an array/list/tuple containing all elements of self indexed by their
296        power with respect to the internal generator.
297        """
298        cdef int i
299       
300        array = list()
301        for i from 0 <= i < self.order_c():
302            array.append( make_FiniteField_givaroElement(self,i) )
303        return tuple(array)
304
305    def __dealloc__(FiniteField_givaro self):
306        """
307        Free the memory occupied by this Givaro finite field.
308        """
309        delete(self.objectptr)
310
311    def __repr__(FiniteField_givaro self):
312        if self.degree()>1:
313            return "Finite Field in %s of size %d^%d"%(self.variable_name(),self.characteristic(),self.degree())
314        else:
315            return "Finite Field of size %d"%(self.characteristic())
316
317    def characteristic(FiniteField_givaro self):
318        """
319        Return the characteristic of this field.
320
321        EXAMPLES:
322            sage: p = GF(19^5,'a').characteristic(); p
323            19
324            sage: type(p)
325            <type 'sage.rings.integer.Integer'>
326        """
327        return Integer(self.objectptr.characteristic())
328
329    def order(FiniteField_givaro self):
330        """
331        Return the cardinality of this field.
332
333        OUTPUT:
334            Integer -- the number of elements in self.
335
336        EXAMPLES:
337            sage: n = GF(19^5,'a').order(); n
338            2476099
339            sage: type(n)
340            <type 'sage.rings.integer.Integer'>       
341        """
342        return Integer(self.order_c())
343
344    cdef order_c(FiniteField_givaro self):
345        return self.objectptr.cardinality()
346
347
348    def cardinality(FiniteField_givaro self):
349        """
350        Return the cardinality of this field.
351
352        OUTPUT:
353            Integer -- the cardinality of self.
354
355        NOTE: this is the same as self.order()
356
357        EXAMPLES:
358            sage: GF(3^4,'a').cardinality()
359            81       
360        """
361        return int(self.objectptr.cardinality())
362
363    def __len__(self):
364        """
365        len(k) is returns the cardlinality of k, i.e., the number of elements in k.
366
367        EXAMPLE:
368            sage: k = GF(23**3, 'a')
369            sage: len(k)
370            12167
371            sage: k = GF(2)
372            sage: len(k)
373            2
374        """
375        return self.order_c()
376
377    def degree(FiniteField_givaro self):
378        r"""
379        If \code{self.cardinality() == p^n} this method returns $n$.
380
381        OUTPUT:
382            Integer -- the degree
383
384        EXAMPLES:
385            sage: GF(3^4,'a').degree()
386            4
387        """
388        return Integer(self.objectptr.exponent())
389
390    def is_atomic_repr(FiniteField_givaro self):
391        """
392        Return whether elements of self are printed using an atomic
393        representation.
394
395        EXAMPLES:
396            sage: GF(3^4,'a').is_atomic_repr()
397            False       
398        """
399        if self.repr==0: #modulus
400            return False
401        else:
402            return True
403 
404    def is_prime_field(FiniteField_givaro self):
405        """
406        Return True if self is a prime field, i.e., has degree 1.
407
408        EXAMPLES:
409            sage: GF(3^7, 'a').is_prime_field()
410            False
411            sage: GF(3, 'a').is_prime_field()
412            True
413        """
414        return self.degree()==1
415
416    def is_prime(FiniteField_givaro self):
417        """
418        Return True if self has prime cardinality.
419
420        EXAMPLES:
421            sage: GF(3, 'a').is_prime()
422            True
423        """
424        return self.degree()==1
425
426    def random_element(FiniteField_givaro self):
427        """
428        Return a random element of self.
429
430        EXAMPLES:
431            sage: k = GF(23**3, 'a')
432            sage: e = k.random_element()
433            sage: type(e)
434            <type 'sage.rings.finite_field_givaro.FiniteField_givaroElement'>
435        """
436        cdef int res
437        cdef GivRandom generator
438        res = self.objectptr.random(generator,res)
439        return make_FiniteField_givaroElement(self,res)
440
441    def __call__(FiniteField_givaro self, e):
442        """
443        Coerces several data types to self.
444
445        INPUT:
446            e -- data to coerce
447
448        EXAMPLES:
449
450            FiniteField_givaroElement are accepted where the parent
451            is either self, equals self or is the prime subfield
452       
453            sage: k = GF(2**8, 'a')
454            sage: k.gen() == k(k.gen())
455            True
456
457
458            Floats, ints, longs, Integer are interpreted modulo characteristic
459           
460            sage: k(2)
461            0
462
463            Floats coerce in:
464            sage: k(float(2.0))
465            0
466           
467            Rational are interpreted as
468                             self(numerator)/self(denominator).
469            Both may not be >= self.characteristic().
470
471            sage: k = GF(3**8, 'a')
472            sage: k(1/2) == k(1)/k(2)
473            True
474
475            Free modulo elements over self.prime_subfield() are interpreted 'little endian'
476           
477            sage: k = GF(2**8, 'a')
478            sage: e = k.vector_space().gen(1); e
479            (0, 1, 0, 0, 0, 0, 0, 0)
480            sage: k(e)
481            a
482
483            Strings are evaluated as polynomial representation of elements in self
484
485            sage: k('a^2+1')
486            a^2 + 1
487
488            PARI elements are interpreted as finite field elements; this PARI flexibility
489            is (absurdly!) liberal:
490
491            sage: k(pari('Mod(1,2)'))
492            1
493            sage: k(pari('Mod(2,3)'))
494            0
495            sage: k(pari('Mod(1,3)*a^20'))
496            a^7 + a^5 + a^4 + a^2
497
498            GAP elements need to be finite field elements:
499
500            sage: from sage.rings.finite_field_givaro import FiniteField_givaro
501            sage: x = gap('Z(13)')
502            sage: F = FiniteField_givaro(13)
503            sage: F(x)
504            2
505            sage: F(gap('0*Z(13)'))
506            0
507            sage: F = FiniteField_givaro(13^2)
508            sage: x = gap('Z(13)')
509            sage: F(x)
510            2
511            sage: x = gap('Z(13^2)^3')
512            sage: F(x)
513            12*a + 11
514            sage: F.multiplicative_generator()^3
515            12*a + 11
516
517            sage: k.<a> = GF(29^3)
518            sage: k(48771/1225)
519            28
520
521        """
522
523        cdef int res
524        cdef int g
525        cdef int x
526        cdef int e_int
527
528
529        ########
530
531        if PY_TYPE_CHECK(e, FiniteField_givaroElement):
532            if e.parent() is self:
533                return e
534            if e.parent() == self:
535                return make_FiniteField_givaroElement(self,(<FiniteField_givaroElement>e).element)
536            if e.parent() is self.prime_subfield_C() or e.parent() == self.prime_subfield_C():
537                res = self.int_to_log(int(e))
538
539        elif PY_TYPE_CHECK(e, int) or \
540             PY_TYPE_CHECK(e, Integer) or \
541             PY_TYPE_CHECK(e, long) or is_IntegerMod(e):
542            try:
543                e_int = e
544                if e != e_int:       # overflow in Pyrex is often not detected correctly... but this is bullet proof.
545                                     # sometimes it is detected correctly, so we do have to use exceptions though.
546                                     # todo -- be more eloquent here!!
547                    raise OverflowError   
548                res = self.objectptr.initi(res,e_int)
549            except OverflowError:
550                res = self.objectptr.initi(res,int(e)%int(self.objectptr.characteristic()))
551
552        elif PY_TYPE_CHECK(e, float):
553            res = self.objectptr.initd(res,e)
554           
555        elif PY_TYPE_CHECK(e, str):
556            return self(eval(e.replace("^","**"),{str(self.variable_name()):self.gen()}))
557
558        elif PY_TYPE_CHECK(e, FreeModuleElement):
559            if self.vector_space() != e.parent():
560                raise TypeError, "e.parent must match self.vector_space"
561            ret = self.zero()
562            for i in range(len(e)):
563                ret = ret + self(int(e[i]))*self.gen()**i
564            return ret
565
566        elif PY_TYPE_CHECK(e, MPolynomial) or PY_TYPE_CHECK(e, Polynomial):
567            if e.is_constant():
568                return self(e.constant_coefficient())
569            else:
570                raise TypeError, "no coercion defined"
571
572        elif PY_TYPE_CHECK(e, Rational):
573            num = e.numer()
574            den = e.denom()
575            return self(num)/self(den)
576
577        elif PY_TYPE_CHECK(e, gen):
578            pass # handle this in next if clause
579
580        elif PY_TYPE_CHECK(e,FiniteField_ext_pariElement):
581            # reduce FiniteFieldElements to pari
582            e = e._pari_()
583
584        elif sage.interfaces.gap.is_GapElement(e):
585            return gap_to_givaro_c(e, self)
586
587        else:
588            raise TypeError, "unable to coerce"
589
590        if PY_TYPE_CHECK(e, gen):
591            e = e.lift().lift()
592            try:
593                res = self.int_to_log(e[0])
594            except TypeError:
595                res = self.int_to_log(e)
596               
597            g = self.objectptr.sage_generator()
598            x = self.objectptr.one
599
600            for i from 0 < i <= e.poldegree():
601                x = self.objectptr.mul(x,x,g)
602                res = self.objectptr.axpyin( res, self.int_to_log(e[i]) , x)
603
604        return make_FiniteField_givaroElement(self,res)
605
606    cdef _coerce_c_impl(self, x):
607        """
608        Coercion accepts elements of self.parent(), ints, and prime subfield elements.
609        """
610        cdef int r, cx
611       
612        if PY_TYPE_CHECK(x, int) \
613               or PY_TYPE_CHECK(x, long) or PY_TYPE_CHECK(x, Integer):
614            cx = x % self.characteristic()
615            r = (<FiniteField_givaro>self).objectptr.initi(r, cx%self.objectptr.characteristic())
616            return make_FiniteField_givaroElement(<FiniteField_givaro>self,r)
617       
618        if PY_TYPE_CHECK(x, FiniteFieldElement) or \
619               PY_TYPE_CHECK(x, FiniteField_givaroElement) or is_IntegerMod(x):
620            K = x.parent()
621            if K is <object>self:
622                return x
623            if PY_TYPE_CHECK(K, IntegerModRing_generic) \
624                   and K.characteristic() % self.characteristic() == 0:
625                return self(int(x))
626            if K.characteristic() == self.characteristic():
627                if K.degree() == 1:
628                    return self(int(x))
629                elif self.degree() % K.degree() == 0:
630                    # This is where we *would* do coercion from one nontrivial finite field to another...
631                    raise TypeError, 'no canonical coercion defined'
632        raise TypeError, 'no canonical coercion defined'
633
634
635    def one(FiniteField_givaro self):
636        """
637        Return 1 element in self, which satisfies 1*p=p for every
638        element of self != 0.
639
640        EXAMPLES:
641            sage: k = GF(3^4, 'b'); k
642            Finite Field in b of size 3^4
643            sage: o = k.one(); o
644            1
645            sage: o == 1
646            True
647            sage: o is k.one()
648            True           
649        """
650        return self._one_element
651
652    def zero(FiniteField_givaro self):
653        """
654        Return 0 element in self, which satisfies 0+p=p for every
655        element of self.
656
657        EXAMPLES:
658            sage: k = GF(3^4, 'b'); k
659            Finite Field in b of size 3^4
660            sage: o = k.zero(); o
661            0
662            sage: o == 0
663            True
664            sage: o is k.zero()
665            True       
666        """
667        return self._zero_element
668   
669
670    def gen(FiniteField_givaro self, ignored=None):
671        r"""
672        Return a generator of self. All elements x of self are
673        expressed as $\log_{self.gen()}(p)$ internally. If self is
674        a prime field this method returns 1.
675
676        EXAMPLES:
677            sage: k = GF(3^4, 'b'); k.gen()
678            b       
679        """
680        cdef int r
681        from sage.rings.arith import primitive_root
682       
683        if self.degree() == 1:
684            return self(primitive_root(self.order_c()))
685        else:
686            return make_FiniteField_givaroElement(self,self.objectptr.sage_generator())
687
688    cdef prime_subfield_C(FiniteField_givaro self):
689        if self._prime_subfield is None:
690            self._prime_subfield = finite_field.FiniteField(self.characteristic())
691        return self._prime_subfield
692
693    def prime_subfield(FiniteField_givaro self):
694        r"""
695        Return the prime subfield $\FF_p$ of self if self is $\FF_{p^n}$.
696
697        EXAMPLES:
698            sage: GF(3^4, 'b').prime_subfield()
699            Finite Field of size 3
700
701            sage: S.<b> = GF(5^2); S
702            Finite Field in b of size 5^2
703            sage: S.prime_subfield()
704            Finite Field of size 5
705            sage: type(S.prime_subfield())
706            <class 'sage.rings.finite_field.FiniteField_prime_modn'>           
707        """
708        return self.prime_subfield_C()
709
710
711    def log_to_int(FiniteField_givaro self, int n):
712        r"""
713        Given an integer $n$ this method returns $i$ where $i$
714        satisfies \code{self.gen()^n == i}, if the result is
715        interpreted as an integer.
716
717        INPUT:
718            n -- log representation of a finite field element
719
720        OUTPUT:
721            integer representation of a finite field element.
722
723        EXAMPLE:
724            sage: k = GF(2**8, 'a')
725            sage: k.log_to_int(4)
726            16
727            sage: k.log_to_int(20)
728            180
729        """
730        cdef int ret
731
732        if n<0:
733            raise ArithmeticError, "Cannot serve negative exponent %d"%n
734        elif n>=self.order_c():
735            raise IndexError, "n=%d must be < self.order()"%n
736        _sig_on
737        ret = int(self.objectptr.convert(ret, n))
738        _sig_off
739        return ret
740
741    def int_to_log(FiniteField_givaro self, int n):
742        r"""
743        Given an integer $n$ this method returns $i$ where $i$ satisfies
744        \code{self.gen()^i==(n\%self.characteristic())}.
745
746        INPUT:
747            n -- integer representation of an finite field element
748
749        OUTPUT:
750            log representation of n
751
752        EXAMPLE:
753            sage: k = GF(7**3, 'a')
754            sage: k.int_to_log(4)
755            228
756            sage: k.int_to_log(3)
757            57
758            sage: k.gen()^57
759            3
760        """
761        cdef int r
762        _sig_on
763        ret =  int(self.objectptr.initi(r,n))
764        _sig_off
765        return ret
766
767    def fetch_int(FiniteField_givaro self, int n):
768        r"""
769        Given an integer $n$ return a finite field element in self
770        which equals $n$ under the condition that  self.gen() is set to
771        self.characteristic().
772
773        EXAMPLE:
774            sage: k.<a> = GF(2^8)
775            sage: k.fetch_int(8)
776            a^3
777            sage: e = k.fetch_int(151); e
778            a^7 + a^4 + a^2 + a + 1
779            sage: 2^7 + 2^4 + 2^2 + 2 + 1
780            151
781        """
782        cdef GivaroGfq *k = self.objectptr
783        cdef int ret = k.zero
784        cdef int a = k.sage_generator()
785        cdef int at = k.one
786        cdef unsigned int ch = k.characteristic()
787        cdef int _n, t, i
788
789        if n<0 or n>k.cardinality():
790            raise TypeError, "n must be between 0 and self.order()"
791
792        _n = n
793       
794        for i from 0 <= i < k.exponent():
795            t = k.initi(t, _n%ch)
796            ret = k.axpy(ret, t, at, ret)
797            at = k.mul(at,at,a)
798            _n = _n/ch
799        return make_FiniteField_givaroElement(self, ret)
800
801    def polynomial(self):
802        """
803        Return the defining polynomial of this field as an element of
804        self.polynomial_ring().
805       
806        This is the same as the characteristic polynomial of the
807        generator of self.
808
809        EXAMPLES:
810            sage: k = GF(3^4, 'a')
811            sage: k.polynomial()
812            a^4 + 2*a^3 + 2       
813        """
814        if self._polynomial is None:
815            quo = int(-(self.gen()**(self.degree())))
816            b   = int(self.characteristic())
817
818            ret = []
819            for i in range(self.degree()):
820                ret.append(quo%b)
821                quo = quo/b
822            ret = ret + [1]
823            R = self.polynomial_ring_c(None)
824            self._polynomial = R(ret)
825        return self._polynomial
826
827    def modulus(self):
828        r"""
829        Return the minimal polynomial of the generator of self in
830        \code{self.polynomial_ring('x')}.
831
832        EXAMPLES:
833            sage: k = GF(3^5, 'a')
834            sage: k.modulus()
835            x^5 + 2*x + 1
836
837            sage: k.polynomial()
838            a^5 + 2*a + 1       
839        """
840        return self.polynomial_ring_c("x")(self.polynomial().list())
841
842    def _pari_modulus(self):
843        """
844        EXAMPLES:
845            sage: GF(3^4,'a')._pari_modulus()
846            Mod(1, 3)*a^4 + Mod(2, 3)*a^3 + Mod(2, 3)       
847        """
848        f = pari(str(self.modulus()))
849        return f.subst('x', 'a') * pari("Mod(1,%s)"%self.characteristic())
850
851    cdef polynomial_ring_c(self, variable_name):
852        if self._polynomial_ring is None or variable_name is not None:
853            from sage.rings.polynomial.polynomial_ring import PolynomialRing
854            if variable_name is None:
855                # todo: is this cache necessary?
856                self._polynomial_ring = PolynomialRing(self.prime_subfield_C(),self.variable_name())
857                return self._polynomial_ring
858            else:
859                return PolynomialRing(self.prime_subfield_C(), variable_name)
860        else:
861            return self._polynomial_ring
862
863    def polynomial_ring(self):
864        """
865        Return the polynomial ring over the prime subfield in the
866        same variable as this finite field.
867
868        EXAMPLES:
869            sage: GF(3^4,'z').polynomial_ring()
870            Univariate Polynomial Ring in z over Finite Field of size 3
871        """
872        return self.polynomial_ring_c(None)
873
874    def _finite_field_ext_pari_(self):  # todo -- cache
875        """
876        Return a FiniteField_ext_pari isomorphic to self with the same
877        defining polynomial.
878
879        EXAMPLES:
880            sage: GF(3^4,'z')._finite_field_ext_pari_()
881            Finite Field in z of size 3^4
882        """
883        f = self.polynomial()
884        return finite_field.FiniteField_ext_pari(self.order_c(),
885                                   self.variable_name(), f)
886       
887    def _finite_field_ext_pari_modulus_as_str(self):  # todo -- cache
888        return self._finite_field_ext_pari_().modulus()._pari_init_()
889
890    def vector_space(FiniteField_givaroElement self):
891         """
892         Returns self interpreted as a VectorSpace over
893         self.prime_subfield()
894         
895         EXAMPLE:
896             sage: k = GF(3**5, 'a')
897             sage: k.vector_space()
898             Vector space of dimension 5 over Finite Field of size 3
899
900         """
901         import sage.modules.all
902         V = sage.modules.all.VectorSpace(self.prime_subfield(),self.degree())
903         return V
904
905    def __iter__(FiniteField_givaro self):
906        """
907        Finite fields may be iterated over:
908
909        EXAMPLE:
910            sage: list(GF(2**2, 'a'))
911            [0, a, a + 1, 1]
912        """
913        return FiniteField_givaro_iterator(self)
914
915    def __richcmp__(left, right, int op):
916        return (<Parent>left)._richcmp(right, op)
917   
918    cdef int _cmp_c_impl(left, Parent right) except -2:
919        """
920        Finite Fields are considered to be equal if
921         * their implementation is the same (Givaro)
922         * their characteristics match
923         * their degrees match
924         * their moduli match if degree > 1
925
926        This will probably change in the future so that different
927        implementations are equal.
928        """
929        if not isinstance(right, FiniteField_givaro):
930            return cmp(type(left), type(right))
931        c = cmp(left.characteristic(), right.characteristic())
932        if c: return c
933        c = cmp(left.degree(), right.degree())
934        if c: return c
935        # TODO comparing the polynomials themselves would recursively call
936        # this cmp...  Also, as mentioned above, we will get rid of this.
937        if left.degree() > 1:
938            c = cmp(str(left.polynomial()), str(right.polynomial()))
939            if c: return c
940        return 0
941
942    def __hash__(FiniteField_givaro self):
943        """
944        The hash of a Givaro finite field is a hash over it's
945        characterstic polynomial and the string 'givaro'
946
947        EXAMPLES:
948            sage: hash(GF(3^4, 'a'))
949            695660592                 # 32-bit
950            -4281682415996964816      # 64-bit
951        """
952        if self._hash is None:
953            pass
954        if self.degree()>1:
955            self._hash = hash((self.characteristic(),self.polynomial(),self.variable_name(),"givaro"))
956        else:
957            self._hash = hash((self.characteristic(),self.variable_name(),"givaro"))
958        return self._hash
959
960    def _element_repr(FiniteField_givaro self, FiniteField_givaroElement e):
961        """
962        Wrapper for log, int, and poly representations.
963
964        EXAMPLES:
965            sage: k.<a> = GF(3^4); k
966            Finite Field in a of size 3^4
967            sage: k._element_repr(a^20)
968            '2*a^3 + 2*a^2 + 2'
969           
970            sage: k = sage.rings.finite_field_givaro.FiniteField_givaro(3^4,'a', repr='int')
971            sage: a = k.gen()
972            sage: k._element_repr(a^20)
973            '74'
974           
975            sage: k = sage.rings.finite_field_givaro.FiniteField_givaro(3^4,'a', repr='log')
976            sage: a = k.gen()
977            sage: k._element_repr(a^20)
978            '20'
979        """
980        if self.repr==0:
981            return self._element_poly_repr(e)
982        elif self.repr==1:
983            return self._element_log_repr(e)
984        else:
985            return self._element_int_repr(e)
986
987    def _element_log_repr(FiniteField_givaro self, FiniteField_givaroElement e):
988        r"""
989        Return str(i) where \code{base.gen()^i==self}.
990
991        TODO -- this isn't what it does -- see below.
992
993        EXAMPLES:
994            sage: k.<a> = GF(3^4); k
995            Finite Field in a of size 3^4
996            sage: k._element_log_repr(a^20)
997            '20'
998            sage: k._element_log_repr(a)    # TODO -- why 41 ?? why not 1?
999            '41'
1000        """
1001        return str(int(e.element))
1002
1003    def _element_int_repr(FiniteField_givaro self, FiniteField_givaroElement e):
1004        """
1005        Return integer representation of e.
1006       
1007        Elements of this field are represented as ints in as follows:
1008        for $e \in \FF_p[x]$ with $e = a_0 + a_1x + a_2x^2 + \cdots $, $e$ is
1009        represented as: $n= a_0 + a_1  p + a_2  p^2 + \cdots$.
1010
1011        EXAMPLES:
1012            sage: k.<a> = GF(3^4); k
1013            Finite Field in a of size 3^4
1014            sage: k._element_int_repr(a^20)
1015            '74'       
1016        """
1017        return str(int(e))
1018
1019    def _element_poly_repr(FiniteField_givaro self, FiniteField_givaroElement e, varname = None):
1020        """
1021        Return a polynomial expression in base.gen() of self.
1022
1023        EXAMPLES:
1024            sage: k.<a> = GF(3^4); k
1025            Finite Field in a of size 3^4
1026            sage: k._element_poly_repr(a^20)
1027            '2*a^3 + 2*a^2 + 2'       
1028        """
1029        if varname is None:
1030            variable = self.variable_name()
1031        else:
1032            variable = varname
1033       
1034        quo = self.log_to_int(e.element)
1035        b   = int(self.characteristic())
1036
1037        ret = ""
1038        for i in range(self.degree()):
1039            coeff = quo%b
1040            if coeff != 0:
1041                if i>0:
1042                    if coeff==1:
1043                        coeff=""
1044                    else:
1045                        coeff=str(coeff)+"*"
1046                    if i>1:
1047                        ret = coeff + variable + "^" + str(i) + " + " + ret
1048                    else:
1049                        ret = coeff + variable + " + " + ret
1050                else:
1051                    ret = str(coeff) + " + " + ret
1052            quo = quo/b
1053        if ret == '':
1054            return "0"
1055        return ret[:-3]
1056
1057    def a_times_b_plus_c(FiniteField_givaro self,FiniteField_givaroElement a, FiniteField_givaroElement b, FiniteField_givaroElement c):
1058        """
1059        Return r = a*b + c. This is faster than multiplying a and b
1060        first and adding c to the result.
1061
1062        INPUT:
1063            a -- FiniteField_givaroElement
1064            b -- FiniteField_givaroElement
1065            c -- FiniteField_givaroElement
1066
1067        EXAMPLE:
1068            sage: k.<a> = GF(2**8)
1069            sage: k.a_times_b_plus_c(a,a,k(1))
1070            a^2 + 1
1071        """
1072        cdef int r
1073
1074        r = self.objectptr.axpy(r, a.element, b.element, c.element)
1075        return make_FiniteField_givaroElement(self,r)
1076
1077    def a_times_b_minus_c(FiniteField_givaro self,FiniteField_givaroElement a, FiniteField_givaroElement b, FiniteField_givaroElement c):
1078        """
1079        Return r = a*b - c.
1080
1081        INPUT:
1082            a -- FiniteField_givaroElement
1083            b -- FiniteField_givaroElement
1084            c -- FiniteField_givaroElement
1085
1086        EXAMPLE:
1087            sage: k.<a> = GF(3**3)
1088            sage: k.a_times_b_minus_c(a,a,k(1))
1089            a^2 + 2
1090        """
1091        cdef int r
1092
1093        r = self.objectptr.axmy(r, a.element, b.element, c.element, )
1094        return make_FiniteField_givaroElement(self,r)
1095
1096    def c_minus_a_times_b(FiniteField_givaro self,FiniteField_givaroElement a,
1097                          FiniteField_givaroElement b, FiniteField_givaroElement c):
1098        """
1099        Return r = c - a*b.
1100
1101        INPUT:
1102            a -- FiniteField_givaroElement
1103            b -- FiniteField_givaroElement
1104            c -- FiniteField_givaroElement
1105
1106        EXAMPLE:
1107            sage: k.<a> = GF(3**3)
1108            sage: k.c_minus_a_times_b(a,a,k(1))
1109            2*a^2 + 1
1110        """
1111        cdef int r
1112
1113        r = self.objectptr.amxy(r , a.element, b.element, c.element, )
1114        return make_FiniteField_givaroElement(self,r)
1115
1116    def __reduce__(FiniteField_givaro self):
1117        """
1118        Pickle self:
1119
1120        EXAMPLE:
1121            sage: k.<a> = GF(2**8)
1122            sage: loads(dumps(k)) == k
1123            True
1124        """
1125        if self._array is None:
1126            cache = 0
1127        else:
1128            cache = 1
1129       
1130        return sage.rings.finite_field_givaro.unpickle_FiniteField_givaro, \
1131               (self.order_c(),(self.variable_name(),),
1132                map(int,list(self.modulus())),int(self.repr),int(self._array is not None))
1133
1134def unpickle_FiniteField_givaro(order,variable_name,modulus,rep,cache):
1135    from sage.rings.arith import is_prime
1136
1137    if rep == 0:
1138        rep = 'poly'
1139    elif rep == 1:
1140        rep = 'log'
1141    elif rep == 2:
1142        rep = 'int'
1143   
1144    if not is_prime(order):
1145        return FiniteField_givaro(order,variable_name,modulus,rep,cache=cache)
1146    else:
1147        return FiniteField_givaro(order,cache=cache)
1148
1149cdef class FiniteField_givaro_iterator:
1150    """
1151    Iterator over FiniteField_givaro elements of degree 1. We iterate
1152    over fields of higher degree using the VectorSpace iterator.
1153
1154    EXAMPLES:
1155        sage: for x in GF(2^2,'a'): print x
1156        0
1157        a
1158        a + 1
1159        1
1160    """
1161   
1162    def __init__(self, FiniteField_givaro parent):
1163        self._parent = parent
1164        self.iterator = -1
1165
1166    def __next__(self):
1167        """
1168        """
1169
1170        self.iterator=self.iterator+1
1171       
1172        if self.iterator==self._parent.order_c():
1173            self.iterator = -1
1174            raise StopIteration
1175       
1176        return make_FiniteField_givaroElement(self._parent,self.iterator)
1177
1178    def __repr__(self):
1179        return "Iterator over %s"%self._parent
1180
1181cdef FiniteField_givaro_copy(FiniteField_givaro orig):
1182    cdef FiniteField_givaro copy
1183    copy = FiniteField_givaro(orig.characteristic()**orig.degree())
1184    delete(copy.objectptr)
1185    copy.objectptr = gfq_factorycopy(gfq_deref(orig.objectptr))
1186    copy._zero_element = make_FiniteField_givaroElement(copy,copy.objectptr.zero)
1187    copy._one_element = make_FiniteField_givaroElement(copy,copy.objectptr.one)
1188
1189    return copy
1190
1191cdef class FiniteField_givaroElement(FiniteFieldElement):
1192    """
1193    An element of a (Givaro) finite field.
1194    """
1195   
1196    def __init__(FiniteField_givaroElement self, parent ):
1197        """
1198        Initializes an element in parent. It's much better to use
1199        parent(<value>) or any specialized method of parent
1200        (one,zero,gen) instead.
1201
1202        Alternatively you may provide a value which is directly
1203        assigned to this element. So the value must represent the
1204        log_g of the value you wish to assign.
1205
1206        INPUT:
1207            parent -- base field
1208
1209        OUTPUT:
1210            finite field element.
1211        """
1212        self._parent = <ParentWithBase> parent  # explicit case required for C++
1213        self.element = 0
1214       
1215    cdef FiniteField_givaroElement _new_c(self, int value):
1216        return make_FiniteField_givaroElement(parent_object(self), value)
1217
1218    def __dealloc__(FiniteField_givaroElement self):
1219        pass
1220
1221    def __repr__(FiniteField_givaroElement self):
1222        return (<FiniteField_givaro>self._parent)._element_repr(self)
1223
1224    def parent(self):
1225        """
1226        Return parent finite field.
1227
1228        EXAMPLES:
1229            sage: k.<a> = GF(3^4); k
1230            Finite Field in a of size 3^4
1231            sage: (a*a).parent()
1232            Finite Field in a of size 3^4       
1233        """
1234        return (<FiniteField_givaro>self._parent)
1235
1236    def __nonzero__(FiniteField_givaroElement self):
1237        r"""
1238        Return True if \code{self != k(0)}.
1239
1240        EXAMPLES:
1241            sage: k.<a> = GF(3^4); k
1242            Finite Field in a of size 3^4
1243            sage: a.is_zero()
1244            False
1245            sage: k(0).is_zero()
1246            True       
1247        """
1248        return not (<FiniteField_givaro>self._parent).objectptr.isZero(self.element)
1249       
1250    def is_one(FiniteField_givaroElement self):
1251        r"""
1252        Return True if \code{self == k(1)}.
1253
1254        EXAMPLES:
1255            sage: k.<a> = GF(3^4); k
1256            Finite Field in a of size 3^4
1257            sage: a.is_one()
1258            False
1259            sage: k(1).is_one()
1260            True       
1261        """
1262        return (<FiniteField_givaro>self._parent).objectptr.isOne(self.element)
1263
1264    def is_unit(FiniteField_givaroElement self):
1265        """
1266        Return True if self is nonzero, so it is a unit as an element of the
1267        finite field.
1268
1269        EXAMPLES:
1270            sage: k.<a> = GF(3^4); k
1271            Finite Field in a of size 3^4
1272            sage: a.is_unit()
1273            True
1274            sage: k(0).is_unit()
1275            False       
1276        """
1277        return not (<FiniteField_givaro>self._parent).objectptr.isZero(self.element)
1278        # **WARNING** Givaro seems to define unit to mean in the prime field,
1279        # which is totally wrong!  It's a confusion with the underlying polynomial
1280        # representation maybe??  That's why the following is commented out.
1281        # return (<FiniteField_givaro>self._parent).objectptr.isunit(self.element)
1282
1283
1284    def is_square(FiniteField_givaroElement self):
1285        """
1286        Return True if self is a square in self.parent()
1287
1288        EXAMPLES:
1289            sage: k.<a> = GF(9); k
1290            Finite Field in a of size 3^2
1291            sage: a.is_square()
1292            False
1293            sage: v = set([x^2 for x in k])
1294            sage: [x.is_square() for x in v]
1295            [True, True, True, True, True]
1296            sage: [x.is_square() for x in k if not x in v]
1297            [False, False, False, False]       
1298           
1299        ALGORITHM:
1300            Elements are stored as powers of generators, so we simply check
1301            to see if it is an even power of a generator.
1302           
1303        TESTS:
1304            sage: K = GF(27, 'a')
1305            sage: set([a*a for a in K]) == set([a for a in K if a.is_square()])
1306            True
1307            sage: K = GF(25, 'a')
1308            sage: set([a*a for a in K]) == set([a for a in K if a.is_square()])
1309            True
1310            sage: K = GF(16, 'a')
1311            sage: set([a*a for a in K]) == set([a for a in K if a.is_square()])
1312            True
1313        """
1314        cdef FiniteField_givaro field = <FiniteField_givaro>self._parent
1315        if field.objectptr.characteristic() == 2:
1316            return True
1317        elif self.element == field.objectptr.one:
1318            return True
1319        else:
1320            return self.element % 2 == 0
1321
1322    def sqrt(FiniteField_givaroElement self, all=False, extend=False):
1323        """
1324        Return a square root of this finite field element in its
1325        parent, if there is one.  Otherwise, raise a ValueError.
1326
1327        EXAMPLES:
1328            sage: k.<a> = GF(7^2)
1329            sage: k(2).sqrt()
1330            3
1331            sage: k(3).sqrt()
1332            2*a + 6
1333            sage: k(3).sqrt()**2
1334            3
1335            sage: k(4).sqrt()
1336            2
1337            sage: k.<a> = GF(7^3)
1338            sage: k(3).sqrt()
1339            Traceback (most recent call last):
1340            ...
1341            ValueError: must be a perfect square.
1342
1343        ALGORITHM:
1344            Self is stored as $a^k$ for some generator $a$.
1345            Return $a^(k/2)$ for even $k$.
1346           
1347        TESTS:
1348            sage: K = GF(49, 'a')
1349            sage: all([a.sqrt()*a.sqrt() == a for a in K if a.is_square()])
1350            True
1351            sage: K = GF(27, 'a')
1352            sage: all([a.sqrt()*a.sqrt() == a for a in K if a.is_square()])
1353            True
1354            sage: K = GF(8, 'a')
1355            sage: all([a.sqrt()*a.sqrt() == a for a in K if a.is_square()])
1356            True
1357        """
1358        if all:
1359            a = self.sqrt()
1360            return [a, -a] if -a != a else [a]
1361        cdef FiniteField_givaro field = <FiniteField_givaro>self._parent
1362        if self.element == field.objectptr.one:
1363            return make_FiniteField_givaroElement(field, field.objectptr.one)
1364        elif self.element % 2 == 0:
1365            return make_FiniteField_givaroElement(field, self.element/2)
1366        elif field.objectptr.characteristic() == 2:
1367            return make_FiniteField_givaroElement(field, (field.objectptr.cardinality() - 1 + self.element)/2)
1368        elif extend:
1369            raise NotImplementedError # TODO: fix this once we have nested embeddings of finite fields
1370        else:
1371            raise ValueError, "must be a perfect square."
1372       
1373    cdef ModuleElement _add_c_impl(self, ModuleElement right):
1374        """
1375        Add two elements.
1376
1377        EXAMPLE:
1378            sage: k.<b> = GF(9**2)
1379            sage: b^10 + 2*b
1380            2*b^3 + 2*b^2 + 2*b + 1
1381        """
1382        cdef int r
1383        r = parent_object(self).objectptr.add(r, self.element ,
1384                                              (<FiniteField_givaroElement>right).element )
1385        return make_FiniteField_givaroElement(parent_object(self),r)
1386
1387    cdef RingElement _mul_c_impl(self, RingElement right):
1388        """
1389        Multiply two elements:
1390
1391        EXAMPLE:
1392            sage: k.<c> = GF(7**4)
1393            sage: 3*c
1394            3*c
1395            sage: c*c
1396            c^2
1397        """
1398        cdef int r
1399        r = parent_object(self).objectptr.mul(r, self.element,
1400                                              (<FiniteField_givaroElement>right).element)
1401        return make_FiniteField_givaroElement(parent_object(self),r)
1402
1403    cdef RingElement _div_c_impl(self, RingElement right):
1404        """
1405        Divide two elements
1406
1407        EXAMPLE:
1408            sage: k.<g> = GF(2**8)
1409            sage: g/g
1410            1
1411
1412            sage: k(1) / k(0)
1413            Traceback (most recent call last):
1414            ...
1415            ZeroDivisionError: division by zero in finite field.
1416        """
1417        cdef int r
1418        if (<FiniteField_givaroElement>right).element == 0:
1419            raise ZeroDivisionError, 'division by zero in finite field.'
1420        r = parent_object(self).objectptr.div(r, self.element,
1421                                              (<FiniteField_givaroElement>right).element)
1422        return make_FiniteField_givaroElement(parent_object(self),r)
1423
1424    cdef ModuleElement _sub_c_impl(self, ModuleElement right):
1425        """
1426        Subtract two elements
1427
1428        EXAMPLE:
1429            sage: k.<a> = GF(3**4)
1430            sage: k(3) - k(1)
1431            2
1432            sage: 2*a - a^2
1433            2*a^2 + 2*a
1434        """
1435        cdef int r
1436        r = parent_object(self).objectptr.sub(r, self.element,
1437                                              (<FiniteField_givaroElement>right).element)
1438        return make_FiniteField_givaroElement(parent_object(self),r)
1439
1440    def __neg__(FiniteField_givaroElement self):
1441        """
1442        Negative of an element.
1443
1444        EXAMPLES:
1445            sage: k.<a> = GF(9); k
1446            Finite Field in a of size 3^2
1447            sage: -a
1448            2*a       
1449        """
1450        cdef int r
1451
1452        r = (<FiniteField_givaro>self._parent).objectptr.neg(r, self.element)
1453        return make_FiniteField_givaroElement((<FiniteField_givaro>self._parent),r)
1454
1455    def __invert__(FiniteField_givaroElement self):
1456        """
1457        Return the multiplicative inverse of an element.
1458
1459        EXAMPLES:
1460            sage: k.<a> = GF(9); k
1461            Finite Field in a of size 3^2
1462            sage: ~a
1463            a + 2
1464            sage: ~a*a
1465            1       
1466        """
1467        cdef int r
1468
1469        (<FiniteField_givaro>self._parent).objectptr.inv(r, self.element)
1470        return make_FiniteField_givaroElement((<FiniteField_givaro>self._parent),r)
1471       
1472    def __pow__(FiniteField_givaroElement self, exp, other):
1473        """
1474        EXAMPLE:
1475            sage: K.<a> = GF(3^3, 'a')
1476            sage: a^3 == a*a*a
1477            True
1478            sage: b = a+1
1479            sage: b^5 == b^2 * b^3
1480            True
1481            sage: b^(-1) == 1/b
1482            True
1483            sage: b = K(-1)
1484            sage: b^2 == 1
1485            True
1486           
1487        ALGORITHM:
1488            Givaro objects are stored as integers $i$ such that $self=a^i$, where
1489            $a$ is a generator of $K$ (though necissarily the one returned by K.gens()).
1490            Now it is trivial to compute $(a^i)^exp = a^(i*exp)$, and reducing the exponent
1491            mod the multiplicative order of $K$.
1492           
1493        AUTHOR:
1494            Robert Bradshaw
1495        """
1496        _exp = int(exp)
1497        if _exp != exp:
1498            raise ValueError, "exponent must be an integer"
1499        exp = _exp
1500       
1501        cdef int r
1502        cdef int order
1503        cdef FiniteField_givaro field
1504        field = <FiniteField_givaro>self._parent
1505
1506        if (field.objectptr).isOne(self.element):
1507            return self
1508
1509        elif exp == 0:
1510            if (field.objectptr).isZero(self.element):
1511                raise ArithmeticError, "0^0 is undefined."
1512            return make_FiniteField_givaroElement(field, field.objectptr.one)
1513
1514        elif (field.objectptr).isZero(self.element):
1515            return make_FiniteField_givaroElement(field, field.objectptr.zero)
1516       
1517        order = (field.order_c()-1)
1518        exp = exp % order
1519       
1520        r = exp
1521        if r == 0:
1522            return make_FiniteField_givaroElement(field, field.objectptr.one)
1523           
1524        r = (r * self.element) % order
1525        if r < 0:
1526            r = r + order
1527        if r == 0:
1528            return make_FiniteField_givaroElement(field, field.objectptr.one)
1529           
1530        return make_FiniteField_givaroElement(field, r)
1531
1532
1533    def __richcmp__(left, right, int op):
1534        return (<Element>left)._richcmp(right, op)
1535    cdef int _cmp_c_impl(left, Element right) except -2:
1536        """
1537        Comparison of finite field elements is performed by comparing
1538        their underlying int representation.
1539
1540        EXAMPLES:
1541            sage: k.<a> = GF(9); k
1542            Finite Field in a of size 3^2
1543            sage: a < a^2
1544            True
1545            sage: a^2 < a
1546            False       
1547        """
1548        cdef FiniteField_givaro F
1549        F = left._parent
1550       
1551        return cmp(F.log_to_int(left.element), F.log_to_int((<FiniteField_givaroElement>right).element) )
1552
1553    def __int__(FiniteField_givaroElement self):
1554        """
1555        Return the int representation of self.  When self is in the
1556        prime subfield, the integer returned is equal to self and not
1557        to \code{log_repr}.
1558
1559        Elements of this field are represented as ints in as follows:
1560        for $e \in \FF_p[x]$ with $e = a_0 + a_1x + a_2x^2 + \cdots $, $e$ is
1561        represented as: $n= a_0 + a_1  p + a_2  p^2 + \cdots$.
1562
1563        EXAMPLES:
1564            sage: k.<b> = GF(5^2); k
1565            Finite Field in b of size 5^2
1566            sage: int(k(4))
1567            4
1568            sage: int(b)
1569            5
1570            sage: type(int(b))
1571            <type 'int'>
1572        """
1573        return (<FiniteField_givaro>self._parent).log_to_int(self.element)
1574
1575   
1576    def log_to_int(FiniteField_givaroElement self):
1577        r"""
1578        Returns the int representation of self, as a SAGE integer.   Use
1579        int(self) to directly get a Python int.
1580
1581        Elements of this field are represented as ints in as follows:
1582        for $e \in \FF_p[x]$ with $e = a_0 + a_1x + a_2x^2 + \cdots $, $e$ is
1583        represented as: $n= a_0 + a_1  p + a_2  p^2 + \cdots$.
1584
1585        EXAMPLES:
1586            sage: k.<b> = GF(5^2); k
1587            Finite Field in b of size 5^2
1588            sage: k(4).log_to_int()
1589            4
1590            sage: b.log_to_int()
1591            5
1592            sage: type(b.log_to_int())
1593            <type 'sage.rings.integer.Integer'>       
1594        """
1595        return Integer((<FiniteField_givaro>self._parent).log_to_int(self.element))
1596
1597    def log(FiniteField_givaroElement self, base):
1598        """
1599        Return the log to the base b of self, i.e., an integer n
1600        such that b^n = self.
1601
1602        WARNING:  TODO -- This is currently implemented by solving the discrete
1603        log problem -- which shouldn't be needed because of how finit field
1604        elements are represented.
1605
1606        EXAMPLES:
1607            sage: k.<b> = GF(5^2); k
1608            Finite Field in b of size 5^2
1609            sage: a = b^7
1610            sage: a.log(b)
1611            7       
1612        """
1613        q = (<FiniteField_givaro> self.parent()).order_c() - 1
1614        b = self.parent()(base)
1615        return sage.rings.arith.discrete_log_generic(self, b, q)
1616
1617    def int_repr(FiniteField_givaroElement self):
1618        r"""
1619        Return the sring representation of self as an int (as returned
1620        by \code{log_to_int}).
1621
1622        EXAMPLES:
1623            sage: k.<b> = GF(5^2); k
1624            Finite Field in b of size 5^2
1625            sage: (b+1).int_repr()
1626            '6'       
1627        """
1628        return (<FiniteField_givaro>self._parent)._element_int_repr(self)
1629   
1630    def log_repr(FiniteField_givaroElement self):
1631        r"""
1632        Return the log representation of self as a string.  See the
1633        documentation of the \code{_element_log_repr} function of the
1634        parent field.
1635
1636        EXAMPLES:
1637            sage: k.<b> = GF(5^2); k
1638            Finite Field in b of size 5^2
1639            sage: (b+2).log_repr()
1640            '3'
1641        """
1642        return (<FiniteField_givaro>self._parent)._element_log_repr(self)
1643   
1644    def poly_repr(FiniteField_givaroElement self):
1645        r"""
1646        Return representation of this finite field element as a polynomial
1647        in the generator.
1648
1649        EXAMPLES:
1650            sage: k.<b> = GF(5^2); k
1651            Finite Field in b of size 5^2
1652            sage: (b+2).poly_repr()
1653            'b + 2'
1654        """
1655        return (<FiniteField_givaro>self._parent)._element_poly_repr(self)
1656
1657    def polynomial(FiniteField_givaroElement self, name=None):
1658        """
1659        Return self viewed as a polynomial over self.parent().prime_subfield().
1660
1661        EXAMPLES:
1662            sage: k.<b> = GF(5^2); k
1663            Finite Field in b of size 5^2
1664            sage: f = (b^2+1).polynomial(); f
1665            b + 4
1666            sage: type(f)
1667            <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_dense_mod_p'>
1668            sage: parent(f)
1669            Univariate Polynomial Ring in b over Finite Field of size 5       
1670        """
1671        cdef FiniteField_givaro F
1672        F = self._parent
1673        quo = F.log_to_int(self.element)
1674        b   = int(F.characteristic())
1675        ret = []
1676        for i in range(F.degree()):
1677            coeff = quo%b
1678            ret.append(coeff)
1679            quo = quo/b
1680        if not name is None and F.variable_name() != name:
1681            from sage.rings.polynomial.polynomial_ring import PolynomialRing
1682            return PolynomialRing(F.prime_subfield_C(), name)(ret)
1683        else:
1684            return F.polynomial_ring()(ret)
1685
1686    def _latex_(FiniteField_givaroElement self):
1687        r"""
1688        Return the latex representation of self, which is just the
1689        latex representation of the polynomial representation of self.
1690
1691        EXAMPLES:
1692            sage: k.<b> = GF(5^2); k
1693            Finite Field in b of size 5^2
1694            sage: b._latex_()
1695            'b'
1696            sage: (b^2+1)._latex_()
1697            'b + 4'
1698        """
1699        if (<FiniteField_givaro>self._parent).degree()>1:
1700            return self.polynomial()._latex_()
1701        else:
1702            return str(self)
1703
1704    def _finite_field_ext_pari_element(FiniteField_givaroElement self, k=None):
1705        """
1706        Return an element of k supposed to match this element.  No
1707        checks if k equals self.parent() are performed.
1708
1709        INPUT:
1710            k -- (optional) FiniteField_ext_pari
1711
1712        OUTPUT:
1713            k.gen()^(self.log_repr())
1714
1715        EXAMPLES:
1716            sage: S.<b> = GF(5^2); S
1717            Finite Field in b of size 5^2
1718            sage: b.charpoly('x')
1719            x^2 + 4*x + 2
1720            sage: P = S._finite_field_ext_pari_(); type(P)
1721            <class 'sage.rings.finite_field.FiniteField_ext_pari'>
1722            sage: c = b._finite_field_ext_pari_element(P); c
1723            b
1724            sage: type(c)
1725            <class 'sage.rings.finite_field_element.FiniteField_ext_pariElement'>           
1726            sage: c.charpoly('x')
1727            x^2 + 4*x + 2
1728
1729        The PARI field is automatically determined if it is not given:
1730            sage: d = b._finite_field_ext_pari_element(); d
1731            b
1732            sage: type(d)
1733            <class 'sage.rings.finite_field_element.FiniteField_ext_pariElement'>           
1734        """
1735        if k is None:
1736            k = (<FiniteField_givaro>self._parent)._finite_field_ext_pari_()
1737        elif not isinstance(k, finite_field.FiniteField_ext_pari):
1738            raise TypeError, "k must be a pari finite field."
1739       
1740        variable = k.gen()._pari_()
1741
1742        quo = int(self)
1743        b   = int((<FiniteField_givaro>self._parent).characteristic())
1744
1745        ret = k._pari_one() - k._pari_one()    # TODO -- weird
1746        i = 0
1747        while quo!=0:
1748            coeff = quo%b
1749            if coeff != 0:
1750                ret = coeff * variable ** i + ret
1751            quo = quo/b
1752            i = i+1
1753        return k(ret)
1754
1755    def _pari_init_(FiniteField_givaroElement self, var=None):
1756        """
1757        Return string that when evealuated in PARI defines this element.
1758
1759        EXAMPLES:
1760            sage: S.<b> = GF(5^2); S
1761            Finite Field in b of size 5^2
1762            sage: b._pari_init_()
1763            'Mod(b, Mod(1, 5)*b^2 + Mod(4, 5)*b + Mod(2, 5))'
1764            sage: (2*b+3)._pari_init_()
1765            'Mod(2*b + 3, Mod(1, 5)*b^2 + Mod(4, 5)*b + Mod(2, 5))'       
1766        """
1767        g = (parent_object(self))._finite_field_ext_pari_modulus_as_str()
1768        f = self.poly_repr()
1769        s = 'Mod(%s, %s)'%(f, g)
1770        if var is None:
1771            return s
1772        return s.replace(self.parent().variable_name(), var)
1773
1774    def _pari_(FiniteField_givaroElement self, var=None):
1775        return pari(self._pari_init_(var))
1776
1777       
1778##         variable = k.gen()._pari_()
1779##         quo = int(self)
1780##         b   = (parent_object(self)).characteristic()
1781##         ret = k._pari_one() - k._pari_one() # there is no pari_zero
1782##         i = 0
1783##         while quo!=0:
1784##             coeff = quo%b
1785##             if coeff != 0:
1786##                 ret = coeff * variable ** i + ret
1787##             quo = quo/b
1788##             i = i+1
1789##         return ret
1790
1791    def _magma_init_(self):
1792        """
1793        Return a string representation of self that MAGMA can
1794        understand.
1795
1796        """
1797        km = self.parent()._magma_()
1798        vn = km.gen(1).name()
1799        return self.parent()._element_poly_repr(self,vn)
1800
1801    def multiplicative_order(FiniteField_givaroElement self):
1802        """
1803        Return the multiplicative order of this field element.
1804
1805        EXAMPLES:
1806            sage: S.<b> = GF(5^2); S
1807            Finite Field in b of size 5^2
1808            sage: b.multiplicative_order()
1809            24
1810            sage: (b^6).multiplicative_order()
1811            4       
1812        """
1813        # TODO -- I'm sure this can be made vastly faster
1814        # using how elements are represented as a power of the generator ??
1815       
1816        # code copy'n'pasted from finite_field_element.py
1817        import sage.rings.arith
1818       
1819        if self.__multiplicative_order is not None:
1820            return self.__multiplicative_order
1821        else:
1822            if self.is_zero():
1823                return ArithmeticError, "Multiplicative order of 0 not defined."
1824            n = (parent_object(self)).order_c() - 1
1825            order = 1
1826            for p, e in sage.rings.arith.factor(n):
1827                # Determine the power of p that divides the order.
1828                a = self**(n/(p**e))
1829                while a != 1:
1830                    order = order * p
1831                    a = a**p
1832            self.__multiplicative_order = order
1833            return order
1834
1835    def __copy__(self):
1836        """
1837        Return a copy of this element.  Actually just returns self, since
1838        finite field elements are immutable.
1839
1840        EXAMPLES:
1841            sage: S.<b> = GF(5^2); S
1842            Finite Field in b of size 5^2
1843            sage: c = copy(b); c
1844            b
1845            sage: c is b
1846            True
1847            sage: copy(5r) is 5r
1848            True           
1849        """
1850        return self
1851
1852    def _gap_init_(FiniteField_givaroElement self):
1853        """
1854        Return a string that evaluates to the GAP representation of
1855        this element.
1856
1857        A NotImplementedError is raised if self.parent().modulus() is
1858        not a Conway polynomial, as the isomorphism of finite fields is
1859        not implemented yet.
1860
1861        EXAMPLES:
1862            sage: S.<b> = GF(5^2); S
1863            Finite Field in b of size 5^2
1864            sage: (4*b+3)._gap_init_()
1865            'Z(25)^3'
1866            sage: S(gap('Z(25)^3'))
1867            4*b + 3       
1868        """
1869        #copied from finite_field_element.py
1870        cdef FiniteField_givaro F
1871        F = parent_object(self)
1872        if not F._is_conway:
1873            raise NotImplementedError, "conversion of (Givaro) finite field element to GAP not implemented except for fields defined by Conway polynomials."
1874        if F.order_c() > 65536:
1875            raise TypeError, "order (=%s) must be at most 65536."%F.order_c()
1876        if self == 0:
1877            return '0*Z(%s)'%F.order_c()
1878        assert F.degree() > 1
1879        g = F.multiplicative_generator()
1880        n = self.log(g)
1881        return 'Z(%s)^%s'%(F.order_c(), n)
1882
1883    def charpoly(FiniteField_givaroElement self, var):
1884        """
1885        Return the characteristic polynomial of self as a polynomial with given variable.
1886
1887        EXAMPLES:
1888            sage: k.<a> = GF(19^2)
1889            sage: parent(a)
1890            Finite Field in a of size 19^2
1891            sage: a.charpoly('X')
1892            X^2 + 18*X + 2
1893            sage: a^2 + 18*a + 2
1894            0           
1895        """
1896        from sage.rings.polynomial.polynomial_ring import PolynomialRing
1897        R = PolynomialRing(parent_object(self).prime_subfield_C(), var)
1898        return R(self._pari_().charpoly('x').lift())
1899
1900
1901    def norm(FiniteField_givaroElement self):
1902        """
1903        Return the norm of self down to the prime subfield.
1904
1905        This is the product of the Galois conjugates of self.
1906
1907        EXAMPLES:
1908            sage: S.<b> = GF(5^2); S
1909            Finite Field in b of size 5^2
1910            sage: b.norm()
1911            2
1912            sage: b.charpoly('t')
1913            t^2 + 4*t + 2
1914
1915        Next we consider a cubic extension:
1916            sage: S.<a> = GF(5^3); S
1917            Finite Field in a of size 5^3
1918            sage: a.norm()
1919            2
1920            sage: a.charpoly('t')
1921            t^3 + 3*t + 3
1922            sage: a * a^5 * (a^25)
1923            2           
1924        """
1925        f = self.charpoly('x')
1926        n = f[0]
1927        if f.degree() % 2 != 0:
1928            return -n
1929        else:
1930            return n
1931
1932    def trace(FiniteField_givaroElement self):
1933        """
1934        Return the trace of this element, which is the sum of the
1935        Galois conjugates.
1936
1937        EXAMPLES:
1938            sage: S.<a> = GF(5^3); S
1939            Finite Field in a of size 5^3
1940            sage: a.trace()
1941            0
1942            sage: a.charpoly('t')
1943            t^3 + 3*t + 3
1944            sage: a + a^5 + a^25
1945            0
1946            sage: z = a^2 + a + 1
1947            sage: z.trace()
1948            2
1949            sage: z.charpoly('t')
1950            t^3 + 3*t^2 + 2*t + 2
1951            sage: z + z^5 + z^25
1952            2       
1953        """
1954        return parent_object(self).prime_subfield()(self._pari_().trace().lift())
1955
1956    def __hash__(FiniteField_givaroElement self):
1957        """
1958        Return the hash of this finite field element.  We hash the parent
1959        and the underlying integer representation of this element.
1960
1961        EXAMPLES:
1962            sage: S.<a> = GF(5^3); S
1963            Finite Field in a of size 5^3
1964            sage: hash(a)
1965            5
1966        """
1967        return hash(self.log_to_int())
1968
1969    def vector(FiniteField_givaroElement self):
1970        """
1971        Return a vector in self.parent().vector_space() matching self.
1972
1973        EXAMPLES:
1974            sage: k.<a> = GF(2^4)
1975            sage: e = a^2 + 1
1976            sage: v = e.vector()
1977            sage: v
1978            (1, 0, 1, 0)
1979            sage: k(v)
1980            a^2 + 1
1981
1982            sage: k.<a> = GF(3^4)
1983            sage: e = 2*a^2 + 1
1984            sage: v = e.vector()
1985            sage: v
1986            (1, 0, 2, 0)
1987            sage: k(v)
1988            2*a^2 + 1
1989
1990        """
1991        cdef FiniteField_givaro k = <FiniteField_givaro>self._parent
1992       
1993        quo = k.log_to_int(self.element)
1994        b   = int(k.characteristic())
1995
1996        ret = []
1997        for i in range(k.degree()):
1998            coeff = quo%b
1999            ret.append(coeff)
2000            quo = quo/b
2001        return k.vector_space()(ret)
2002
2003    def __reduce__(FiniteField_givaroElement self):
2004        """
2005        Used for supporting pickling of finite field elements.
2006       
2007        EXAMPLE:
2008            sage: k = GF(2**8, 'a')
2009            sage: e = k.random_element()
2010            sage: loads(dumps(e)) == e
2011            True
2012        """
2013        return unpickle_FiniteField_givaroElement,(parent_object(self),self.element)
2014
2015
2016def unpickle_FiniteField_givaroElement(FiniteField_givaro parent, int x):
2017    return make_FiniteField_givaroElement(parent, x)
2018
2019cdef inline FiniteField_givaroElement make_FiniteField_givaroElement(FiniteField_givaro parent, int x):
2020    cdef FiniteField_givaroElement y
2021    cdef PyObject** w
2022
2023    if parent._array is None:
2024        #y = FiniteField_givaroElement(parent)
2025        y = PY_NEW(FiniteField_givaroElement)
2026        y._parent = <ParentWithBase> parent
2027        y.element = x
2028        return y
2029    else:
2030        return <FiniteField_givaroElement>parent._array[x]
2031
2032def gap_to_givaro(x, F):
2033    """
2034    INPUT:
2035        x -- gap finite field element
2036        F -- Givaro finite field
2037    OUTPUT:
2038        element of F
2039
2040    EXAMPLES:
2041        sage: from sage.rings.finite_field_givaro import FiniteField_givaro
2042        sage: x = gap('Z(13)')
2043        sage: F = FiniteField_givaro(13)
2044        sage: F(x)
2045        2
2046        sage: F(gap('0*Z(13)'))
2047        0
2048        sage: F = FiniteField_givaro(13^2)
2049        sage: x = gap('Z(13)')
2050        sage: F(x)
2051        2
2052        sage: x = gap('Z(13^2)^3')
2053        sage: F(x)
2054        12*a + 11
2055        sage: F.multiplicative_generator()^3
2056        12*a + 11
2057
2058    AUTHOR:
2059        -- David Joyner and William Stein
2060        -- Martin Albrecht (copied from gap_to_sage)
2061    """
2062    return gap_to_givaro_c(x,F)
2063
2064cdef gap_to_givaro_c(x, FiniteField_givaro F):
2065    s = str(x)
2066    if s[:2] == '0*':
2067        return F(0)
2068    i1 = s.index("(")
2069    i2 = s.index(")")
2070    q  = eval(s[i1+1:i2].replace('^','**'))
2071    if q == F.order_c():
2072        K = F
2073    else:
2074        K = finite_field.FiniteField(q,'a')
2075    if s.find(')^') == -1:
2076        e = 1
2077    else:
2078        e = int(s[i2+2:])
2079
2080    if F.degree() == 1:
2081        g = int(sage.interfaces.gap.gap.eval('Int(Z(%s))'%q))
2082    else:
2083        g = K.multiplicative_generator()
2084    return F(K(g**e))
2085
Note: See TracBrowser for help on using the repository browser.