Commutative rings¶
- class sage.categories.commutative_rings.CommutativeRings(base_category)[source]¶
Bases:
CategoryWithAxiom_singleton
The category of commutative rings.
commutative rings with unity, i.e. rings with commutative * and a multiplicative identity
EXAMPLES:
sage: C = CommutativeRings(); C Category of commutative rings sage: C.super_categories() [Category of rings, Category of commutative monoids]
>>> from sage.all import * >>> C = CommutativeRings(); C Category of commutative rings >>> C.super_categories() [Category of rings, Category of commutative monoids]
- class CartesianProducts(category, *args)[source]¶
Bases:
CartesianProductsCategory
- extra_super_categories()[source]¶
Let Sage knows that Cartesian products of commutative rings is a commutative ring.
EXAMPLES:
sage: CommutativeRings().Commutative().CartesianProducts().extra_super_categories() [Category of commutative rings] sage: cartesian_product([ZZ, Zmod(34), ....: QQ, GF(5)]) in CommutativeRings() True
>>> from sage.all import * >>> CommutativeRings().Commutative().CartesianProducts().extra_super_categories() [Category of commutative rings] >>> cartesian_product([ZZ, Zmod(Integer(34)), ... QQ, GF(Integer(5))]) in CommutativeRings() True
- class Finite(base_category)[source]¶
Bases:
CategoryWithAxiom_singleton
Check that Sage knows that Cartesian products of finite commutative rings is a finite commutative ring.
EXAMPLES:
sage: cartesian_product([Zmod(34), ....: GF(5)]) in Rings().Commutative().Finite() True
>>> from sage.all import * >>> cartesian_product([Zmod(Integer(34)), ... GF(Integer(5))]) in Rings().Commutative().Finite() True
- class ParentMethods[source]¶
Bases:
object
- cyclotomic_cosets(q, cosets=None)[source]¶
Return the (multiplicative) orbits of
q
in the ring.Let \(R\) be a finite commutative ring. The group of invertible elements \(R^*\) in \(R\) gives rise to a group action on \(R\) by multiplication. An orbit of the subgroup generated by an invertible element \(q\) is called a \(q\)-cyclotomic coset (since in a finite ring, each invertible element is a root of unity).
These cosets arise in the theory of minimal polynomials of finite fields, duadic codes and combinatorial designs. Fix a primitive element \(z\) of \(GF(q^k)\). The minimal polynomial of \(z^s\) over \(GF(q)\) is given by
\[M_s(x) = \prod_{i \in C_s} (x - z^i),\]where \(C_s\) is the \(q\)-cyclotomic coset mod \(n\) containing \(s\), \(n = q^k - 1\).
Note
When \(R = \ZZ / n \ZZ\) the smallest element of each coset is sometimes called a coset leader. This function returns sorted lists so that the coset leader will always be the first element of the coset.
INPUT:
q
– an invertible element of the ringcosets
– an optional lists of elements ofself
. If provided, the function only return the list of cosets that contain some element fromcosets
.
OUTPUT: list of lists
EXAMPLES:
sage: Zmod(11).cyclotomic_cosets(2) [[0], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]] sage: Zmod(15).cyclotomic_cosets(2) [[0], [1, 2, 4, 8], [3, 6, 9, 12], [5, 10], [7, 11, 13, 14]]
>>> from sage.all import * >>> Zmod(Integer(11)).cyclotomic_cosets(Integer(2)) [[0], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]] >>> Zmod(Integer(15)).cyclotomic_cosets(Integer(2)) [[0], [1, 2, 4, 8], [3, 6, 9, 12], [5, 10], [7, 11, 13, 14]]
Since the group of invertible elements of a finite field is cyclic, the set of squares is a particular case of cyclotomic coset:
sage: # needs sage.rings.finite_rings sage: K = GF(25, 'z') sage: a = K.multiplicative_generator() sage: K.cyclotomic_cosets(a**2, cosets=[1]) [[1, 2, 3, 4, z + 1, z + 3, 2*z + 1, 2*z + 2, 3*z + 3, 3*z + 4, 4*z + 2, 4*z + 4]] sage: sorted(b for b in K if not b.is_zero() and b.is_square()) [1, 2, 3, 4, z + 1, z + 3, 2*z + 1, 2*z + 2, 3*z + 3, 3*z + 4, 4*z + 2, 4*z + 4]
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(25), 'z') >>> a = K.multiplicative_generator() >>> K.cyclotomic_cosets(a**Integer(2), cosets=[Integer(1)]) [[1, 2, 3, 4, z + 1, z + 3, 2*z + 1, 2*z + 2, 3*z + 3, 3*z + 4, 4*z + 2, 4*z + 4]] >>> sorted(b for b in K if not b.is_zero() and b.is_square()) [1, 2, 3, 4, z + 1, z + 3, 2*z + 1, 2*z + 2, 3*z + 3, 3*z + 4, 4*z + 2, 4*z + 4]
We compute some examples of minimal polynomials:
sage: # needs sage.rings.finite_rings sage: K = GF(27, 'z') sage: a = K.multiplicative_generator() sage: R.<X> = PolynomialRing(K, 'X') sage: a.minimal_polynomial('X') X^3 + 2*X + 1 sage: cyc3 = Zmod(26).cyclotomic_cosets(3, cosets=[1]); cyc3 [[1, 3, 9]] sage: prod(X - a**i for i in cyc3[0]) # needs sage.rings.finite_rings X^3 + 2*X + 1 sage: (a**7).minimal_polynomial('X') # needs sage.rings.finite_rings X^3 + X^2 + 2*X + 1 sage: cyc7 = Zmod(26).cyclotomic_cosets(3, cosets=[7]); cyc7 [[7, 11, 21]] sage: prod(X - a**i for i in cyc7[0]) # needs sage.rings.finite_rings X^3 + X^2 + 2*X + 1
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(27), 'z') >>> a = K.multiplicative_generator() >>> R = PolynomialRing(K, 'X', names=('X',)); (X,) = R._first_ngens(1) >>> a.minimal_polynomial('X') X^3 + 2*X + 1 >>> cyc3 = Zmod(Integer(26)).cyclotomic_cosets(Integer(3), cosets=[Integer(1)]); cyc3 [[1, 3, 9]] >>> prod(X - a**i for i in cyc3[Integer(0)]) # needs sage.rings.finite_rings X^3 + 2*X + 1 >>> (a**Integer(7)).minimal_polynomial('X') # needs sage.rings.finite_rings X^3 + X^2 + 2*X + 1 >>> cyc7 = Zmod(Integer(26)).cyclotomic_cosets(Integer(3), cosets=[Integer(7)]); cyc7 [[7, 11, 21]] >>> prod(X - a**i for i in cyc7[Integer(0)]) # needs sage.rings.finite_rings X^3 + X^2 + 2*X + 1
Cyclotomic cosets of fields are useful in combinatorial design theory to provide so called difference families (see Wikipedia article Difference_set and
difference_family
). This is illustrated on the following examples:sage: K = GF(5) sage: a = K.multiplicative_generator() # needs sage.libs.pari sage: H = K.cyclotomic_cosets(a**2, cosets=[1, 2]); H # needs sage.rings.finite_rings [[1, 4], [2, 3]] sage: sorted(x - y for D in H for x in D for y in D if x != y) # needs sage.rings.finite_rings [1, 2, 3, 4] sage: K = GF(37) sage: a = K.multiplicative_generator() # needs sage.libs.pari sage: H = K.cyclotomic_cosets(a**4, cosets=[1]); H # needs sage.rings.finite_rings [[1, 7, 9, 10, 12, 16, 26, 33, 34]] sage: sorted(x - y for D in H for x in D for y in D if x != y) # needs sage.rings.finite_rings [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ..., 33, 34, 34, 35, 35, 36, 36]
>>> from sage.all import * >>> K = GF(Integer(5)) >>> a = K.multiplicative_generator() # needs sage.libs.pari >>> H = K.cyclotomic_cosets(a**Integer(2), cosets=[Integer(1), Integer(2)]); H # needs sage.rings.finite_rings [[1, 4], [2, 3]] >>> sorted(x - y for D in H for x in D for y in D if x != y) # needs sage.rings.finite_rings [1, 2, 3, 4] >>> K = GF(Integer(37)) >>> a = K.multiplicative_generator() # needs sage.libs.pari >>> H = K.cyclotomic_cosets(a**Integer(4), cosets=[Integer(1)]); H # needs sage.rings.finite_rings [[1, 7, 9, 10, 12, 16, 26, 33, 34]] >>> sorted(x - y for D in H for x in D for y in D if x != y) # needs sage.rings.finite_rings [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ..., 33, 34, 34, 35, 35, 36, 36]
The method
cyclotomic_cosets
works on any finite commutative ring:sage: R = cartesian_product([GF(7), Zmod(14)]) sage: a = R((3,5)) sage: R.cyclotomic_cosets((3,5), [(1,1)]) [[(1, 1), (2, 11), (3, 5), (4, 9), (5, 3), (6, 13)]]
>>> from sage.all import * >>> R = cartesian_product([GF(Integer(7)), Zmod(Integer(14))]) >>> a = R((Integer(3),Integer(5))) >>> R.cyclotomic_cosets((Integer(3),Integer(5)), [(Integer(1),Integer(1))]) [[(1, 1), (2, 11), (3, 5), (4, 9), (5, 3), (6, 13)]]
- extra_super_categories()[source]¶
Let Sage know that finite commutative rings are Noetherian.
EXAMPLES:
sage: CommutativeRings().Finite().extra_super_categories() [Category of noetherian rings]
>>> from sage.all import * >>> CommutativeRings().Finite().extra_super_categories() [Category of noetherian rings]
- class ParentMethods[source]¶
Bases:
object
- derivation(arg=None, twist=None)[source]¶
Return the twisted or untwisted derivation over this ring specified by
arg
.Note
A twisted derivation with respect to \(\theta\) (or a \(\theta\)-derivation for short) is an additive map \(d\) satisfying the following axiom for all \(x, y\) in the domain:
\[d(xy) = \theta(x) d(y) + d(x) y.\]INPUT:
arg
– (optional) a generator or a list of coefficients that defines the derivationtwist
– (optional) the twisting homomorphism
EXAMPLES:
sage: R.<x,y,z> = QQ[] sage: R.derivation() # needs sage.modules d/dx
>>> from sage.all import * >>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3) >>> R.derivation() # needs sage.modules d/dx
In that case,
arg
could be a generator:sage: R.derivation(y) # needs sage.modules d/dy
>>> from sage.all import * >>> R.derivation(y) # needs sage.modules d/dy
or a list of coefficients:
sage: R.derivation([1,2,3]) # needs sage.modules d/dx + 2*d/dy + 3*d/dz
>>> from sage.all import * >>> R.derivation([Integer(1),Integer(2),Integer(3)]) # needs sage.modules d/dx + 2*d/dy + 3*d/dz
It is not possible to define derivations with respect to a polynomial which is not a variable:
sage: R.derivation(x^2) # needs sage.modules Traceback (most recent call last): ... ValueError: unable to create the derivation
>>> from sage.all import * >>> R.derivation(x**Integer(2)) # needs sage.modules Traceback (most recent call last): ... ValueError: unable to create the derivation
Here is an example with twisted derivations:
sage: R.<x,y,z> = QQ[] sage: theta = R.hom([x^2, y^2, z^2]) sage: f = R.derivation(twist=theta); f # needs sage.modules 0 sage: f.parent() # needs sage.modules Module of twisted derivations over Multivariate Polynomial Ring in x, y, z over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2)
>>> from sage.all import * >>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3) >>> theta = R.hom([x**Integer(2), y**Integer(2), z**Integer(2)]) >>> f = R.derivation(twist=theta); f # needs sage.modules 0 >>> f.parent() # needs sage.modules Module of twisted derivations over Multivariate Polynomial Ring in x, y, z over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2)
Specifying a scalar, the returned twisted derivation is the corresponding multiple of \(\theta - id\):
sage: R.derivation(1, twist=theta) # needs sage.modules [x |--> x^2, y |--> y^2, z |--> z^2] - id sage: R.derivation(x, twist=theta) # needs sage.modules x*([x |--> x^2, y |--> y^2, z |--> z^2] - id)
>>> from sage.all import * >>> R.derivation(Integer(1), twist=theta) # needs sage.modules [x |--> x^2, y |--> y^2, z |--> z^2] - id >>> R.derivation(x, twist=theta) # needs sage.modules x*([x |--> x^2, y |--> y^2, z |--> z^2] - id)
- derivation_module(codomain=None, twist=None)[source]¶
Return the module of derivations over this ring.
INPUT:
codomain
– an algebra over this ring or a ring homomorphism whose domain is this ring orNone
(default:None
); if it is a morphism, the codomain of derivations will be the codomain of the morphism viewed as an algebra overself
through the given morphism; ifNone
, the codomain will be this ringtwist
– a morphism from this ring tocodomain
orNone
(default:None
); ifNone
, the coercion map from this ring tocodomain
will be used
Note
A twisted derivation with respect to \(\theta\) (or a \(\theta\)-derivation for short) is an additive map \(d\) satisfying the following axiom for all \(x, y\) in the domain:
\[d(xy) = \theta(x) d(y) + d(x) y.\]EXAMPLES:
sage: R.<x,y,z> = QQ[] sage: M = R.derivation_module(); M # needs sage.modules Module of derivations over Multivariate Polynomial Ring in x, y, z over Rational Field sage: M.gens() # needs sage.modules (d/dx, d/dy, d/dz)
>>> from sage.all import * >>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3) >>> M = R.derivation_module(); M # needs sage.modules Module of derivations over Multivariate Polynomial Ring in x, y, z over Rational Field >>> M.gens() # needs sage.modules (d/dx, d/dy, d/dz)
We can specify a different codomain:
sage: K = R.fraction_field() sage: M = R.derivation_module(K); M # needs sage.modules Module of derivations from Multivariate Polynomial Ring in x, y, z over Rational Field to Fraction Field of Multivariate Polynomial Ring in x, y, z over Rational Field sage: M.gen() / x # needs sage.modules 1/x*d/dx
>>> from sage.all import * >>> K = R.fraction_field() >>> M = R.derivation_module(K); M # needs sage.modules Module of derivations from Multivariate Polynomial Ring in x, y, z over Rational Field to Fraction Field of Multivariate Polynomial Ring in x, y, z over Rational Field >>> M.gen() / x # needs sage.modules 1/x*d/dx
Here is an example with a non-canonical defining morphism:
sage: ev = R.hom([QQ(0), QQ(1), QQ(2)]) sage: ev Ring morphism: From: Multivariate Polynomial Ring in x, y, z over Rational Field To: Rational Field Defn: x |--> 0 y |--> 1 z |--> 2 sage: M = R.derivation_module(ev) # needs sage.modules sage: M # needs sage.modules Module of derivations from Multivariate Polynomial Ring in x, y, z over Rational Field to Rational Field
>>> from sage.all import * >>> ev = R.hom([QQ(Integer(0)), QQ(Integer(1)), QQ(Integer(2))]) >>> ev Ring morphism: From: Multivariate Polynomial Ring in x, y, z over Rational Field To: Rational Field Defn: x |--> 0 y |--> 1 z |--> 2 >>> M = R.derivation_module(ev) # needs sage.modules >>> M # needs sage.modules Module of derivations from Multivariate Polynomial Ring in x, y, z over Rational Field to Rational Field
Elements in \(M\) acts as derivations at \((0,1,2)\):
sage: # needs sage.modules sage: Dx = M.gen(0); Dx d/dx sage: Dy = M.gen(1); Dy d/dy sage: Dz = M.gen(2); Dz d/dz sage: f = x^2 + y^2 + z^2 sage: Dx(f) # = 2*x evaluated at (0,1,2) 0 sage: Dy(f) # = 2*y evaluated at (0,1,2) 2 sage: Dz(f) # = 2*z evaluated at (0,1,2) 4
>>> from sage.all import * >>> # needs sage.modules >>> Dx = M.gen(Integer(0)); Dx d/dx >>> Dy = M.gen(Integer(1)); Dy d/dy >>> Dz = M.gen(Integer(2)); Dz d/dz >>> f = x**Integer(2) + y**Integer(2) + z**Integer(2) >>> Dx(f) # = 2*x evaluated at (0,1,2) 0 >>> Dy(f) # = 2*y evaluated at (0,1,2) 2 >>> Dz(f) # = 2*z evaluated at (0,1,2) 4
An example with a twisting homomorphism:
sage: theta = R.hom([x^2, y^2, z^2]) sage: M = R.derivation_module(twist=theta); M # needs sage.modules Module of twisted derivations over Multivariate Polynomial Ring in x, y, z over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2)
>>> from sage.all import * >>> theta = R.hom([x**Integer(2), y**Integer(2), z**Integer(2)]) >>> M = R.derivation_module(twist=theta); M # needs sage.modules Module of twisted derivations over Multivariate Polynomial Ring in x, y, z over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2)
See also
- frobenius_endomorphism(n=1)[source]¶
Return the Frobenius endomorphism.
INPUT:
n
– nonnegative integer (default: 1)
OUTPUT:
The \(n\)-th power of the absolute arithmetic Frobenius endomorphism on this commutative ring.
EXAMPLES:
sage: K.<u> = PowerSeriesRing(GF(5)) sage: Frob = K.frobenius_endomorphism(); Frob Frobenius endomorphism x |--> x^5 of Power Series Ring in u over Finite Field of size 5 sage: Frob(u) u^5
>>> from sage.all import * >>> K = PowerSeriesRing(GF(Integer(5)), names=('u',)); (u,) = K._first_ngens(1) >>> Frob = K.frobenius_endomorphism(); Frob Frobenius endomorphism x |--> x^5 of Power Series Ring in u over Finite Field of size 5 >>> Frob(u) u^5
We can specify a power:
sage: f = K.frobenius_endomorphism(2); f Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u over Finite Field of size 5 sage: f(1+u) 1 + u^25
>>> from sage.all import * >>> f = K.frobenius_endomorphism(Integer(2)); f Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u over Finite Field of size 5 >>> f(Integer(1)+u) 1 + u^25
- is_commutative()[source]¶
Return whether the ring is commutative.
The answer is
True
only if the category is a sub-category ofCommutativeRings
.It is recommended to use instead
R in Rings().Commutative()
.EXAMPLES:
sage: QQ.is_commutative() True sage: QQ['x,y,z'].is_commutative() True
>>> from sage.all import * >>> QQ.is_commutative() True >>> QQ['x,y,z'].is_commutative() True
- over(base=None, gen=None, gens=None, name=None, names=None)[source]¶
Return this ring, considered as an extension of
base
.INPUT:
base
– a commutative ring or a morphism orNone
(default:None
); the base of this extension or its defining morphismgen
– a generator of this extension (over its base) orNone
(default:None
)gens
– list of generators of this extension (over its base) orNone
(default:None
)name
– a variable name orNone
(default:None
)names
– list or a tuple of variable names orNone
(default:None
)
EXAMPLES:
We construct an extension of finite fields:
sage: # needs sage.rings.finite_rings sage: F = GF(5^2) sage: k = GF(5^4) sage: z4 = k.gen() sage: K = k.over(F); K # needs sage.modules Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 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); K # needs sage.modules Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
If not explicitly given, the default generator of the top ring (here k) is used and the same name is kept:
sage: K.gen() # needs sage.modules sage.rings.finite_rings z4 sage: K(z4) # needs sage.modules sage.rings.finite_rings z4
>>> from sage.all import * >>> K.gen() # needs sage.modules sage.rings.finite_rings z4 >>> K(z4) # needs sage.modules sage.rings.finite_rings z4
However, it is possible to specify another generator and/or another name. For example:
sage: # needs sage.modules sage.rings.finite_rings sage: Ka = k.over(F, name='a'); Ka Field in a with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base sage: Ka.gen() a sage: Ka(z4) a sage: # needs sage.modules sage.rings.finite_rings sage: Kb = k.over(F, gen=-z4+1, name='b') sage: Kb Field in b with defining polynomial x^2 + z2*x + 4 over its base sage: Kb.gen() b sage: Kb(-z4+1) b
>>> from sage.all import * >>> # needs sage.modules sage.rings.finite_rings >>> Ka = k.over(F, name='a'); Ka Field in a with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base >>> Ka.gen() a >>> Ka(z4) a >>> # needs sage.modules sage.rings.finite_rings >>> Kb = k.over(F, gen=-z4+Integer(1), name='b') >>> Kb Field in b with defining polynomial x^2 + z2*x + 4 over its base >>> Kb.gen() b >>> Kb(-z4+Integer(1)) b
Note that the shortcut
K.<a>
is also available:sage: KKa.<a> = k.over(F) # needs sage.modules sage.rings.finite_rings sage: KKa is Ka # needs sage.modules sage.rings.finite_rings True
>>> from sage.all import * >>> KKa = k.over(F, names=('a',)); (a,) = KKa._first_ngens(1)# needs sage.modules sage.rings.finite_rings >>> KKa is Ka # needs sage.modules sage.rings.finite_rings True
Building an extension on top of another extension is allowed:
sage: L = GF(5^12).over(K); L # needs sage.modules sage.rings.finite_rings Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base sage: L.base_ring() # needs sage.modules sage.rings.finite_rings Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
>>> from sage.all import * >>> L = GF(Integer(5)**Integer(12)).over(K); L # needs sage.modules sage.rings.finite_rings Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base >>> L.base_ring() # needs sage.modules sage.rings.finite_rings Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base
The successive bases of an extension are accessible via the method
sage.rings.ring_extension.RingExtension_generic.bases()
:sage: L.bases() # needs sage.modules sage.rings.finite_rings [Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base, Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base, Finite Field in z2 of size 5^2]
>>> from sage.all import * >>> L.bases() # needs sage.modules sage.rings.finite_rings [Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base, Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base, Finite Field in z2 of size 5^2]
When
base
is omitted, the canonical base of the ring is used:sage: S.<x> = QQ[] sage: E = S.over(); E # needs sage.modules Univariate Polynomial Ring in x over Rational Field over its base sage: E.base_ring() # needs sage.modules Rational Field
>>> from sage.all import * >>> S = QQ['x']; (x,) = S._first_ngens(1) >>> E = S.over(); E # needs sage.modules Univariate Polynomial Ring in x over Rational Field over its base >>> E.base_ring() # needs sage.modules Rational Field
Here is an example where
base
is a defining morphism:sage: # needs sage.modules sage.rings.number_field sage: k.<a> = QQ.extension(x^2 - 2) sage: l.<b> = QQ.extension(x^4 - 2) sage: f = k.hom([b^2]) sage: L = l.over(f) sage: L Field in b with defining polynomial x^2 - a over its base sage: L.base_ring() Number Field in a with defining polynomial x^2 - 2
>>> from sage.all import * >>> # needs sage.modules sage.rings.number_field >>> k = QQ.extension(x**Integer(2) - Integer(2), names=('a',)); (a,) = k._first_ngens(1) >>> l = QQ.extension(x**Integer(4) - Integer(2), names=('b',)); (b,) = l._first_ngens(1) >>> f = k.hom([b**Integer(2)]) >>> L = l.over(f) >>> L Field in b with defining polynomial x^2 - a over its base >>> L.base_ring() Number Field in a with defining polynomial x^2 - 2
Similarly, one can create a tower of extensions:
sage: # needs sage.modules sage.rings.number_field sage: K = k.over() sage: L = l.over(Hom(K, l)(f)); L Field in b with defining polynomial x^2 - a over its base sage: L.base_ring() Field in a with defining polynomial x^2 - 2 over its base sage: L.bases() [Field in b with defining polynomial x^2 - a over its base, Field in a with defining polynomial x^2 - 2 over its base, Rational Field]
>>> from sage.all import * >>> # needs sage.modules sage.rings.number_field >>> K = k.over() >>> L = l.over(Hom(K, l)(f)); L Field in b with defining polynomial x^2 - a over its base >>> L.base_ring() Field in a with defining polynomial x^2 - 2 over its base >>> L.bases() [Field in b with defining polynomial x^2 - a over its base, Field in a with defining polynomial x^2 - 2 over its base, Rational Field]