Homomorphisms of rings¶
We give a large number of examples of ring homomorphisms.
EXAMPLES:
Natural inclusion \(\ZZ \hookrightarrow \QQ\):
sage: H = Hom(ZZ, QQ)
sage: phi = H([1])
sage: phi(10)
10
sage: phi(3/1)
3
sage: phi(2/3)
Traceback (most recent call last):
...
TypeError: 2/3 fails to convert into the map's domain Integer Ring, but a `pushforward` method is not properly implemented
There is no homomorphism in the other direction:
sage: H = Hom(QQ, ZZ)
sage: H([1])
Traceback (most recent call last):
...
ValueError: relations do not all (canonically) map to 0 under map determined by images of generators
EXAMPLES:
Reduction to finite field:
sage: H = Hom(ZZ, GF(9, 'a'))
sage: phi = H([1])
sage: phi(5)
2
sage: psi = H([4])
sage: psi(5)
2
Map from single variable polynomial ring:
sage: R.<x> = ZZ[]
sage: phi = R.hom([2], GF(5))
sage: phi
Ring morphism:
From: Univariate Polynomial Ring in x over Integer Ring
To: Finite Field of size 5
Defn: x > 2
sage: phi(x + 12)
4
Identity map on the real numbers:
sage: f = RR.hom([RR(1)]); f
Ring endomorphism of Real Field with 53 bits of precision
Defn: 1.00000000000000 > 1.00000000000000
sage: f(2.5)
2.50000000000000
sage: f = RR.hom( [2.0] )
Traceback (most recent call last):
...
ValueError: relations do not all (canonically) map to 0 under map determined by images of generators
Homomorphism from one precision of field to another.
From smaller to bigger doesn’t make sense:
sage: R200 = RealField(200)
sage: f = RR.hom( R200 )
Traceback (most recent call last):
...
TypeError: natural coercion morphism from Real Field with 53 bits of precision to Real Field with 200 bits of precision not defined
From bigger to small does:
sage: f = RR.hom( RealField(15) )
sage: f(2.5)
2.500
sage: f(RR.pi())
3.142
Inclusion map from the reals to the complexes:
sage: i = RR.hom([CC(1)]); i
Ring morphism:
From: Real Field with 53 bits of precision
To: Complex Field with 53 bits of precision
Defn: 1.00000000000000 > 1.00000000000000
sage: i(RR('3.1'))
3.10000000000000
A map from a multivariate polynomial ring to itself:
sage: R.<x,y,z> = PolynomialRing(QQ,3)
sage: phi = R.hom([y,z,x^2]); phi
Ring endomorphism of Multivariate Polynomial Ring in x, y, z over Rational Field
Defn: x > y
y > z
z > x^2
sage: phi(x+y+z)
x^2 + y + z
An endomorphism of a quotient of a multivariate polynomial ring:
sage: R.<x,y> = PolynomialRing(QQ)
sage: S.<a,b> = quo(R, ideal(1 + y^2))
sage: phi = S.hom([a^2, b])
sage: phi
Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (y^2 + 1)
Defn: a > a^2
b > b
sage: phi(b)
b
sage: phi(a^2 + b^2)
a^4  1
The reduction map from the integers to the integers modulo 8, viewed as a quotient ring:
sage: R = ZZ.quo(8*ZZ)
sage: pi = R.cover()
sage: pi
Ring morphism:
From: Integer Ring
To: Ring of integers modulo 8
Defn: Natural quotient map
sage: pi.domain()
Integer Ring
sage: pi.codomain()
Ring of integers modulo 8
sage: pi(10)
2
sage: pi.lift()
Settheoretic ring morphism:
From: Ring of integers modulo 8
To: Integer Ring
Defn: Choice of lifting map
sage: pi.lift(13)
5
Inclusion of GF(2)
into GF(4,'a')
:
sage: k = GF(2)
sage: i = k.hom(GF(4, 'a'))
sage: i
Ring morphism:
From: Finite Field of size 2
To: Finite Field in a of size 2^2
Defn: 1 > 1
sage: i(0)
0
sage: a = i(1); a.parent()
Finite Field in a of size 2^2
We next compose the inclusion with reduction from the integers to
GF(2)
:
sage: pi = ZZ.hom(k)
sage: pi
Natural morphism:
From: Integer Ring
To: Finite Field of size 2
sage: f = i * pi
sage: f
Composite map:
From: Integer Ring
To: Finite Field in a of size 2^2
Defn: Natural morphism:
From: Integer Ring
To: Finite Field of size 2
then
Ring morphism:
From: Finite Field of size 2
To: Finite Field in a of size 2^2
Defn: 1 > 1
sage: a = f(5); a
1
sage: a.parent()
Finite Field in a of size 2^2
Inclusion from \(\QQ\) to the 3adic field:
sage: phi = QQ.hom(Qp(3, print_mode = 'series'))
sage: phi
Ring morphism:
From: Rational Field
To: 3adic Field with capped relative precision 20
sage: phi.codomain()
3adic Field with capped relative precision 20
sage: phi(394)
1 + 2*3 + 3^2 + 2*3^3 + 3^4 + 3^5 + O(3^20)
An automorphism of a quotient of a univariate polynomial ring:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<sqrt2> = R.quo(x^22)
sage: sqrt2^2
2
sage: (3+sqrt2)^10
993054*sqrt2 + 1404491
sage: c = S.hom([sqrt2])
sage: c(1+sqrt2)
sqrt2 + 1
Note that Sage verifies that the morphism is valid:
sage: (1  sqrt2)^2
2*sqrt2 + 3
sage: c = S.hom([1sqrt2]) # this is not valid
Traceback (most recent call last):
...
ValueError: relations do not all (canonically) map to 0 under map determined by images of generators
Endomorphism of power series ring:
sage: R.<t> = PowerSeriesRing(QQ); R
Power Series Ring in t over Rational Field
sage: f = R.hom([t^2]); f
Ring endomorphism of Power Series Ring in t over Rational Field
Defn: t > t^2
sage: R.set_default_prec(10)
sage: s = 1/(1 + t); s
1  t + t^2  t^3 + t^4  t^5 + t^6  t^7 + t^8  t^9 + O(t^10)
sage: f(s)
1  t^2 + t^4  t^6 + t^8  t^10 + t^12  t^14 + t^16  t^18 + O(t^20)
Frobenius on a power series ring over a finite field:
sage: R.<t> = PowerSeriesRing(GF(5))
sage: f = R.hom([t^5]); f
Ring endomorphism of Power Series Ring in t over Finite Field of size 5
Defn: t > t^5
sage: a = 2 + t + 3*t^2 + 4*t^3 + O(t^4)
sage: b = 1 + t + 2*t^2 + t^3 + O(t^5)
sage: f(a)
2 + t^5 + 3*t^10 + 4*t^15 + O(t^20)
sage: f(b)
1 + t^5 + 2*t^10 + t^15 + O(t^25)
sage: f(a*b)
2 + 3*t^5 + 3*t^10 + t^15 + O(t^20)
sage: f(a)*f(b)
2 + 3*t^5 + 3*t^10 + t^15 + O(t^20)
Homomorphism of Laurent series ring:
sage: R.<t> = LaurentSeriesRing(QQ, 10)
sage: f = R.hom([t^3 + t]); f
Ring endomorphism of Laurent Series Ring in t over Rational Field
Defn: t > t + t^3
sage: s = 2/t^2 + 1/(1 + t); s
2*t^2 + 1  t + t^2  t^3 + t^4  t^5 + t^6  t^7 + t^8  t^9 + O(t^10)
sage: f(s)
2*t^2  3  t + 7*t^2  2*t^3  5*t^4  4*t^5 + 16*t^6  9*t^7 + O(t^8)
sage: f = R.hom([t^3]); f
Ring endomorphism of Laurent Series Ring in t over Rational Field
Defn: t > t^3
sage: f(s)
2*t^6 + 1  t^3 + t^6  t^9 + t^12  t^15 + t^18  t^21 + t^24  t^27 + O(t^30)
Note that the homomorphism must result in a converging Laurent series, so the valuation of the image of the generator must be positive:
sage: R.hom([1/t])
Traceback (most recent call last):
...
ValueError: relations do not all (canonically) map to 0 under map determined by images of generators
sage: R.hom([1])
Traceback (most recent call last):
...
ValueError: relations do not all (canonically) map to 0 under map determined by images of generators
Complex conjugation on cyclotomic fields:
sage: K.<zeta7> = CyclotomicField(7)
sage: c = K.hom([1/zeta7]); c
Ring endomorphism of Cyclotomic Field of order 7 and degree 6
Defn: zeta7 > zeta7^5  zeta7^4  zeta7^3  zeta7^2  zeta7  1
sage: a = (1+zeta7)^5; a
zeta7^5 + 5*zeta7^4 + 10*zeta7^3 + 10*zeta7^2 + 5*zeta7 + 1
sage: c(a)
5*zeta7^5 + 5*zeta7^4  4*zeta7^2  5*zeta7  4
sage: c(zeta7 + 1/zeta7) # this element is obviously fixed by inversion
zeta7^5  zeta7^4  zeta7^3  zeta7^2  1
sage: zeta7 + 1/zeta7
zeta7^5  zeta7^4  zeta7^3  zeta7^2  1
Embedding a number field into the reals:
sage: R.<x> = PolynomialRing(QQ)
sage: K.<beta> = NumberField(x^3  2)
sage: alpha = RR(2)^(1/3); alpha
1.25992104989487
sage: i = K.hom([alpha],check=False); i
Ring morphism:
From: Number Field in beta with defining polynomial x^3  2
To: Real Field with 53 bits of precision
Defn: beta > 1.25992104989487
sage: i(beta)
1.25992104989487
sage: i(beta^3)
2.00000000000000
sage: i(beta^2 + 1)
2.58740105196820
An example from Jim Carlson:
sage: K = QQ # by the way :)
sage: R.<a,b,c,d> = K[]; R
Multivariate Polynomial Ring in a, b, c, d over Rational Field
sage: S.<u> = K[]; S
Univariate Polynomial Ring in u over Rational Field
sage: f = R.hom([0,0,0,u], S); f
Ring morphism:
From: Multivariate Polynomial Ring in a, b, c, d over Rational Field
To: Univariate Polynomial Ring in u over Rational Field
Defn: a > 0
b > 0
c > 0
d > u
sage: f(a+b+c+d)
u
sage: f( (a+b+c+d)^2 )
u^2
sage: K.<zeta7> = CyclotomicField(7)
sage: c = K.hom([1/zeta7])
sage: c == loads(dumps(c))
True
sage: R.<t> = PowerSeriesRing(GF(5))
sage: f = R.hom([t^5])
sage: f == loads(dumps(f))
True
We define the identity map in many possible ways. These should all compare equal:
sage: k = GF(2)
sage: R.<x> = k[]
sage: F4.<a> = R.quo(x^2+x+1)
sage: H = End(F4)
sage: from sage.rings.morphism import *
sage: phi1 = H.identity(); phi1
Identity endomorphism of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1
sage: phi2 = H([a]); phi2
Ring endomorphism of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1
Defn: a > a
sage: phi3 = RingHomomorphism_from_base(H, R.hom([x])); phi3
Ring endomorphism of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1
Defn: Induced from base ring by
Ring endomorphism of Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)
Defn: x > x
sage: phi4 = RingHomomorphism_cover(H); phi4
Ring endomorphism of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1
Defn: Natural quotient map
sage: phi5 = F4.frobenius_endomorphism() ^ 2; phi5
Frobenius endomorphism x > x^(2^2) of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1
sage: maps = [phi1, phi2, phi3, phi4, phi5]
sage: for f in maps:
....: for g in maps:
....: if f != g:
....: print("{} != {}".format(f, g))

class
sage.rings.morphism.
FrobeniusEndomorphism_generic
¶ Bases:
sage.rings.morphism.RingHomomorphism
A class implementing Frobenius endomorphisms on rings of prime characteristic.

power
()¶ Return an integer \(n\) such that this endomorphism is the \(n\)th power of the absolute (arithmetic) Frobenius.
EXAMPLES:
sage: K.<u> = PowerSeriesRing(GF(5)) sage: Frob = K.frobenius_endomorphism() sage: Frob.power() 1 sage: (Frob^9).power() 9


class
sage.rings.morphism.
RingHomomorphism
¶ Bases:
sage.rings.morphism.RingMap
Homomorphism of rings.

inverse_image
(I)¶ Return the inverse image of the ideal \(I\) under this ring homomorphism.
EXAMPLES:
This is not implemented in any generality yet:
sage: f = ZZ.hom(Zp(2)) sage: f.inverse_image(ZZ.ideal(2)) Traceback (most recent call last): ... NotImplementedError

lift
(x=None)¶ Return a lifting homomorphism associated to this homomorphism, if it has been defined.
If
x
is notNone
, return the value of the lift morphism onx
.EXAMPLES:
sage: R.<x,y> = QQ[] sage: f = R.hom([x,x]) sage: f(x+y) 2*x sage: f.lift() Traceback (most recent call last): ... ValueError: no lift map defined sage: g = R.hom(R) sage: f._set_lift(g) sage: f.lift() == g True sage: f.lift(x) x

pushforward
(I)¶ Returns the pushforward of the ideal \(I\) under this ring homomorphism.
EXAMPLES:
sage: R.<x,y> = QQ[]; S.<xx,yy> = R.quo([x^2,y^2]); f = S.cover() sage: f.pushforward(R.ideal([x,3*x+x*y+y^2])) Ideal (xx, xx*yy + 3*xx) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2)


class
sage.rings.morphism.
RingHomomorphism_coercion
¶ Bases:
sage.rings.morphism.RingHomomorphism
A ring homomorphism that is a coercion.

class
sage.rings.morphism.
RingHomomorphism_cover
¶ Bases:
sage.rings.morphism.RingHomomorphism
A homomorphism induced by quotienting a ring out by an ideal.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ, 2) sage: S.<a,b> = R.quo(x^2 + y^2) sage: phi = S.cover(); phi Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) Defn: Natural quotient map sage: phi(x+y) a + b

kernel
()¶ Return the kernel of this covering morphism, which is the ideal that was quotiented out by.
EXAMPLES:
sage: f = Zmod(6).cover() sage: f.kernel() Principal ideal (6) of Integer Ring


class
sage.rings.morphism.
RingHomomorphism_from_base
¶ Bases:
sage.rings.morphism.RingHomomorphism
A ring homomorphism determined by a ring homomorphism of the base ring.
AUTHOR:
 Simon King (initial version, 20100430)
EXAMPLES:
We define two polynomial rings and a ring homomorphism:
sage: R.<x,y> = QQ[] sage: S.<z> = QQ[] sage: f = R.hom([2*z,3*z],S)
Now we construct polynomial rings based on
R
andS
, and letf
act on the coefficients:sage: PR.<t> = R[] sage: PS = S['t'] sage: Pf = PR.hom(f,PS) sage: Pf Ring morphism: From: Univariate Polynomial Ring in t over Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in t over Univariate Polynomial Ring in z over Rational Field Defn: Induced from base ring by Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in z over Rational Field Defn: x > 2*z y > 3*z sage: p = (x  4*y + 1/13)*t^2 + (1/2*x^2  1/3*y^2)*t + 2*y^2 + x sage: Pf(p) (10*z + 1/13)*t^2  z^2*t + 18*z^2 + 2*z
Similarly, we can construct the induced homomorphism on a matrix ring over our polynomial rings:
sage: MR = MatrixSpace(R,2,2) sage: MS = MatrixSpace(S,2,2) sage: M = MR([x^2 + 1/7*x*y  y^2,  1/2*y^2 + 2*y + 1/6, 4*x^2  14*x, 1/2*y^2 + 13/4*x  2/11*y]) sage: Mf = MR.hom(f,MS) sage: Mf Ring morphism: From: Full MatrixSpace of 2 by 2 dense matrices over Multivariate Polynomial Ring in x, y over Rational Field To: Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in z over Rational Field Defn: Induced from base ring by Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in z over Rational Field Defn: x > 2*z y > 3*z sage: Mf(M) [ 29/7*z^2 9/2*z^2 + 6*z + 1/6] [ 16*z^2  28*z 9/2*z^2 + 131/22*z]
The construction of induced homomorphisms is recursive, and so we have:
sage: MPR = MatrixSpace(PR, 2) sage: MPS = MatrixSpace(PS, 2) sage: M = MPR([( x + y)*t^2 + 58*t  3*x^2 + x*y, ( 1/7*x*y  1/40*x)*t^2 + (5*x^2 + y^2)*t + 2*y, ( 1/3*y + 1)*t^2 + 1/3*x*y + y^2 + 5/2*y + 1/4, (x + 6*y + 1)*t^2]) sage: MPf = MPR.hom(f,MPS); MPf Ring morphism: From: Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in t over Multivariate Polynomial Ring in x, y over Rational Field To: Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in t over Univariate Polynomial Ring in z over Rational Field Defn: Induced from base ring by Ring morphism: From: Univariate Polynomial Ring in t over Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in t over Univariate Polynomial Ring in z over Rational Field Defn: Induced from base ring by Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in z over Rational Field Defn: x > 2*z y > 3*z sage: MPf(M) [ z*t^2 + 58*t  6*z^2 (6/7*z^2  1/20*z)*t^2 + 29*z^2*t + 6*z] [ (z + 1)*t^2 + 11*z^2 + 15/2*z + 1/4 (20*z + 1)*t^2]

underlying_map
()¶ Return the underlying homomorphism of the base ring.
EXAMPLES:
sage: R.<x,y> = QQ[] sage: S.<z> = QQ[] sage: f = R.hom([2*z,3*z],S) sage: MR = MatrixSpace(R,2) sage: MS = MatrixSpace(S,2) sage: g = MR.hom(f,MS) sage: g.underlying_map() == f True

class
sage.rings.morphism.
RingHomomorphism_from_quotient
¶ Bases:
sage.rings.morphism.RingHomomorphism
A ring homomorphism with domain a generic quotient ring.
INPUT:
parent
– a ring homsetHom(R,S)
phi
– a ring homomorphismC > S
, whereC
is the domain ofR.cover()
OUTPUT: a ring homomorphism
The domain \(R\) is a quotient object \(C \to R\), and
R.cover()
is the ring homomorphism \(\varphi: C \to R\). The condition on the elementsim_gens
of \(S\) is that they define a homomorphism \(C \to S\) such that each generator of the kernel of \(\varphi\) maps to \(0\).EXAMPLES:
sage: R.<x, y, z> = PolynomialRing(QQ, 3) sage: S.<a, b, c> = R.quo(x^3 + y^3 + z^3) sage: phi = S.hom([b, c, a]); phi Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by the ideal (x^3 + y^3 + z^3) Defn: a > b b > c c > a sage: phi(a+b+c) a + b + c sage: loads(dumps(phi)) == phi True
Validity of the homomorphism is determined, when possible, and a
TypeError
is raised if there is no homomorphism sending the generators to the given images:sage: S.hom([b^2, c^2, a^2]) Traceback (most recent call last): ... TypeError: images do not define a valid homomorphism

morphism_from_cover
()¶ Underlying morphism used to define this quotient map, i.e., the morphism from the cover of the domain.
EXAMPLES:
sage: R.<x,y> = QQ[]; S.<xx,yy> = R.quo([x^2,y^2]) sage: S.hom([yy,xx]).morphism_from_cover() Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2) Defn: x > yy y > xx

class
sage.rings.morphism.
RingHomomorphism_im_gens
¶ Bases:
sage.rings.morphism.RingHomomorphism
A ring homomorphism determined by the images of generators.

im_gens
()¶ Return the images of the generators of the domain.
OUTPUT:
list
– a copy of the list of gens (it is safe to change this)
EXAMPLES:
sage: R.<x,y> = QQ[] sage: f = R.hom([x,x+y]) sage: f.im_gens() [x, x + y]
We verify that the returned list of images of gens is a copy, so changing it doesn’t change
f
:sage: f.im_gens()[0] = 5 sage: f.im_gens() [x, x + y]


class
sage.rings.morphism.
RingMap
¶ Bases:
sage.categories.morphism.Morphism
Settheoretic map between rings.

class
sage.rings.morphism.
RingMap_lift
¶ Bases:
sage.rings.morphism.RingMap
Given rings \(R\) and \(S\) such that for any \(x \in R\) the function
x.lift()
is an element that naturally coerces to \(S\), this returns the settheoretic ring map \(R \to S\) sending \(x\) tox.lift()
.EXAMPLES:
sage: R.<x,y> = QQ[] sage: S.<xbar,ybar> = R.quo( (x^2 + y^2, y) ) sage: S.lift() Settheoretic ring morphism: From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2, y) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map sage: S.lift() == 0 False
Since trac ticket #11068, it is possible to create quotient rings of noncommutative rings by twosided ideals. It was needed to modify
RingMap_lift
so that rings can be accepted that are no instances ofsage.rings.ring.Ring
, as in the following example:sage: MS = MatrixSpace(GF(5),2,2) sage: I = MS*[MS.0*MS.1,MS.2+MS.3]*MS sage: Q = MS.quo(I) sage: Q.0*Q.1 # indirect doctest [0 1] [0 0]

sage.rings.morphism.
is_RingHomomorphism
(phi)¶ Return
True
ifphi
is of typeRingHomomorphism
.EXAMPLES:
sage: f = Zmod(8).cover() sage: sage.rings.morphism.is_RingHomomorphism(f) doctest:warning ... DeprecationWarning: is_RingHomomorphism() should not be used anymore. Check whether the category_for() your morphism is a subcategory of Rings() instead. See http://trac.sagemath.org/23204 for details. True sage: sage.rings.morphism.is_RingHomomorphism(2/3) False