### Navigation

- index
- modules |
- next |
- previous |
- General Rings, Ideals, and Morphisms »

# Homomorphisms of rings

Homomorphisms of rings

We give a large number of examples of ring homomorphisms.

EXAMPLE:

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):
    ...
    TypeError: images do not define a valid homomorphism

EXAMPLES:

Reduction to finite field:

    sage: H = Hom(ZZ, GF(9, 'a'))
    sage: phi = H([1])
    sage: phi(5)
    2
    sage: psi = H([4])
    sage: psi(5)
    2

Map from single variable polynomial ring:

    sage: R, x = PolynomialRing(ZZ, 'x').objgen()
    sage: phi = R.hom([2], GF(5))
    sage: phi
    Ring morphism:
      From: Univariate Polynomial Ring in x over Integer Ring
      To:   Finite Field of size 5
      Defn: x |--> 2
    sage: phi(x + 12)
    4

Identity map on the real numbers:

    sage: f = RR.hom([RR(1)]); f
    Ring endomorphism of Real Field with 53 bits of precision
      Defn: 1.00000000000000 |--> 1.00000000000000
    sage: f(2.5)
    2.50000000000000
    sage: f = RR.hom( [2.0] )
    Traceback (most recent call last):
    ...
    TypeError: images do not define a valid homomorphism

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)
    sage: i = k.hom(GF(4, 'a'))
    sage: i
    Ring Coercion morphism:
      From: Finite Field of size 2
      To:   Finite Field in a of size 2^2
    sage: i(0)
    0
    sage: a = i(1); a.parent()
    Finite Field in a of size 2^2

We next compose the inclusion with reduction from the integers to `GF(2)`:

    sage: pi = ZZ.hom(k)
    sage: pi
    Ring Coercion morphism:
      From: Integer Ring
      To:   Finite Field of size 2
    sage: f = i * pi
    sage: f
    Composite map:
      From: Integer Ring
      To:   Finite Field in a of size 2^2
      Defn:   Ring Coercion morphism:
              From: Integer Ring
              To:   Finite Field of size 2
            then
              Ring Coercion morphism:
              From: Finite Field of size 2
              To:   Finite Field in a of size 2^2
    sage: a = f(5); a
    1
    sage: a.parent()
    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'))
    sage: phi
    Ring Coercion 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)

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):
    ...
    TypeError: images do not define a valid homomorphism

Endomorphism of power series ring:

    sage: R.<t> = PowerSeriesRing(QQ); R
    Power Series Ring in t over Rational Field
    sage: f = R.hom([t^2]); f
    Ring endomorphism of Power Series Ring in t over Rational Field
      Defn: t |--> t^2
    sage: R.set_default_prec(10)
    sage: s = 1/(1 + t); s
    1 - t + t^2 - t^3 + t^4 - t^5 + t^6 - t^7 + t^8 - t^9 + O(t^10)
    sage: f(s)
    1 - t^2 + t^4 - t^6 + t^8 - t^10 + t^12 - t^14 + t^16 - t^18 + O(t^20)

Frobenius on a power series ring over a finite field:

    sage: R.<t> = PowerSeriesRing(GF(5))
    sage: f = R.hom([t^5]); f
    Ring endomorphism of Power Series Ring in t over Finite Field of size 5
      Defn: t |--> t^5
    sage: a = 2 + t + 3*t^2 + 4*t^3 + O(t^4)
    sage: b = 1 + t + 2*t^2 + t^3 + O(t^5)
    sage: f(a)
    2 + t^5 + 3*t^10 + 4*t^15 + O(t^20)
    sage: f(b)
    1 + t^5 + 2*t^10 + t^15 + O(t^25)
    sage: f(a*b)
    2 + 3*t^5 + 3*t^10 + t^15 + O(t^20)
    sage: f(a)*f(b)
    2 + 3*t^5 + 3*t^10 + t^15 + O(t^20)

Homomorphism of Laurent series ring:

    sage: R.<t> = LaurentSeriesRing(QQ)
    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: R.set_default_prec(10)
    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):
    ...
    TypeError: images do not define a valid homomorphism
    sage: R.hom([1])
    Traceback (most recent call last):
    ...
    TypeError: images do not define a valid homomorphism

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

TESTS:

    sage: H = Hom(ZZ, QQ)
    sage: H == loads(dumps(H))
    True

    sage: K.<zeta7> = CyclotomicField(7)
    sage: c = K.hom([1/zeta7])
    sage: c == loads(dumps(c))
    True

    sage: R.<t> = PowerSeriesRing(GF(5))
    sage: f = R.hom([t^5])
    sage: f == loads(dumps(f))
    True

class `sage.rings.morphism.``FrobeniusEndomorphism_generic`

  Bases: `sage.rings.morphism.RingHomomorphism`

  A class implementing Frobenius endomorphisms on rings of prime characteristic.

  `power`()

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

    EXAMPLES:

        sage: K.<u> = PowerSeriesRing(GF(5))
        sage: Frob = K.frobenius_endomorphism()
        sage: Frob.power()
        1
        sage: (Frob^9).power()
        9

class `sage.rings.morphism.``RingHomomorphism`

  Bases: `sage.rings.morphism.RingMap`

  Homomorphism of rings.

  `inverse_image`(I)

    Return the inverse image of the ideal \(I\) under this ring homomorphism.

    EXAMPLES:

    This is not implemented in any generality yet:

        sage: f = ZZ.hom(ZZ)
        sage: f.inverse_image(ZZ.ideal(2))
        Traceback (most recent call last):
        ...
        NotImplementedError

  `is_injective`()

    Return whether or not this morphism is injective, or raise a `NotImplementedError`.

    EXAMPLES:

    Note that currently this is not implemented in most interesting cases:

        sage: f = ZZ.hom(QQ)
        sage: f.is_injective()
        Traceback (most recent call last):
        ...
        NotImplementedError

  `is_zero`()

    Return `True` if this is the zero map and `False` otherwise.

    A ring homomorphism is considered to be 0 if and only if it sends the 1 element of the domain to the 0 element of the codomain. Since rings in Sage all have a 1 element, the zero homomorphism is only to a ring of order 1, where `1 == 0`, e.g., the ring `Integers(1)`.

    EXAMPLES:

    First an example of a map that is obviously nonzero:

        sage: h = Hom(ZZ, QQ)
        sage: f = h.natural_map()
        sage: f.is_zero()
        False

    Next we make the zero ring as \(\ZZ/1\ZZ\):

        sage: R = Integers(1)
        sage: R
        Ring of integers modulo 1
        sage: h = Hom(ZZ, R)
        sage: f = h.natural_map()
        sage: f.is_zero()
        True

    Finally we check an example in characteristic 2:

        sage: h = Hom(ZZ, GF(2))
        sage: f = h.natural_map()
        sage: f.is_zero()
        False

  `lift`(x=None)

    Return a lifting homomorphism 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()
        sage: f.pushforward(R.ideal([x,3*x+x*y+y^2]))
        Ideal (xx, xx*yy + 3*xx) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2)

class `sage.rings.morphism.``RingHomomorphism_coercion`

  Bases: `sage.rings.morphism.RingHomomorphism`

  Initialize `self`.

  INPUT:

  - `parent` – ring homset
  - `check` – bool (default: `True`)

  EXAMPLES:

      sage: f = ZZ.hom(QQ); f                    # indirect doctest
      Ring Coercion morphism:
        From: Integer Ring
        To:   Rational Field

      sage: f == loads(dumps(f))
      True

class `sage.rings.morphism.``RingHomomorphism_cover`

  Bases: `sage.rings.morphism.RingHomomorphism`

  A homomorphism induced by quotienting a ring out by an ideal.

  EXAMPLES:

      sage: R.<x,y> = PolynomialRing(QQ, 2)
      sage: S.<a,b> = R.quo(x^2 + y^2)
      sage: phi = S.cover(); phi
      Ring morphism:
        From: Multivariate Polynomial Ring in x, y over Rational Field
        To:   Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2)
        Defn: Natural quotient map
      sage: phi(x+y)
      a + b

  `kernel`()

    Return the kernel of this covering morphism, which is the ideal that was quotiented out by.

    EXAMPLES:

        sage: f = Zmod(6).cover()
        sage: f.kernel()
        Principal ideal (6) of Integer Ring

class `sage.rings.morphism.``RingHomomorphism_from_base`

  Bases: `sage.rings.morphism.RingHomomorphism`

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

  AUTHOR:

  - Simon King (initial version, 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)
      sage: MS = MatrixSpace(S,2,2)
      sage: M = MR([x^2 + 1/7*x*y - y^2, - 1/2*y^2 + 2*y + 1/6, 4*x^2 - 14*x, 1/2*y^2 + 13/4*x - 2/11*y])
      sage: Mf = MR.hom(f,MS)
      sage: Mf
      Ring morphism:
        From: Full MatrixSpace of 2 by 2 dense matrices over Multivariate Polynomial Ring in x, y over Rational Field
        To:   Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in z over Rational Field
        Defn: Induced from base ring by
              Ring morphism:
                From: Multivariate Polynomial Ring in x, y over Rational Field
                To:   Univariate Polynomial Ring in z over Rational Field
                Defn: x |--> 2*z
                      y |--> 3*z
      sage: Mf(M)
      [           -29/7*z^2 -9/2*z^2 + 6*z + 1/6]
      [       16*z^2 - 28*z   9/2*z^2 + 131/22*z]

  The construction of induced homomorphisms is recursive, and so we have:

      sage: MPR = MatrixSpace(PR, 2)
      sage: MPS = MatrixSpace(PS, 2)
      sage: M = MPR([(- x + y)*t^2 + 58*t - 3*x^2 + x*y, (- 1/7*x*y - 1/40*x)*t^2 + (5*x^2 + y^2)*t + 2*y, (- 1/3*y + 1)*t^2 + 1/3*x*y + y^2 + 5/2*y + 1/4, (x + 6*y + 1)*t^2])
      sage: MPf = MPR.hom(f,MPS); MPf
      Ring morphism:
        From: Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in t over Multivariate Polynomial Ring in x, y over Rational Field
        To:   Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in t over Univariate Polynomial Ring in z over Rational Field
        Defn: Induced from base ring by
              Ring morphism:
                From: Univariate Polynomial Ring in t over Multivariate Polynomial Ring in x, y over Rational Field
                To:   Univariate Polynomial Ring in t over Univariate Polynomial Ring in z over Rational Field
                Defn: Induced from base ring by
                      Ring morphism:
                        From: Multivariate Polynomial Ring in x, y over Rational Field
                        To:   Univariate Polynomial Ring in z over Rational Field
                        Defn: x |--> 2*z
                              y |--> 3*z
      sage: MPf(M)
      [                    z*t^2 + 58*t - 6*z^2 (-6/7*z^2 - 1/20*z)*t^2 + 29*z^2*t + 6*z]
      [    (-z + 1)*t^2 + 11*z^2 + 15/2*z + 1/4                           (20*z + 1)*t^2]

  `underlying_map`()

    Return the underlying homomorphism of the base ring.

    EXAMPLES:

        sage: R.<x,y> = QQ[]
        sage: S.<z> = QQ[]
        sage: f = R.hom([2*z,3*z],S)
        sage: MR = MatrixSpace(R,2)
        sage: MS = MatrixSpace(S,2)
        sage: g = MR.hom(f,MS)
        sage: g.underlying_map() == f
        True

class `sage.rings.morphism.``RingHomomorphism_from_quotient`

  Bases: `sage.rings.morphism.RingHomomorphism`

  A ring homomorphism with domain a generic quotient ring.

  INPUT:

  - `parent` – a ring 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)
      sage: phi = S.hom([b, c, a]); phi
      Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by the ideal (x^3 + y^3 + z^3)
        Defn: a |--> b
              b |--> c
              c |--> a
      sage: phi(a+b+c)
      a + b + c
      sage: loads(dumps(phi)) == phi
      True

  Validity of the homomorphism is determined, when possible, and a `TypeError` is raised if there is no homomorphism sending the generators to the given images:

      sage: S.hom([b^2, c^2, a^2])
      Traceback (most recent call last):
      ...
      TypeError: images do not define a valid homomorphism

  `morphism_from_cover`()

    Underlying morphism used to define this quotient map, i.e., the morphism from the cover of the domain.

    EXAMPLES:

        sage: R.<x,y> = QQ[]; S.<xx,yy> = R.quo([x^2,y^2])
        sage: S.hom([yy,xx]).morphism_from_cover()
        Ring morphism:
          From: Multivariate Polynomial Ring in x, y over Rational Field
          To:   Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2)
          Defn: x |--> yy
                y |--> xx

class `sage.rings.morphism.``RingHomomorphism_im_gens`

  Bases: `sage.rings.morphism.RingHomomorphism`

  A ring homomorphism determined by the images of generators.

  `im_gens`()

    Return the images of the generators of the domain.

    OUTPUT:

    - `list` – a copy of the list of gens (it is safe to change this)

    EXAMPLES:

        sage: R.<x,y> = QQ[]
        sage: f = R.hom([x,x+y])
        sage: f.im_gens()
        [x, x + y]

    We verify that the returned list of images of gens is a copy, so changing it doesn’t change `f`:

        sage: f.im_gens()[0] = 5
        sage: f.im_gens()
        [x, x + y]

class `sage.rings.morphism.``RingMap`

  Bases: `sage.categories.morphism.Morphism`

  Set-theoretic map between rings.

class `sage.rings.morphism.``RingMap_lift`

  Bases: `sage.rings.morphism.RingMap`

  Given rings \(R\) and \(S\) such that for any \(x \in R\) the function `x.lift()` is an element that naturally coerces to \(S\), this returns the set-theoretic ring map \(R \to S\) sending \(x\) to `x.lift()`.

  EXAMPLES:

      sage: R, (x,y) = PolynomialRing(QQ, 2, 'xy').objgens()
      sage: S.<xbar,ybar> = R.quo( (x^2 + y^2, y) )
      sage: S.lift()
      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
      False

  Since trac ticket #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)
      sage: I = MS*[MS.0*MS.1,MS.2+MS.3]*MS
      sage: Q = MS.quo(I)
      sage: Q.0*Q.1   # indirect doctest
      [0 1]
      [0 0]

`sage.rings.morphism.``is_RingHomomorphism`(phi)

  Return `True` if `phi` is of type `RingHomomorphism`.

  EXAMPLES:

      sage: f = Zmod(8).cover()
      sage: sage.rings.morphism.is_RingHomomorphism(f)
      True
      sage: sage.rings.morphism.is_RingHomomorphism(2/3)
      False

### Navigation

- index
- modules |
- next |
- previous |
- General Rings, Ideals, and Morphisms »