Extension of rings¶
Sage offers the possibility to work with ring extensions \(L/K\) as actual parents and perform meaningful operations on them and their elements.
The simplest way to build an extension is to use the method
sage.categories.commutative_rings.CommutativeRings.ParentMethods.over() on the top ring,
that is \(L\).
For example, the following line constructs the extension of
finite fields \(\mathbf{F}_{5^4}/\mathbf{F}_{5^2}\):
sage: GF(5^4).over(GF(5^2))                                                         # needs sage.rings.finite_rings
Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
>>> from sage.all import *
>>> GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2)))                                                         # needs sage.rings.finite_rings
Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
By default, Sage reuses the canonical generator of the top ring (here \(z_4 \in \mathbf{F}_{5^4}\)), together with its name. However, the user can customize them by passing in appropriate arguments:
sage: # needs sage.rings.finite_rings
sage: F = GF(5^2)
sage: k = GF(5^4)
sage: z4 = k.gen()
sage: K.<a> = k.over(F, gen=1-z4); K
Field in a with defining polynomial x^2 + z2*x + 4 over its base
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> F = GF(Integer(5)**Integer(2))
>>> k = GF(Integer(5)**Integer(4))
>>> z4 = k.gen()
>>> K = k.over(F, gen=Integer(1)-z4, names=('a',)); (a,) = K._first_ngens(1); K
Field in a with defining polynomial x^2 + z2*x + 4 over its base
The base of the extension is available via the method base() (or
equivalently base_ring()):
sage: K.base()                                                                      # needs sage.rings.finite_rings
Finite Field in z2 of size 5^2
>>> from sage.all import *
>>> K.base()                                                                      # needs sage.rings.finite_rings
Finite Field in z2 of size 5^2
It is also possible to build an extension on top of another extension, obtaining this way a tower of extensions:
sage: L.<b> = GF(5^8).over(K); L                                                    # needs sage.rings.finite_rings
Field in b with defining polynomial x^2 + (4*z2 + 3*a)*x + 1 - a over its base
sage: L.base()                                                                      # needs sage.rings.finite_rings
Field in a with defining polynomial x^2 + z2*x + 4 over its base
sage: L.base().base()                                                               # needs sage.rings.finite_rings
Finite Field in z2 of size 5^2
>>> from sage.all import *
>>> L = GF(Integer(5)**Integer(8)).over(K, names=('b',)); (b,) = L._first_ngens(1); L                                                    # needs sage.rings.finite_rings
Field in b with defining polynomial x^2 + (4*z2 + 3*a)*x + 1 - a over its base
>>> L.base()                                                                      # needs sage.rings.finite_rings
Field in a with defining polynomial x^2 + z2*x + 4 over its base
>>> L.base().base()                                                               # needs sage.rings.finite_rings
Finite Field in z2 of size 5^2
The method bases() gives access to the complete list of rings in
a tower:
sage: L.bases()                                                                     # needs sage.rings.finite_rings
[Field in b with defining polynomial x^2 + (4*z2 + 3*a)*x + 1 - a over its base,
 Field in a with defining polynomial x^2 + z2*x + 4 over its base,
 Finite Field in z2 of size 5^2]
>>> from sage.all import *
>>> L.bases()                                                                     # needs sage.rings.finite_rings
[Field in b with defining polynomial x^2 + (4*z2 + 3*a)*x + 1 - a over its base,
 Field in a with defining polynomial x^2 + z2*x + 4 over its base,
 Finite Field in z2 of size 5^2]
Once we have constructed an extension (or a tower of extensions), we have interesting methods attached to it. As a basic example, one can compute a basis of the top ring over any base in the tower:
sage: L.basis_over(K)                                                               # needs sage.rings.finite_rings
[1, b]
sage: L.basis_over(F)                                                               # needs sage.rings.finite_rings
[1, a, b, a*b]
>>> from sage.all import *
>>> L.basis_over(K)                                                               # needs sage.rings.finite_rings
[1, b]
>>> L.basis_over(F)                                                               # needs sage.rings.finite_rings
[1, a, b, a*b]
When the base is omitted, the default is the natural base of the extension:
sage: L.basis_over()                                                                # needs sage.rings.finite_rings
[1, b]
>>> from sage.all import *
>>> L.basis_over()                                                                # needs sage.rings.finite_rings
[1, b]
The method sage.rings.ring_extension_element.RingExtensionWithBasis.vector()
computes the coordinates of an element according to the above basis:
sage: u = a + 2*b + 3*a*b                                                           # needs sage.rings.finite_rings
sage: u.vector()   # over K                                                         # needs sage.rings.finite_rings
(a, 2 + 3*a)
sage: u.vector(F)                                                                   # needs sage.rings.finite_rings
(0, 1, 2, 3)
>>> from sage.all import *
>>> u = a + Integer(2)*b + Integer(3)*a*b                                                           # needs sage.rings.finite_rings
>>> u.vector()   # over K                                                         # needs sage.rings.finite_rings
(a, 2 + 3*a)
>>> u.vector(F)                                                                   # needs sage.rings.finite_rings
(0, 1, 2, 3)
One can also compute traces and norms with respect to any base of the tower:
sage: # needs sage.rings.finite_rings
sage: u.trace()           # over K
(2*z2 + 1) + (2*z2 + 1)*a
sage: u.trace(F)
z2 + 1
sage: u.trace().trace()   # over K, then over F
z2 + 1
sage: u.norm()            # over K
(z2 + 1) + (4*z2 + 2)*a
sage: u.norm(F)
2*z2 + 2
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> u.trace()           # over K
(2*z2 + 1) + (2*z2 + 1)*a
>>> u.trace(F)
z2 + 1
>>> u.trace().trace()   # over K, then over F
z2 + 1
>>> u.norm()            # over K
(z2 + 1) + (4*z2 + 2)*a
>>> u.norm(F)
2*z2 + 2
And minimal polynomials:
sage: u.minpoly()                                                                   # needs sage.rings.finite_rings
x^2 + ((3*z2 + 4) + (3*z2 + 4)*a)*x + (z2 + 1) + (4*z2 + 2)*a
sage: u.minpoly(F)                                                                  # needs sage.rings.finite_rings
x^4 + (4*z2 + 4)*x^3 + x^2 + (z2 + 1)*x + 2*z2 + 2
>>> from sage.all import *
>>> u.minpoly()                                                                   # needs sage.rings.finite_rings
x^2 + ((3*z2 + 4) + (3*z2 + 4)*a)*x + (z2 + 1) + (4*z2 + 2)*a
>>> u.minpoly(F)                                                                  # needs sage.rings.finite_rings
x^4 + (4*z2 + 4)*x^3 + x^2 + (z2 + 1)*x + 2*z2 + 2
AUTHOR:
- Xavier Caruso (2019) 
- class sage.rings.ring_extension.RingExtensionFactory[source]¶
- Bases: - UniqueFactory- Factory for ring extensions. - create_key_and_extra_args(ring, defining_morphism=None, gens=None, names=None, constructors=None)[source]¶
- Create a key and return it together with a list of constructors of the object. - INPUT: - ring– a commutative ring
- defining_morphism– a ring homomorphism or a commutative ring or- None(default:- None); the defining morphism of this extension or its base (if it coerces to- ring)
- gens– list of generators of this extension (over its base) or- None(default:- None)
- names– list or a tuple of variable names or- None(default:- None)
- constructors– list of constructors; each constructor is a pair \((class, arguments)\) where \(class\) is the class implementing the extension and \(arguments\) is the dictionary of arguments to pass in to init function
 
 
- class sage.rings.ring_extension.RingExtensionFractionField[source]¶
- Bases: - RingExtension_generic- A class for ring extensions of the form ` extrm{Frac}(A)/A`. - Element[source]¶
- alias of - RingExtensionFractionFieldElement
 - ring()[source]¶
- Return the ring whose fraction field is this extension. - EXAMPLES: - sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') sage: A.<a> = ZZ.extension(x^2 - 2) sage: OK = A.over() sage: K = OK.fraction_field(); K Fraction Field of Maximal Order generated by a in Number Field in a with defining polynomial x^2 - 2 over its base sage: K.ring() Maximal Order generated by a in Number Field in a with defining polynomial x^2 - 2 over its base sage: K.ring() is OK True - >>> from sage.all import * >>> # needs sage.rings.number_field >>> x = polygen(ZZ, 'x') >>> A = ZZ.extension(x**Integer(2) - Integer(2), names=('a',)); (a,) = A._first_ngens(1) >>> OK = A.over() >>> K = OK.fraction_field(); K Fraction Field of Maximal Order generated by a in Number Field in a with defining polynomial x^2 - 2 over its base >>> K.ring() Maximal Order generated by a in Number Field in a with defining polynomial x^2 - 2 over its base >>> K.ring() is OK True 
 
- class sage.rings.ring_extension.RingExtensionWithBasis[source]¶
- Bases: - RingExtension_generic- A class for finite free ring extensions equipped with a basis. - Element[source]¶
- alias of - RingExtensionWithBasisElement
 - basis_over(base=None)[source]¶
- Return a basis of this extension over - base.- INPUT: - base– a commutative ring (which might be itself an extension)
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: F.<a> = GF(5^2).over() # over GF(5) sage: K.<b> = GF(5^4).over(F) sage: L.<c> = GF(5^12).over(K) sage: L.basis_over(K) [1, c, c^2] sage: L.basis_over(F) [1, b, c, b*c, c^2, b*c^2] sage: L.basis_over(GF(5)) [1, a, b, a*b, c, a*c, b*c, a*b*c, c^2, a*c^2, b*c^2, a*b*c^2] - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = F._first_ngens(1)# over GF(5) >>> K = GF(Integer(5)**Integer(4)).over(F, names=('b',)); (b,) = K._first_ngens(1) >>> L = GF(Integer(5)**Integer(12)).over(K, names=('c',)); (c,) = L._first_ngens(1) >>> L.basis_over(K) [1, c, c^2] >>> L.basis_over(F) [1, b, c, b*c, c^2, b*c^2] >>> L.basis_over(GF(Integer(5))) [1, a, b, a*b, c, a*c, b*c, a*b*c, c^2, a*c^2, b*c^2, a*b*c^2] - If - baseis omitted, it is set to its default which is the base of the extension:- sage: L.basis_over() # needs sage.rings.finite_rings [1, c, c^2] sage: K.basis_over() # needs sage.rings.finite_rings [1, b] - >>> from sage.all import * >>> L.basis_over() # needs sage.rings.finite_rings [1, c, c^2] >>> K.basis_over() # needs sage.rings.finite_rings [1, b] - Note that - basemust be an explicit base over which the extension has been defined (as listed by the method- bases()):- sage: L.degree_over(GF(5^6)) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field in z6 of size 5^6 - >>> from sage.all import * >>> L.degree_over(GF(Integer(5)**Integer(6))) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field in z6 of size 5^6 
 - fraction_field(extend_base=False)[source]¶
- Return the fraction field of this extension. - INPUT: - extend_base– boolean (default:- False)
 - If - extend_baseis- False, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/L/K\), except is \(L\) is already a field in which base the fraction field of \(L/K\) is \(L/K\) itself.- If - extend_baseis- True, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/\textrm{Frac}(K)\) (provided that the defining morphism extends to the fraction fields, i.e. is injective).- EXAMPLES: - sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') sage: A.<a> = ZZ.extension(x^2 - 5) sage: OK = A.over() # over ZZ sage: OK Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base sage: K1 = OK.fraction_field(); K1 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base sage: K1.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Integer Ring] sage: K2 = OK.fraction_field(extend_base=True); K2 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base sage: K2.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Rational Field] - >>> from sage.all import * >>> # needs sage.rings.number_field >>> x = polygen(ZZ, 'x') >>> A = ZZ.extension(x**Integer(2) - Integer(5), names=('a',)); (a,) = A._first_ngens(1) >>> OK = A.over() # over ZZ >>> OK Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base >>> K1 = OK.fraction_field(); K1 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base >>> K1.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Integer Ring] >>> K2 = OK.fraction_field(extend_base=True); K2 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base >>> K2.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Rational Field] - Note that there is no coercion map between \(K_1\) and \(K_2\): - sage: K1.has_coerce_map_from(K2) # needs sage.rings.number_field False sage: K2.has_coerce_map_from(K1) # needs sage.rings.number_field False - >>> from sage.all import * >>> K1.has_coerce_map_from(K2) # needs sage.rings.number_field False >>> K2.has_coerce_map_from(K1) # needs sage.rings.number_field False - We check that when the extension is a field, its fraction field does not change: - sage: K1.fraction_field() is K1 # needs sage.rings.number_field True sage: K2.fraction_field() is K2 # needs sage.rings.number_field True - >>> from sage.all import * >>> K1.fraction_field() is K1 # needs sage.rings.number_field True >>> K2.fraction_field() is K2 # needs sage.rings.number_field True 
 - free_module(base=None, map=True)[source]¶
- Return a free module V over - basewhich is isomorphic to this ring- INPUT: - base– a commutative ring (which might be itself an extension) or- None(default:- None)
- map– boolean (default:- True); whether to return isomorphisms between this ring and V
 - OUTPUT: - A finite-rank free module V over - base
- The isomorphism from V to this ring corresponding to the basis output by the method - basis_over()(only included if- mapis- True)
- The reverse isomorphism of the isomorphism above (only included if - mapis- True)
 - EXAMPLES: - sage: F = GF(11) sage: K.<a> = GF(11^2).over() # needs sage.rings.finite_rings sage: L.<b> = GF(11^6).over(K) # needs sage.rings.finite_rings - >>> from sage.all import * >>> F = GF(Integer(11)) >>> K = GF(Integer(11)**Integer(2)).over(names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.finite_rings >>> L = GF(Integer(11)**Integer(6)).over(K, names=('b',)); (b,) = L._first_ngens(1)# needs sage.rings.finite_rings - Forgetting a part of the multiplicative structure, the field L can be viewed as a vector space of dimension 3 over K, equipped with a distinguished basis, namely \((1, b, b^2)\): - sage: # needs sage.rings.finite_rings sage: V, i, j = L.free_module(K) sage: V Vector space of dimension 3 over Field in a with defining polynomial x^2 + 7*x + 2 over its base sage: i Generic map: From: Vector space of dimension 3 over Field in a with defining polynomial x^2 + 7*x + 2 over its base To: Field in b with defining polynomial x^3 + (7 + 2*a)*x^2 + (2 - a)*x - a over its base sage: j Generic map: From: Field in b with defining polynomial x^3 + (7 + 2*a)*x^2 + (2 - a)*x - a over its base To: Vector space of dimension 3 over Field in a with defining polynomial x^2 + 7*x + 2 over its base sage: j(b) (0, 1, 0) sage: i((1, a, a+1)) 1 + a*b + (1 + a)*b^2 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> V, i, j = L.free_module(K) >>> V Vector space of dimension 3 over Field in a with defining polynomial x^2 + 7*x + 2 over its base >>> i Generic map: From: Vector space of dimension 3 over Field in a with defining polynomial x^2 + 7*x + 2 over its base To: Field in b with defining polynomial x^3 + (7 + 2*a)*x^2 + (2 - a)*x - a over its base >>> j Generic map: From: Field in b with defining polynomial x^3 + (7 + 2*a)*x^2 + (2 - a)*x - a over its base To: Vector space of dimension 3 over Field in a with defining polynomial x^2 + 7*x + 2 over its base >>> j(b) (0, 1, 0) >>> i((Integer(1), a, a+Integer(1))) 1 + a*b + (1 + a)*b^2 - Similarly, one can view L as a F-vector space of dimension 6: - sage: V, i, j, = L.free_module(F) # needs sage.rings.finite_rings sage: V # needs sage.rings.finite_rings Vector space of dimension 6 over Finite Field of size 11 - >>> from sage.all import * >>> V, i, j, = L.free_module(F) # needs sage.rings.finite_rings >>> V # needs sage.rings.finite_rings Vector space of dimension 6 over Finite Field of size 11 - In this case, the isomorphisms between \(V\) and \(L\) are given by the basis \((1, a, b, ab, b^2, ab^2)\): - sage: j(a*b) # needs sage.rings.finite_rings (0, 0, 0, 1, 0, 0) sage: i((1,2,3,4,5,6)) # needs sage.rings.finite_rings (1 + 2*a) + (3 + 4*a)*b + (5 + 6*a)*b^2 - When - baseis omitted, the default is the base of this extension:- sage: L.free_module(map=False) # needs sage.rings.finite_rings Vector space of dimension 3 over Field in a with defining polynomial x^2 + 7*x + 2 over its base - >>> from sage.all import * >>> L.free_module(map=False) # needs sage.rings.finite_rings Vector space of dimension 3 over Field in a with defining polynomial x^2 + 7*x + 2 over its base - Note that - basemust be an explicit base over which the extension has been defined (as listed by the method- bases()):- sage: L.degree(GF(11^3)) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field in z3 of size 11^3 - >>> from sage.all import * >>> L.degree(GF(Integer(11)**Integer(3))) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field in z3 of size 11^3 
 
- class sage.rings.ring_extension.RingExtensionWithGen[source]¶
- Bases: - RingExtensionWithBasis- A class for finite free ring extensions generated by a single element - fraction_field(extend_base=False)[source]¶
- Return the fraction field of this extension. - INPUT: - extend_base– boolean (default:- False)
 - If - extend_baseis- False, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/L/K\), except is \(L\) is already a field in which base the fraction field of \(L/K\) is \(L/K\) itself.- If - extend_baseis- True, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/\textrm{Frac}(K)\) (provided that the defining morphism extends to the fraction fields, i.e. is injective).- EXAMPLES: - sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') sage: A.<a> = ZZ.extension(x^2 - 5) sage: OK = A.over() # over ZZ sage: OK Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base sage: K1 = OK.fraction_field(); K1 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base sage: K1.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Integer Ring] sage: K2 = OK.fraction_field(extend_base=True); K2 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base sage: K2.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Rational Field] - >>> from sage.all import * >>> # needs sage.rings.number_field >>> x = polygen(ZZ, 'x') >>> A = ZZ.extension(x**Integer(2) - Integer(5), names=('a',)); (a,) = A._first_ngens(1) >>> OK = A.over() # over ZZ >>> OK Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base >>> K1 = OK.fraction_field(); K1 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base >>> K1.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Integer Ring] >>> K2 = OK.fraction_field(extend_base=True); K2 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base >>> K2.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Rational Field] - Note that there is no coercion map between \(K_1\) and \(K_2\): - sage: K1.has_coerce_map_from(K2) # needs sage.rings.number_field False sage: K2.has_coerce_map_from(K1) # needs sage.rings.number_field False - >>> from sage.all import * >>> K1.has_coerce_map_from(K2) # needs sage.rings.number_field False >>> K2.has_coerce_map_from(K1) # needs sage.rings.number_field False - We check that when the extension is a field, its fraction field does not change: - sage: K1.fraction_field() is K1 # needs sage.rings.number_field True sage: K2.fraction_field() is K2 # needs sage.rings.number_field True - >>> from sage.all import * >>> K1.fraction_field() is K1 # needs sage.rings.number_field True >>> K2.fraction_field() is K2 # needs sage.rings.number_field True 
 - gens(base=None)[source]¶
- Return the generators of this extension over - base.- INPUT: - base– a commutative ring (which might be itself an extension) or- None(default:- None)
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: K.<a> = GF(5^2).over() # over GF(5) sage: K.gens() (a,) sage: L.<b> = GF(5^4).over(K) sage: L.gens() (b,) sage: L.gens(GF(5)) (b, a) - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = K._first_ngens(1)# over GF(5) >>> K.gens() (a,) >>> L = GF(Integer(5)**Integer(4)).over(K, names=('b',)); (b,) = L._first_ngens(1) >>> L.gens() (b,) >>> L.gens(GF(Integer(5))) (b, a) 
 - modulus(var='x')[source]¶
- Return the defining polynomial of this extension, that is the minimal polynomial of the given generator of this extension. - INPUT: - var– a variable name (default:- x)
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: K.<u> = GF(7^10).over(GF(7^2)); K Field in u with defining polynomial x^5 + (6*z2 + 4)*x^4 + (3*z2 + 5)*x^3 + (2*z2 + 2)*x^2 + 4*x + 6*z2 over its base sage: P = K.modulus(); P x^5 + (6*z2 + 4)*x^4 + (3*z2 + 5)*x^3 + (2*z2 + 2)*x^2 + 4*x + 6*z2 sage: P(u) 0 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(7)**Integer(10)).over(GF(Integer(7)**Integer(2)), names=('u',)); (u,) = K._first_ngens(1); K Field in u with defining polynomial x^5 + (6*z2 + 4)*x^4 + (3*z2 + 5)*x^3 + (2*z2 + 2)*x^2 + 4*x + 6*z2 over its base >>> P = K.modulus(); P x^5 + (6*z2 + 4)*x^4 + (3*z2 + 5)*x^3 + (2*z2 + 2)*x^2 + 4*x + 6*z2 >>> P(u) 0 - We can use a different variable name: - sage: K.modulus('y') # needs sage.rings.finite_rings y^5 + (6*z2 + 4)*y^4 + (3*z2 + 5)*y^3 + (2*z2 + 2)*y^2 + 4*y + 6*z2 - >>> from sage.all import * >>> K.modulus('y') # needs sage.rings.finite_rings y^5 + (6*z2 + 4)*y^4 + (3*z2 + 5)*y^3 + (2*z2 + 2)*y^2 + 4*y + 6*z2 
 
- class sage.rings.ring_extension.RingExtension_generic[source]¶
- Bases: - Parent- A generic class for all ring extensions. - Element[source]¶
- alias of - RingExtensionElement
 - absolute_base()[source]¶
- Return the absolute base of this extension. - By definition, the absolute base of an iterated extension \(K_n/\cdots K_2/K_1\) is the ring \(K_1\). - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: F = GF(5^2).over() # over GF(5) sage: K = GF(5^4).over(F) sage: L = GF(5^12).over(K) sage: F.absolute_base() Finite Field of size 5 sage: K.absolute_base() Finite Field of size 5 sage: L.absolute_base() Finite Field of size 5 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F = GF(Integer(5)**Integer(2)).over() # over GF(5) >>> K = GF(Integer(5)**Integer(4)).over(F) >>> L = GF(Integer(5)**Integer(12)).over(K) >>> F.absolute_base() Finite Field of size 5 >>> K.absolute_base() Finite Field of size 5 >>> L.absolute_base() Finite Field of size 5 - See also 
 - absolute_degree()[source]¶
- Return the degree of this extension over its absolute base. - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: A = GF(5^4).over(GF(5^2)) sage: B = GF(5^12).over(A) sage: A.absolute_degree() 2 sage: B.absolute_degree() 6 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> A = GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2))) >>> B = GF(Integer(5)**Integer(12)).over(A) >>> A.absolute_degree() 2 >>> B.absolute_degree() 6 - See also 
 - backend(force=False)[source]¶
- Return the backend of this extension. - INPUT: - force– boolean (default:- False); if- False, raise an error if the backend is not exposed
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: K = GF(5^3) sage: E = K.over() sage: E Field in z3 with defining polynomial x^3 + 3*x + 3 over its base sage: E.backend() Finite Field in z3 of size 5^3 sage: E.backend() is K True - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(5)**Integer(3)) >>> E = K.over() >>> E Field in z3 with defining polynomial x^3 + 3*x + 3 over its base >>> E.backend() Finite Field in z3 of size 5^3 >>> E.backend() is K True 
 - base()[source]¶
- Return the base of this extension. - EXAMPLES: - sage: F = GF(5^2) # needs sage.rings.finite_rings sage: K = GF(5^4).over(F) # needs sage.rings.finite_rings sage: K.base() # needs sage.rings.finite_rings Finite Field in z2 of size 5^2 - >>> from sage.all import * >>> F = GF(Integer(5)**Integer(2)) # needs sage.rings.finite_rings >>> K = GF(Integer(5)**Integer(4)).over(F) # needs sage.rings.finite_rings >>> K.base() # needs sage.rings.finite_rings Finite Field in z2 of size 5^2 - In case of iterated extensions, the base is itself an extension: - sage: L = GF(5^8).over(K) # needs sage.rings.finite_rings sage: L.base() # needs sage.rings.finite_rings Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base sage: L.base() is K # needs sage.rings.finite_rings True - >>> from sage.all import * >>> L = GF(Integer(5)**Integer(8)).over(K) # needs sage.rings.finite_rings >>> L.base() # needs sage.rings.finite_rings Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base >>> L.base() is K # needs sage.rings.finite_rings True - See also 
 - bases()[source]¶
- Return the list of successive bases of this extension (including itself). - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: F = GF(5^2).over() # over GF(5) sage: K = GF(5^4).over(F) sage: L = GF(5^12).over(K) sage: F.bases() [Field in z2 with defining polynomial x^2 + 4*x + 2 over its base, Finite Field of size 5] sage: K.bases() [Field in z4 with defining polynomial x^2 + (3 - z2)*x + z2 over its base, Field in z2 with defining polynomial x^2 + 4*x + 2 over its base, Finite Field of size 5] sage: L.bases() [Field in z12 with defining polynomial x^3 + (1 + (2 - z2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base, Field in z4 with defining polynomial x^2 + (3 - z2)*x + z2 over its base, Field in z2 with defining polynomial x^2 + 4*x + 2 over its base, Finite Field of size 5] - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F = GF(Integer(5)**Integer(2)).over() # over GF(5) >>> K = GF(Integer(5)**Integer(4)).over(F) >>> L = GF(Integer(5)**Integer(12)).over(K) >>> F.bases() [Field in z2 with defining polynomial x^2 + 4*x + 2 over its base, Finite Field of size 5] >>> K.bases() [Field in z4 with defining polynomial x^2 + (3 - z2)*x + z2 over its base, Field in z2 with defining polynomial x^2 + 4*x + 2 over its base, Finite Field of size 5] >>> L.bases() [Field in z12 with defining polynomial x^3 + (1 + (2 - z2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base, Field in z4 with defining polynomial x^2 + (3 - z2)*x + z2 over its base, Field in z2 with defining polynomial x^2 + 4*x + 2 over its base, Finite Field of size 5] - See also 
 - characteristic()[source]¶
- Return the characteristic of the extension as a ring. - OUTPUT: a prime number or zero - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: F = GF(5^2).over() # over GF(5) sage: K = GF(5^4).over(F) sage: L = GF(5^12).over(K) sage: F.characteristic() 5 sage: K.characteristic() 5 sage: L.characteristic() 5 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F = GF(Integer(5)**Integer(2)).over() # over GF(5) >>> K = GF(Integer(5)**Integer(4)).over(F) >>> L = GF(Integer(5)**Integer(12)).over(K) >>> F.characteristic() 5 >>> K.characteristic() 5 >>> L.characteristic() 5 - sage: F = RR.over(ZZ) sage: F.characteristic() 0 - >>> from sage.all import * >>> F = RR.over(ZZ) >>> F.characteristic() 0 - sage: F = GF(11) sage: A.<x> = F[] sage: K = Frac(F).over(F) sage: K.characteristic() 11 - >>> from sage.all import * >>> F = GF(Integer(11)) >>> A = F['x']; (x,) = A._first_ngens(1) >>> K = Frac(F).over(F) >>> K.characteristic() 11 - sage: E = GF(7).over(ZZ) sage: E.characteristic() 7 - >>> from sage.all import * >>> E = GF(Integer(7)).over(ZZ) >>> E.characteristic() 7 
 - construction()[source]¶
- Return the functorial construction of this extension, if defined. - EXAMPLES: - sage: E = GF(5^3).over() # needs sage.rings.finite_rings sage: E.construction() # needs sage.rings.finite_rings - >>> from sage.all import * >>> E = GF(Integer(5)**Integer(3)).over() # needs sage.rings.finite_rings >>> E.construction() # needs sage.rings.finite_rings 
 - defining_morphism(base=None)[source]¶
- Return the defining morphism of this extension over - base.- INPUT: - base– a commutative ring (which might be itself an extension) or- None(default:- None)
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: F = GF(5^2) sage: K = GF(5^4).over(F) sage: L = GF(5^12).over(K) sage: K.defining_morphism() Ring morphism: From: Finite Field in z2 of size 5^2 To: Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base Defn: z2 |--> z2 sage: L.defining_morphism() Ring morphism: From: Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base To: Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base Defn: z4 |--> z4 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F = GF(Integer(5)**Integer(2)) >>> K = GF(Integer(5)**Integer(4)).over(F) >>> L = GF(Integer(5)**Integer(12)).over(K) >>> K.defining_morphism() Ring morphism: From: Finite Field in z2 of size 5^2 To: Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base Defn: z2 |--> z2 >>> L.defining_morphism() Ring morphism: From: Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base To: Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base Defn: z4 |--> z4 - One can also pass in a base over which the extension is explicitly defined (see also - is_defined_over()):- sage: L.defining_morphism(F) # needs sage.rings.finite_rings Ring morphism: From: Finite Field in z2 of size 5^2 To: Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base Defn: z2 |--> z2 sage: L.defining_morphism(GF(5)) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field of size 5 - >>> from sage.all import * >>> L.defining_morphism(F) # needs sage.rings.finite_rings Ring morphism: From: Finite Field in z2 of size 5^2 To: Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base Defn: z2 |--> z2 >>> L.defining_morphism(GF(Integer(5))) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field of size 5 
 - degree(base)[source]¶
- Return the degree of this extension over - base.- INPUT: - base– a commutative ring (which might be itself an extension)
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: A = GF(5^4).over(GF(5^2)) sage: B = GF(5^12).over(A) sage: A.degree(GF(5^2)) 2 sage: B.degree(A) 3 sage: B.degree(GF(5^2)) 6 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> A = GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2))) >>> B = GF(Integer(5)**Integer(12)).over(A) >>> A.degree(GF(Integer(5)**Integer(2))) 2 >>> B.degree(A) 3 >>> B.degree(GF(Integer(5)**Integer(2))) 6 - Note that - basemust be an explicit base over which the extension has been defined (as listed by the method- bases()):- sage: A.degree(GF(5)) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field of size 5 - >>> from sage.all import * >>> A.degree(GF(Integer(5))) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field of size 5 - See also 
 - degree_over(base=None)[source]¶
- Return the degree of this extension over - base.- INPUT: - base– a commutative ring (which might be itself an extension) or- None(default:- None)
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: F = GF(5^2) sage: K = GF(5^4).over(F) sage: L = GF(5^12).over(K) sage: K.degree_over(F) 2 sage: L.degree_over(K) 3 sage: L.degree_over(F) 6 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> F = GF(Integer(5)**Integer(2)) >>> K = GF(Integer(5)**Integer(4)).over(F) >>> L = GF(Integer(5)**Integer(12)).over(K) >>> K.degree_over(F) 2 >>> L.degree_over(K) 3 >>> L.degree_over(F) 6 - If - baseis omitted, the degree is computed over the base of the extension:- sage: K.degree_over() # needs sage.rings.finite_rings 2 sage: L.degree_over() # needs sage.rings.finite_rings 3 - >>> from sage.all import * >>> K.degree_over() # needs sage.rings.finite_rings 2 >>> L.degree_over() # needs sage.rings.finite_rings 3 - Note that - basemust be an explicit base over which the extension has been defined (as listed by the method- bases()):- sage: K.degree_over(GF(5)) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field of size 5 - >>> from sage.all import * >>> K.degree_over(GF(Integer(5))) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not (explicitly) defined over Finite Field of size 5 
 - fraction_field(extend_base=False)[source]¶
- Return the fraction field of this extension. - INPUT: - extend_base– boolean (default:- False)
 - If - extend_baseis- False, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/L/K\), except if \(L\) is already a field in which base the fraction field of \(L/K\) is \(L/K\) itself.- If - extend_baseis- True, the fraction field of the extension \(L/K\) is defined as \(\textrm{Frac}(L)/\textrm{Frac}(K)\) (provided that the defining morphism extends to the fraction fields, i.e. is injective).- EXAMPLES: - sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') sage: A.<a> = ZZ.extension(x^2 - 5) sage: OK = A.over() # over ZZ sage: OK Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base sage: K1 = OK.fraction_field(); K1 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base sage: K1.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Integer Ring] sage: K2 = OK.fraction_field(extend_base=True); K2 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base sage: K2.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Rational Field] - >>> from sage.all import * >>> # needs sage.rings.number_field >>> x = polygen(ZZ, 'x') >>> A = ZZ.extension(x**Integer(2) - Integer(5), names=('a',)); (a,) = A._first_ngens(1) >>> OK = A.over() # over ZZ >>> OK Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base >>> K1 = OK.fraction_field(); K1 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base >>> K1.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Integer Ring] >>> K2 = OK.fraction_field(extend_base=True); K2 Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base >>> K2.bases() [Fraction Field of Order of conductor 2 generated by a in Number Field in a with defining polynomial x^2 - 5 over its base, Rational Field] - Note that there is no coercion between \(K_1\) and \(K_2\): - sage: K1.has_coerce_map_from(K2) # needs sage.rings.number_field False sage: K2.has_coerce_map_from(K1) # needs sage.rings.number_field False - >>> from sage.all import * >>> K1.has_coerce_map_from(K2) # needs sage.rings.number_field False >>> K2.has_coerce_map_from(K1) # needs sage.rings.number_field False - We check that when the extension is a field, its fraction field does not change: - sage: K1.fraction_field() is K1 # needs sage.rings.number_field True sage: K2.fraction_field() is K2 # needs sage.rings.number_field True - >>> from sage.all import * >>> K1.fraction_field() is K1 # needs sage.rings.number_field True >>> K2.fraction_field() is K2 # needs sage.rings.number_field True 
 - from_base_ring(r)[source]¶
- Return the canonical embedding of - rinto this extension.- INPUT: - r– an element of the base of the ring of this extension
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: k = GF(5) sage: K.<u> = GF(5^2).over(k) sage: L.<v> = GF(5^4).over(K) sage: x = L.from_base_ring(k(2)); x 2 sage: x.parent() Field in v with defining polynomial x^2 + (3 - u)*x + u over its base sage: x = L.from_base_ring(u); x u sage: x.parent() Field in v with defining polynomial x^2 + (3 - u)*x + u over its base - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)) >>> K = GF(Integer(5)**Integer(2)).over(k, names=('u',)); (u,) = K._first_ngens(1) >>> L = GF(Integer(5)**Integer(4)).over(K, names=('v',)); (v,) = L._first_ngens(1) >>> x = L.from_base_ring(k(Integer(2))); x 2 >>> x.parent() Field in v with defining polynomial x^2 + (3 - u)*x + u over its base >>> x = L.from_base_ring(u); x u >>> x.parent() Field in v with defining polynomial x^2 + (3 - u)*x + u over its base 
 - gen()[source]¶
- Return the first generator of this extension. - EXAMPLES: - sage: K = GF(5^2).over() # over GF(5) # needs sage.rings.finite_rings sage: x = K.gen(); x # needs sage.rings.finite_rings z2 - >>> from sage.all import * >>> K = GF(Integer(5)**Integer(2)).over() # over GF(5) # needs sage.rings.finite_rings >>> x = K.gen(); x # needs sage.rings.finite_rings z2 - Observe that the generator lives in the extension: - sage: x.parent() # needs sage.rings.finite_rings Field in z2 with defining polynomial x^2 + 4*x + 2 over its base sage: x.parent() is K # needs sage.rings.finite_rings True - >>> from sage.all import * >>> x.parent() # needs sage.rings.finite_rings Field in z2 with defining polynomial x^2 + 4*x + 2 over its base >>> x.parent() is K # needs sage.rings.finite_rings True 
 - gens(base=None)[source]¶
- Return the generators of this extension over - base.- INPUT: - base– a commutative ring (which might be itself an extension) or- None(default:- None); if omitted, use the base of this extension
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: K.<a> = GF(5^2).over() # over GF(5) sage: K.gens() (a,) sage: L.<b> = GF(5^4).over(K) sage: L.gens() (b,) sage: L.gens(GF(5)) (b, a) sage: S.<x> = QQ[] sage: T.<y> = S[] sage: T.over(S).gens() (y,) sage: T.over(QQ).gens() (y, x) - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = K._first_ngens(1)# over GF(5) >>> K.gens() (a,) >>> L = GF(Integer(5)**Integer(4)).over(K, names=('b',)); (b,) = L._first_ngens(1) >>> L.gens() (b,) >>> L.gens(GF(Integer(5))) (b, a) >>> S = QQ['x']; (x,) = S._first_ngens(1) >>> T = S['y']; (y,) = T._first_ngens(1) >>> T.over(S).gens() (y,) >>> T.over(QQ).gens() (y, x) 
 - hom(im_gens, codomain=None, base_map=None, category=None, check=True)[source]¶
- Return the unique homomorphism from this extension to - codomainthat sends- self.gens()to the entries of- im_gensand induces the map- base_mapon the base ring.- INPUT: - im_gens– the images of the generators of this extension
- codomain– the codomain of the homomorphism; if omitted, it is set to the smallest parent containing all the entries of- im_gens
- base_map– a map from one of the bases of this extension into something that coerces into the codomain; if omitted, coercion maps are used
- category– the category of the resulting morphism
- check– boolean (default:- True); whether to verify that the images of generators extend to define a map (using only canonical coercions)
 - EXAMPLES: - sage: K.<a> = GF(5^2).over() # over GF(5) # needs sage.rings.finite_rings sage: L.<b> = GF(5^6).over(K) # needs sage.rings.finite_rings - >>> from sage.all import * >>> K = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = K._first_ngens(1)# over GF(5) # needs sage.rings.finite_rings >>> L = GF(Integer(5)**Integer(6)).over(K, names=('b',)); (b,) = L._first_ngens(1)# needs sage.rings.finite_rings - We define (by hand) the relative Frobenius endomorphism of the extension \(L/K\): - sage: L.hom([b^25]) # needs sage.rings.finite_rings Ring endomorphism of Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base Defn: b |--> 2 + 2*a*b + (2 - a)*b^2 - >>> from sage.all import * >>> L.hom([b**Integer(25)]) # needs sage.rings.finite_rings Ring endomorphism of Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base Defn: b |--> 2 + 2*a*b + (2 - a)*b^2 - Defining the absolute Frobenius of \(L\) is a bit more complicated because it is not a homomorphism of \(K\)-algebras. For this reason, the construction - L.hom([b^5])fails:- sage: L.hom([b^5]) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: images do not define a valid homomorphism - >>> from sage.all import * >>> L.hom([b**Integer(5)]) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: images do not define a valid homomorphism - What we need is to specify a base map: - sage: FrobK = K.hom([a^5]) # needs sage.rings.finite_rings sage: FrobL = L.hom([b^5], base_map=FrobK); FrobL # needs sage.rings.finite_rings Ring endomorphism of Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base Defn: b |--> (-1 + a) + (1 + 2*a)*b + a*b^2 with map on base ring: a |--> 1 - a - >>> from sage.all import * >>> FrobK = K.hom([a**Integer(5)]) # needs sage.rings.finite_rings >>> FrobL = L.hom([b**Integer(5)], base_map=FrobK); FrobL # needs sage.rings.finite_rings Ring endomorphism of Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base Defn: b |--> (-1 + a) + (1 + 2*a)*b + a*b^2 with map on base ring: a |--> 1 - a - As a shortcut, we may use the following construction: - sage: phi = L.hom([b^5, a^5]); phi # needs sage.rings.finite_rings Ring endomorphism of Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base Defn: b |--> (-1 + a) + (1 + 2*a)*b + a*b^2 with map on base ring: a |--> 1 - a sage: phi == FrobL # needs sage.rings.finite_rings True - >>> from sage.all import * >>> phi = L.hom([b**Integer(5), a**Integer(5)]); phi # needs sage.rings.finite_rings Ring endomorphism of Field in b with defining polynomial x^3 + (2 + 2*a)*x - a over its base Defn: b |--> (-1 + a) + (1 + 2*a)*b + a*b^2 with map on base ring: a |--> 1 - a >>> phi == FrobL # needs sage.rings.finite_rings True 
 - is_defined_over(base)[source]¶
- Return whether or not - baseis one of the bases of this extension.- INPUT: - base– a commutative ring, which might be itself an extension
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: A = GF(5^4).over(GF(5^2)) sage: B = GF(5^12).over(A) sage: A.is_defined_over(GF(5^2)) True sage: A.is_defined_over(GF(5)) False sage: # needs sage.rings.finite_rings sage: B.is_defined_over(A) True sage: B.is_defined_over(GF(5^4)) True sage: B.is_defined_over(GF(5^2)) True sage: B.is_defined_over(GF(5)) False - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> A = GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2))) >>> B = GF(Integer(5)**Integer(12)).over(A) >>> A.is_defined_over(GF(Integer(5)**Integer(2))) True >>> A.is_defined_over(GF(Integer(5))) False >>> # needs sage.rings.finite_rings >>> B.is_defined_over(A) True >>> B.is_defined_over(GF(Integer(5)**Integer(4))) True >>> B.is_defined_over(GF(Integer(5)**Integer(2))) True >>> B.is_defined_over(GF(Integer(5))) False - Note that an extension is defined over itself: - sage: A.is_defined_over(A) # needs sage.rings.finite_rings True sage: A.is_defined_over(GF(5^4)) # needs sage.rings.finite_rings True - >>> from sage.all import * >>> A.is_defined_over(A) # needs sage.rings.finite_rings True >>> A.is_defined_over(GF(Integer(5)**Integer(4))) # needs sage.rings.finite_rings True - See also 
 - is_field(proof=True)[source]¶
- Return whether or not this extension is a field. - INPUT: - proof– boolean (default:- False)
 - EXAMPLES: - sage: K = GF(5^5).over() # over GF(5) # needs sage.rings.finite_rings sage: K.is_field() # needs sage.rings.finite_rings True sage: S.<x> = QQ[] sage: A = S.over(QQ) sage: A.is_field() False sage: B = A.fraction_field() sage: B.is_field() True - >>> from sage.all import * >>> K = GF(Integer(5)**Integer(5)).over() # over GF(5) # needs sage.rings.finite_rings >>> K.is_field() # needs sage.rings.finite_rings True >>> S = QQ['x']; (x,) = S._first_ngens(1) >>> A = S.over(QQ) >>> A.is_field() False >>> B = A.fraction_field() >>> B.is_field() True 
 - is_finite_over(base=None)[source]¶
- Return whether or not this extension is finite over - base(as a module).- INPUT: - base– a commutative ring (which might be itself an extension) or- None(default:- None)
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: K = GF(5^2).over() # over GF(5) sage: L = GF(5^4).over(K) sage: L.is_finite_over(K) True sage: L.is_finite_over(GF(5)) True - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(5)**Integer(2)).over() # over GF(5) >>> L = GF(Integer(5)**Integer(4)).over(K) >>> L.is_finite_over(K) True >>> L.is_finite_over(GF(Integer(5))) True - If - baseis omitted, it is set to its default which is the base of the extension:- sage: L.is_finite_over() # needs sage.rings.finite_rings True - >>> from sage.all import * >>> L.is_finite_over() # needs sage.rings.finite_rings True 
 - is_free_over(base=None)[source]¶
- Return - Trueif this extension is free (as a module) over- base- INPUT: - base– a commutative ring (which might be itself an extension) or- None(default:- None)
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: K = GF(5^2).over() # over GF(5) sage: L = GF(5^4).over(K) sage: L.is_free_over(K) True sage: L.is_free_over(GF(5)) True - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(5)**Integer(2)).over() # over GF(5) >>> L = GF(Integer(5)**Integer(4)).over(K) >>> L.is_free_over(K) True >>> L.is_free_over(GF(Integer(5))) True - If - baseis omitted, it is set to its default which is the base of the extension:- sage: L.is_free_over() # needs sage.rings.finite_rings True - >>> from sage.all import * >>> L.is_free_over() # needs sage.rings.finite_rings True 
 - ngens(base=None)[source]¶
- Return the number of generators of this extension over - base.- INPUT: - base– a commutative ring (which might be itself an extension) or- None(default:- None)
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: K = GF(5^2).over() # over GF(5) sage: K.gens() (z2,) sage: K.ngens() 1 sage: L = GF(5^4).over(K) sage: L.gens(GF(5)) (z4, z2) sage: L.ngens(GF(5)) 2 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(5)**Integer(2)).over() # over GF(5) >>> K.gens() (z2,) >>> K.ngens() 1 >>> L = GF(Integer(5)**Integer(4)).over(K) >>> L.gens(GF(Integer(5))) (z4, z2) >>> L.ngens(GF(Integer(5))) 2 
 - print_options(**options)[source]¶
- Update the printing options of this extension. - INPUT: - over– integer or- Infinity(default:- 0); the maximum number of bases included in the printing of this extension
- base– a base over which this extension is finite free; elements in this extension will be printed as a linear combinaison of a basis of this extension over the given base
 - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: A.<a> = GF(5^2).over() # over GF(5) sage: B.<b> = GF(5^4).over(A) sage: C.<c> = GF(5^12).over(B) sage: D.<d> = GF(5^24).over(C) - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> A = GF(Integer(5)**Integer(2)).over(names=('a',)); (a,) = A._first_ngens(1)# over GF(5) >>> B = GF(Integer(5)**Integer(4)).over(A, names=('b',)); (b,) = B._first_ngens(1) >>> C = GF(Integer(5)**Integer(12)).over(B, names=('c',)); (c,) = C._first_ngens(1) >>> D = GF(Integer(5)**Integer(24)).over(C, names=('d',)); (d,) = D._first_ngens(1) - Observe what happens when we modify the option - over:- sage: # needs sage.rings.finite_rings sage: D Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over its base sage: D.print_options(over=2) sage: D Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over Field in c with defining polynomial x^3 + (1 + (2 - a)*b)*x^2 + (2 + 2*b)*x - b over Field in b with defining polynomial x^2 + (3 - a)*x + a over its base sage: D.print_options(over=Infinity) sage: D Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over Field in c with defining polynomial x^3 + (1 + (2 - a)*b)*x^2 + (2 + 2*b)*x - b over Field in b with defining polynomial x^2 + (3 - a)*x + a over Field in a with defining polynomial x^2 + 4*x + 2 over Finite Field of size 5 - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> D Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over its base >>> D.print_options(over=Integer(2)) >>> D Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over Field in c with defining polynomial x^3 + (1 + (2 - a)*b)*x^2 + (2 + 2*b)*x - b over Field in b with defining polynomial x^2 + (3 - a)*x + a over its base >>> D.print_options(over=Infinity) >>> D Field in d with defining polynomial x^2 + ((1 - a) + ((1 + 2*a) - b)*c + ((2 + a) + (1 - a)*b)*c^2)*x + c over Field in c with defining polynomial x^3 + (1 + (2 - a)*b)*x^2 + (2 + 2*b)*x - b over Field in b with defining polynomial x^2 + (3 - a)*x + a over Field in a with defining polynomial x^2 + 4*x + 2 over Finite Field of size 5 - Now the option - base:- sage: # needs sage.rings.finite_rings sage: d^2 -c + ((-1 + a) + ((-1 + 3*a) + b)*c + ((3 - a) + (-1 + a)*b)*c^2)*d sage: D.basis_over(B) [1, c, c^2, d, c*d, c^2*d] sage: D.print_options(base=B) sage: d^2 -c + (-1 + a)*d + ((-1 + 3*a) + b)*c*d + ((3 - a) + (-1 + a)*b)*c^2*d sage: D.basis_over(A) [1, b, c, b*c, c^2, b*c^2, d, b*d, c*d, b*c*d, c^2*d, b*c^2*d] sage: D.print_options(base=A) sage: d^2 -c + (-1 + a)*d + (-1 + 3*a)*c*d + b*c*d + (3 - a)*c^2*d + (-1 + a)*b*c^2*d - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> d**Integer(2) -c + ((-1 + a) + ((-1 + 3*a) + b)*c + ((3 - a) + (-1 + a)*b)*c^2)*d >>> D.basis_over(B) [1, c, c^2, d, c*d, c^2*d] >>> D.print_options(base=B) >>> d**Integer(2) -c + (-1 + a)*d + ((-1 + 3*a) + b)*c*d + ((3 - a) + (-1 + a)*b)*c^2*d >>> D.basis_over(A) [1, b, c, b*c, c^2, b*c^2, d, b*d, c*d, b*c*d, c^2*d, b*c^2*d] >>> D.print_options(base=A) >>> d**Integer(2) -c + (-1 + a)*d + (-1 + 3*a)*c*d + b*c*d + (3 - a)*c^2*d + (-1 + a)*b*c^2*d 
 - random_element()[source]¶
- Return a random element in this extension. - EXAMPLES: - sage: # needs sage.rings.finite_rings sage: K = GF(5^2).over() # over GF(5) sage: x = K.random_element(); x # random 3 + z2 sage: x.parent() Field in z2 with defining polynomial x^2 + 4*x + 2 over its base sage: x.parent() is K True - >>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(5)**Integer(2)).over() # over GF(5) >>> x = K.random_element(); x # random 3 + z2 >>> x.parent() Field in z2 with defining polynomial x^2 + 4*x + 2 over its base >>> x.parent() is K True 
 - relative_degree()[source]¶
- Return the degree of this extension over its base. - EXAMPLES: - sage: A = GF(5^4).over(GF(5^2)) # needs sage.rings.finite_rings sage: A.relative_degree() # needs sage.rings.finite_rings 2 - >>> from sage.all import * >>> A = GF(Integer(5)**Integer(4)).over(GF(Integer(5)**Integer(2))) # needs sage.rings.finite_rings >>> A.relative_degree() # needs sage.rings.finite_rings 2 - See also 
 
- sage.rings.ring_extension.common_base(K, L, degree)[source]¶
- Return a common base on which - Kand- Lare defined.- INPUT: - K– a commutative ring
- L– a commutative ring
- degree– boolean; if- True, return the degree of- Kand- Lover their common base
 - EXAMPLES: - sage: from sage.rings.ring_extension import common_base sage: common_base(GF(5^3), GF(5^7), False) # needs sage.rings.finite_rings Finite Field of size 5 sage: common_base(GF(5^3), GF(5^7), True) # needs sage.rings.finite_rings (Finite Field of size 5, 3, 7) sage: common_base(GF(5^3), GF(7^5), False) # needs sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: unable to find a common base - >>> from sage.all import * >>> from sage.rings.ring_extension import common_base >>> common_base(GF(Integer(5)**Integer(3)), GF(Integer(5)**Integer(7)), False) # needs sage.rings.finite_rings Finite Field of size 5 >>> common_base(GF(Integer(5)**Integer(3)), GF(Integer(5)**Integer(7)), True) # needs sage.rings.finite_rings (Finite Field of size 5, 3, 7) >>> common_base(GF(Integer(5)**Integer(3)), GF(Integer(7)**Integer(5)), False) # needs sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: unable to find a common base - When - degreeis set to- True, we only look up for bases on which both- Kand- Lare finite:- sage: S.<x> = QQ[] sage: common_base(S, QQ, False) Rational Field sage: common_base(S, QQ, True) Traceback (most recent call last): ... NotImplementedError: unable to find a common base - >>> from sage.all import * >>> S = QQ['x']; (x,) = S._first_ngens(1) >>> common_base(S, QQ, False) Rational Field >>> common_base(S, QQ, True) Traceback (most recent call last): ... NotImplementedError: unable to find a common base 
- sage.rings.ring_extension.generators(ring, base)[source]¶
- Return the generators of - ringover- base.- INPUT: - ring– a commutative ring
- base– a commutative ring
 - EXAMPLES: - sage: from sage.rings.ring_extension import generators sage: S.<x> = QQ[] sage: T.<y> = S[] sage: generators(T, S) (y,) sage: generators(T, QQ) (y, x) - >>> from sage.all import * >>> from sage.rings.ring_extension import generators >>> S = QQ['x']; (x,) = S._first_ngens(1) >>> T = S['y']; (y,) = T._first_ngens(1) >>> generators(T, S) (y,) >>> generators(T, QQ) (y, x) 
- sage.rings.ring_extension.tower_bases(ring, degree)[source]¶
- Return the list of bases of - ring(including itself); if degree is- True, restrict to finite extensions and return in addition the degree of- ringover each base.- INPUT: - ring– a commutative ring
- degree– boolean
 - EXAMPLES: - sage: from sage.rings.ring_extension import tower_bases sage: S.<x> = QQ[] sage: T.<y> = S[] sage: tower_bases(T, False) ([Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field, Univariate Polynomial Ring in x over Rational Field, Rational Field], []) sage: tower_bases(T, True) ([Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field], [1]) sage: K.<a> = Qq(5^2) # needs sage.rings.padics sage: L.<w> = K.extension(x^3 - 5) # needs sage.rings.padics sage: tower_bases(L, True) # needs sage.rings.padics ([5-adic Eisenstein Extension Field in w defined by x^3 - 5 over its base field, 5-adic Unramified Extension Field in a defined by x^2 + 4*x + 2, 5-adic Field with capped relative precision 20], [1, 3, 6]) - >>> from sage.all import * >>> from sage.rings.ring_extension import tower_bases >>> S = QQ['x']; (x,) = S._first_ngens(1) >>> T = S['y']; (y,) = T._first_ngens(1) >>> tower_bases(T, False) ([Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field, Univariate Polynomial Ring in x over Rational Field, Rational Field], []) >>> tower_bases(T, True) ([Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field], [1]) >>> K = Qq(Integer(5)**Integer(2), names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.padics >>> L = K.extension(x**Integer(3) - Integer(5), names=('w',)); (w,) = L._first_ngens(1)# needs sage.rings.padics >>> tower_bases(L, True) # needs sage.rings.padics ([5-adic Eisenstein Extension Field in w defined by x^3 - 5 over its base field, 5-adic Unramified Extension Field in a defined by x^2 + 4*x + 2, 5-adic Field with capped relative precision 20], [1, 3, 6]) 
- sage.rings.ring_extension.variable_names(ring, base)[source]¶
- Return the variable names of the generators of - ringover- base.- INPUT: - ring– a commutative ring
- base– a commutative ring
 - EXAMPLES: - sage: from sage.rings.ring_extension import variable_names sage: S.<x> = QQ[] sage: T.<y> = S[] sage: variable_names(T, S) ('y',) sage: variable_names(T, QQ) ('y', 'x') - >>> from sage.all import * >>> from sage.rings.ring_extension import variable_names >>> S = QQ['x']; (x,) = S._first_ngens(1) >>> T = S['y']; (y,) = T._first_ngens(1) >>> variable_names(T, S) ('y',) >>> variable_names(T, QQ) ('y', 'x')