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 – a list of generators of this extension (over its base) or None (default: None);

• names – a list or a tuple of variable names or None (default: None)

• constructors – a 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

create_object(version, key, **extra_args)[source]#

Return the object associated to a given key.

class sage.rings.ring_extension.RingExtensionFractionField[source]#

A class for ring extensions of the form  extrm{Frac}(A)/A.

Element[source]#
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]#

A class for finite free ring extensions equipped with a basis.

Element[source]#
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 base is 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 base must 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 – a boolean (default: False);

If extend_base is 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_base is 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 base which 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 map is True)

• The reverse isomorphism of the isomorphism above (only included if map is 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 base is 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 base must 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]#

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 – a boolean (default: False);

If extend_base is 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_base is 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]#

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

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

backend(force=False)[source]#

Return the backend of this extension.

INPUT:

• force – a 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

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]

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 base must 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

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 base is 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 base must 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 – a boolean (default: False);

If extend_base is 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_base is 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 r into 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 codomain that sends self.gens() to the entries of im_gens and induces the map base_map on 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 – a 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 base is 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

is_field(proof=True)[source]#

Return whether or not this extension is a field.

INPUT:

• proof – a 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 base is 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 True if 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 base is 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 – an 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

sage.rings.ring_extension.common_base(K, L, degree)[source]#

Return a common base on which K and L are defined.

INPUT:

• K – a commutative ring

• L – a commutative ring

• degree – a boolean; if true, return the degree of K and L over 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 degree is set to True, we only look up for bases on which both K and L are 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 ring over 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 ring over each base.

INPUT:

• ring – a commutative ring

• degree – a 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 ring over 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')