### Navigation

- index
- modules |
- next |
- previous |
- Schemes »

# Scheme morphism

Note

You should never create the morphisms directy. Instead, use the `hom()` and `Hom()` methods that are inherited by all schemes.

If you want to extend the Sage library with some new kind of scheme, your new class (say, `myscheme`) should provide a method

- `myscheme._morphism(*args, **kwds)` returning a morphism between two schemes in your category, usually defined via polynomials. Your morphism class should derive from `SchemeMorphism_polynomial`. These morphisms will usually be elements of the Hom-set `SchemeHomset_generic`.

Optionally, you can also provide a special Hom-set class for your subcategory of schemes. If you want to do this, you should also provide a method

- `myscheme._homset(*args, **kwds)` returning a Hom-set, which must be an element of a derived class of \(class:`~sage.schemes.generic.homset.SchemeHomset_generic\). If your new Hom-set class does not use `myscheme._morphism` then you do not have to provide it.

Note that points on schemes are morphisms \(Spec(K)\to X\), too. But we typically use a different notation, so they are implemented in a different derived class. For this, you should implement a method

- `myscheme._point(*args, **kwds)` returning a point, that is, a morphism \(Spec(K)\to X\). Your point class should derive from `SchemeMorphism_point`.

Optionally, you can also provide a special Hom-set for the points, for example the point Hom-set can provide a method to enumerate all points. If you want to do this, you should also provide a method

- `myscheme._point_homset(*args, **kwds)` returning the `homset` of points. The Hom-sets of points are implemented in classes named `SchemeHomset_points_...`. If your new Hom-set class does not use `myscheme._point` then you do not have to provide it.

AUTHORS:

- David Kohel, William Stein
- William Stein (2006-02-11): fixed bug where P(0,0,0) was allowed as a projective point.
- Volker Braun (2011-08-08): Renamed classes, more documentation, misc cleanups.
- Ben Hutz (June 2012): added support for projective ring
- Simon King (2013-10): copy the changes of `Morphism` that have been introduced in trac ticket #14711.

class `sage.schemes.generic.morphism.``SchemeMorphism`(parent, codomain=None)

  Bases: `sage.structure.element.Element`

  Base class for scheme morphisms

  INPUT:

  - `parent` – the parent of the morphism.

  Todo

  Currently, `SchemeMorphism` copies code from `Map` rather than inheriting from it. This is to work around a bug in Cython: We want to create a common sub-class of `ModuleElement` and `SchemeMorphism`, but Cython would currently confuse cpdef attributes of the two base classes. Proper inheritance should be used as soon as this bug is fixed.

  EXAMPLES:

      sage: X = Spec(ZZ)
      sage: Hom = X.Hom(X)
      sage: from sage.schemes.generic.morphism import SchemeMorphism
      sage: f = SchemeMorphism(Hom)
      sage: type(f)
      <class 'sage.schemes.generic.morphism.SchemeMorphism'>

  TESTS:

      sage: A2 = AffineSpace(QQ,2)
      sage: A2.structure_morphism().domain()
      Affine Space of dimension 2 over Rational Field
      sage: A2.structure_morphism().category()
      Category of homsets of schemes

  `category`()

    Return the category of the Hom-set.

    OUTPUT:

    A category.

    EXAMPLES:

        sage: A2 = AffineSpace(QQ,2)
        sage: A2.structure_morphism().category()
        Category of homsets of schemes

  `category_for`()

    Return the category which this morphism belongs to.

    EXAMPLES:

        sage: A2 = AffineSpace(QQ,2)
        sage: A2.structure_morphism().category_for()
        Category of schemes

  `glue_along_domains`(other)

    Glue two morphism

    INPUT:

    - `other` – a scheme morphism with the same domain.

    OUTPUT:

    Assuming that self and other are open immersions with the same domain, return scheme obtained by gluing along the images.

    EXAMPLES:

    We construct a scheme isomorphic to the projective line over \(\mathrm{Spec}(\QQ)\) by gluing two copies of \(\mathbb{A}^1\) minus a point:

        sage: R.<x,y> = PolynomialRing(QQ, 2)
        sage: S.<xbar, ybar> = R.quotient(x*y - 1)
        sage: Rx = PolynomialRing(QQ, 'x')
        sage: i1 = Rx.hom([xbar])
        sage: Ry = PolynomialRing(QQ, 'y')
        sage: i2 = Ry.hom([ybar])
        sage: Sch = Schemes()
        sage: f1 = Sch(i1)
        sage: f2 = Sch(i2)

    Now f1 and f2 have the same domain, which is a \(\mathbb{A}^1\) minus a point. We glue along the domain:

        sage: P1 = f1.glue_along_domains(f2)
        sage: P1
        Scheme obtained by gluing X and Y along U, where
          X: Spectrum of Univariate Polynomial Ring in x over Rational Field
          Y: Spectrum of Univariate Polynomial Ring in y over Rational Field
          U: Spectrum of Quotient of Multivariate Polynomial Ring in x, y
          over Rational Field by the ideal (x*y - 1)

        sage: a, b = P1.gluing_maps()
        sage: a
        Affine Scheme morphism:
         From: Spectrum of Quotient of Multivariate Polynomial Ring in x, y
               over Rational Field by the ideal (x*y - 1)
          To:   Spectrum of Univariate Polynomial Ring in x over Rational Field
          Defn: Ring morphism:
                  From: Univariate Polynomial Ring in x over Rational Field
                  To:   Quotient of Multivariate Polynomial Ring in x, y over
                        Rational Field by the ideal (x*y - 1)
                  Defn: x |--> xbar
        sage: b
        Affine Scheme morphism:
          From: Spectrum of Quotient of Multivariate Polynomial Ring in x, y
                over Rational Field by the ideal (x*y - 1)
          To:   Spectrum of Univariate Polynomial Ring in y over Rational Field
          Defn: Ring morphism:
                  From: Univariate Polynomial Ring in y over Rational Field
                  To:   Quotient of Multivariate Polynomial Ring in x, y over
                        Rational Field by the ideal (x*y - 1)
                  Defn: y |--> ybar

  `is_endomorphism`()

    Return wether the morphism is an endomorphism.

    OUTPUT:

    Boolean. Whether the domain and codomain are identical.

    EXAMPLES:

        sage: X = AffineSpace(QQ,2)
        sage: X.structure_morphism().is_endomorphism()
        False
        sage: X.identity_morphism().is_endomorphism()
        True

class `sage.schemes.generic.morphism.``SchemeMorphism_id`(X)

  Bases: `sage.schemes.generic.morphism.SchemeMorphism`

  Return the identity morphism from \(X\) to itself.

  INPUT:

  - `X` – the scheme.

  EXAMPLES:

      sage: X = Spec(ZZ)
      sage: X.identity_morphism()  # indirect doctest
      Scheme endomorphism of Spectrum of Integer Ring
        Defn: Identity map

class `sage.schemes.generic.morphism.``SchemeMorphism_point`(parent, codomain=None)

  Bases: `sage.schemes.generic.morphism.SchemeMorphism`

  Base class for rational points on schemes.

  Recall that the \(K\)-rational points of a scheme \(X\) over \(k\) can be identified with the set of morphisms \(Spec(K) o X\). In Sage, the rational points are implemented by such scheme morphisms.

  EXAMPLES:

      sage: from sage.schemes.generic.morphism import SchemeMorphism
      sage: f = SchemeMorphism(Spec(ZZ).Hom(Spec(ZZ)))
      sage: type(f)
      <class 'sage.schemes.generic.morphism.SchemeMorphism'>

  `change_ring`(R, check=True)

    Returns a new `SchemeMorphism_point` which is self coerced to R. If \(check\) is true, then the initialization checks are performed.

    INPUT:

    - `R` – a ring
    - `check` – Boolean (optional)

    OUTPUT:

    - `SchemeMorphism_point`

    EXAMPLES:

        sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)
        sage: X=P.subscheme(x^2-y^2)
        sage: X(23,23,1).change_ring(GF(13))
        (10 : 10 : 1)

        sage: P.<x,y>=ProjectiveSpace(QQ,1)
        sage: P(-2/3,1).change_ring(CC)
        (-0.666666666666667 : 1.00000000000000)

        sage: P.<x,y>=ProjectiveSpace(ZZ,1)
        sage: P(152,113).change_ring(Zp(5))
        (2 + 5^2 + 5^3 + O(5^20) : 3 + 2*5 + 4*5^2 + O(5^20))

  `scheme`()

    Return the scheme whose point is represented.

    OUTPUT:

    A scheme.

    EXAMPLES:

        sage: A = AffineSpace(2, QQ)
        sage: a = A(1,2)
        sage: a.scheme()
        Affine Space of dimension 2 over Rational Field

class `sage.schemes.generic.morphism.``SchemeMorphism_polynomial`(parent, polys, check=True)

  Bases: `sage.schemes.generic.morphism.SchemeMorphism`

  A morphism of schemes determined by polynomials that define what the morphism does on points in the ambient space.

  INPUT:

  - `parent` – Hom-set whose domain and codomain are affine schemes.
  - `polys` – a list/tuple/iterable of polynomials defining the scheme morphism.
  - `check` – boolean (optional, default:`True`). Whether to check the input for consistency.

  EXAMPLES:

  An example involving the affine plane:

      sage: R.<x,y> = QQ[]
      sage: A2 = AffineSpace(R)
      sage: H = A2.Hom(A2)
      sage: f = H([x-y, x*y])
      sage: f([0,1])
      (-1, 0)

  An example involving the projective line:

      sage: R.<x,y> = QQ[]
      sage: P1 = ProjectiveSpace(R)
      sage: H = P1.Hom(P1)
      sage: f = H([x^2+y^2,x*y])
      sage: f([0,1])
      (1 : 0)

  Some checks are performed to make sure the given polynomials define a morphism:

      sage: f = H([exp(x),exp(y)])
      Traceback (most recent call last):
      ...
      TypeError: polys (=[e^x, e^y]) must be elements of
      Multivariate Polynomial Ring in x, y over Rational Field

  `base_ring`()

    Return the base ring of `self`, that is, the ring over which the coefficients of `self` is given as polynomials.

    OUTPUT:

    - ring

    EXAMPLES:

        sage: P.<x,y>=ProjectiveSpace(QQ,1)
        sage: H=Hom(P,P)
        sage: f=H([3/5*x^2,6*y^2])
        sage: f.base_ring()
        Rational Field

        sage: R.<t>=PolynomialRing(ZZ,1)
        sage: P.<x,y>=ProjectiveSpace(R,1)
        sage: H=Hom(P,P)
        sage: f=H([3*x^2,y^2])
        sage: f.base_ring()
        Multivariate Polynomial Ring in t over Integer Ring

  `change_ring`(R, check=True)

    Returns a new `SchemeMorphism_polynomial` which is `self` coerced to `R`. If `check` is `True`, then the initialization checks are performed.

    INPUT:

    - `R` – ring
    - `check` – Boolean

    OUTPUT:

    - A new :class: \(SchemeMorphism_polynomial\) which is `self` coerced to `R`.

    EXAMPLES:

        sage: P.<x,y>=ProjectiveSpace(ZZ,1)
        sage: H=Hom(P,P)
        sage: f=H([3*x^2,y^2])
        sage: f.change_ring(GF(3))
        Traceback (most recent call last):
        ...
        ValueError: polys (=[0, y^2]) must be of the same degree

        sage: P.<x,y,z>=ProjectiveSpace(QQ,2)
        sage: H=Hom(P,P)
        sage: f=H([5/2*x^3 + 3*x*y^2-y^3,3*z^3 + y*x^2, x^3-z^3])
        sage: f.change_ring(GF(3))
        Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 3
            Defn: Defined on coordinates by sending (x : y : z) to
                (x^3 - y^3 : x^2*y : x^3 - z^3)

        sage: P.<x,y>=ProjectiveSpace(QQ,1)
        sage: X=P.subscheme([5*x^2-y^2])
        sage: H=Hom(X,X)
        sage: f=H([x,y])
        sage: f.change_ring(GF(3))
        Scheme endomorphism of Closed subscheme of Projective Space of dimension
        1 over Finite Field of size 3 defined by:
            -x^2 - y^2
            Defn: Defined on coordinates by sending (x : y) to
                (x : y)

        Check that :trac:'16834' is fixed::

            sage: A.<x,y,z> = AffineSpace(RR,3)
            sage: h = Hom(A,A)
            sage: f = h([x^2+1.5,y^3,z^5-2.0])
            sage: f.change_ring(CC)
            Scheme endomorphism of Affine Space of dimension 3 over Complex Field with 53 bits of precision
            Defn: Defined on coordinates by sending (x, y, z) to
                (x^2 + 1.50000000000000, y^3, z^5 - 2.00000000000000)

        ::

            sage: A.<x,y> = ProjectiveSpace(ZZ,1)
            sage: B.<u,v> = AffineSpace(QQ,2)
            sage: h = Hom(A,B)
            sage: f = h([x^2, y^2])
            sage: f.change_ring(QQ)
            Scheme morphism:
                From: Projective Space of dimension 1 over Rational Field
                To:   Affine Space of dimension 2 over Rational Field
                Defn: Defined on coordinates by sending (x : y) to
                (x^2, y^2)

  `coordinate_ring`()

    Returns the coordinate ring of the ambient projective space the multivariable polynomial ring over the base ring

    OUTPUT:

    - ring

    EXAMPLES:

        sage: P.<x,y>=ProjectiveSpace(QQ,1)
        sage: H=Hom(P,P)
        sage: f=H([3/5*x^2,6*y^2])
        sage: f.coordinate_ring()
        Multivariate Polynomial Ring in x, y over Rational Field

        sage: R.<t>=PolynomialRing(ZZ,1)
        sage: P.<x,y>=ProjectiveSpace(R,1)
        sage: H=Hom(P,P)
        sage: f=H([3*x^2,y^2])
        sage: f.coordinate_ring()
        Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring
        in t over Integer Ring

  `defining_polynomials`()

    Return the defining polynomials.

    OUTPUT:

    An immutable sequence of polynomials that defines this scheme morphism.

    EXAMPLES:

        sage: R.<x,y> = QQ[]
        sage: A.<x,y> = AffineSpace(R)
        sage: H = A.Hom(A)
        sage: H([x^3+y, 1-x-y]).defining_polynomials()
        [x^3 + y, -x - y + 1]

class `sage.schemes.generic.morphism.``SchemeMorphism_spec`(parent, phi, check=True)

  Bases: `sage.schemes.generic.morphism.SchemeMorphism`

  Morphism of spectra of rings

  INPUT:

  - `parent` – Hom-set whose domain and codomain are affine schemes.
  - `phi` – a ring morphism with matching domain and codomain.
  - `check` – boolean (optional, default:`True`). Whether to check the input for consistency.

  EXAMPLES:

      sage: R.<x> = PolynomialRing(QQ)
      sage: phi = R.hom([QQ(7)]); phi
      Ring morphism:
        From: Univariate Polynomial Ring in x over Rational Field
        To:   Rational Field
        Defn: x |--> 7

      sage: X = Spec(QQ); Y = Spec(R)
      sage: f = X.hom(phi); f
      Affine Scheme morphism:
        From: Spectrum of Rational Field
        To:   Spectrum of Univariate Polynomial Ring in x over Rational Field
        Defn: Ring morphism:
                From: Univariate Polynomial Ring in x over Rational Field
                To:   Rational Field
                Defn: x |--> 7

      sage: f.ring_homomorphism()
      Ring morphism:
        From: Univariate Polynomial Ring in x over Rational Field
        To:   Rational Field
        Defn: x |--> 7

  `ring_homomorphism`()

    Return the underlying ring homomorphism.

    OUTPUT:

    A ring homomorphism.

    EXAMPLES:

        sage: R.<x> = PolynomialRing(QQ)
        sage: phi = R.hom([QQ(7)])
        sage: X = Spec(QQ); Y = Spec(R)
        sage: f = X.hom(phi)
        sage: f.ring_homomorphism()
        Ring morphism:
          From: Univariate Polynomial Ring in x over Rational Field
          To:   Rational Field
          Defn: x |--> 7

class `sage.schemes.generic.morphism.``SchemeMorphism_structure_map`(parent, codomain=None)

  Bases: `sage.schemes.generic.morphism.SchemeMorphism`

  The structure morphism

  INPUT:

  - `parent` – Hom-set with codomain equal to the base scheme of the domain.

  EXAMPLES:

      sage: Spec(ZZ).structure_morphism()    # indirect doctest
      Scheme endomorphism of Spectrum of Integer Ring
        Defn: Structure map

`sage.schemes.generic.morphism.``is_SchemeMorphism`(f)

  Test whether `f` is a scheme morphism.

  INPUT:

  - `f` – anything.

  OUTPUT:

  Boolean. Return `True` if `f` is a scheme morphism or a point on an elliptic curve.

  EXAMPLES:

      sage: A.<x,y> = AffineSpace(QQ,2); H = A.Hom(A)
      sage: f = H([y,x^2+y]); f
      Scheme endomorphism of Affine Space of dimension 2 over Rational Field
        Defn: Defined on coordinates by sending (x, y) to
              (y, x^2 + y)
      sage: from sage.schemes.generic.morphism import is_SchemeMorphism
      sage: is_SchemeMorphism(f)
      True

### Navigation

- index
- modules |
- next |
- previous |
- Schemes »