Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/rings/finite_rings/finite_field_base.pyx
8820 views
1
"""
2
Base Classes for Finite Fields
3
4
TESTS::
5
6
sage: K.<a> = NumberField(x^2 + 1)
7
sage: F = K.factor(3)[0][0].residue_field()
8
sage: loads(dumps(F)) == F
9
True
10
"""
11
include "sage/ext/stdsage.pxi"
12
13
from sage.structure.parent cimport Parent
14
from sage.misc.cachefunc import cached_method
15
from sage.misc.prandom import randrange
16
17
cdef class FiniteFieldIterator:
18
r"""
19
An iterator over a finite field. This should only be used when the field
20
is an extension of a smaller field which already has a separate iterator
21
function.
22
"""
23
cdef object iter
24
cdef FiniteField parent
25
26
def __init__(self,FiniteField parent):
27
r"""
28
Initialize ``self``.
29
30
EXAMPLES::
31
32
sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
33
sage: k = iter(FiniteField_ext_pari(9, 'a')) # indirect doctest
34
sage: isinstance(k, sage.rings.finite_rings.finite_field_base.FiniteFieldIterator)
35
True
36
"""
37
self.parent = parent
38
self.iter =iter(self.parent.vector_space())
39
40
def __next__(self):
41
r"""
42
Return the next element in the iterator.
43
44
EXAMPLE::
45
46
sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
47
sage: k = iter(FiniteField_ext_pari(9, 'a'))
48
sage: k.next() # indirect doctest
49
0
50
"""
51
return self.parent(self.iter.next())
52
53
def __iter__(self):
54
"""
55
Return ``self`` since this is an interator class.
56
57
EXAMPLES::
58
59
sage: K.<a> = GF(7^4)
60
sage: K.list()[:7]
61
[0, a, a^2, a^3, 2*a^2 + 3*a + 4, 2*a^3 + 3*a^2 + 4*a, 3*a^3 + a^2 + 6*a + 1]
62
sage: K.<a> = GF(5^9)
63
sage: for x in K:
64
... if x == a+3: break
65
... print x
66
0
67
1
68
2
69
3
70
4
71
a
72
a + 1
73
a + 2
74
"""
75
return self
76
77
from sage.categories.finite_fields import FiniteFields
78
_FiniteFields = FiniteFields()
79
cdef class FiniteField(Field):
80
"""
81
Abstract base class for finite fields.
82
"""
83
def __init__(self, base, names, normalize):
84
"""
85
Initialize ``self``.
86
87
EXAMPLES::
88
89
sage: K = GF(7); K
90
Finite Field of size 7
91
sage: loads(K.dumps()) == K
92
True
93
sage: GF(7^10, 'a')
94
Finite Field in a of size 7^10
95
sage: K = GF(7^10, 'a'); K
96
Finite Field in a of size 7^10
97
sage: loads(K.dumps()) == K
98
True
99
"""
100
Field.__init__(self, base, names, normalize, category=_FiniteFields)
101
102
def __repr__(self):
103
"""
104
String representation of this finite field.
105
106
EXAMPLES::
107
108
sage: k = GF(127)
109
sage: k # indirect doctest
110
Finite Field of size 127
111
112
sage: k.<b> = GF(2^8)
113
sage: k
114
Finite Field in b of size 2^8
115
116
sage: k.<c> = GF(2^20)
117
sage: k
118
Finite Field in c of size 2^20
119
120
sage: k.<d> = GF(7^20)
121
sage: k
122
Finite Field in d of size 7^20
123
"""
124
if self.degree()>1:
125
return "Finite Field in %s of size %s^%s"%(self.variable_name(),self.characteristic(),self.degree())
126
else:
127
return "Finite Field of size %s"%(self.characteristic())
128
129
def _latex_(self):
130
r"""
131
Returns a string denoting the name of the field in LaTeX.
132
133
The :func:`~sage.misc.latex.latex` function calls the
134
``_latex_`` attribute when available.
135
136
EXAMPLES:
137
138
The ``latex`` command parses the string::
139
140
sage: GF(81, 'a')._latex_()
141
'\\Bold{F}_{3^{4}}'
142
sage: latex(GF(81, 'a'))
143
\Bold{F}_{3^{4}}
144
sage: GF(3)._latex_()
145
'\\Bold{F}_{3}'
146
sage: latex(GF(3))
147
\Bold{F}_{3}
148
"""
149
if self.degree() > 1:
150
e = "^{%s}"%self.degree()
151
else:
152
e = ""
153
return "\\Bold{F}_{%s%s}"%(self.characteristic(), e)
154
155
def _gap_init_(self):
156
"""
157
Return string that initializes the GAP version of
158
this finite field.
159
160
EXAMPLES::
161
162
sage: GF(9,'a')._gap_init_()
163
'GF(9)'
164
"""
165
return 'GF(%s)'%self.order()
166
167
def _magma_init_(self, magma):
168
"""
169
Return string representation of ``self`` that Magma can
170
understand.
171
172
EXAMPLES::
173
174
sage: GF(97,'a')._magma_init_(magma) # optional - magma
175
'GF(97)'
176
sage: GF(9,'a')._magma_init_(magma) # optional - magma
177
'SageCreateWithNames(ext<GF(3)|_sage_[...]![GF(3)!2,GF(3)!2,GF(3)!1]>,["a"])'
178
sage: magma(GF(9,'a')) # optional - magma
179
Finite field of size 3^2
180
sage: magma(GF(9,'a')).1 # optional - magma
181
a
182
"""
183
if self.degree() == 1:
184
return 'GF(%s)'%self.order()
185
B = self.base_ring()
186
p = self.polynomial()
187
s = "ext<%s|%s>"%(B._magma_init_(magma),p._magma_init_(magma))
188
return magma._with_names(s, self.variable_names())
189
190
def _macaulay2_init_(self):
191
"""
192
Returns the string representation of ``self`` that Macaulay2 can
193
understand.
194
195
EXAMPLES::
196
197
sage: GF(97,'a')._macaulay2_init_()
198
'GF 97'
199
200
sage: macaulay2(GF(97, 'a')) # optional - macaulay2
201
GF 97
202
sage: macaulay2(GF(49, 'a')) # optional - macaulay2
203
GF 49
204
"""
205
return "GF %s"%(self.order())
206
207
def _sage_input_(self, sib, coerced):
208
r"""
209
Produce an expression which will reproduce this value when evaluated.
210
211
EXAMPLES::
212
213
sage: sage_input(GF(5), verify=True)
214
# Verified
215
GF(5)
216
sage: sage_input(GF(32, 'a'), verify=True)
217
# Verified
218
R.<x> = GF(2)[]
219
GF(2^5, 'a', x^5 + x^2 + 1)
220
sage: K = GF(125, 'b')
221
sage: sage_input((K, K), verify=True)
222
# Verified
223
R.<x> = GF(5)[]
224
GF_5_3 = GF(5^3, 'b', x^3 + 3*x + 3)
225
(GF_5_3, GF_5_3)
226
sage: from sage.misc.sage_input import SageInputBuilder
227
sage: GF(81, 'a')._sage_input_(SageInputBuilder(), False)
228
{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}})}
229
"""
230
if self.degree() == 1:
231
v = sib.name('GF')(sib.int(self.characteristic()))
232
name = 'GF_%d' % self.characteristic()
233
else:
234
v = sib.name('GF')(sib.int(self.characteristic()) ** sib.int(self.degree()),
235
self.variable_name(),
236
self.modulus())
237
name = 'GF_%d_%d' % (self.characteristic(), self.degree())
238
sib.cache(self, v, name)
239
return v
240
241
def _cmp_(left, Parent right):
242
"""
243
Compares this finite field with other.
244
245
.. WARNING::
246
247
The notation of equality of finite fields in Sage is
248
currently not stable, i.e., it may change in a future version.
249
250
EXAMPLES::
251
252
sage: FiniteField(3**2, 'c') == FiniteField(3**3, 'c') # indirect doctest
253
False
254
sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'c')
255
True
256
257
The variable name is (currently) relevant for comparison of finite
258
fields::
259
260
sage: FiniteField(3**2, 'c') == FiniteField(3**2, 'd')
261
False
262
"""
263
if not PY_TYPE_CHECK(right, FiniteField):
264
return cmp(type(left), type(right))
265
c = cmp(left.characteristic(), right.characteristic())
266
if c: return c
267
c = cmp(left.degree(), right.degree())
268
if c: return c
269
# TODO comparing the polynomials themselves would recursively call
270
# this cmp... Also, as mentioned above, we will get rid of this.
271
if left.degree() > 1:
272
c = cmp(str(left.polynomial()), str(right.polynomial()))
273
if c: return c
274
return 0
275
276
def __iter__(self):
277
"""
278
Return an iterator over the elements of this finite field. This generic
279
implementation uses the fairly simple :class:`FiniteFieldIterator`
280
class; derived classes may implement their own more sophisticated
281
replacements.
282
283
EXAMPLES::
284
285
sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari
286
sage: k = FiniteField_ext_pari(8, 'a')
287
sage: i = iter(k); i # indirect doctest
288
<sage.rings.finite_rings.finite_field_base.FiniteFieldIterator object at ...>
289
sage: i.next()
290
0
291
sage: list(k) # indirect doctest
292
[0, 1, a, a + 1, a^2, a^2 + 1, a^2 + a, a^2 + a + 1]
293
"""
294
return FiniteFieldIterator(self)
295
296
def _is_valid_homomorphism_(self, codomain, im_gens):
297
"""
298
Return ``True`` if the map from self to codomain sending
299
``self.0`` to the unique element of ``im_gens`` is a valid field
300
homomorphism. Otherwise, return ``False``.
301
302
EXAMPLES::
303
304
sage: k = FiniteField(73^2, 'a')
305
sage: K = FiniteField(73^3, 'b') ; b = K.0
306
sage: L = FiniteField(73^4, 'c') ; c = L.0
307
sage: k.hom([c]) # indirect doctest
308
Traceback (most recent call last):
309
...
310
TypeError: images do not define a valid homomorphism
311
312
sage: k.hom([c^(73*73+1)])
313
Ring morphism:
314
From: Finite Field in a of size 73^2
315
To: Finite Field in c of size 73^4
316
Defn: a |--> 7*c^3 + 13*c^2 + 65*c + 71
317
318
sage: k.hom([b])
319
Traceback (most recent call last):
320
...
321
TypeError: images do not define a valid homomorphism
322
"""
323
if (self.characteristic() != codomain.characteristic()):
324
raise ValueError, "no map from %s to %s"%(self, codomain)
325
if (len(im_gens) != 1):
326
raise ValueError, "only one generator for finite fields."
327
328
return (im_gens[0].charpoly())(self.gen(0)).is_zero()
329
330
def _Hom_(self, codomain, cat=None):
331
"""
332
Return homset of homomorphisms from ``self`` to the finite field
333
codomain. This function is implicitly called by the Hom method or
334
function.
335
336
The ``cat`` option is currently ignored.
337
338
EXAMPLES::
339
340
sage: K.<a> = GF(25); K
341
Finite Field in a of size 5^2
342
sage: K.Hom(K) # indirect doctest
343
Automorphism group of Finite Field in a of size 5^2
344
"""
345
from sage.rings.finite_rings.homset import FiniteFieldHomset
346
return FiniteFieldHomset(self, codomain)
347
348
def gen(self):
349
r"""
350
Return a generator of this field (over its prime field). As this is an
351
abstract base class, this just raises a ``NotImplementedError``.
352
353
EXAMPLES::
354
355
sage: K = GF(17)
356
sage: sage.rings.finite_rings.finite_field_base.FiniteField.gen(K)
357
Traceback (most recent call last):
358
...
359
NotImplementedError
360
"""
361
raise NotImplementedError
362
363
def zeta_order(self):
364
"""
365
Return the order of the distinguished root of unity in ``self``.
366
367
EXAMPLES::
368
369
sage: GF(9,'a').zeta_order()
370
8
371
sage: GF(9,'a').zeta()
372
a
373
sage: GF(9,'a').zeta().multiplicative_order()
374
8
375
"""
376
return self.order() - 1
377
378
def zeta(self, n=None):
379
"""
380
Returns an element of multiplicative order ``n`` in this
381
finite field, if there is one. Raises a ``ValueError`` if there
382
is not.
383
384
EXAMPLES::
385
386
sage: k = GF(7)
387
sage: k.zeta()
388
3
389
sage: k.zeta().multiplicative_order()
390
6
391
sage: k.zeta(3)
392
2
393
sage: k.zeta(3).multiplicative_order()
394
3
395
sage: k = GF(49, 'a')
396
sage: k.zeta().multiplicative_order()
397
48
398
sage: k.zeta(6)
399
3
400
401
Even more examples::
402
403
sage: GF(9,'a').zeta_order()
404
8
405
sage: GF(9,'a').zeta()
406
a
407
sage: GF(9,'a').zeta(4)
408
a + 1
409
sage: GF(9,'a').zeta()^2
410
a + 1
411
"""
412
z = self.multiplicative_generator()
413
if n is None:
414
return z
415
else:
416
import sage.rings.integer
417
n = sage.rings.integer.Integer(n)
418
m = z.multiplicative_order()
419
if m % n != 0:
420
raise ValueError, "No %sth root of unity in self"%n
421
return z**(m.__floordiv__(n))
422
423
def multiplicative_generator(self):
424
"""
425
Return a primitive element of this finite field, i.e. a generator
426
of the multiplicative group.
427
428
You can use :meth:`multiplicative_generator()` or
429
:meth:`primitive_element()`, these mean the same thing.
430
431
.. WARNING::
432
433
This generator might change from one version of Sage to another.
434
435
EXAMPLES::
436
437
sage: k = GF(997)
438
sage: k.multiplicative_generator()
439
7
440
sage: k.<a> = GF(11^3)
441
sage: k.primitive_element()
442
a
443
sage: k.<b> = GF(19^32)
444
sage: k.multiplicative_generator()
445
b + 4
446
447
TESTS:
448
449
Check that large characteristics work (:trac:`11946`)::
450
451
sage: p = 10^20 + 39
452
sage: x = polygen(GF(p))
453
sage: K.<a> = GF(p^2, modulus=x^2+1)
454
sage: K.multiplicative_generator()
455
a + 12
456
"""
457
from sage.rings.arith import primitive_root
458
459
if self.__multiplicative_generator is not None:
460
return self.__multiplicative_generator
461
if self.degree() == 1:
462
self.__multiplicative_generator = self(primitive_root(self.order()))
463
return self.__multiplicative_generator
464
n = self.order() - 1
465
g = self.gen(0)
466
# We check whether x+g is a multiplicative generator, where
467
# x runs through the finite field.
468
# This has the advantage that g is the first element we try,
469
# so we always get g as generator if possible. Second, the
470
# PARI finite field iterator gives all the constant elements
471
# first, so we try g+(constant) before anything else.
472
for x in self:
473
a = g+x
474
if a != 0 and a.multiplicative_order() == n:
475
self.__multiplicative_generator = a
476
return a
477
478
primitive_element = multiplicative_generator
479
480
def ngens(self):
481
"""
482
The number of generators of the finite field. Always 1.
483
484
EXAMPLES::
485
486
sage: k = FiniteField(3^4, 'b')
487
sage: k.ngens()
488
1
489
"""
490
return 1
491
492
def is_field(self, proof = True):
493
"""
494
Returns whether or not the finite field is a field, i.e.,
495
always returns ``True``.
496
497
EXAMPLES::
498
499
sage: k.<a> = FiniteField(3^4)
500
sage: k.is_field()
501
True
502
"""
503
return True
504
505
def is_finite(self):
506
"""
507
Return ``True`` since a finite field is finite.
508
509
EXAMPLES::
510
511
sage: GF(997).is_finite()
512
True
513
"""
514
return True
515
516
def order(self):
517
"""
518
Return the order of this finite field.
519
520
EXAMPLES::
521
522
sage: GF(997).order()
523
997
524
"""
525
raise NotImplementedError
526
527
# cached because constructing the Factorization is slow;
528
# see :trac:`11628`.
529
@cached_method
530
def factored_order(self):
531
"""
532
Returns the factored order of this field. For compatibility with
533
:mod:`~sage.rings.finite_rings.integer_mod_ring`.
534
535
EXAMPLES::
536
537
sage: GF(7^2,'a').factored_order()
538
7^2
539
"""
540
from sage.structure.factorization import Factorization
541
return Factorization([(self.characteristic(), self.degree())])
542
543
def factored_unit_order(self):
544
"""
545
Returns the factorization of ``self.order()-1``, as a 1-element list.
546
547
The format is for compatibility with
548
:mod:`~sage.rings.finite_rings.integer_mod_ring`.
549
550
EXAMPLES::
551
552
sage: GF(7^2,'a').factored_unit_order()
553
[2^4 * 3]
554
"""
555
if self.__factored_unit_order is None:
556
self.__factored_unit_order = [(self.order()-1).factor()]
557
return self.__factored_unit_order
558
559
def cardinality(self):
560
"""
561
Return the cardinality of ``self``.
562
563
Same as :meth:`order`.
564
565
EXAMPLES::
566
567
sage: GF(997).cardinality()
568
997
569
"""
570
return self.order()
571
572
__len__ = cardinality
573
574
def is_prime_field(self):
575
"""
576
Return ``True`` if ``self`` is a prime field, i.e., has degree 1.
577
578
EXAMPLES::
579
580
sage: GF(3^7, 'a').is_prime_field()
581
False
582
sage: GF(3, 'a').is_prime_field()
583
True
584
"""
585
return self.degree()==1
586
587
def modulus(self):
588
r"""
589
Return the minimal polynomial of the generator of self (over an
590
appropriate base field).
591
592
The minimal polynomial of an element `a` in a field is the unique
593
irreducible polynomial of smallest degree with coefficients in the base
594
field that has `a` as a root. In finite field extensions, `\GF{p^n}`,
595
the base field is `\GF{p}`. Here are several examples::
596
597
sage: F.<a> = GF(7^2, 'a'); F
598
Finite Field in a of size 7^2
599
sage: F.polynomial_ring()
600
Univariate Polynomial Ring in a over Finite Field of size 7
601
sage: f = F.modulus(); f
602
x^2 + 6*x + 3
603
sage: f(a)
604
0
605
606
Although `f` is irreducible over the base field, we can double-check
607
whether or not `f` factors in `F` as follows. The command
608
``F[x](f)`` coerces `f` as a polynomial with coefficients in `F`.
609
(Instead of a polynomial with coefficients over the base field.)
610
611
::
612
613
sage: f.factor()
614
x^2 + 6*x + 3
615
sage: F[x](f).factor()
616
(x + a + 6) * (x + 6*a)
617
618
Here is an example with a degree 3 extension::
619
620
sage: G.<b> = GF(7^3, 'b'); G
621
Finite Field in b of size 7^3
622
sage: g = G.modulus(); g
623
x^3 + 6*x^2 + 4
624
sage: g.degree(); G.degree()
625
3
626
3
627
"""
628
return self.polynomial_ring("x")(self.polynomial().list())
629
630
def unit_group_exponent(self):
631
"""
632
The exponent of the unit group of the finite field. For a
633
finite field, this is always the order minus 1.
634
635
EXAMPLES::
636
637
sage: k = GF(2^10, 'a')
638
sage: k.order()
639
1024
640
sage: k.unit_group_exponent()
641
1023
642
"""
643
return self.order() - 1
644
645
646
def random_element(self, *args, **kwds):
647
r"""
648
A random element of the finite field. Passes arguments to
649
``random_element()`` function of underlying vector space.
650
651
EXAMPLES::
652
653
sage: k = GF(19^4, 'a')
654
sage: k.random_element()
655
a^3 + 3*a^2 + 6*a + 9
656
657
Passes extra positional or keyword arguments through::
658
659
sage: k.random_element(prob=0)
660
0
661
662
"""
663
if self.degree() == 1:
664
return self(randrange(self.order()))
665
v = self.vector_space().random_element(*args, **kwds)
666
return self(v)
667
668
def some_elements(self):
669
"""
670
Returns a collection of elements of this finite field for use in unit
671
testing.
672
673
EXAMPLES::
674
675
sage: k = GF(2^8,'a')
676
sage: k.some_elements() # random output
677
[a^4 + a^3 + 1, a^6 + a^4 + a^3, a^5 + a^4 + a, a^2 + a]
678
"""
679
return [self.random_element() for i in range(4)]
680
681
def polynomial(self):
682
"""
683
Return the defining polynomial of this finite field.
684
685
EXAMPLES::
686
687
sage: f = GF(27,'a').polynomial(); f
688
a^3 + 2*a + 1
689
sage: parent(f)
690
Univariate Polynomial Ring in a over Finite Field of size 3
691
"""
692
raise NotImplementedError
693
694
def polynomial_ring(self, variable_name=None):
695
"""
696
Returns the polynomial ring over the prime subfield in the
697
same variable as this finite field.
698
699
EXAMPLES::
700
701
sage: k.<alpha> = FiniteField(3^4)
702
sage: k.polynomial_ring()
703
Univariate Polynomial Ring in alpha over Finite Field of size 3
704
"""
705
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
706
from sage.rings.finite_rings.constructor import FiniteField as GF
707
708
if variable_name is None and self.__polynomial_ring is not None:
709
return self.__polynomial_ring
710
else:
711
if variable_name is None:
712
self.__polynomial_ring = PolynomialRing(GF(self.characteristic()), self.variable_name())
713
return self.__polynomial_ring
714
else:
715
return PolynomialRing(GF(self.characteristic()), variable_name)
716
717
def vector_space(self):
718
"""
719
Return the vector space over the prime subfield isomorphic
720
to this finite field as a vector space.
721
722
EXAMPLES::
723
724
sage: GF(27,'a').vector_space()
725
Vector space of dimension 3 over Finite Field of size 3
726
"""
727
if self.__vector_space is not None:
728
return self.__vector_space
729
else:
730
import sage.modules.all
731
V = sage.modules.all.VectorSpace(self.prime_subfield(),self.degree())
732
self.__vector_space = V
733
return V
734
735
def __hash__(self):
736
r"""
737
Return a hash of this finite field.
738
739
EXAMPLES::
740
741
sage: hash(GF(17))
742
-1709973406 # 32-bit
743
9088054599082082 # 64-bit
744
"""
745
return hash("GF") + hash(self.order())
746
747
cpdef _coerce_map_from_(self, R):
748
r"""
749
Canonical coercion to ``self``.
750
751
TESTS::
752
753
sage: k.<a> = GF(2^8)
754
sage: a + 1
755
a + 1
756
sage: a + int(1)
757
a + 1
758
sage: a + GF(2)(1)
759
a + 1
760
761
sage: k.<a> = GF(3^8)
762
sage: a + 1
763
a + 1
764
sage: a + int(1)
765
a + 1
766
sage: a + GF(3)(1)
767
a + 1
768
769
sage: k = GF(4, 'a')
770
sage: k._coerce_(GF(2)(1))
771
1
772
sage: k._coerce_(k.0)
773
a
774
sage: k._coerce_(3)
775
1
776
sage: k._coerce_(2/3)
777
Traceback (most recent call last):
778
...
779
TypeError: no canonical coercion from Rational Field to Finite Field in a of size 2^2
780
781
sage: FiniteField(16, 'a', conway=True, prefix='z')._coerce_(FiniteField(4, 'a', conway=True, prefix='z').0)
782
a^2 + a
783
784
sage: FiniteField(8, 'a')._coerce_(FiniteField(4, 'a').0)
785
Traceback (most recent call last):
786
...
787
TypeError: no canonical coercion from Finite Field in a of size 2^2 to Finite Field in a of size 2^3
788
789
sage: FiniteField(8, 'a')._coerce_(FiniteField(7, 'a')(2))
790
Traceback (most recent call last):
791
...
792
TypeError: no canonical coercion from Finite Field of size 7 to Finite Field in a of size 2^3
793
"""
794
from sage.rings.integer_ring import ZZ
795
from sage.rings.finite_rings.finite_field_base import is_FiniteField
796
from sage.rings.finite_rings.integer_mod_ring import is_IntegerModRing
797
if R is int or R is long or R is ZZ:
798
return True
799
if is_IntegerModRing(R) and self.characteristic().divides(R.characteristic()):
800
return True
801
if is_FiniteField(R):
802
if R is self:
803
return True
804
from sage.rings.residue_field import ResidueField_generic
805
if isinstance(R, ResidueField_generic):
806
return False
807
if R.characteristic() == self.characteristic():
808
if R.degree() == 1:
809
return True
810
if self.degree() % R.degree() == 0:
811
if hasattr(self, '_prefix') and hasattr(R, '_prefix'):
812
return R.hom((self.gen() ** ((self.order() - 1)//(R.order() - 1)),))
813
814
def construction(self):
815
"""
816
Return the construction of this finite field, as a ``ConstructionFunctor``
817
and the base field.
818
819
EXAMPLES::
820
821
sage: v = GF(3^3, conway=True, prefix='z').construction(); v
822
(AlgebraicExtensionFunctor, Finite Field of size 3)
823
sage: v[0].polys[0]
824
3
825
sage: v = GF(2^1000, 'a').construction(); v[0].polys[0]
826
a^1000 + a^5 + a^4 + a^3 + 1
827
"""
828
from sage.categories.pushout import AlgebraicExtensionFunctor
829
if self.degree() == 1:
830
# this is not of type FiniteField_prime_modn
831
from sage.rings.integer import Integer
832
return AlgebraicExtensionFunctor([self.polynomial()], [None], [None], conway=1), self.base_ring()
833
elif hasattr(self, '_prefix'):
834
return (AlgebraicExtensionFunctor([self.degree()], [self.variable_name()], [None],
835
conway=True, prefix=self._prefix),
836
self.base_ring())
837
else:
838
return (AlgebraicExtensionFunctor([self.polynomial()], [self.variable_name()], [None]),
839
self.base_ring())
840
841
def extension(self, modulus, name=None, names=None, map=False, embedding=None, **kwds):
842
"""
843
Return an extension of this finite field.
844
845
INPUT:
846
847
- ``modulus`` -- a polynomial with coefficients in ``self``,
848
or an integer.
849
850
- ``name`` -- string: the name of the generator in the new
851
extension
852
853
- ``map`` -- boolean (default: ``False``): if ``False``,
854
return just the extension `E`; if ``True``, return a pair
855
`(E, f)`, where `f` is an embedding of ``self`` into `E`.
856
857
- ``embedding`` -- currently not used; for compatibility with
858
other ``AlgebraicExtensionFunctor`` calls.
859
860
- ``**kwds``: further keywords, passed to the finite field
861
constructor.
862
863
OUTPUT:
864
865
An extension of the given modulus, or pseudo-Conway of the
866
given degree if ``modulus`` is an integer.
867
868
EXAMPLES::
869
870
sage: k = GF(2)
871
sage: R.<x> = k[]
872
sage: k.extension(x^1000 + x^5 + x^4 + x^3 + 1, 'a')
873
Finite Field in a of size 2^1000
874
sage: k = GF(3^4, conway=True, prefix='z')
875
sage: R.<x> = k[]
876
sage: k.extension(3, conway=True, prefix='z')
877
Finite Field in z12 of size 3^12
878
879
An example using the ``map`` argument::
880
881
sage: F = GF(5)
882
sage: E, f = F.extension(2, 'b', map=True)
883
sage: E
884
Finite Field in b of size 5^2
885
sage: f
886
Conversion map:
887
From: Finite Field of size 5
888
To: Finite Field in b of size 5^2
889
sage: f.parent()
890
Set of field embeddings from Finite Field of size 5 to Finite Field in b of size 5^2
891
892
Extensions of non-prime finite fields by polynomials are not yet
893
supported: we fall back to generic code::
894
895
sage: k.extension(x^5 + x^2 + x - 1)
896
Univariate Quotient Polynomial Ring in x over Finite Field in z4 of size 3^4 with modulus x^5 + x^2 + x + 2
897
"""
898
from constructor import GF
899
from sage.rings.polynomial.all import is_Polynomial
900
from sage.rings.integer import Integer
901
if name is None and names is not None:
902
name = names
903
if self.degree() == 1:
904
if isinstance(modulus, Integer):
905
E = GF(self.characteristic()**modulus, name=name, **kwds)
906
elif isinstance(modulus, (list, tuple)):
907
E = GF(self.characteristic()**(len(modulus) - 1), name=name, modulus=modulus, **kwds)
908
elif is_Polynomial(modulus):
909
if modulus.change_ring(self).is_irreducible():
910
E = GF(self.characteristic()**(modulus.degree()), name=name, modulus=modulus, **kwds)
911
else:
912
E = Field.extension(self, modulus, name=name, embedding=embedding)
913
elif isinstance(modulus, Integer):
914
E = GF(self.order()**modulus, name=name, **kwds)
915
else:
916
E = Field.extension(self, modulus, name=name, embedding=embedding)
917
if not map:
918
return E
919
# Use the canonical map if it exists.
920
f = E.coerce_map_from(self)
921
if f is None:
922
from sage.categories.homset import Hom
923
f = Hom(self, E).an_element()
924
return (E, f)
925
926
def subfields(self, degree=0, name=None):
927
"""
928
Return all subfields of ``self`` of the given ``degree``,
929
or all possible degrees if ``degree`` is `0`.
930
931
The subfields are returned as absolute fields together with
932
an embedding into ``self``.
933
934
INPUT:
935
936
- ``degree`` -- (default: `0`) an integer
937
938
- ``name`` -- a string, a dictionary or ``None``:
939
940
- If ``degree`` is nonzero, then ``name`` must be a string
941
(or ``None``, if this is a pseudo-Conway extension),
942
and will be the variable name of the returned field.
943
- If ``degree`` is zero, the dictionary should have keys the divisors
944
of the degree of this field, with the desired variable name for the
945
field of that degree as an entry.
946
- As a shortcut, you can provide a string and the degree of each
947
subfield will be appended for the variable name of that subfield.
948
- If ``None``, uses the prefix of this field.
949
950
OUTPUT:
951
952
A list of pairs ``(K, e)``, where ``K`` ranges over the subfields of
953
this field and ``e`` gives an embedding of ``K`` into ``self``.
954
955
EXAMPLES::
956
957
sage: k.<a> = GF(2^21, conway=True, prefix='z')
958
sage: k.subfields()
959
[(Finite Field of size 2,
960
Conversion map:
961
From: Finite Field of size 2
962
To: Finite Field in a of size 2^21),
963
(Finite Field in z3 of size 2^3,
964
Ring morphism:
965
From: Finite Field in z3 of size 2^3
966
To: Finite Field in a of size 2^21
967
Defn: z3 |--> a^20 + a^19 + a^17 + a^15 + a^11 + a^9 + a^8 + a^6 + a^2),
968
(Finite Field in z7 of size 2^7,
969
Ring morphism:
970
From: Finite Field in z7 of size 2^7
971
To: Finite Field in a of size 2^21
972
Defn: z7 |--> a^20 + a^19 + a^17 + a^15 + a^14 + a^6 + a^4 + a^3 + a),
973
(Finite Field in z21 of size 2^21,
974
Ring morphism:
975
From: Finite Field in z21 of size 2^21
976
To: Finite Field in a of size 2^21
977
Defn: z21 |--> a)]
978
"""
979
from sage.rings.integer import Integer
980
from constructor import GF
981
p = self.characteristic()
982
n = self.degree()
983
if degree != 0:
984
degree = Integer(degree)
985
if not degree.divides(n):
986
return []
987
elif hasattr(self, '_prefix'):
988
K = GF(p**degree, name=name, conway=True, prefix=self._prefix)
989
return [(K, self.coerce_map_from(K))]
990
elif degree == 1:
991
K = GF(p)
992
return [(K, self.coerce_map_from(K))]
993
else:
994
gen = self.gen()**((self.order() - 1)//(p**degree - 1))
995
K = GF(p**degree, modulus=gen.minimal_polynomial(), name=name)
996
return [(K, K.hom((gen,)))]
997
else:
998
divisors = n.divisors()
999
if name is None:
1000
if hasattr(self, '_prefix'):
1001
name = self._prefix
1002
else:
1003
name = self.variable_name()
1004
if isinstance(name, str):
1005
name = {m: name + str(m) for m in divisors}
1006
elif not isinstance(name, dict):
1007
raise ValueError, "name must be None, a string or a dictionary indexed by divisors of the degree"
1008
return [self.subfields(m, name=name[m])[0] for m in divisors]
1009
1010
def algebraic_closure(self):
1011
"""
1012
Return the algebraic closure of ``self`` (not implemented).
1013
1014
.. NOTE::
1015
1016
This is not yet implemented for finite fields.
1017
1018
EXAMPLES::
1019
1020
sage: GF(5).algebraic_closure()
1021
Traceback (most recent call last):
1022
...
1023
NotImplementedError: Algebraic closures of finite fields not implemented.
1024
"""
1025
raise NotImplementedError, "Algebraic closures of finite fields not implemented."
1026
1027
@cached_method
1028
def is_conway(self):
1029
"""
1030
Return ``True`` if self is defined by a Conway polynomial.
1031
1032
EXAMPLES:
1033
1034
sage: GF(5^3, 'a').is_conway()
1035
True
1036
sage: GF(5^3, 'a', modulus='adleman-lenstra').is_conway()
1037
False
1038
sage: GF(next_prime(2^16, 2), 'a').is_conway()
1039
False
1040
"""
1041
from conway_polynomials import conway_polynomial, exists_conway_polynomial
1042
p = self.characteristic()
1043
n = self.degree()
1044
return (exists_conway_polynomial(p, n)
1045
and self.polynomial() == self.polynomial_ring()(conway_polynomial(p, n)))
1046
1047
def frobenius_endomorphism(self, n=1):
1048
"""
1049
INPUT:
1050
1051
- ``n`` -- an integer (default: 1)
1052
1053
OUTPUT:
1054
1055
The `n`-th power of the absolute arithmetic Frobenius
1056
endomorphism on this finite field.
1057
1058
EXAMPLES::
1059
1060
sage: k.<t> = GF(3^5)
1061
sage: Frob = k.frobenius_endomorphism(); Frob
1062
Frobenius endomorphism t |--> t^3 on Finite Field in t of size 3^5
1063
1064
sage: a = k.random_element()
1065
sage: Frob(a) == a^3
1066
True
1067
1068
We can specify a power::
1069
1070
sage: k.frobenius_endomorphism(2)
1071
Frobenius endomorphism t |--> t^(3^2) on Finite Field in t of size 3^5
1072
1073
The result is simplified if possible::
1074
1075
sage: k.frobenius_endomorphism(6)
1076
Frobenius endomorphism t |--> t^3 on Finite Field in t of size 3^5
1077
sage: k.frobenius_endomorphism(5)
1078
Identity endomorphism of Finite Field in t of size 3^5
1079
1080
Comparisons work::
1081
1082
sage: k.frobenius_endomorphism(6) == Frob
1083
True
1084
sage: from sage.categories.morphism import IdentityMorphism
1085
sage: k.frobenius_endomorphism(5) == IdentityMorphism(k)
1086
True
1087
1088
AUTHOR:
1089
1090
- Xavier Caruso (2012-06-29)
1091
"""
1092
from sage.rings.finite_rings.hom_finite_field import FrobeniusEndomorphism_finite_field
1093
return FrobeniusEndomorphism_finite_field(self, n)
1094
1095
1096
def unpickle_FiniteField_ext(_type, order, variable_name, modulus, kwargs):
1097
r"""
1098
Used to unpickle extensions of finite fields. Now superseded (hence no
1099
doctest), but kept around for backward compatibility.
1100
1101
EXAMPLES::
1102
1103
sage: # not tested
1104
"""
1105
return _type(order, variable_name, modulus, **kwargs)
1106
1107
def unpickle_FiniteField_prm(_type, order, variable_name, kwargs):
1108
r"""
1109
Used to unpickle finite prime fields. Now superseded (hence no doctest),
1110
but kept around for backward compatibility.
1111
1112
EXAMPLE::
1113
1114
sage: # not tested
1115
"""
1116
return _type(order, variable_name, **kwargs)
1117
1118
1119
def is_FiniteField(x):
1120
"""
1121
Return ``True`` if ``x`` is of type finite field, and ``False`` otherwise.
1122
1123
EXAMPLES::
1124
1125
sage: from sage.rings.finite_rings.finite_field_base import is_FiniteField
1126
sage: is_FiniteField(GF(9,'a'))
1127
True
1128
sage: is_FiniteField(GF(next_prime(10^10)))
1129
True
1130
1131
Note that the integers modulo n are not of type finite field,
1132
so this function returns ``False``::
1133
1134
sage: is_FiniteField(Integers(7))
1135
False
1136
"""
1137
return IS_INSTANCE(x, FiniteField)
1138
1139