Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/rings/finite_rings/finite_field_base.pyx
4108 views
1
"""
2
TESTS::
3
4
sage: K.<a> = NumberField(x^2 + 1)
5
sage: F = K.factor(3)[0][0].residue_field()
6
sage: loads(dumps(F)) == F
7
True
8
"""
9
include "../../ext/stdsage.pxi"
10
11
from sage.structure.parent cimport Parent
12
from sage.misc.prandom import randrange
13
from sage.rings.finite_rings.homset import FiniteFieldHomset
14
15
cdef class FiniteFieldIterator:
16
r"""
17
An iterator over a finite field. This should only be used when the field is
18
an extension of a smaller field which already has a separate iterator function.
19
"""
20
cdef object iter
21
cdef FiniteField parent
22
23
def __init__(self,FiniteField parent):
24
r"""
25
Standard init function.
26
27
EXAMPLE::
28
29
sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
30
sage: k = iter(FiniteField_ext_pari(9, 'a')) # indirect doctest
31
sage: isinstance(k, sage.rings.finite_rings.finite_field_base.FiniteFieldIterator)
32
True
33
"""
34
self.parent = parent
35
self.iter =iter(self.parent.vector_space())
36
37
def __next__(self):
38
r"""
39
Return the next element in the iterator.
40
41
EXAMPLE::
42
43
sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
44
sage: k = iter(FiniteField_ext_pari(9, 'a'))
45
sage: k.next() # indirect doctest
46
0
47
"""
48
return self.parent(self.iter.next())
49
50
def __iter__(self):
51
"""
52
53
EXAMPLES::
54
55
sage: K.<a> = GF(7^4)
56
sage: K.list()[:7]
57
[0, 6*a, a^2, 6*a^3, 2*a^2 + 3*a + 4, 5*a^3 + 4*a^2 + 3*a, 3*a^3 + a^2 + 6*a + 1]
58
sage: K.<a> = GF(5^9)
59
sage: for x in K:
60
... if x == a+3: break
61
... print x
62
0
63
1
64
2
65
3
66
4
67
a
68
a + 1
69
a + 2
70
"""
71
return self
72
73
from sage.categories.finite_fields import FiniteFields
74
_FiniteFields = FiniteFields()
75
cdef class FiniteField(Field):
76
def __init__(self, base, names, normalize):
77
"""
78
EXAMPLES::
79
80
sage: K = GF(7); K
81
Finite Field of size 7
82
sage: loads(K.dumps()) == K
83
True
84
sage: GF(7^10, 'a')
85
Finite Field in a of size 7^10
86
sage: K = GF(7^10, 'a'); K
87
Finite Field in a of size 7^10
88
sage: loads(K.dumps()) == K
89
True
90
"""
91
Field.__init__(self, base, names, normalize, category=_FiniteFields)
92
93
def __repr__(self):
94
"""
95
String representation of this finite field.
96
97
EXAMPLES::
98
99
sage: k = GF(127)
100
sage: k # indirect doctest
101
Finite Field of size 127
102
103
sage: k.<b> = GF(2^8)
104
sage: k
105
Finite Field in b of size 2^8
106
107
sage: k.<c> = GF(2^20)
108
sage: k
109
Finite Field in c of size 2^20
110
111
sage: k.<d> = GF(7^20)
112
sage: k
113
Finite Field in d of size 7^20
114
"""
115
if self.degree()>1:
116
return "Finite Field in %s of size %s^%s"%(self.variable_name(),self.characteristic(),self.degree())
117
else:
118
return "Finite Field of size %s"%(self.characteristic())
119
120
def _latex_(self):
121
r"""
122
Returns a string denoting the name of the field in LaTeX.
123
124
The :func:`sage.misc.latex.latex` function calls the
125
``_latex_`` attribute when available.
126
127
EXAMPLES:
128
129
The ``latex`` command parses the string::
130
131
sage: GF(81, 'a')._latex_()
132
'\\Bold{F}_{3^{4}}'
133
sage: latex(GF(81, 'a'))
134
\Bold{F}_{3^{4}}
135
sage: GF(3)._latex_()
136
'\\Bold{F}_{3}'
137
sage: latex(GF(3))
138
\Bold{F}_{3}
139
"""
140
if self.degree() > 1:
141
e = "^{%s}"%self.degree()
142
else:
143
e = ""
144
return "\\Bold{F}_{%s%s}"%(self.characteristic(), e)
145
146
def _gap_init_(self):
147
"""
148
Return string that initializes the GAP version of
149
this finite field.
150
151
EXAMPLES::
152
153
sage: GF(9,'a')._gap_init_()
154
'GF(9)'
155
"""
156
return 'GF(%s)'%self.order()
157
158
def _magma_init_(self, magma):
159
"""
160
Return string representation of self that Magma can
161
understand.
162
163
EXAMPLES::
164
165
sage: GF(97,'a')._magma_init_(magma) # optional - magma
166
'GF(97)'
167
sage: GF(9,'a')._magma_init_(magma) # optional - magma
168
'SageCreateWithNames(ext<GF(3)|_sage_[...]![GF(3)!2,GF(3)!2,GF(3)!1]>,["a"])'
169
sage: magma(GF(9,'a')) # optional - magma
170
Finite field of size 3^2
171
sage: magma(GF(9,'a')).1 # optional - magma
172
a
173
"""
174
if self.degree() == 1:
175
return 'GF(%s)'%self.order()
176
B = self.base_ring()
177
p = self.polynomial()
178
s = "ext<%s|%s>"%(B._magma_init_(magma),p._magma_init_(magma))
179
return magma._with_names(s, self.variable_names())
180
181
def _macaulay2_init_(self):
182
"""
183
Returns the string representation of self that Macaulay2 can
184
understand.
185
186
EXAMPLES::
187
188
sage: GF(97,'a')._macaulay2_init_()
189
'GF 97'
190
191
sage: macaulay2(GF(97, 'a')) # optional - macaulay2
192
ZZ
193
--
194
97
195
sage: macaulay2(GF(49, 'a')) # optional - macaulay2
196
GF 49
197
"""
198
return "GF %s"%(self.order())
199
200
def _sage_input_(self, sib, coerced):
201
r"""
202
Produce an expression which will reproduce this value when evaluated.
203
204
EXAMPLES::
205
206
sage: sage_input(GF(5), verify=True)
207
# Verified
208
GF(5)
209
sage: sage_input(GF(32, 'a'), verify=True)
210
# Verified
211
R.<x> = GF(2)[]
212
GF(2^5, 'a', x^5 + x^2 + 1)
213
sage: K = GF(125, 'b')
214
sage: sage_input((K, K), verify=True)
215
# Verified
216
R.<x> = GF(5)[]
217
GF_5_3 = GF(5^3, 'b', x^3 + 3*x + 3)
218
(GF_5_3, GF_5_3)
219
sage: from sage.misc.sage_input import SageInputBuilder
220
sage: GF(81, 'a')._sage_input_(SageInputBuilder(), False)
221
{call: {atomic:GF}({binop:** {atomic:3} {atomic:4}}, {atomic:'a'}, {binop:+ {binop:+ {binop:** {gen:x {constr_parent: {subscr: {call: {atomic:GF}({atomic:3})}[{atomic:'x'}]} with gens: ('x',)}} {atomic:4}} {binop:* {atomic:2} {binop:** {gen:x {constr_parent: {subscr: {call: {atomic:GF}({atomic:3})}[{atomic:'x'}]} with gens: ('x',)}} {atomic:3}}}} {atomic:2}})}
222
"""
223
if self.degree() == 1:
224
v = sib.name('GF')(sib.int(self.characteristic()))
225
name = 'GF_%d' % self.characteristic()
226
else:
227
v = sib.name('GF')(sib.int(self.characteristic()) ** sib.int(self.degree()),
228
self.variable_name(),
229
self.modulus())
230
name = 'GF_%d_%d' % (self.characteristic(), self.degree())
231
sib.cache(self, v, name)
232
return v
233
234
def _cmp_(left, Parent right):
235
"""
236
Compares this finite field with other.
237
238
.. warning::
239
240
The notation of equality of finite fields in Sage is
241
currently not stable, i.e., it may change in a future version.
242
243
EXAMPLES::
244
245
sage: FiniteField(3**2, 'c') == FiniteField(3**3, 'c') # indirect doctest
246
False
247
sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'c')
248
True
249
250
The variable name is (currently) relevant for comparison of finite fields::
251
252
sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'd')
253
False
254
"""
255
if not PY_TYPE_CHECK(right, FiniteField):
256
return cmp(type(left), type(right))
257
c = cmp(left.characteristic(), right.characteristic())
258
if c: return c
259
c = cmp(left.degree(), right.degree())
260
if c: return c
261
# TODO comparing the polynomials themselves would recursively call
262
# this cmp... Also, as mentioned above, we will get rid of this.
263
if left.degree() > 1:
264
c = cmp(str(left.polynomial()), str(right.polynomial()))
265
if c: return c
266
return 0
267
268
def __iter__(self):
269
"""
270
Return an iterator over the elements of this finite field. This generic
271
implementation uses the fairly simple :class:`FiniteFieldIterator`
272
class; derived classes may implement their own more sophisticated
273
replacements.
274
275
EXAMPLE::
276
277
sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
278
sage: k = FiniteField_ext_pari(8, 'a')
279
sage: i = iter(k); i # indirect doctest
280
<sage.rings.finite_rings.finite_field_base.FiniteFieldIterator object at ...>
281
sage: i.next()
282
0
283
sage: list(k) # indirect doctest
284
[0, 1, a, a + 1, a^2, a^2 + 1, a^2 + a, a^2 + a + 1]
285
"""
286
return FiniteFieldIterator(self)
287
288
def _is_valid_homomorphism_(self, codomain, im_gens):
289
"""
290
Return True if the map from self to codomain sending
291
self.0 to the unique element of im_gens is a valid field
292
homomorphism. Otherwise, return False.
293
294
EXAMPLES::
295
296
sage: k = FiniteField(73^2, 'a')
297
sage: K = FiniteField(73^3, 'b') ; b = K.0
298
sage: L = FiniteField(73^4, 'c') ; c = L.0
299
sage: k.hom([c]) # indirect doctest
300
Traceback (most recent call last):
301
...
302
TypeError: images do not define a valid homomorphism
303
304
sage: k.hom([c^(73*73+1)])
305
Ring morphism:
306
From: Finite Field in a of size 73^2
307
To: Finite Field in c of size 73^4
308
Defn: a |--> 7*c^3 + 13*c^2 + 65*c + 71
309
310
sage: k.hom([b])
311
Traceback (most recent call last):
312
...
313
TypeError: images do not define a valid homomorphism
314
"""
315
316
if (self.characteristic() != codomain.characteristic()):
317
raise ValueError, "no map from %s to %s"%(self, codomain)
318
if (len(im_gens) != 1):
319
raise ValueError, "only one generator for finite fields."
320
321
return (im_gens[0].charpoly())(self.gen(0)).is_zero()
322
323
def _Hom_(self, codomain, cat=None):
324
"""
325
Return homset of homomorphisms from self to the finite field codomain.
326
This function is implicitly called by the Hom method or function.
327
328
The cat option is currently ignored.
329
330
EXAMPLES::
331
332
sage: K.<a> = GF(25); K
333
Finite Field in a of size 5^2
334
sage: K.Hom(K) # indirect doctest
335
Automorphism group of Finite Field in a of size 5^2
336
"""
337
return FiniteFieldHomset(self, codomain)
338
339
def gen(self):
340
r"""
341
Return a generator of this field (over its prime field). As this is an abstract base class,
342
this just raises a NotImplementedError.
343
344
EXAMPLE::
345
346
sage: K = GF(17)
347
sage: sage.rings.finite_rings.finite_field_base.FiniteField.gen(K)
348
Traceback (most recent call last):
349
...
350
NotImplementedError
351
"""
352
raise NotImplementedError
353
354
def zeta_order(self):
355
"""
356
Return the order of the distinguished root of unity in self.
357
358
EXAMPLES::
359
360
sage: GF(9,'a').zeta_order()
361
8
362
sage: GF(9,'a').zeta()
363
a
364
sage: GF(9,'a').zeta().multiplicative_order()
365
8
366
"""
367
return self.order() - 1
368
369
def zeta(self, n=None):
370
"""
371
Returns an element of multiplicative order n in this
372
finite field, if there is one. Raises a ValueError if there
373
is not.
374
375
EXAMPLES::
376
377
sage: k = GF(7)
378
sage: k.zeta()
379
3
380
sage: k.zeta().multiplicative_order()
381
6
382
sage: k.zeta(3)
383
2
384
sage: k.zeta(3).multiplicative_order()
385
3
386
sage: k = GF(49, 'a')
387
sage: k.zeta().multiplicative_order()
388
48
389
sage: k.zeta(6)
390
3
391
392
Even more examples::
393
394
sage: GF(9,'a').zeta_order()
395
8
396
sage: GF(9,'a').zeta()
397
a
398
sage: GF(9,'a').zeta(4)
399
a + 1
400
sage: GF(9,'a').zeta()^2
401
a + 1
402
"""
403
z = self.multiplicative_generator()
404
if n is None:
405
return z
406
else:
407
import sage.rings.integer
408
n = sage.rings.integer.Integer(n)
409
m = z.multiplicative_order()
410
if m % n != 0:
411
raise ValueError, "No %sth root of unity in self"%n
412
return z**(m.__floordiv__(n))
413
414
def multiplicative_generator(self):
415
"""
416
Return a primitive element of this finite field, i.e. a generator
417
of the multiplicative group.
418
419
You can use ``self.multiplicative_generator()`` or
420
``self.primitive_element()``, these mean the same thing.
421
422
.. WARNING::
423
424
This generator might change from one version of Sage to another.
425
426
EXAMPLES::
427
428
sage: k = GF(997)
429
sage: k.multiplicative_generator()
430
7
431
sage: k.<a> = GF(11^3)
432
sage: k.primitive_element()
433
a
434
sage: k.<b> = GF(19^32)
435
sage: k.multiplicative_generator()
436
b + 5
437
438
TESTS:
439
440
Check that large characteristics work (Trac #11946)::
441
442
sage: p = 10^20 + 39
443
sage: x = polygen(GF(p))
444
sage: K.<a> = GF(p^2, modulus=x^2+1)
445
sage: K.multiplicative_generator()
446
a + 12
447
"""
448
from sage.rings.arith import primitive_root
449
450
if self.__multiplicative_generator is not None:
451
return self.__multiplicative_generator
452
if self.degree() == 1:
453
self.__multiplicative_generator = self(primitive_root(self.order()))
454
return self.__multiplicative_generator
455
n = self.order() - 1
456
g = self.gen(0)
457
# We check whether x+g is a multiplicative generator, where
458
# x runs through the finite field.
459
# This has the advantage that g is the first element we try,
460
# so we always get g as generator if possible. Second, the
461
# PARI finite field iterator gives all the constant elements
462
# first, so we try g+(constant) before anything else.
463
for x in self:
464
a = g+x
465
if a != 0 and a.multiplicative_order() == n:
466
self.__multiplicative_generator = a
467
return a
468
469
primitive_element = multiplicative_generator
470
471
def ngens(self):
472
"""
473
The number of generators of the finite field. Always 1.
474
475
EXAMPLES::
476
477
sage: k = FiniteField(3^4, 'b')
478
sage: k.ngens()
479
1
480
"""
481
return 1
482
483
def is_field(self, proof = True):
484
"""
485
Returns whether or not the finite field is a field, i.e.,
486
always returns True.
487
488
EXAMPLES::
489
490
sage: k.<a> = FiniteField(3^4)
491
sage: k.is_field()
492
True
493
"""
494
return True
495
496
def is_finite(self):
497
"""
498
Return True since a finite field is finite.
499
500
EXAMPLES::
501
502
sage: GF(997).is_finite()
503
True
504
"""
505
return True
506
507
def order(self):
508
"""
509
Return the order of this finite field.
510
511
EXAMPLES::
512
513
sage: GF(997).order()
514
997
515
"""
516
raise NotImplementedError
517
518
def factored_order(self):
519
"""
520
Returns the factored order of this field. For compatibility with IntegerModRing.
521
522
EXAMPLES::
523
524
sage: GF(7^2,'a').factored_order()
525
7^2
526
"""
527
from sage.structure.factorization import Factorization
528
return Factorization([(self.characteristic(), self.degree())])
529
530
def factored_unit_order(self):
531
"""
532
Returns the factorization of ``self.order()-1``, as a 1-element list. The format is for compatibility with IntegerModRing.
533
534
EXAMPLES::
535
536
sage: GF(7^2,'a').factored_unit_order()
537
[2^4 * 3]
538
"""
539
if self.__factored_unit_order is None:
540
if self.characteristic() in []: # want to be [2,3,5,7,11] once #7240 is finished.
541
self.__factored_unit_order = [(self.order()-1)._factor_cunningham()]
542
else:
543
self.__factored_unit_order = [(self.order()-1).factor()]
544
return self.__factored_unit_order
545
546
def cardinality(self):
547
"""
548
Return the order of this finite field (same as self.order()).
549
550
EXAMPLES::
551
552
sage: GF(997).cardinality()
553
997
554
"""
555
return self.order()
556
557
def __len__(self):
558
"""
559
len(k) returns the cardinality of k, i.e., the number of elements in k.
560
561
EXAMPLE::
562
563
sage: len(GF(8,'a'))
564
8
565
"""
566
return self.order()
567
568
def is_prime_field(self):
569
"""
570
Return True if self is a prime field, i.e., has degree 1.
571
572
EXAMPLES::
573
574
sage: GF(3^7, 'a').is_prime_field()
575
False
576
sage: GF(3, 'a').is_prime_field()
577
True
578
"""
579
return self.degree()==1
580
581
def modulus(self):
582
r"""
583
Return the minimal polynomial of the generator of self (over an
584
appropriate base field).
585
586
The minimal polynomial of an element `a` in a field is the unique
587
irreducible polynomial of smallest degree with coefficients in the base
588
field that has `a` as a root. In finite field extensions, `\GF{p^n}`,
589
the base field is `\GF{p}`. Here are several examples::
590
591
sage: F.<a> = GF(7^2, 'a'); F
592
Finite Field in a of size 7^2
593
sage: F.polynomial_ring()
594
Univariate Polynomial Ring in a over Finite Field of size 7
595
sage: f = F.modulus(); f
596
x^2 + 6*x + 3
597
sage: f(a)
598
0
599
600
Although `f` is irreducible over the base field, we can double-check
601
whether or not `f` factors in `F` as follows. The command
602
`F[x](f)` coerces `f` as a polynomial with coefficients in `F`.
603
(Instead of a polynomial with coefficients over the base field.)
604
605
::
606
607
sage: f.factor()
608
x^2 + 6*x + 3
609
sage: F[x](f).factor()
610
(x + a + 6) * (x + 6*a)
611
612
Here is an example with a degree 3 extension::
613
614
sage: G.<b> = GF(7^3, 'b'); G
615
Finite Field in b of size 7^3
616
sage: g = G.modulus(); g
617
x^3 + 6*x^2 + 4
618
sage: g.degree(); G.degree()
619
3
620
3
621
"""
622
return self.polynomial_ring("x")(self.polynomial().list())
623
624
def unit_group_exponent(self):
625
"""
626
The exponent of the unit group of the finite field. For a
627
finite field, this is always the order minus 1.
628
629
EXAMPLES::
630
631
sage: k = GF(2^10, 'a')
632
sage: k.order()
633
1024
634
sage: k.unit_group_exponent()
635
1023
636
"""
637
return self.order() - 1
638
639
640
def random_element(self, *args, **kwds):
641
r"""
642
A random element of the finite field. Passes arguments to
643
``random_element()`` function of underlying vector space.
644
645
EXAMPLES::
646
647
sage: k = GF(19^4, 'a')
648
sage: k.random_element()
649
a^3 + 3*a^2 + 6*a + 9
650
651
Passes extra positional or keyword arguments through::
652
653
sage: k.random_element(prob=0)
654
0
655
656
"""
657
if self.degree() == 1:
658
return self(randrange(self.order()))
659
v = self.vector_space().random_element(*args, **kwds)
660
return self(v)
661
662
def some_elements(self):
663
"""
664
Returns a collection of elements of this finite field for use in unit testing.
665
666
EXAMPLES::
667
668
sage: k = GF(2^8,'a')
669
sage: k.some_elements() # random output
670
[a^4 + a^3 + 1, a^6 + a^4 + a^3, a^5 + a^4 + a, a^2 + a]
671
"""
672
return [self.random_element() for i in range(4)]
673
674
def polynomial(self):
675
"""
676
Return the defining polynomial of this finite field.
677
678
EXAMPLES::
679
680
sage: f = GF(27,'a').polynomial(); f
681
a^3 + 2*a + 1
682
sage: parent(f)
683
Univariate Polynomial Ring in a over Finite Field of size 3
684
"""
685
raise NotImplementedError
686
687
def polynomial_ring(self, variable_name=None):
688
"""
689
Returns the polynomial ring over the prime subfield in the
690
same variable as this finite field.
691
692
EXAMPLES::
693
694
sage: k.<alpha> = FiniteField(3^4)
695
sage: k.polynomial_ring()
696
Univariate Polynomial Ring in alpha over Finite Field of size 3
697
"""
698
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
699
from sage.rings.finite_rings.constructor import FiniteField as GF
700
701
if variable_name is None and self.__polynomial_ring is not None:
702
return self.__polynomial_ring
703
else:
704
if variable_name is None:
705
self.__polynomial_ring = PolynomialRing(GF(self.characteristic()), self.variable_name())
706
return self.__polynomial_ring
707
else:
708
return PolynomialRing(GF(self.characteristic()), variable_name)
709
710
def vector_space(self):
711
"""
712
Return the vector space over the prime subfield isomorphic
713
to this finite field as a vector space.
714
715
EXAMPLES::
716
717
sage: GF(27,'a').vector_space()
718
Vector space of dimension 3 over Finite Field of size 3
719
"""
720
if self.__vector_space is not None:
721
return self.__vector_space
722
else:
723
import sage.modules.all
724
V = sage.modules.all.VectorSpace(self.prime_subfield(),self.degree())
725
self.__vector_space = V
726
return V
727
728
def __hash__(self):
729
r"""
730
Return a hash of this finite field.
731
732
EXAMPLES::
733
734
sage: hash(GF(17))
735
-1709973406 # 32-bit
736
9088054599082082 # 64-bit
737
"""
738
return hash("GF") + hash(self.order())
739
740
def algebraic_closure(self):
741
"""
742
Return the algebraic closure of self (not implemented).
743
744
.. note::
745
746
This is not yet implemented for finite fields.
747
748
EXAMPLES::
749
750
sage: GF(5).algebraic_closure()
751
Traceback (most recent call last):
752
...
753
NotImplementedError: Algebraic closures of finite fields not implemented.
754
"""
755
raise NotImplementedError, "Algebraic closures of finite fields not implemented."
756
757
758
def unpickle_FiniteField_ext(_type, order, variable_name, modulus, kwargs):
759
r"""
760
Used to unpickle extensions of finite fields. Now superseded (hence no
761
doctest), but kept around for backward compatibility.
762
763
EXAMPLE::
764
765
sage: # not tested
766
"""
767
return _type(order, variable_name, modulus, **kwargs)
768
769
def unpickle_FiniteField_prm(_type, order, variable_name, kwargs):
770
r"""
771
Used to unpickle finite prime fields. Now superseded (hence no doctest),
772
but kept around for backward compatibility.
773
774
EXAMPLE::
775
776
sage: # not tested
777
"""
778
return _type(order, variable_name, **kwargs)
779
780
781
def is_FiniteField(x):
782
"""
783
Return True if x is of type finite field, and False otherwise.
784
785
EXAMPLES::
786
787
sage: from sage.rings.finite_rings.finite_field_base import is_FiniteField
788
sage: is_FiniteField(GF(9,'a'))
789
True
790
sage: is_FiniteField(GF(next_prime(10^10)))
791
True
792
793
Note that the integers modulo n are not of type finite field,
794
so this function returns False::
795
796
sage: is_FiniteField(Integers(7))
797
False
798
"""
799
return IS_INSTANCE(x, FiniteField)
800
801
802