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
>>> from sage.all import *
>>> H = Hom(ZZ, QQ)
>>> phi = H([Integer(1)])
>>> phi(Integer(10))
10
>>> phi(Integer(3)/Integer(1))
3
>>> phi(Integer(2)/Integer(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
>>> from sage.all import *
>>> H = Hom(QQ, ZZ)
>>> H([Integer(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: # needs sage.rings.finite_rings
sage: H = Hom(ZZ, GF(9, 'a'))
sage: phi = H([1])
sage: phi(5)
2
sage: psi = H([4])
sage: psi(5)
2
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> H = Hom(ZZ, GF(Integer(9), 'a'))
>>> phi = H([Integer(1)])
>>> phi(Integer(5))
2
>>> psi = H([Integer(4)])
>>> psi(Integer(5))
2

Map from single variable polynomial ring:

sage: R.<x> = ZZ[]
sage: phi = R.hom([2], GF(5)); 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
>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> phi = R.hom([Integer(2)], GF(Integer(5))); phi
Ring morphism:
  From: Univariate Polynomial Ring in x over Integer Ring
  To:   Finite Field of size 5
  Defn: x |--> 2
>>> phi(x + Integer(12))
4

Identity map on the real numbers:

sage: # needs sage.rings.real_mpfr
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
>>> from sage.all import *
>>> # needs sage.rings.real_mpfr
>>> f = RR.hom([RR(Integer(1))]); f
Ring endomorphism of Real Field with 53 bits of precision
  Defn: 1.00000000000000 |--> 1.00000000000000
>>> f(RealNumber('2.5'))
2.50000000000000
>>> f = RR.hom([RealNumber('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)                                                         # needs sage.rings.real_mpfr
sage: f = RR.hom( R200 )                                                            # needs sage.rings.real_mpfr
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 sage.all import *
>>> R200 = RealField(Integer(200))                                                         # needs sage.rings.real_mpfr
>>> f = RR.hom( R200 )                                                            # needs sage.rings.real_mpfr
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))                                                     # needs sage.rings.real_mpfr
sage: f(2.5)                                                                        # needs sage.rings.real_mpfr
2.500
sage: f(RR.pi())                                                                    # needs sage.rings.real_mpfr
3.142
>>> from sage.all import *
>>> f = RR.hom(RealField(Integer(15)))                                                     # needs sage.rings.real_mpfr
>>> f(RealNumber('2.5'))                                                                        # needs sage.rings.real_mpfr
2.500
>>> f(RR.pi())                                                                    # needs sage.rings.real_mpfr
3.142

Inclusion map from the reals to the complexes:

sage: # needs sage.rings.real_mpfr
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
>>> from sage.all import *
>>> # needs sage.rings.real_mpfr
>>> i = RR.hom([CC(Integer(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
>>> 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
>>> from sage.all import *
>>> R = PolynomialRing(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
>>> phi = R.hom([y, z, x**Integer(2)]); phi
Ring endomorphism of Multivariate Polynomial Ring in x, y, z over Rational Field
  Defn: x |--> y
        y |--> z
        z |--> x^2
>>> phi(x + y + z)
x^2 + y + z

An endomorphism of a quotient of a multi-variate polynomial ring:

sage: # needs sage.libs.singular
sage: R.<x,y> = PolynomialRing(QQ)
sage: S.<a,b> = quo(R, ideal(1 + y^2))
sage: phi = S.hom([a^2, -b]); 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
>>> from sage.all import *
>>> # needs sage.libs.singular
>>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
>>> S = quo(R, ideal(Integer(1) + y**Integer(2)), names=('a', 'b',)); (a, b,) = S._first_ngens(2)
>>> phi = S.hom([a**Integer(2), -b]); 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
>>> phi(b)
-b
>>> phi(a**Integer(2) + b**Integer(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(); 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
>>> from sage.all import *
>>> R = ZZ.quo(Integer(8)*ZZ)
>>> pi = R.cover(); pi
Ring morphism:
  From: Integer Ring
  To:   Ring of integers modulo 8
  Defn: Natural quotient map
>>> pi.domain()
Integer Ring
>>> pi.codomain()
Ring of integers modulo 8
>>> pi(Integer(10))
2
>>> pi.lift()
Set-theoretic ring morphism:
  From: Ring of integers modulo 8
  To:   Integer Ring
  Defn: Choice of lifting map
>>> pi.lift(Integer(13))
5

Inclusion of GF(2) into GF(4,'a'):

sage: # needs sage.rings.finite_rings
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
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> k = GF(Integer(2))
>>> i = k.hom(GF(Integer(4), 'a'))
>>> i
Ring morphism:
  From: Finite Field of size 2
  To:   Finite Field in a of size 2^2
  Defn: 1 |--> 1
>>> i(Integer(0))
0
>>> a = i(Integer(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: # needs sage.rings.finite_rings
sage: pi = ZZ.hom(k); pi
Natural morphism:
  From: Integer Ring
  To:   Finite Field of size 2
sage: f = i * pi; 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
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> pi = ZZ.hom(k); pi
Natural morphism:
  From: Integer Ring
  To:   Finite Field of size 2
>>> f = i * pi; 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
>>> a = f(Integer(5)); a
1
>>> a.parent()
Finite Field in a of size 2^2

Inclusion from \(\QQ\) to the 3-adic field:

sage: # needs sage.rings.padics
sage: phi = QQ.hom(Qp(3, print_mode='series'))
sage: phi
Ring morphism:
  From: Rational Field
  To:   3-adic Field with capped relative precision 20
sage: phi.codomain()
3-adic Field with capped relative precision 20
sage: phi(394)
1 + 2*3 + 3^2 + 2*3^3 + 3^4 + 3^5 + O(3^20)
>>> from sage.all import *
>>> # needs sage.rings.padics
>>> phi = QQ.hom(Qp(Integer(3), print_mode='series'))
>>> phi
Ring morphism:
  From: Rational Field
  To:   3-adic Field with capped relative precision 20
>>> phi.codomain()
3-adic Field with capped relative precision 20
>>> phi(Integer(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: # needs sage.libs.pari
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
>>> from sage.all import *
>>> # needs sage.libs.pari
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quo(x**Integer(2) - Integer(2), names=('sqrt2',)); (sqrt2,) = S._first_ngens(1)
>>> sqrt2**Integer(2)
2
>>> (Integer(3)+sqrt2)**Integer(10)
993054*sqrt2 + 1404491
>>> c = S.hom([-sqrt2])
>>> c(Integer(1)+sqrt2)
-sqrt2 + 1

Note that Sage verifies that the morphism is valid:

sage: (1 - sqrt2)^2                                                                 # needs sage.libs.pari
-2*sqrt2 + 3
sage: c = S.hom([1 - sqrt2])    # this is not valid                                 # needs sage.libs.pari
Traceback (most recent call last):
...
ValueError: relations do not all (canonically) map to 0
under map determined by images of generators
>>> from sage.all import *
>>> (Integer(1) - sqrt2)**Integer(2)                                                                 # needs sage.libs.pari
-2*sqrt2 + 3
>>> c = S.hom([Integer(1) - sqrt2])    # this is not valid                                 # needs sage.libs.pari
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)
>>> from sage.all import *
>>> R = PowerSeriesRing(QQ, default_prec=Integer(10), names=('t',)); (t,) = R._first_ngens(1); R
Power Series Ring in t over Rational Field
>>> f = R.hom([t**Integer(2)]); f
Ring endomorphism of Power Series Ring in t over Rational Field
  Defn: t |--> t^2
>>> s = Integer(1)/(Integer(1) + t); s
1 - t + t^2 - t^3 + t^4 - t^5 + t^6 - t^7 + t^8 - t^9 + O(t^10)
>>> 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)
>>> from sage.all import *
>>> R = PowerSeriesRing(GF(Integer(5)), names=('t',)); (t,) = R._first_ngens(1)
>>> f = R.hom([t**Integer(5)]); f
Ring endomorphism of Power Series Ring in t over Finite Field of size 5
  Defn: t |--> t^5
>>> a = Integer(2) + t + Integer(3)*t**Integer(2) + Integer(4)*t**Integer(3) + O(t**Integer(4))
>>> b = Integer(1) + t + Integer(2)*t**Integer(2) + t**Integer(3) + O(t**Integer(5))
>>> f(a)
2 + t^5 + 3*t^10 + 4*t^15 + O(t^20)
>>> f(b)
1 + t^5 + 2*t^10 + t^15 + O(t^25)
>>> f(a*b)
2 + 3*t^5 + 3*t^10 + t^15 + O(t^20)
>>> 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)
>>> from sage.all import *
>>> R = LaurentSeriesRing(QQ, Integer(10), names=('t',)); (t,) = R._first_ngens(1)
>>> f = R.hom([t**Integer(3) + t]); f
Ring endomorphism of Laurent Series Ring in t over Rational Field
  Defn: t |--> t + t^3
>>> s = Integer(2)/t**Integer(2) + Integer(1)/(Integer(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)
>>> 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)
>>> f = R.hom([t**Integer(3)]); f
Ring endomorphism of Laurent Series Ring in t over Rational Field
  Defn: t |--> t^3
>>> 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
>>> from sage.all import *
>>> R.hom([Integer(1)/t])
Traceback (most recent call last):
...
ValueError: relations do not all (canonically) map to 0
under map determined by images of generators
>>> R.hom([Integer(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: # needs sage.rings.number_field
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
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = CyclotomicField(Integer(7), names=('zeta7',)); (zeta7,) = K._first_ngens(1)
>>> c = K.hom([Integer(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
>>> a = (Integer(1)+zeta7)**Integer(5); a
zeta7^5 + 5*zeta7^4 + 10*zeta7^3 + 10*zeta7^2 + 5*zeta7 + 1
>>> c(a)
5*zeta7^5 + 5*zeta7^4 - 4*zeta7^2 - 5*zeta7 - 4
>>> c(zeta7 + Integer(1)/zeta7)       # this element is obviously fixed by inversion
-zeta7^5 - zeta7^4 - zeta7^3 - zeta7^2 - 1
>>> zeta7 + Integer(1)/zeta7
-zeta7^5 - zeta7^4 - zeta7^3 - zeta7^2 - 1

Embedding a number field into the reals:

sage: # needs sage.rings.number_field
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
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(3) - Integer(2), names=('beta',)); (beta,) = K._first_ngens(1)
>>> alpha = RR(Integer(2))**(Integer(1)/Integer(3)); alpha
1.25992104989487
>>> 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
>>> i(beta)
1.25992104989487
>>> i(beta**Integer(3))
2.00000000000000
>>> i(beta**Integer(2) + Integer(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
>>> from sage.all import *
>>> K = QQ  # by the way :-)
>>> R = K['a, b, c, d']; (a, b, c, d,) = R._first_ngens(4); R
Multivariate Polynomial Ring in a, b, c, d over Rational Field
>>> S = K['u']; (u,) = S._first_ngens(1); S
Univariate Polynomial Ring in u over Rational Field
>>> f = R.hom([Integer(0),Integer(0),Integer(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
>>> f(a + b + c + d)
u
>>> f((a+b+c+d)**Integer(2))
u^2
class sage.rings.morphism.FrobeniusEndomorphism_generic[source]#

Bases: RingHomomorphism

A class implementing Frobenius endomorphisms on rings of prime characteristic.

power()[source]#

Return an integer \(n\) such that this endomorphism is the \(n\)-th power of the absolute (arithmetic) Frobenius.

EXAMPLES:

sage: # needs sage.rings.finite_rings
sage: K.<u> = PowerSeriesRing(GF(5))
sage: Frob = K.frobenius_endomorphism()
sage: Frob.power()
1
sage: (Frob^9).power()
9
>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> K = PowerSeriesRing(GF(Integer(5)), names=('u',)); (u,) = K._first_ngens(1)
>>> Frob = K.frobenius_endomorphism()
>>> Frob.power()
1
>>> (Frob**Integer(9)).power()
9
class sage.rings.morphism.RingHomomorphism[source]#

Bases: RingMap

Homomorphism of rings.

inverse()[source]#

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()                                                           # needs sage.libs.singular
Ring endomorphism of Univariate Polynomial Ring in t over Rational Field
  Defn: t |--> 1/2*t + 1/2
>>> from sage.all import *
>>> R = QQ['t']; (t,) = R._first_ngens(1)
>>> f = R.hom([Integer(2)*t - Integer(1)], R)
>>> f.inverse()                                                           # needs 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: # needs sage.libs.singular
sage: R.<x,y,z> = QQ[]
sage: f = R.hom([y*z, x*z, x*y], R)
sage: f.inverse()
Traceback (most recent call last):
...
ZeroDivisionError: ring homomorphism not surjective
sage: f.is_injective()
True
sage: Q.<x,y,z> = R.quotient(x*y*z - 1)
sage: g = Q.hom([y*z, x*z, x*y], Q)
sage: g.inverse()
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
>>> from sage.all import *
>>> # needs sage.libs.singular
>>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
>>> f = R.hom([y*z, x*z, x*y], R)
>>> f.inverse()
Traceback (most recent call last):
...
ZeroDivisionError: ring homomorphism not surjective
>>> f.is_injective()
True
>>> Q = R.quotient(x*y*z - Integer(1), names=('x', 'y', 'z',)); (x, y, z,) = Q._first_ngens(3)
>>> g = Q.hom([y*z, x*z, x*y], Q)
>>> g.inverse()
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()                                                           # needs 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()                                       # needs sage.libs.singular
True
>>> from sage.all import *
>>> S = ZZ['x, y']; (x, y,) = S._first_ngens(2)
>>> f = S.hom([x + Integer(2)*y, x + Integer(3)*y], S)
>>> f.inverse()                                                           # needs sage.libs.singular
Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring
  Defn: x |--> 3*x - 2*y
        y |--> -x + y
>>> (f.inverse() * f).is_identity()                                       # needs 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()                                                           # needs 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()                                       # needs sage.libs.singular
True
>>> from sage.all import *
>>> g = S.hom([x + y, x - y - Integer(2)], S)
>>> g.inverse()                                                           # needs sage.libs.singular
Traceback (most recent call last):
...
ZeroDivisionError: ring homomorphism not surjective
>>> R = QQ[x,y]; (x, y,) = R._first_ngens(2)
>>> h = R.hom([x + y, x - y - Integer(2)], R)
>>> (h.inverse() * h).is_identity()                                       # needs 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                                            # needs 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()                                           # needs sage.libs.singular
True
>>> from sage.all import *
>>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
>>> sigma = R.hom([x - Integer(2)*y*(z*x+y**Integer(2)) - z*(z*x+y**Integer(2))**Integer(2),
...                y + z*(z*x+y**Integer(2)), z], R)
>>> tau = sigma.inverse(); tau                                            # needs 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
>>> (tau * sigma).is_identity()                                           # needs 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())                        # needs sage.libs.singular
True
sage: phi.inverse().im_gens()[:5]                                           # needs 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()                                   # needs sage.libs.singular
True
>>> from sage.all import *
>>> d = Integer(12)
>>> T = TermOrder('wdegrevlex', (ellipsis_range(Integer(1),Ellipsis,d)))
>>> R = PolynomialRing(QQ, ['x%s' % j for j in (ellipsis_iter(Integer(1),Ellipsis,d))], order=T)
>>> S = PowerSeriesRing(R, names=('t',)); (t,) = S._first_ngens(1)
>>> egf = S([Integer(0)] + list(R.gens())).ogf_to_egf().exp(prec=d+Integer(1))
>>> phi = R.hom(egf.egf_to_ogf().list()[Integer(1):], R)
>>> phi.im_gens()[:Integer(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]
>>> all(p.is_homogeneous() for p in phi.im_gens())                        # needs sage.libs.singular
True
>>> phi.inverse().im_gens()[:Integer(5)]                                           # needs 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]
>>> (phi.inverse() * phi).is_identity()                                   # needs sage.libs.singular
True

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

sage: K.<zeta7> = CyclotomicField(7)                                        # needs sage.rings.number_field
sage: c = K.hom([1/zeta7])                                                  # needs sage.rings.number_field
sage: (c.inverse() * c).is_identity()                                       # needs sage.libs.singular sage.rings.number_field
True

sage: F.<t> = GF(7^3)                                                       # needs sage.rings.finite_rings
sage: f = F.hom(t^7, F)                                                     # needs sage.rings.finite_rings
sage: (f.inverse() * f).is_identity()                                       # needs sage.libs.singular sage.rings.finite_rings
True
>>> from sage.all import *
>>> K = CyclotomicField(Integer(7), names=('zeta7',)); (zeta7,) = K._first_ngens(1)# needs sage.rings.number_field
>>> c = K.hom([Integer(1)/zeta7])                                                  # needs sage.rings.number_field
>>> (c.inverse() * c).is_identity()                                       # needs sage.libs.singular sage.rings.number_field
True

>>> F = GF(Integer(7)**Integer(3), names=('t',)); (t,) = F._first_ngens(1)# needs sage.rings.finite_rings
>>> f = F.hom(t**Integer(7), F)                                                     # needs sage.rings.finite_rings
>>> (f.inverse() * f).is_identity()                                       # needs sage.libs.singular sage.rings.finite_rings
True

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

sage: # needs sage.libs.singular sage.rings.number_field
sage: K.<i> = QuadraticField(-1)
sage: A.<z,w> = K['z,w'].quotient('z*w - 1')
sage: B.<x,y> = K['x,y'].quotient('x^2 + y^2 - 1')
sage: f = A.hom([x + i*y, x - i*y], B)
sage: g = f.inverse()
sage: g.morphism_from_cover().im_gens()
[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())
True
>>> from sage.all import *
>>> # needs sage.libs.singular sage.rings.number_field
>>> K = QuadraticField(-Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> A = K['z,w'].quotient('z*w - 1', names=('z', 'w',)); (z, w,) = A._first_ngens(2)
>>> B = K['x,y'].quotient('x^2 + y^2 - 1', names=('x', 'y',)); (x, y,) = B._first_ngens(2)
>>> f = A.hom([x + i*y, x - i*y], B)
>>> g = f.inverse()
>>> g.morphism_from_cover().im_gens()
[1/2*z + 1/2*w, (-1/2*i)*z + (1/2*i)*w]
>>> all(g(f(z)) == z for z in A.gens())
True
inverse_image(I)[source]#

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                                             # needs 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                                                             # needs sage.libs.singular
True
>>> from sage.all import *
>>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
>>> S = QQ['u, v']; (u, v,) = S._first_ngens(2)
>>> f = R.hom([u**Integer(2), u*v, v**Integer(2)], S)
>>> I = S.ideal([u**Integer(6), u**Integer(5)*v, u**Integer(4)*v**Integer(2), u**Integer(3)*v**Integer(3)])
>>> J = f.inverse_image(I); J                                             # needs 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
>>> f(J) == I                                                             # needs 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]]               # needs sage.libs.singular
[x, x^2, x*y*z + y]
sage: f.inverse_image(u*v^2)                                                # needs sage.libs.singular
Traceback (most recent call last):
...
ValueError: element u*v^2 does not have preimage
>>> from sage.all import *
>>> [f.inverse_image(p) for p in [u**Integer(2), u**Integer(4), u*v + u**Integer(3)*v**Integer(3)]]               # needs sage.libs.singular
[x, x^2, x*y*z + y]
>>> f.inverse_image(u*v**Integer(2))                                                # needs 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: # needs sage.libs.singular sage.rings.number_field
sage: S.<u,v> = QQ['u,v'].quotient('v^2 - 2')
sage: f = QuadraticField(2).hom([v], S)
sage: I = S.ideal(u + v)
sage: J = f.inverse_image(I)
sage: J.is_zero()
True
sage: f(J) < I
True
>>> from sage.all import *
>>> # needs sage.libs.singular sage.rings.number_field
>>> S = QQ['u,v'].quotient('v^2 - 2', names=('u', 'v',)); (u, v,) = S._first_ngens(2)
>>> f = QuadraticField(Integer(2)).hom([v], S)
>>> I = S.ideal(u + v)
>>> J = f.inverse_image(I)
>>> J.is_zero()
True
>>> f(J) < I
True

Fractional ideals are not yet fully supported:

sage: # needs sage.rings.number_field
sage: K.<a> = NumberField(QQ['x']('x^2+2'))
sage: f = K.hom([-a], K)
sage: I = K.ideal([a + 1])
sage: f.inverse_image(I)                                                    # needs sage.libs.singular
Traceback (most recent call last):
...
NotImplementedError: inverse image not implemented...
sage: f.inverse_image(K.ideal(0)).is_zero()                                 # needs sage.libs.singular
True
sage: f.inverse()(I)                                                        # needs sage.rings.padics
Fractional ideal (-a + 1)
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = NumberField(QQ['x']('x^2+2'), names=('a',)); (a,) = K._first_ngens(1)
>>> f = K.hom([-a], K)
>>> I = K.ideal([a + Integer(1)])
>>> f.inverse_image(I)                                                    # needs sage.libs.singular
Traceback (most recent call last):
...
NotImplementedError: inverse image not implemented...
>>> f.inverse_image(K.ideal(Integer(0))).is_zero()                                 # needs sage.libs.singular
True
>>> f.inverse()(I)                                                        # needs sage.rings.padics
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()[source]#

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()                             # needs sage.libs.singular
False
sage: Q.<x,y,z> = R.quotient(x*y*z - 1)                                     # needs sage.libs.singular
sage: Q.hom([y*z, x*z, x*y], Q).is_invertible()                             # needs sage.libs.singular
True
>>> from sage.all import *
>>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
>>> R.hom([y*z, x*z, x*y], R).is_invertible()                             # needs sage.libs.singular
False
>>> Q = R.quotient(x*y*z - Integer(1), names=('x', 'y', 'z',)); (x, y, z,) = Q._first_ngens(3)# needs sage.libs.singular
>>> Q.hom([y*z, x*z, x*y], Q).is_invertible()                             # needs sage.libs.singular
True

ALGORITHM:

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

is_surjective()[source]#

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()                             # needs sage.libs.singular
False
sage: Q.<x,y,z> = R.quotient(x*y*z - 1)                                     # needs sage.libs.singular
sage: R.hom([y*z, x*z, x*y], Q).is_surjective()                             # needs sage.libs.singular
True
>>> from sage.all import *
>>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
>>> R.hom([y*z, x*z, x*y], R).is_surjective()                             # needs sage.libs.singular
False
>>> Q = R.quotient(x*y*z - Integer(1), names=('x', 'y', 'z',)); (x, y, z,) = Q._first_ngens(3)# needs sage.libs.singular
>>> R.hom([y*z, x*z, x*y], Q).is_surjective()                             # needs sage.libs.singular
True

ALGORITHM:

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

kernel()[source]#

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()                                                            # needs 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
>>> from sage.all import *
>>> A = QQ['x, y']; (x, y,) = A._first_ngens(2)
>>> B = QQ['t']; (t,) = B._first_ngens(1)
>>> f = A.hom([t**Integer(4), t**Integer(3) - t**Integer(2)], B)
>>> f.kernel()                                                            # needs 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))        # needs sage.libs.singular
True
sage: Q = A.quotient(f.kernel())                                            # needs sage.libs.singular
sage: Q.hom(f.im_gens(), B).is_injective()                                  # needs sage.libs.singular
True
>>> from sage.all import *
>>> A = QQ['a, b, c, d']; (a, b, c, d,) = A._first_ngens(4)
>>> B = QQ['u, v']; (u, v,) = B._first_ngens(2)
>>> f = A.hom([u**Integer(3), u**Integer(2)*v, u*v**Integer(2), v**Integer(3)], B)
>>> f.kernel() == A.ideal(matrix.hankel([a, b, c], [d]).minors(Integer(2)))        # needs sage.libs.singular
True
>>> Q = A.quotient(f.kernel())                                            # needs sage.libs.singular
>>> Q.hom(f.im_gens(), B).is_injective()                                  # needs 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)
sage: f = R.hom([x*y, x*z, y*z], S)                                         # needs sage.libs.singular
sage: f.kernel()                                                            # needs 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
>>> from sage.all import *
>>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
>>> S = R.quotient(x**Integer(2) + y**Integer(2) + z**Integer(2) - Integer(1))
>>> f = R.hom([x*y, x*z, y*z], S)                                         # needs sage.libs.singular
>>> f.kernel()                                                            # needs 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)[source]#

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
>>> from sage.all import *
>>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
>>> f = R.hom([x,x])
>>> f(x+y)
2*x
>>> f.lift()
Traceback (most recent call last):
...
ValueError: no lift map defined
>>> g = R.hom(R)
>>> f._set_lift(g)
>>> f.lift() == g
True
>>> f.lift(x)
x
pushforward(I)[source]#

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()          # needs sage.libs.singular
sage: f.pushforward(R.ideal([x, 3*x + x*y + y^2]))                          # needs 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)
>>> from sage.all import *
>>> R = QQ['x, y']; (x, y,) = R._first_ngens(2); S = R.quo([x**Integer(2), y**Integer(2)], names=('xx', 'yy',)); (xx, yy,) = S._first_ngens(2); f = S.cover()          # needs sage.libs.singular
>>> f.pushforward(R.ideal([x, Integer(3)*x + x*y + y**Integer(2)]))                          # needs 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_cover[source]#

Bases: 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)                                                # needs sage.libs.singular
sage: phi = S.cover(); phi                                                      # needs 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)                                                                # needs sage.libs.singular
a + b
>>> from sage.all import *
>>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2)
>>> S = R.quo(x**Integer(2) + y**Integer(2), names=('a', 'b',)); (a, b,) = S._first_ngens(2)# needs sage.libs.singular
>>> phi = S.cover(); phi                                                      # needs 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
>>> phi(x + y)                                                                # needs sage.libs.singular
a + b
kernel()[source]#

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
>>> from sage.all import *
>>> f = Zmod(Integer(6)).cover()
>>> f.kernel()
Principal ideal (6) of Integer Ring
class sage.rings.morphism.RingHomomorphism_from_base[source]#

Bases: RingHomomorphism

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)
>>> from sage.all import *
>>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
>>> S = QQ['z']; (z,) = S._first_ngens(1)
>>> f = R.hom([Integer(2)*z,Integer(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
>>> from sage.all import *
>>> PR = R['t']; (t,) = PR._first_ngens(1)
>>> PS = S['t']
>>> Pf = PR.hom(f,PS)
>>> 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
>>> p = (x - Integer(4)*y + Integer(1)/Integer(13))*t**Integer(2) + (Integer(1)/Integer(2)*x**Integer(2) - Integer(1)/Integer(3)*y**Integer(2))*t + Integer(2)*y**Integer(2) + x
>>> 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: # needs sage.modules
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]
>>> from sage.all import *
>>> # needs sage.modules
>>> MR = MatrixSpace(R, Integer(2), Integer(2))
>>> MS = MatrixSpace(S, Integer(2), Integer(2))
>>> M = MR([x**Integer(2) + Integer(1)/Integer(7)*x*y - y**Integer(2), -Integer(1)/Integer(2)*y**Integer(2) + Integer(2)*y + Integer(1)/Integer(6),
...         Integer(4)*x**Integer(2) - Integer(14)*x, Integer(1)/Integer(2)*y**Integer(2) + Integer(13)/Integer(4)*x - Integer(2)/Integer(11)*y])
>>> Mf = MR.hom(f, MS)
>>> 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
>>> 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: # needs sage.modules
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]
>>> from sage.all import *
>>> # needs sage.modules
>>> MPR = MatrixSpace(PR, Integer(2))
>>> MPS = MatrixSpace(PS, Integer(2))
>>> M = MPR([(-x + y)*t**Integer(2) + Integer(58)*t - Integer(3)*x**Integer(2) + x*y,
...          (- Integer(1)/Integer(7)*x*y - Integer(1)/Integer(40)*x)*t**Integer(2) + (Integer(5)*x**Integer(2) + y**Integer(2))*t + Integer(2)*y,
...          (- Integer(1)/Integer(3)*y + Integer(1))*t**Integer(2) + Integer(1)/Integer(3)*x*y + y**Integer(2) + Integer(5)/Integer(2)*y + Integer(1)/Integer(4),
...          (x + Integer(6)*y + Integer(1))*t**Integer(2)])
>>> 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
>>> 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]
inverse()[source]#

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)
sage: PR.<t> = R[]
sage: PS = S['t']
sage: Pf = PR.hom(f, PS)
sage: Pf.inverse()                                                          # needs 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))                                         # needs sage.libs.singular
x*t^2 + y*t
>>> from sage.all import *
>>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
>>> S = QQ['a, b']; (a, b,) = S._first_ngens(2)
>>> f = R.hom([a + b, a - b], S)
>>> PR = R['t']; (t,) = PR._first_ngens(1)
>>> PS = S['t']
>>> Pf = PR.hom(f, PS)
>>> Pf.inverse()                                                          # needs 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
>>> Pf.inverse()(Pf(x*t**Integer(2) + y*t))                                         # needs sage.libs.singular
x*t^2 + y*t
underlying_map()[source]#

Return the underlying homomorphism of the base ring.

EXAMPLES:

sage: # needs sage.modules
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
>>> from sage.all import *
>>> # needs sage.modules
>>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
>>> S = QQ['z']; (z,) = S._first_ngens(1)
>>> f = R.hom([Integer(2)*z, Integer(3)*z], S)
>>> MR = MatrixSpace(R, Integer(2))
>>> MS = MatrixSpace(S, Integer(2))
>>> g = MR.hom(f, MS)
>>> g.underlying_map() == f
True
class sage.rings.morphism.RingHomomorphism_from_fraction_field[source]#

Bases: RingHomomorphism

Morphisms between fraction fields.

inverse()[source]#

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()                                      # needs sage.libs.singular
sage: g.inverse()                                                           # needs sage.libs.singular
Ring endomorphism of Fraction Field of Univariate Polynomial Ring
 in x over Rational Field
  Defn: x |--> 1/2*x + 1/2
>>> from sage.all import *
>>> S = QQ['x']; (x,) = S._first_ngens(1)
>>> f = S.hom([Integer(2)*x - Integer(1)])
>>> g = f.extend_to_fraction_field()                                      # needs sage.libs.singular
>>> g.inverse()                                                           # needs 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[source]#

Bases: RingHomomorphism

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: # needs sage.libs.singular
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
>>> from sage.all import *
>>> # needs sage.libs.singular
>>> R = PolynomialRing(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
>>> S = R.quo(x**Integer(3) + y**Integer(3) + z**Integer(3), names=('a', 'b', 'c',)); (a, b, c,) = S._first_ngens(3)
>>> 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
>>> phi(a + b + c)
a + b + c
>>> 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])                                                    # needs sage.libs.singular
Traceback (most recent call last):
...
ValueError: relations do not all (canonically) map to 0
under map determined by images of generators
>>> from sage.all import *
>>> S.hom([b**Integer(2), c**Integer(2), a**Integer(2)])                                                    # needs 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()[source]#

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])                         # needs sage.libs.singular
sage: S.hom([yy,xx]).morphism_from_cover()                                  # needs 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
>>> from sage.all import *
>>> R = QQ['x, y']; (x, y,) = R._first_ngens(2); S = R.quo([x**Integer(2), y**Integer(2)], names=('xx', 'yy',)); (xx, yy,) = S._first_ngens(2)# needs sage.libs.singular
>>> S.hom([yy,xx]).morphism_from_cover()                                  # needs 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[source]#

Bases: RingHomomorphism

A ring homomorphism determined by the images of generators.

base_map()[source]#

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: # needs sage.rings.number_field
sage: R.<x> = ZZ[]
sage: K.<i> = NumberField(x^2 + 1)
sage: cc = K.hom([-i])
sage: S.<y> = K[]
sage: phi = S.hom([y^2], base_map=cc)
sage: phi
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)
y^2
sage: phi(i*y)
-i*y^2
sage: phi.base_map()
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
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> cc = K.hom([-i])
>>> S = K['y']; (y,) = S._first_ngens(1)
>>> phi = S.hom([y**Integer(2)], base_map=cc)
>>> phi
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
>>> phi(y)
y^2
>>> phi(i*y)
-i*y^2
>>> phi.base_map()
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()[source]#

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]
>>> from sage.all import *
>>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
>>> f = R.hom([x, x + y])
>>> 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]
>>> from sage.all import *
>>> f.im_gens()[Integer(0)] = Integer(5)
>>> f.im_gens()
[x, x + y]
class sage.rings.morphism.RingMap[source]#

Bases: Morphism

Set-theoretic map between rings.

class sage.rings.morphism.RingMap_lift[source]#

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) )                                   # needs sage.libs.singular
sage: S.lift()                                                                  # needs 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                                                             # needs sage.libs.singular
False
>>> from sage.all import *
>>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
>>> S = R.quo( (x**Integer(2) + y**Integer(2), y) , names=('xbar', 'ybar',)); (xbar, ybar,) = S._first_ngens(2)# needs sage.libs.singular
>>> S.lift()                                                                  # needs 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
>>> S.lift() == Integer(0)                                                             # needs sage.libs.singular
False

Since 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: # needs sage.modules sage.rings.finite_rings
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]
>>> from sage.all import *
>>> # needs sage.modules sage.rings.finite_rings
>>> MS = MatrixSpace(GF(Integer(5)), Integer(2), Integer(2))
>>> I = MS * [MS.gen(0)*MS.gen(1), MS.gen(2)+MS.gen(3)] * MS
>>> Q = MS.quo(I)
>>> Q.gen(0)*Q.gen(1)   # indirect doctest
[0 1]
[0 0]