Algebraic closures of finite fields¶
Let \(\Bold{F}\) be a finite field, and let \(\overline{\Bold{F}}\) be an algebraic closure of \(\Bold{F}\); this is unique up to (non-canonical) isomorphism. For every \(n\ge 1\), there is a unique subfield \(\Bold{F}_n\) of \(\overline{\Bold{F}}\) such that \(\Bold{F}\subset\Bold{F}_n\) and \([\Bold{F}_n:\Bold{F}]=n\).
In Sage, algebraic closures of finite fields are implemented using compatible systems of finite fields. The resulting Sage object keeps track of a finite lattice of the subfields \(\Bold{F}_n\) and the embeddings between them. This lattice is extended as necessary.
The Sage class corresponding to \(\overline{\Bold{F}}\) can be
constructed from the finite field \(\Bold{F}\) by using the
algebraic_closure()
method.
The Sage class for elements of \(\overline{\Bold{F}}\) is
AlgebraicClosureFiniteFieldElement.  Such an element is
represented as an element of one of the \(\Bold{F}_n\).  This means that
each element \(x\in\Bold{F}\) has infinitely many different
representations, one for each \(n\) such that \(x\) is in \(\Bold{F}_n\).
Note
Only prime finite fields are currently accepted as base fields for algebraic closures. To obtain an algebraic closure of a non-prime finite field \(\Bold{F}\), take an algebraic closure of the prime field of \(\Bold{F}\) and embed \(\Bold{F}\) into this.
Algebraic closures of finite fields are currently implemented
using (pseudo-)Conway polynomials; see
AlgebraicClosureFiniteField_pseudo_conway and the module
conway_polynomials.  Other
implementations may be added by creating appropriate subclasses of
AlgebraicClosureFiniteField_generic.
In the current implementation, algebraic closures do not satisfy the unique parent condition. Moreover, there is no coercion map between different algebraic closures of the same finite field. There is a conceptual reason for this, namely that the definition of pseudo-Conway polynomials only determines an algebraic closure up to non-unique isomorphism. This means in particular that different algebraic closures, and their respective elements, never compare equal.
AUTHORS:
- Peter Bruin (August 2013): initial version 
- Vincent Delecroix (November 2013): additional methods 
- sage.rings.algebraic_closure_finite_field.AlgebraicClosureFiniteField(base_ring, name, category=None, implementation=None, **kwds)[source]¶
- Construct an algebraic closure of a finite field. - The recommended way to use this functionality is by calling the - algebraic_closure()method of the finite field.- Note - Algebraic closures of finite fields in Sage do not have the unique representation property, because they are not determined up to unique isomorphism by their defining data. - EXAMPLES: - sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField sage: F = GF(2).algebraic_closure() sage: F1 = AlgebraicClosureFiniteField(GF(2), 'z') sage: F1 is F False - >>> from sage.all import * >>> from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField >>> F = GF(Integer(2)).algebraic_closure() >>> F1 = AlgebraicClosureFiniteField(GF(Integer(2)), 'z') >>> F1 is F False - In the pseudo-Conway implementation, non-identical instances never compare equal: - sage: F1 == F False sage: loads(dumps(F)) == F False - >>> from sage.all import * >>> F1 == F False >>> loads(dumps(F)) == F False - This is to ensure that the result of comparing two instances cannot change with time. 
- class sage.rings.algebraic_closure_finite_field.AlgebraicClosureFiniteFieldElement(parent, value)[source]¶
- Bases: - FieldElement- Element of an algebraic closure of a finite field. - EXAMPLES: - sage: F = GF(3).algebraic_closure() sage: F.gen(2) z2 sage: type(F.gen(2)) <class 'sage.rings.algebraic_closure_finite_field.AlgebraicClosureFiniteField_pseudo_conway_with_category.element_class'> - >>> from sage.all import * >>> F = GF(Integer(3)).algebraic_closure() >>> F.gen(Integer(2)) z2 >>> type(F.gen(Integer(2))) <class 'sage.rings.algebraic_closure_finite_field.AlgebraicClosureFiniteField_pseudo_conway_with_category.element_class'> - as_finite_field_element(minimal=False)[source]¶
- Return - selfas a finite field element.- INPUT: - minimal– boolean (default:- False); if- True, always return the smallest subfield containing- self
 - OUTPUT: - a triple ( - field,- element,- morphism) where- fieldis a finite field,- elementan element of- fieldand- morphisma morphism from- fieldto- self.parent().
 - EXAMPLES: - sage: F = GF(3).algebraic_closure('t') sage: t = F.gen(5) sage: t.as_finite_field_element() (Finite Field in t5 of size 3^5, t5, Ring morphism: From: Finite Field in t5 of size 3^5 To: Algebraic closure of Finite Field of size 3 Defn: t5 |--> t5) - >>> from sage.all import * >>> F = GF(Integer(3)).algebraic_closure('t') >>> t = F.gen(Integer(5)) >>> t.as_finite_field_element() (Finite Field in t5 of size 3^5, t5, Ring morphism: From: Finite Field in t5 of size 3^5 To: Algebraic closure of Finite Field of size 3 Defn: t5 |--> t5) - By default, - fieldis not necessarily minimal. We can force it to be minimal using the- minimaloption:- sage: s = t + 1 - t sage: s.as_finite_field_element()[0] Finite Field in t5 of size 3^5 sage: s.as_finite_field_element(minimal=True)[0] Finite Field of size 3 - >>> from sage.all import * >>> s = t + Integer(1) - t >>> s.as_finite_field_element()[Integer(0)] Finite Field in t5 of size 3^5 >>> s.as_finite_field_element(minimal=True)[Integer(0)] Finite Field of size 3 - This also works when the element has to be converted between two non-trivial finite subfields (see Issue #16509): - sage: K = GF(5).algebraic_closure() sage: z = K.gen(5) - K.gen(5) + K.gen(2) sage: z.as_finite_field_element(minimal=True) (Finite Field in z2 of size 5^2, z2, Ring morphism: From: Finite Field in z2 of size 5^2 To: Algebraic closure of Finite Field of size 5 Defn: z2 |--> z2) - >>> from sage.all import * >>> K = GF(Integer(5)).algebraic_closure() >>> z = K.gen(Integer(5)) - K.gen(Integer(5)) + K.gen(Integer(2)) >>> z.as_finite_field_element(minimal=True) (Finite Field in z2 of size 5^2, z2, Ring morphism: From: Finite Field in z2 of size 5^2 To: Algebraic closure of Finite Field of size 5 Defn: z2 |--> z2) - There are automatic coercions between the various subfields: - sage: a = K.gen(2) + 1 sage: _,b,_ = a.as_finite_field_element() sage: K4 = K.subfield(4)[0] sage: K4(b) z4^3 + z4^2 + z4 + 4 sage: b.minimal_polynomial() == K4(b).minimal_polynomial() True sage: K(K4(b)) == K(b) True - >>> from sage.all import * >>> a = K.gen(Integer(2)) + Integer(1) >>> _,b,_ = a.as_finite_field_element() >>> K4 = K.subfield(Integer(4))[Integer(0)] >>> K4(b) z4^3 + z4^2 + z4 + 4 >>> b.minimal_polynomial() == K4(b).minimal_polynomial() True >>> K(K4(b)) == K(b) True - You can also use the inclusions that are implemented at the level of the algebraic closure: - sage: f = K.inclusion(2,4); f Ring morphism: From: Finite Field in z2 of size 5^2 To: Finite Field in z4 of size 5^4 Defn: z2 |--> z4^3 + z4^2 + z4 + 3 sage: f(b) z4^3 + z4^2 + z4 + 4 - >>> from sage.all import * >>> f = K.inclusion(Integer(2),Integer(4)); f Ring morphism: From: Finite Field in z2 of size 5^2 To: Finite Field in z4 of size 5^4 Defn: z2 |--> z4^3 + z4^2 + z4 + 3 >>> f(b) z4^3 + z4^2 + z4 + 4 
 - change_level(n)[source]¶
- Return a representation of - selfas an element of the subfield of degree \(n\) of the parent, if possible.- EXAMPLES: - sage: F = GF(3).algebraic_closure() sage: z = F.gen(4) sage: (z^10).change_level(6) 2*z6^5 + 2*z6^3 + z6^2 + 2*z6 + 2 sage: z.change_level(6) Traceback (most recent call last): ... ValueError: z4 is not in the image of Ring morphism: From: Finite Field in z2 of size 3^2 To: Finite Field in z4 of size 3^4 Defn: z2 |--> 2*z4^3 + 2*z4^2 + 1 sage: a = F(1).change_level(3); a 1 sage: a.change_level(2) 1 sage: F.gen(3).change_level(1) Traceback (most recent call last): ... ValueError: z3 is not in the image of Ring morphism: From: Finite Field of size 3 To: Finite Field in z3 of size 3^3 Defn: 1 |--> 1 - >>> from sage.all import * >>> F = GF(Integer(3)).algebraic_closure() >>> z = F.gen(Integer(4)) >>> (z**Integer(10)).change_level(Integer(6)) 2*z6^5 + 2*z6^3 + z6^2 + 2*z6 + 2 >>> z.change_level(Integer(6)) Traceback (most recent call last): ... ValueError: z4 is not in the image of Ring morphism: From: Finite Field in z2 of size 3^2 To: Finite Field in z4 of size 3^4 Defn: z2 |--> 2*z4^3 + 2*z4^2 + 1 >>> a = F(Integer(1)).change_level(Integer(3)); a 1 >>> a.change_level(Integer(2)) 1 >>> F.gen(Integer(3)).change_level(Integer(1)) Traceback (most recent call last): ... ValueError: z3 is not in the image of Ring morphism: From: Finite Field of size 3 To: Finite Field in z3 of size 3^3 Defn: 1 |--> 1 
 - is_square()[source]¶
- Return - Trueif- selfis a square.- This always returns - True.- EXAMPLES: - sage: F = GF(3).algebraic_closure() sage: F.gen(2).is_square() True - >>> from sage.all import * >>> F = GF(Integer(3)).algebraic_closure() >>> F.gen(Integer(2)).is_square() True 
 - minimal_polynomial()[source]¶
- Return the minimal polynomial of - selfover the prime field.- EXAMPLES: - sage: F = GF(11).algebraic_closure() sage: F.gen(3).minpoly() x^3 + 2*x + 9 - >>> from sage.all import * >>> F = GF(Integer(11)).algebraic_closure() >>> F.gen(Integer(3)).minpoly() x^3 + 2*x + 9 
 - minpoly()[source]¶
- Return the minimal polynomial of - selfover the prime field.- EXAMPLES: - sage: F = GF(11).algebraic_closure() sage: F.gen(3).minpoly() x^3 + 2*x + 9 - >>> from sage.all import * >>> F = GF(Integer(11)).algebraic_closure() >>> F.gen(Integer(3)).minpoly() x^3 + 2*x + 9 
 - multiplicative_order()[source]¶
- Return the multiplicative order of - self.- EXAMPLES: - sage: K = GF(7).algebraic_closure() sage: K.gen(5).multiplicative_order() 16806 sage: (K.gen(1) + K.gen(2) + K.gen(3)).multiplicative_order() 7353 - >>> from sage.all import * >>> K = GF(Integer(7)).algebraic_closure() >>> K.gen(Integer(5)).multiplicative_order() 16806 >>> (K.gen(Integer(1)) + K.gen(Integer(2)) + K.gen(Integer(3))).multiplicative_order() 7353 
 - nth_root(n)[source]¶
- Return an \(n\)-th root of - self.- EXAMPLES: - sage: F = GF(5).algebraic_closure() sage: t = F.gen(2) + 1 sage: s = t.nth_root(15); s 4*z6^5 + 3*z6^4 + 2*z6^3 + 2*z6^2 + 4 sage: s**15 == t True - >>> from sage.all import * >>> F = GF(Integer(5)).algebraic_closure() >>> t = F.gen(Integer(2)) + Integer(1) >>> s = t.nth_root(Integer(15)); s 4*z6^5 + 3*z6^4 + 2*z6^3 + 2*z6^2 + 4 >>> s**Integer(15) == t True - Todo - This function could probably be made faster. 
 - pth_power(k=1)[source]¶
- Return the \(p^k\)-th power of - self, where \(p\) is the characteristic of- self.parent().- EXAMPLES: - sage: K = GF(13).algebraic_closure('t') sage: t3 = K.gen(3) sage: s = 1 + t3 + t3**2 sage: s.pth_power() 10*t3^2 + 6*t3 sage: s.pth_power(2) 2*t3^2 + 6*t3 + 11 sage: s.pth_power(3) t3^2 + t3 + 1 sage: s.pth_power(3).parent() is K True - >>> from sage.all import * >>> K = GF(Integer(13)).algebraic_closure('t') >>> t3 = K.gen(Integer(3)) >>> s = Integer(1) + t3 + t3**Integer(2) >>> s.pth_power() 10*t3^2 + 6*t3 >>> s.pth_power(Integer(2)) 2*t3^2 + 6*t3 + 11 >>> s.pth_power(Integer(3)) t3^2 + t3 + 1 >>> s.pth_power(Integer(3)).parent() is K True 
 - pth_root(k=1)[source]¶
- Return the unique \(p^k\)-th root of - self, where \(p\) is the characteristic of- self.parent().- EXAMPLES: - sage: K = GF(13).algebraic_closure('t') sage: t3 = K.gen(3) sage: s = 1 + t3 + t3**2 sage: s.pth_root() 2*t3^2 + 6*t3 + 11 sage: s.pth_root(2) 10*t3^2 + 6*t3 sage: s.pth_root(3) t3^2 + t3 + 1 sage: s.pth_root(2).parent() is K True - >>> from sage.all import * >>> K = GF(Integer(13)).algebraic_closure('t') >>> t3 = K.gen(Integer(3)) >>> s = Integer(1) + t3 + t3**Integer(2) >>> s.pth_root() 2*t3^2 + 6*t3 + 11 >>> s.pth_root(Integer(2)) 10*t3^2 + 6*t3 >>> s.pth_root(Integer(3)) t3^2 + t3 + 1 >>> s.pth_root(Integer(2)).parent() is K True 
 - sqrt(all=False)[source]¶
- Return a square root of - self.- If the optional keyword argument - allis set to- True, return a list of all square roots of- selfinstead.- EXAMPLES: - sage: F = GF(3).algebraic_closure() sage: F.gen(2).sqrt() z4^3 + z4 + 1 sage: F.gen(2).sqrt(all=True) [z4^3 + z4 + 1, 2*z4^3 + 2*z4 + 2] sage: (F.gen(2)^2).sqrt() z2 sage: (F.gen(2)^2).sqrt(all=True) [z2, 2*z2] - >>> from sage.all import * >>> F = GF(Integer(3)).algebraic_closure() >>> F.gen(Integer(2)).sqrt() z4^3 + z4 + 1 >>> F.gen(Integer(2)).sqrt(all=True) [z4^3 + z4 + 1, 2*z4^3 + 2*z4 + 2] >>> (F.gen(Integer(2))**Integer(2)).sqrt() z2 >>> (F.gen(Integer(2))**Integer(2)).sqrt(all=True) [z2, 2*z2] 
 
- class sage.rings.algebraic_closure_finite_field.AlgebraicClosureFiniteField_generic(base_ring, name, category=None)[source]¶
- Bases: - Field- Algebraic closure of a finite field. - Element[source]¶
- alias of - AlgebraicClosureFiniteFieldElement
 - algebraic_closure()[source]¶
- Return an algebraic closure of - self.- This always returns - self.- EXAMPLES: - sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField sage: F = AlgebraicClosureFiniteField(GF(5), 'z') sage: F.algebraic_closure() is F True - >>> from sage.all import * >>> from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField >>> F = AlgebraicClosureFiniteField(GF(Integer(5)), 'z') >>> F.algebraic_closure() is F True 
 - characteristic()[source]¶
- Return the characteristic of - self.- EXAMPLES: - sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField sage: p = next_prime(1000) sage: F = AlgebraicClosureFiniteField(GF(p), 'z') sage: F.characteristic() == p True - >>> from sage.all import * >>> from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField >>> p = next_prime(Integer(1000)) >>> F = AlgebraicClosureFiniteField(GF(p), 'z') >>> F.characteristic() == p True 
 - gen(n)[source]¶
- Return the \(n\)-th generator of - self.- EXAMPLES: - sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField sage: F = AlgebraicClosureFiniteField(GF(5), 'z') sage: F.gen(2) z2 - >>> from sage.all import * >>> from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField >>> F = AlgebraicClosureFiniteField(GF(Integer(5)), 'z') >>> F.gen(Integer(2)) z2 
 - gens()[source]¶
- Return a family of generators of - self.- OUTPUT: - a - Family, indexed by the positive integers, whose \(n\)-th element is- self.gen(n).
 - EXAMPLES: - sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField sage: F = AlgebraicClosureFiniteField(GF(5), 'z') sage: g = F.gens(); g Lazy family (...(i))_{i in Positive integers} sage: g[3] z3 - >>> from sage.all import * >>> from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField >>> F = AlgebraicClosureFiniteField(GF(Integer(5)), 'z') >>> g = F.gens(); g Lazy family (...(i))_{i in Positive integers} >>> g[Integer(3)] z3 
 - inclusion(m, n)[source]¶
- Return the canonical inclusion map from the subfield of degree \(m\) to the subfield of degree \(n\). - EXAMPLES: - sage: F = GF(3).algebraic_closure() sage: F.inclusion(1, 2) Ring morphism: From: Finite Field of size 3 To: Finite Field in z2 of size 3^2 Defn: 1 |--> 1 sage: F.inclusion(2, 4) Ring morphism: From: Finite Field in z2 of size 3^2 To: Finite Field in z4 of size 3^4 Defn: z2 |--> 2*z4^3 + 2*z4^2 + 1 - >>> from sage.all import * >>> F = GF(Integer(3)).algebraic_closure() >>> F.inclusion(Integer(1), Integer(2)) Ring morphism: From: Finite Field of size 3 To: Finite Field in z2 of size 3^2 Defn: 1 |--> 1 >>> F.inclusion(Integer(2), Integer(4)) Ring morphism: From: Finite Field in z2 of size 3^2 To: Finite Field in z4 of size 3^4 Defn: z2 |--> 2*z4^3 + 2*z4^2 + 1 
 - ngens()[source]¶
- Return the number of generators of - self, which is infinity.- EXAMPLES: - sage: from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField sage: AlgebraicClosureFiniteField(GF(5), 'z').ngens() +Infinity - >>> from sage.all import * >>> from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField >>> AlgebraicClosureFiniteField(GF(Integer(5)), 'z').ngens() +Infinity 
 - some_elements()[source]¶
- Return some elements of this field. - EXAMPLES: - sage: F = GF(7).algebraic_closure() sage: F.some_elements() (1, z2, z3 + 1) - >>> from sage.all import * >>> F = GF(Integer(7)).algebraic_closure() >>> F.some_elements() (1, z2, z3 + 1) 
 - subfield(n)[source]¶
- Return the unique subfield of degree \(n\) of - selftogether with its canonical embedding into- self.- EXAMPLES: - sage: F = GF(3).algebraic_closure() sage: F.subfield(1) (Finite Field of size 3, Ring morphism: From: Finite Field of size 3 To: Algebraic closure of Finite Field of size 3 Defn: 1 |--> 1) sage: F.subfield(4) (Finite Field in z4 of size 3^4, Ring morphism: From: Finite Field in z4 of size 3^4 To: Algebraic closure of Finite Field of size 3 Defn: z4 |--> z4) - >>> from sage.all import * >>> F = GF(Integer(3)).algebraic_closure() >>> F.subfield(Integer(1)) (Finite Field of size 3, Ring morphism: From: Finite Field of size 3 To: Algebraic closure of Finite Field of size 3 Defn: 1 |--> 1) >>> F.subfield(Integer(4)) (Finite Field in z4 of size 3^4, Ring morphism: From: Finite Field in z4 of size 3^4 To: Algebraic closure of Finite Field of size 3 Defn: z4 |--> z4) 
 
- class sage.rings.algebraic_closure_finite_field.AlgebraicClosureFiniteField_pseudo_conway(base_ring, name, category=None, lattice=None, use_database=True)[source]¶
- Bases: - WithEqualityById,- AlgebraicClosureFiniteField_generic- Algebraic closure of a finite field, constructed using pseudo-Conway polynomials. - EXAMPLES: - sage: F = GF(5).algebraic_closure(implementation='pseudo_conway') sage: F.cardinality() +Infinity sage: F.algebraic_closure() is F True sage: x = F(3).nth_root(12); x z4^3 + z4^2 + 4*z4 sage: x**12 3 - >>> from sage.all import * >>> F = GF(Integer(5)).algebraic_closure(implementation='pseudo_conway') >>> F.cardinality() +Infinity >>> F.algebraic_closure() is F True >>> x = F(Integer(3)).nth_root(Integer(12)); x z4^3 + z4^2 + 4*z4 >>> x**Integer(12) 3