# 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'))                                                       # optional - sage.rings.finite_rings
sage: phi = H([1])                                                                  # optional - sage.rings.finite_rings
sage: phi(5)                                                                        # optional - sage.rings.finite_rings
2
sage: psi = H([4])                                                                  # optional - sage.rings.finite_rings
sage: psi(5)                                                                        # optional - sage.rings.finite_rings
2


Map from single variable polynomial ring:

sage: R.<x> = ZZ[]
sage: phi = R.hom([2], GF(5))                                                       # optional - sage.rings.finite_rings
sage: phi                                                                           # optional - sage.rings.finite_rings
Ring morphism:
From: Univariate Polynomial Ring in x over Integer Ring
To:   Finite Field of size 5
Defn: x |--> 2
sage: phi(x + 12)                                                                   # optional - sage.rings.finite_rings
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 multi-variate 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()
Set-theoretic 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)                                                                     # optional - sage.rings.finite_rings
sage: i = k.hom(GF(4, 'a'))                                                         # optional - sage.rings.finite_rings
sage: i                                                                             # optional - sage.rings.finite_rings
Ring morphism:
From: Finite Field of size 2
To:   Finite Field in a of size 2^2
Defn: 1 |--> 1
sage: i(0)                                                                          # optional - sage.rings.finite_rings
0
sage: a = i(1); a.parent()                                                          # optional - sage.rings.finite_rings
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)                                                                # optional - sage.rings.finite_rings
sage: pi                                                                            # optional - sage.rings.finite_rings
Natural morphism:
From: Integer Ring
To:   Finite Field of size 2
sage: f = i * pi                                                                    # optional - sage.rings.finite_rings
sage: f                                                                             # optional - sage.rings.finite_rings
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                                                                   # optional - sage.rings.finite_rings
1
sage: a.parent()                                                                    # optional - sage.rings.finite_rings
Finite Field in a of size 2^2


Inclusion from $$\QQ$$ to the 3-adic field:

sage: phi = QQ.hom(Qp(3, print_mode='series'))                                      # optional - sage.rings.padics
sage: phi                                                                           # optional - sage.rings.padics
Ring morphism:
From: Rational Field
To:   3-adic Field with capped relative precision 20
sage: phi.codomain()                                                                # optional - sage.rings.padics
3-adic Field with capped relative precision 20
sage: phi(394)                                                                      # optional - sage.rings.padics
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^2 - 2)
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([1-sqrt2])    # 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, default_prec=10); 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: 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))                                                # optional - sage.rings.finite_rings
sage: f = R.hom([t^5]); f                                                           # optional - sage.rings.finite_rings
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)                                            # optional - sage.rings.finite_rings
sage: b = 1 + t + 2*t^2 + t^3 + O(t^5)                                              # optional - sage.rings.finite_rings
sage: f(a)                                                                          # optional - sage.rings.finite_rings
2 + t^5 + 3*t^10 + 4*t^15 + O(t^20)
sage: f(b)                                                                          # optional - sage.rings.finite_rings
1 + t^5 + 2*t^10 + t^15 + O(t^25)
sage: f(a*b)                                                                        # optional - sage.rings.finite_rings
2 + 3*t^5 + 3*t^10 + t^15 + O(t^20)
sage: f(a)*f(b)                                                                     # optional - sage.rings.finite_rings
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

class sage.rings.morphism.FrobeniusEndomorphism_generic#

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))                                        # optional - sage.rings.finite_rings
sage: Frob = K.frobenius_endomorphism()                                     # optional - sage.rings.finite_rings
sage: Frob.power()                                                          # optional - sage.rings.finite_rings
1
sage: (Frob^9).power()                                                      # optional - sage.rings.finite_rings
9

class sage.rings.morphism.RingHomomorphism#

Bases: RingMap

Homomorphism of rings.

inverse()#

Return the inverse of this ring homomorphism if it exists.

Raises a ZeroDivisionError if the inverse does not exist.

ALGORITHM:

By default, this computes a Gröbner basis of the ideal corresponding to the graph of the ring homomorphism.

EXAMPLES:

sage: R.<t> = QQ[]
sage: f = R.hom([2*t - 1], R)
sage: f.inverse()                                                           # optional - sage.libs.singular
Ring endomorphism of Univariate Polynomial Ring in t over Rational Field
Defn: t |--> 1/2*t + 1/2


The following non-linear homomorphism is not invertible, but it induces an isomorphism on a quotient ring:

sage: R.<x,y,z> = QQ[]
sage: f = R.hom([y*z, x*z, x*y], R)
sage: f.inverse()                                                           # optional - sage.libs.singular
Traceback (most recent call last):
...
ZeroDivisionError: ring homomorphism not surjective
sage: f.is_injective()                                                      # optional - sage.libs.singular
True
sage: Q.<x,y,z> = R.quotient(x*y*z - 1)                                     # optional - sage.libs.singular
sage: g = Q.hom([y*z, x*z, x*y], Q)                                         # optional - sage.libs.singular
sage: g.inverse()                                                           # optional - sage.libs.singular
Ring endomorphism of Quotient of Multivariate Polynomial Ring
in x, y, z over Rational Field by the ideal (x*y*z - 1)
Defn: x |--> y*z
y |--> x*z
z |--> x*y


Homomorphisms over the integers are supported:

sage: S.<x,y> = ZZ[]
sage: f = S.hom([x + 2*y, x + 3*y], S)
sage: f.inverse()                                                           # optional - sage.libs.singular
Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring
Defn: x |--> 3*x - 2*y
y |--> -x + y
sage: (f.inverse() * f).is_identity()                                       # optional - sage.libs.singular
True


The following homomorphism is invertible over the rationals, but not over the integers:

sage: g = S.hom([x + y, x - y - 2], S)
sage: g.inverse()                                                           # optional - sage.libs.singular
Traceback (most recent call last):
...
ZeroDivisionError: ring homomorphism not surjective
sage: R.<x,y> = QQ[x,y]
sage: h = R.hom([x + y, x - y - 2], R)
sage: (h.inverse() * h).is_identity()                                       # optional - sage.libs.singular
True


This example by M. Nagata is a wild automorphism:

sage: R.<x,y,z> = QQ[]
sage: sigma = R.hom([x - 2*y*(z*x+y^2) - z*(z*x+y^2)^2,
....:                y + z*(z*x+y^2), z], R)
sage: tau = sigma.inverse(); tau                                            # optional - sage.libs.singular
Ring endomorphism of Multivariate Polynomial Ring in x, y, z over
Rational Field
Defn: x |--> -y^4*z - 2*x*y^2*z^2 - x^2*z^3 + 2*y^3 + 2*x*y*z + x
y |--> -y^2*z - x*z^2 + y
z |--> z
sage: (tau * sigma).is_identity()                                           # optional - sage.libs.singular
True


We compute the triangular automorphism that converts moments to cumulants, as well as its inverse, using the moment generating function. The choice of a term ordering can have a great impact on the computation time of a Gröbner basis, so here we choose a weighted ordering such that the images of the generators are homogeneous polynomials.

sage: d = 12
sage: T = TermOrder('wdegrevlex', [1..d])
sage: R = PolynomialRing(QQ, ['x%s' % j for j in (1..d)], order=T)
sage: S.<t> = PowerSeriesRing(R)
sage: egf = S([0] + list(R.gens())).ogf_to_egf().exp(prec=d+1)
sage: phi = R.hom(egf.egf_to_ogf().list()[1:], R)
sage: phi.im_gens()[:5]
[x1,
x1^2 + x2,
x1^3 + 3*x1*x2 + x3,
x1^4 + 6*x1^2*x2 + 3*x2^2 + 4*x1*x3 + x4,
x1^5 + 10*x1^3*x2 + 15*x1*x2^2 + 10*x1^2*x3 + 10*x2*x3 + 5*x1*x4 + x5]
sage: all(p.is_homogeneous() for p in phi.im_gens())
True
sage: phi.inverse().im_gens()[:5]                                           # optional - sage.libs.singular
[x1,
-x1^2 + x2,
2*x1^3 - 3*x1*x2 + x3,
-6*x1^4 + 12*x1^2*x2 - 3*x2^2 - 4*x1*x3 + x4,
24*x1^5 - 60*x1^3*x2 + 30*x1*x2^2 + 20*x1^2*x3 - 10*x2*x3 - 5*x1*x4 + x5]
sage: (phi.inverse() * phi).is_identity()                                   # optional - sage.libs.singular
True


Automorphisms of number fields as well as Galois fields are supported:

sage: K.<zeta7> = CyclotomicField(7)                                        # optional - sage.rings.number_field
sage: c = K.hom([1/zeta7])                                                  # optional - sage.rings.number_field
sage: (c.inverse() * c).is_identity()                                       # optional - sage.rings.number_field
True
sage: F.<t> = GF(7^3)                                                       # optional - sage.rings.finite_rings
sage: f = F.hom(t^7, F)                                                     # optional - sage.rings.finite_rings
sage: (f.inverse() * f).is_identity()                                       # optional - sage.rings.finite_rings
True


An isomorphism between the algebraic torus and the circle over a number field:

sage: K.<i> = QuadraticField(-1)                                            # optional - sage.rings.number_field
sage: A.<z,w> = K['z,w'].quotient('z*w - 1')                                # optional - sage.rings.number_field
sage: B.<x,y> = K['x,y'].quotient('x^2 + y^2 - 1')                          # optional - sage.rings.number_field
sage: f = A.hom([x + i*y, x - i*y], B)                                      # optional - sage.rings.number_field
sage: g = f.inverse()                                                       # optional - sage.rings.number_field
sage: g.morphism_from_cover().im_gens()                                     # optional - sage.rings.number_field
[1/2*z + 1/2*w, (-1/2*i)*z + (1/2*i)*w]
sage: all(g(f(z)) == z for z in A.gens())                                   # optional - sage.rings.number_field
True

inverse_image(I)#

Return the inverse image of an ideal or an element in the codomain of this ring homomorphism.

INPUT:

• I – an ideal or element in the codomain

OUTPUT:

For an ideal $$I$$ in the codomain, this returns the largest ideal in the domain whose image is contained in $$I$$.

Given an element $$b$$ in the codomain, this returns an arbitrary element $$a$$ in the domain such that self(a) = b if one such exists. The element $$a$$ is unique if this ring homomorphism is injective.

EXAMPLES:

sage: R.<x,y,z> = QQ[]
sage: S.<u,v> = QQ[]
sage: f = R.hom([u^2, u*v, v^2], S)
sage: I = S.ideal([u^6, u^5*v, u^4*v^2, u^3*v^3])
sage: J = f.inverse_image(I); J                                             # optional - sage.libs.singular
Ideal (y^2 - x*z, x*y*z, x^2*z, x^2*y, x^3)
of Multivariate Polynomial Ring in x, y, z over Rational Field
sage: f(J) == I                                                             # optional - sage.libs.singular
True


Under the above homomorphism, there exists an inverse image for every element that only involves monomials of even degree:

sage: [f.inverse_image(p) for p in [u^2, u^4, u*v + u^3*v^3]]               # optional - sage.libs.singular
[x, x^2, x*y*z + y]
sage: f.inverse_image(u*v^2)                                                # optional - sage.libs.singular
Traceback (most recent call last):
...
ValueError: element u*v^2 does not have preimage


The image of the inverse image ideal can be strictly smaller than the original ideal:

sage: S.<u,v> = QQ['u,v'].quotient('v^2 - 2')                               # optional - sage.libs.singular
sage: f = QuadraticField(2).hom([v], S)                                     # optional - sage.libs.singular sage.rings.number_field
sage: I = S.ideal(u + v)                                                    # optional - sage.libs.singular sage.rings.number_field
sage: J = f.inverse_image(I)                                                # optional - sage.libs.singular sage.rings.number_field
sage: J.is_zero()                                                           # optional - sage.libs.singular sage.rings.number_field
True
sage: f(J) < I                                                              # optional - sage.libs.singular sage.rings.number_field
True


Fractional ideals are not yet fully supported:

sage: K.<a> = NumberField(QQ['x']('x^2+2'))                                 # optional - sage.rings.number_field
sage: f = K.hom([-a], K)                                                    # optional - sage.rings.number_field
sage: I = K.ideal([a + 1])                                                  # optional - sage.rings.number_field
sage: f.inverse_image(I)                                                    # optional - sage.rings.number_field
Traceback (most recent call last):
...
NotImplementedError: inverse image not implemented...
sage: f.inverse_image(K.ideal(0)).is_zero()                                 # optional - sage.rings.number_field
True
sage: f.inverse()(I)                                                        # optional - sage.rings.number_field
Fractional ideal (-a + 1)


ALGORITHM:

By default, this computes a Gröbner basis of an ideal related to the graph of the ring homomorphism.

REFERENCES:

is_invertible()#

Return whether this ring homomorphism is bijective.

EXAMPLES:

sage: R.<x,y,z> = QQ[]
sage: R.hom([y*z, x*z, x*y], R).is_invertible()                             # optional - sage.libs.singular
False
sage: Q.<x,y,z> = R.quotient(x*y*z - 1)                                     # optional - sage.libs.singular
sage: Q.hom([y*z, x*z, x*y], Q).is_invertible()                             # optional - sage.libs.singular
True


ALGORITHM:

By default, this requires the computation of a Gröbner basis.

is_surjective()#

Return whether this ring homomorphism is surjective.

EXAMPLES:

sage: R.<x,y,z> = QQ[]
sage: R.hom([y*z, x*z, x*y], R).is_surjective()                             # optional - sage.libs.singular
False
sage: Q.<x,y,z> = R.quotient(x*y*z - 1)                                     # optional - sage.libs.singular
sage: R.hom([y*z, x*z, x*y], Q).is_surjective()                             # optional - sage.libs.singular
True


ALGORITHM:

By default, this requires the computation of a Gröbner basis.

kernel()#

Return the kernel ideal of this ring homomorphism.

EXAMPLES:

sage: A.<x,y> = QQ[]
sage: B.<t> = QQ[]
sage: f = A.hom([t^4, t^3 - t^2], B)
sage: f.kernel()                                                            # optional - sage.libs.singular
Ideal (y^4 - x^3 + 4*x^2*y - 2*x*y^2 + x^2)
of Multivariate Polynomial Ring in x, y over Rational Field


We express a Veronese subring of a polynomial ring as a quotient ring:

sage: A.<a,b,c,d> = QQ[]
sage: B.<u,v> = QQ[]
sage: f = A.hom([u^3, u^2*v, u*v^2, v^3], B)
sage: f.kernel() == A.ideal(matrix.hankel([a, b, c], [d]).minors(2))        # optional - sage.libs.singular
True
sage: Q = A.quotient(f.kernel())                                            # optional - sage.libs.singular
sage: Q.hom(f.im_gens(), B).is_injective()                                  # optional - sage.libs.singular
True


The Steiner-Roman surface:

sage: R.<x,y,z> = QQ[]
sage: S = R.quotient(x^2 + y^2 + z^2 - 1)                                   # optional - sage.libs.singular
sage: f = R.hom([x*y, x*z, y*z], S)                                         # optional - sage.libs.singular
sage: f.kernel()                                                            # optional - sage.libs.singular
Ideal (x^2*y^2 + x^2*z^2 + y^2*z^2 - x*y*z)
of Multivariate Polynomial Ring in x, y, z over Rational Field

lift(x=None)#

Return a lifting map associated to this homomorphism, if it has been defined.

If x is not None, return the value of the lift morphism on x.

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()          # optional - sage.libs.singular
sage: f.pushforward(R.ideal([x, 3*x + x*y + y^2]))                          # optional - sage.libs.singular
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#

A ring homomorphism that is a coercion.

Warning

This class is obsolete. Set the category of your morphism to a subcategory of Rings instead.

class sage.rings.morphism.RingHomomorphism_cover#

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)                                                # optional - sage.libs.singular
sage: phi = S.cover(); phi                                                      # optional - sage.libs.singular
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)                                                                # optional - sage.libs.singular
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#

A ring homomorphism determined by a ring homomorphism of the base ring.

AUTHOR:

• Simon King (initial version, 2010-04-30)

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 and S, and let f 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)                                                 # optional - sage.modules
sage: MS = MatrixSpace(S, 2, 2)                                                 # optional - sage.modules
sage: M = MR([x^2 + 1/7*x*y - y^2, -1/2*y^2 + 2*y + 1/6,                        # optional - sage.modules
....:         4*x^2 - 14*x, 1/2*y^2 + 13/4*x - 2/11*y])
sage: Mf = MR.hom(f, MS)                                                        # optional - sage.modules
sage: Mf                                                                        # optional - sage.modules
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)                                                                     # optional - sage.modules
[           -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)                                                  # optional - sage.modules
sage: MPS = MatrixSpace(PS, 2)                                                  # optional - sage.modules
sage: M = MPR([(-x + y)*t^2 + 58*t - 3*x^2 + x*y,                               # optional - sage.modules
....:          (- 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                                                # optional - sage.modules
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)                                                                    # optional - sage.modules
[                    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]

inverse()#

Return the inverse of this ring homomorphism if the underlying homomorphism of the base ring is invertible.

EXAMPLES:

sage: R.<x,y> = QQ[]
sage: S.<a,b> = QQ[]
sage: f = R.hom([a + b, a - b], S)                                          # optional - sage.libs.singular
sage: PR.<t> = R[]
sage: PS = S['t']
sage: Pf = PR.hom(f, PS)                                                    # optional - sage.libs.singular
sage: Pf.inverse()                                                          # optional - sage.libs.singular
Ring morphism:
From: Univariate Polynomial Ring in t over Multivariate
Polynomial Ring in a, b over Rational Field
To:   Univariate Polynomial Ring in t over Multivariate
Polynomial Ring in x, y over Rational Field
Defn: Induced from base ring by
Ring morphism:
From: Multivariate Polynomial Ring in a, b over Rational Field
To:   Multivariate Polynomial Ring in x, y over Rational Field
Defn: a |--> 1/2*x + 1/2*y
b |--> 1/2*x - 1/2*y
sage: Pf.inverse()(Pf(x*t^2 + y*t))                                         # optional - sage.libs.singular
x*t^2 + y*t

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)                                                # optional - sage.modules
sage: MS = MatrixSpace(S, 2)                                                # optional - sage.modules
sage: g = MR.hom(f, MS)                                                     # optional - sage.modules
sage: g.underlying_map() == f                                               # optional - sage.modules
True

class sage.rings.morphism.RingHomomorphism_from_fraction_field#

Morphisms between fraction fields.

inverse()#

Return the inverse of this ring homomorphism if it exists.

EXAMPLES:

sage: S.<x> = QQ[]
sage: f = S.hom([2*x - 1])
sage: g = f.extend_to_fraction_field()                                      # optional - sage.libs.singular
sage: g.inverse()                                                           # optional - sage.libs.singular
Ring endomorphism of Fraction Field of Univariate Polynomial Ring
in x over Rational Field
Defn: x |--> 1/2*x + 1/2

class sage.rings.morphism.RingHomomorphism_from_quotient#

A ring homomorphism with domain a generic quotient ring.

INPUT:

• parent – a ring homset Hom(R,S)

• phi – a ring homomorphism C --> S, where C is the domain of R.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 elements im_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)                                      # optional - sage.libs.singular
sage: phi = S.hom([b, c, a]); phi                                               # optional - sage.libs.singular
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)                                                            # optional - sage.libs.singular
a + b + c
sage: loads(dumps(phi)) == phi                                                  # optional - sage.libs.singular
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])                                                    # optional - sage.libs.singular
Traceback (most recent call last):
...
ValueError: relations do not all (canonically) map to 0
under map determined by images of generators

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])                         # optional - sage.libs.singular
sage: S.hom([yy,xx]).morphism_from_cover()                                  # optional - sage.libs.singular
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#

A ring homomorphism determined by the images of generators.

base_map()#

Return the map on the base ring that is part of the defining data for this morphism. May return None if a coercion is used.

EXAMPLES:

sage: R.<x> = ZZ[]
sage: K.<i> = NumberField(x^2 + 1)                                          # optional - sage.rings.number_field
sage: cc = K.hom([-i])                                                      # optional - sage.rings.number_field
sage: S.<y> = K[]                                                           # optional - sage.rings.number_field
sage: phi = S.hom([y^2], base_map=cc)                                       # optional - sage.rings.number_field
sage: phi                                                                   # optional - sage.rings.number_field
Ring endomorphism of Univariate Polynomial Ring in y
over Number Field in i with defining polynomial x^2 + 1
Defn: y |--> y^2
with map of base ring
sage: phi(y)                                                                # optional - sage.rings.number_field
y^2
sage: phi(i*y)                                                              # optional - sage.rings.number_field
-i*y^2
sage: phi.base_map()                                                        # optional - sage.rings.number_field
Composite map:
From: Number Field in i with defining polynomial x^2 + 1
To:   Univariate Polynomial Ring in y over Number Field in i
with defining polynomial x^2 + 1
Defn:   Ring endomorphism of Number Field in i with defining polynomial x^2 + 1
Defn: i |--> -i
then
Polynomial base injection morphism:
From: Number Field in i with defining polynomial x^2 + 1
To:   Univariate Polynomial Ring in y over Number Field in i
with defining polynomial x^2 + 1

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: Morphism

Set-theoretic map between rings.

class sage.rings.morphism.RingMap_lift#

Bases: 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 set-theoretic ring map $$R \to S$$ sending $$x$$ to x.lift().

EXAMPLES:

sage: R.<x,y> = QQ[]
sage: S.<xbar,ybar> = R.quo( (x^2 + y^2, y) )                                   # optional - sage.libs.singular
sage: S.lift()                                                                  # optional - sage.libs.singular
Set-theoretic 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                                                             # optional - sage.libs.singular
False


Since github issue #11068, it is possible to create quotient rings of non-commutative rings by two-sided ideals. It was needed to modify RingMap_lift so that rings can be accepted that are no instances of sage.rings.ring.Ring, as in the following example:

sage: MS = MatrixSpace(GF(5), 2, 2)                                             # optional - sage.modules sage.rings.finite_rings
sage: I = MS * [MS.0*MS.1, MS.2+MS.3] * MS                                      # optional - sage.modules sage.rings.finite_rings
sage: Q = MS.quo(I)                                                             # optional - sage.modules sage.rings.finite_rings
sage: Q.0*Q.1   # indirect doctest                                              # optional - sage.modules sage.rings.finite_rings
[0 1]
[0 0]

sage.rings.morphism.is_RingHomomorphism(phi)#

Return True if phi is of type RingHomomorphism.

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 https://github.com/sagemath/sage/issues/23204 for details.
True
sage: sage.rings.morphism.is_RingHomomorphism(2/3)
False