Path: blob/master/src/sage/schemes/generic/morphism.py
8820 views
r"""1Scheme morphism23.. note::45You should never create the morphisms directy. Instead, use the6:meth:`~sage.schemes.generic.scheme.hom` and7:meth:`~sage.structure.parent.Hom` methods that are inherited by8all schemes.910If you want to extend the Sage library with some new kind of scheme,11your new class (say, ``myscheme``) should provide a method1213* ``myscheme._morphism(*args, **kwds)`` returning a morphism14between two schemes in your category, usually defined via15polynomials. Your morphism class should derive from16:class:`SchemeMorphism_polynomial`. These morphisms will usually be17elements of the Hom-set18:class:`~sage.schemes.generic.homset.SchemeHomset_generic`.1920Optionally, you can also provide a special Hom-set class for your21subcategory of schemes. If you want to do this, you should also22provide a method2324* ``myscheme._homset(*args, **kwds)`` returning a25Hom-set, which must be an element of a derived class of26`class:`~sage.schemes.generic.homset.SchemeHomset_generic`. If your27new Hom-set class does not use ``myscheme._morphism`` then you28do not have to provide it.2930Note that points on schemes are morphisms `Spec(K)\to X`, too. But we31typically use a different notation, so they are implemented in a32different derived class. For this, you should implement a method3334* ``myscheme._point(*args, **kwds)`` returning a point, that is,35a morphism `Spec(K)\to X`. Your point class should derive from36:class:`SchemeMorphism_point`.3738Optionally, you can also provide a special Hom-set for the points, for39example the point Hom-set can provide a method to enumerate all40points. If you want to do this, you should also provide a method4142* ``myscheme._point_homset(*args, **kwds)`` returning43the :mod:`~sage.schemes.generic.homset` of points. The Hom-sets of44points are implemented in classes named ``SchemeHomset_points_...``.45If your new Hom-set class does not use ``myscheme._point`` then46you do not have to provide it.4748AUTHORS:4950- David Kohel, William Stein5152- William Stein (2006-02-11): fixed bug where P(0,0,0) was allowed as53a projective point.5455- Volker Braun (2011-08-08): Renamed classes, more documentation, misc56cleanups.5758- Ben Hutz (June 2012): added support for projective ring59"""6061# Historical note: in trac #11599, V.B. renamed62# * _point_morphism_class -> _morphism63# * _homset_class -> _point_homset6465#*****************************************************************************66# Copyright (C) 2011 Volker Braun <[email protected]>67# Copyright (C) 2006 David Kohel <[email protected]>68# Copyright (C) 2006 William Stein <[email protected]>69#70# Distributed under the terms of the GNU General Public License (GPL)71# as published by the Free Software Foundation; either version 2 of72# the License, or (at your option) any later version.73# http://www.gnu.org/licenses/74#*****************************************************************************757677from sage.structure.element import AdditiveGroupElement, RingElement, Element, generic_power78from sage.structure.sequence import Sequence79from sage.categories.homset import Homset80from sage.rings.all import Integer81from sage.rings.commutative_ring import is_CommutativeRing82from sage.rings.morphism import is_RingHomomorphism83from point import is_SchemeTopologicalPoint84from sage.rings.infinity import infinity85import scheme8687from sage.rings.arith import gcd, lcm88from sage.categories.gcd_domains import GcdDomains89from sage.rings.quotient_ring import QuotientRing_generic90from sage.categories.homset import Hom919293def is_SchemeMorphism(f):94"""95Test whether ``f`` is a scheme morphism.9697INPUT:9899- ``f`` -- anything.100101OUTPUT:102103Boolean. Return ``True`` if ``f`` is a scheme morphism or a point104on an elliptic curve.105106EXAMPLES::107108sage: A.<x,y> = AffineSpace(QQ,2); H = A.Hom(A)109sage: f = H([y,x^2+y]); f110Scheme endomorphism of Affine Space of dimension 2 over Rational Field111Defn: Defined on coordinates by sending (x, y) to112(y, x^2 + y)113sage: from sage.schemes.generic.morphism import is_SchemeMorphism114sage: is_SchemeMorphism(f)115True116"""117from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field118return isinstance(f, (SchemeMorphism, EllipticCurvePoint_field));119120121class SchemeMorphism(Element):122"""123Base class for scheme morphisms124125INPUT:126127- ``parent`` -- the parent of the morphism.128129EXAMPLES::130131sage: X = Spec(ZZ)132sage: Hom = X.Hom(X)133sage: from sage.schemes.generic.morphism import SchemeMorphism134sage: f = SchemeMorphism(Hom)135sage: type(f)136<class 'sage.schemes.generic.morphism.SchemeMorphism'>137"""138def __init__(self, parent):139"""140The Python constructor.141142EXAMPLES::143144sage: X = Spec(ZZ)145sage: Hom = X.Hom(X)146sage: from sage.schemes.generic.morphism import SchemeMorphism147sage: f = SchemeMorphism(Hom)148sage: type(f)149<class 'sage.schemes.generic.morphism.SchemeMorphism'>150"""151if not isinstance(parent, Homset):152raise TypeError, "parent (=%s) must be a Homspace"%parent153Element.__init__(self, parent)154self._domain = parent.domain()155self._codomain = parent.codomain()156157def _repr_defn(self):158r"""159Return a string representation of the definition of ``self``.160161OUTPUT:162163String.164165EXAMPLES::166167sage: X = Spec(ZZ)168sage: Hom = X.Hom(X)169sage: from sage.schemes.generic.morphism import SchemeMorphism170sage: f = SchemeMorphism(Hom)171sage: f._repr_defn()172Traceback (most recent call last):173...174NotImplementedError175"""176raise NotImplementedError177178def _repr_type(self):179r"""180Return a string representation of the type of ``self``.181182OUTPUT:183184String.185186EXAMPLES::187188sage: from sage.schemes.generic.scheme import Scheme189sage: X = Scheme(ZZ)190sage: Hom = X.Hom(X)191sage: from sage.schemes.generic.morphism import SchemeMorphism192sage: f = SchemeMorphism(Hom)193sage: f._repr_type()194'Scheme'195"""196return "Scheme"197198def _repr_(self):199r"""200Return a string representation of ``self``.201202OUTPUT:203204String.205206EXAMPLES::207208sage: X = Spec(ZZ)209sage: Hom = X.Hom(X)210sage: from sage.schemes.generic.morphism import SchemeMorphism211sage: f = SchemeMorphism(Hom)212sage: f._repr_()213Traceback (most recent call last):214...215NotImplementedError216"""217if self.is_endomorphism():218s = "%s endomorphism of %s"%(self._repr_type(), self.domain())219else:220s = "%s morphism:"%self._repr_type()221s += "\n From: %s"%self.domain()222s += "\n To: %s"%self.codomain()223d = self._repr_defn()224if d != '':225s += "\n Defn: %s"%('\n '.join(self._repr_defn().split('\n')))226return s227228def domain(self):229"""230Return the domain of the morphism.231232OUTPUT:233234A scheme. The domain of the morphism ``self``.235236EXAMPLES::237238sage: A2 = AffineSpace(QQ,2)239sage: A2.structure_morphism().domain()240Affine Space of dimension 2 over Rational Field241"""242return self._domain243244def codomain(self):245"""246Return the codomain (range) of the morphism.247248OUTPUT:249250A scheme. The codomain of the morphism ``self``.251252EXAMPLES::253254sage: A2 = AffineSpace(QQ,2)255sage: A2.structure_morphism().codomain()256Spectrum of Rational Field257"""258return self.parent().codomain()259260def category(self):261"""262Return the category of the Hom-set.263264OUTPUT:265266A category.267268EXAMPLES::269270sage: A2 = AffineSpace(QQ,2)271sage: A2.structure_morphism().category()272Category of hom sets in Category of Schemes273"""274return self.parent().category()275276def is_endomorphism(self):277"""278Return wether the morphism is an endomorphism.279280OUTPUT:281282Boolean. Whether the domain and codomain are identical.283284EXAMPLES::285286sage: X = AffineSpace(QQ,2)287sage: X.structure_morphism().is_endomorphism()288False289sage: X.identity_morphism().is_endomorphism()290True291"""292return self.parent().is_endomorphism_set()293294def _composition_(self, right, homset):295"""296Helper to construct the composition of two morphisms.297298EXAMPLES::299300sage: X = AffineSpace(QQ,2)301sage: f = X.structure_morphism()302sage: g = X.identity_morphism()303sage: f._composition_(g, f.parent())304Traceback (most recent call last):305...306NotImplementedError307308sage: f * g309Traceback (most recent call last):310...311TypeError: unsupported operand type(s) for *:312'SchemeMorphism_structure_map' and 'SchemeMorphism_id'313"""314raise NotImplementedError315316def __pow__(self, n, dummy=None):317"""318Exponentiate an endomorphism.319320INPUT:321322- ``n`` -- integer. The exponent.323324OUTPUT:325326A scheme morphism in the same endomorphism set as ``self``.327328EXAMPLES::329330sage: X = AffineSpace(QQ,2)331sage: id = X.identity_morphism()332sage: id^0333Scheme endomorphism of Affine Space of dimension 2 over Rational Field334Defn: Identity map335sage: id^2336Traceback (most recent call last):337...338TypeError: unsupported operand type(s) for *:339'SchemeMorphism_id' and 'SchemeMorphism_id'340"""341if not self.is_endomorphism():342raise TypeError, "self must be an endomorphism."343if n==0:344return self.domain().identity_morphism()345return generic_power(self, n)346347def glue_along_domains(self, other):348r"""349Glue two morphism350351INPUT:352353- ``other`` -- a scheme morphism with the same domain.354355OUTPUT:356357Assuming that self and other are open immersions with the same358domain, return scheme obtained by gluing along the images.359360EXAMPLES:361362We construct a scheme isomorphic to the projective line over363`\mathrm{Spec}(\QQ)` by gluing two copies of `\mathbb{A}^1`364minus a point::365366sage: R.<x,y> = PolynomialRing(QQ, 2)367sage: S.<xbar, ybar> = R.quotient(x*y - 1)368sage: Rx = PolynomialRing(QQ, 'x')369sage: i1 = Rx.hom([xbar])370sage: Ry = PolynomialRing(QQ, 'y')371sage: i2 = Ry.hom([ybar])372sage: Sch = Schemes()373sage: f1 = Sch(i1)374sage: f2 = Sch(i2)375376Now f1 and f2 have the same domain, which is a377`\mathbb{A}^1` minus a point. We glue along the domain::378379sage: P1 = f1.glue_along_domains(f2)380sage: P1381Scheme obtained by gluing X and Y along U, where382X: Spectrum of Univariate Polynomial Ring in x over Rational Field383Y: Spectrum of Univariate Polynomial Ring in y over Rational Field384U: Spectrum of Quotient of Multivariate Polynomial Ring in x, y385over Rational Field by the ideal (x*y - 1)386387sage: a, b = P1.gluing_maps()388sage: a389Affine Scheme morphism:390From: Spectrum of Quotient of Multivariate Polynomial Ring in x, y391over Rational Field by the ideal (x*y - 1)392To: Spectrum of Univariate Polynomial Ring in x over Rational Field393Defn: Ring morphism:394From: Univariate Polynomial Ring in x over Rational Field395To: Quotient of Multivariate Polynomial Ring in x, y over396Rational Field by the ideal (x*y - 1)397Defn: x |--> xbar398sage: b399Affine Scheme morphism:400From: Spectrum of Quotient of Multivariate Polynomial Ring in x, y401over Rational Field by the ideal (x*y - 1)402To: Spectrum of Univariate Polynomial Ring in y over Rational Field403Defn: Ring morphism:404From: Univariate Polynomial Ring in y over Rational Field405To: Quotient of Multivariate Polynomial Ring in x, y over406Rational Field by the ideal (x*y - 1)407Defn: y |--> ybar408"""409import glue410return glue.GluedScheme(self, other)411412class SchemeMorphism_id(SchemeMorphism):413"""414Return the identity morphism from `X` to itself.415416INPUT:417418- ``X`` -- the scheme.419420EXAMPLES::421422sage: X = Spec(ZZ)423sage: X.identity_morphism() # indirect doctest424Scheme endomorphism of Spectrum of Integer Ring425Defn: Identity map426"""427def __init__(self, X):428"""429The Python constructor.430431See :class:`SchemeMorphism_id` for details.432433TESTS::434435sage: Spec(ZZ).identity_morphism()436Scheme endomorphism of Spectrum of Integer Ring437Defn: Identity map438"""439SchemeMorphism.__init__(self, X.Hom(X))440441def _repr_defn(self):442r"""443Return a string representation of the definition of ``self``.444445OUTPUT:446447String.448449EXAMPLES::450451sage: Spec(ZZ).identity_morphism()._repr_defn()452'Identity map'453"""454return 'Identity map'455456457class SchemeMorphism_structure_map(SchemeMorphism):458r"""459The structure morphism460461INPUT:462463- ``parent`` -- Hom-set with codomain equal to the base scheme of464the domain.465466EXAMPLES::467468sage: Spec(ZZ).structure_morphism() # indirect doctest469Scheme morphism:470From: Spectrum of Integer Ring471To: Spectrum of Integer Ring472Defn: Structure map473"""474def __init__(self, parent):475"""476The Python constuctor.477478See :class:`SchemeMorphism_structure_map` for details.479480TESTS::481482sage: from sage.schemes.generic.morphism import SchemeMorphism_structure_map483sage: SchemeMorphism_structure_map( Spec(QQ).Hom(Spec(ZZ)) )484Scheme morphism:485From: Spectrum of Rational Field486To: Spectrum of Integer Ring487Defn: Structure map488"""489SchemeMorphism.__init__(self, parent)490if self.domain().base_scheme() != self.codomain():491raise ValueError, "parent must have codomain equal the base scheme of domain."492493def _repr_defn(self):494r"""495Return a string representation of the definition of ``self``.496497OUTPUT:498499String.500501EXAMPLES::502503sage: Spec(ZZ).structure_morphism()._repr_defn()504'Structure map'505"""506return 'Structure map'507508509class SchemeMorphism_spec(SchemeMorphism):510"""511Morphism of spectra of rings512513INPUT:514515- ``parent`` -- Hom-set whose domain and codomain are affine schemes.516517- ``phi`` -- a ring morphism with matching domain and codomain.518519- ``check`` -- boolean (optional, default:``True``). Whether to520check the input for consistency.521522EXAMPLES::523524sage: R.<x> = PolynomialRing(QQ)525sage: phi = R.hom([QQ(7)]); phi526Ring morphism:527From: Univariate Polynomial Ring in x over Rational Field528To: Rational Field529Defn: x |--> 7530531sage: X = Spec(QQ); Y = Spec(R)532sage: f = X.hom(phi); f533Affine Scheme morphism:534From: Spectrum of Rational Field535To: Spectrum of Univariate Polynomial Ring in x over Rational Field536Defn: Ring morphism:537From: Univariate Polynomial Ring in x over Rational Field538To: Rational Field539Defn: x |--> 7540541sage: f.ring_homomorphism()542Ring morphism:543From: Univariate Polynomial Ring in x over Rational Field544To: Rational Field545Defn: x |--> 7546"""547def __init__(self, parent, phi, check=True):548"""549The Python constuctor.550551See :class:`SchemeMorphism_structure_map` for details.552553TESTS::554555sage: from sage.schemes.generic.morphism import SchemeMorphism_spec556sage: SchemeMorphism_spec(Spec(QQ).Hom(Spec(ZZ)), ZZ.hom(QQ))557Affine Scheme morphism:558From: Spectrum of Rational Field559To: Spectrum of Integer Ring560Defn: Ring Coercion morphism:561From: Integer Ring562To: Rational Field563"""564SchemeMorphism.__init__(self, parent)565if check:566if not is_RingHomomorphism(phi):567raise TypeError("phi (=%s) must be a ring homomorphism" % phi)568if phi.domain() != parent.codomain().coordinate_ring():569raise TypeError("phi (=%s) must have domain %s"570% (phi, parent.codomain().coordinate_ring()))571if phi.codomain() != parent.domain().coordinate_ring():572raise TypeError("phi (=%s) must have codomain %s"573% (phi, parent.domain().coordinate_ring()))574self.__ring_homomorphism = phi575576def __call__(self, P):577r"""578Make morphisms callable.579580INPUT:581582- ``P`` -- a scheme point.583584OUTPUT:585586The image scheme point.587588EXAMPLES::589590sage: R.<x> = PolynomialRing(QQ)591sage: phi = R.hom([QQ(7)])592sage: X = Spec(QQ); Y = Spec(R)593sage: f = X.hom(phi)594sage: f(X.an_element())595Traceback (most recent call last):596...597NotImplementedError598"""599if not is_SchemeTopologicalPoint(P) and P in self.domain():600raise TypeError, "P (=%s) must be a topological scheme point of %s"%(P, self)601S = self.ring_homomorphism().inverse_image(P.prime_ideal())602return self.codomain()(S)603604def _repr_type(self):605r"""606Return a string representation of the type of ``self``.607608OUTPUT:609610String.611612EXAMPLES::613614sage: R.<x> = PolynomialRing(QQ)615sage: phi = R.hom([QQ(7)])616sage: X = Spec(QQ); Y = Spec(R)617sage: f = X.hom(phi)618sage: f._repr_type()619'Affine Scheme'620"""621return "Affine Scheme"622623def _repr_defn(self):624r"""625Return a string representation of the definition of ``self``.626627OUTPUT:628629String.630631EXAMPLES::632633sage: R.<x> = PolynomialRing(QQ)634sage: phi = R.hom([QQ(7)])635sage: X = Spec(QQ); Y = Spec(R)636sage: f = X.hom(phi)637sage: print f._repr_defn()638Ring morphism:639From: Univariate Polynomial Ring in x over Rational Field640To: Rational Field641Defn: x |--> 7642"""643return repr(self.ring_homomorphism())644645def ring_homomorphism(self):646"""647Return the underlying ring homomorphism.648649OUTPUT:650651A ring homomorphism.652653EXAMPLES::654655sage: R.<x> = PolynomialRing(QQ)656sage: phi = R.hom([QQ(7)])657sage: X = Spec(QQ); Y = Spec(R)658sage: f = X.hom(phi)659sage: f.ring_homomorphism()660Ring morphism:661From: Univariate Polynomial Ring in x over Rational Field662To: Rational Field663Defn: x |--> 7664"""665return self.__ring_homomorphism666667668############################################################################669# Morphisms between schemes given on points670# The _affine and _projective below refer to the CODOMAIN.671# The domain can be either affine or projective regardless672# of the class673############################################################################674class SchemeMorphism_polynomial(SchemeMorphism):675"""676A morphism of schemes determined by polynomials that define what677the morphism does on points in the ambient space.678679INPUT:680681- ``parent`` -- Hom-set whose domain and codomain are affine schemes.682683- ``polys`` -- a list/tuple/iterable of polynomials defining the684scheme morphism.685686- ``check`` -- boolean (optional, default:``True``). Whether to687check the input for consistency.688689EXAMPLES:690691An example involving the affine plane::692693sage: R.<x,y> = QQ[]694sage: A2 = AffineSpace(R)695sage: H = A2.Hom(A2)696sage: f = H([x-y, x*y])697sage: f([0,1])698(-1, 0)699700An example involving the projective line::701702sage: R.<x,y> = QQ[]703sage: P1 = ProjectiveSpace(R)704sage: H = P1.Hom(P1)705sage: f = H([x^2+y^2,x*y])706sage: f([0,1])707(1 : 0)708709Some checks are performed to make sure the given polynomials710define a morphism::711712sage: f = H([exp(x),exp(y)])713Traceback (most recent call last):714...715TypeError: polys (=[e^x, e^y]) must be elements of716Multivariate Polynomial Ring in x, y over Rational Field717"""718def __init__(self, parent, polys, check=True):719"""720The Python constructor.721722See :class:`SchemeMorphism_polynomial` for details.723724EXAMPLES::725726sage: A2.<x,y> = AffineSpace(QQ,2)727sage: H = A2.Hom(A2)728sage: H([x-y, x*y])729Scheme endomorphism of Affine Space of dimension 2 over Rational Field730Defn: Defined on coordinates by sending (x, y) to731(x - y, x*y)732"""733if check:734if not isinstance(polys, (list, tuple)):735raise TypeError, "polys (=%s) must be a list or tuple"%polys736source_ring = parent.domain().coordinate_ring()737target = parent.codomain().ambient_space()738if len(polys) != target.ngens():739raise ValueError, "there must be %s polynomials"%target.ngens()740try:741polys = [source_ring(poly) for poly in polys]742except TypeError:743raise TypeError, "polys (=%s) must be elements of %s"%(polys,source_ring)744if isinstance(source_ring, QuotientRing_generic):745lift_polys = [f.lift() for f in polys]746else:747lift_polys = polys748polys = Sequence(lift_polys)749self._polys = polys750SchemeMorphism.__init__(self, parent)751752def defining_polynomials(self):753"""754Return the defining polynomials.755756OUTPUT:757758An immutable sequence of polynomials that defines this scheme759morphism.760761EXAMPLES::762763sage: R.<x,y> = QQ[]764sage: A.<x,y> = AffineSpace(R)765sage: H = A.Hom(A)766sage: H([x^3+y, 1-x-y]).defining_polynomials()767[x^3 + y, -x - y + 1]768"""769return self._polys770771def __call__(self, x,check=True):772"""773Apply this morphism to a point in the domain.774775INPUT:776777- ``x`` -- a point in the domain or a list or tuple that defines a point in the domain.778779OUTPUT:780781A point in the codomain.782783EXAMPLES::784785sage: R.<x,y> = QQ[]786sage: A.<x,y> = AffineSpace(R)787sage: H = A.Hom(A)788sage: f = H([y,x^2+y])789sage: f([2,3])790(3, 7)791792An example with algebraic schemes::793794sage: A.<x,y> = AffineSpace(QQ, 2)795sage: X = A.subscheme(x)796sage: Y = A.subscheme(y)797sage: Hom_XY = X.Hom(Y)798sage: f = Hom_XY([y,0]) # (0,y) |-> (y,0)799sage: f800Scheme morphism:801From: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:802x803To: Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:804y805Defn: Defined on coordinates by sending (x, y) to806(y, 0)807sage: f([0,3])808(3, 0)809810We illustrate type checking of the input::811812sage: f(0)813Traceback (most recent call last):814...815TypeError: Argument v (=(0,)) must have 2 coordinates.816817::818819It is possible to avoid the checks on the resulting point which can be useful for indeterminacies,820but be careful!!821822sage: PS.<x,y>=ProjectiveSpace(QQ,1)823sage: H=Hom(PS,PS)824sage: f=H([x^3,x*y^2])825sage: P=PS(0,1)826sage: f(P,check=False)827(0 : 0)828829::830831sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)832sage: X=P.subscheme(x^2-y^2);833sage: H=Hom(X,X)834sage: f=H([x^2,y^2,z^2]);835sage: f([4,4,1])836(16 : 16 : 1)837838::839840sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)841sage: X=P.subscheme(x^2-y^2);842sage: H=Hom(X,X)843sage: f=H([x^2,y^2,z^2]);844sage: f(P([4,4,1]))845Traceback (most recent call last):846...847TypeError: Point must be in the domain of the function848849"""850if check:851if not isinstance(x,SchemeMorphism_point):852x = self.domain()(x)853elif x.codomain()!=self.domain():854raise TypeError, "Point must be in the domain of the function"855P = [f(x._coords) for f in self.defining_polynomials()]856return self.codomain().point(P,check)857858859def _repr_defn(self):860"""861Return a string representation of the definition of ``self``.862863OUTPUT:864865String.866867EXAMPLES::868869sage: R.<x,y> = QQ[]870sage: A.<x,y> = AffineSpace(R)871sage: H = A.Hom(A)872sage: f = H([y,x^2+y])873sage: print f._repr_defn()874Defined on coordinates by sending (x, y) to875(y, x^2 + y)876"""877i = self.domain().ambient_space()._repr_generic_point()878o = self.codomain().ambient_space()._repr_generic_point(self.defining_polynomials())879return "Defined on coordinates by sending %s to\n%s"%(i,o)880881def __getitem__(self,i):882"""883returns the ith poly with self[i]884885INPUT::886887- ``i``- integer888889OTUPUT::890891- element of the coordinate ring of the domain892893Examples::894895sage: P.<x,y>=ProjectiveSpace(QQ,1)896sage: H=Hom(P,P)897sage: f=H([3/5*x^2,6*y^2])898sage: f[1]8996*y^2900"""901return(self._polys[i])902903def __copy__(self):904r"""905Returns a copy of ``self``.906907OUTPUT:908909- :class:`SchemeMorphism_polynomial`910911EXAMPLES::912913sage: P.<x,y>=ProjectiveSpace(QQ,1)914sage: H=Hom(P,P)915sage: f=H([3/5*x^2,6*y^2])916sage: g =copy(f)917sage: f==g918True919sage: f is g920False921922::923924sage: P.<x,y,z>=ProjectiveSpace(QQ,2)925sage: X=P.subscheme(x^2-y^2);926sage: Q=X(23,23,46)927sage: P=X(1,1,1)928sage: P!=Q929True930"""931H=Hom(self.domain(),self.codomain())932return(H(self._polys))933934def base_ring(self):935r"""936Return the base ring of ``self``, that is, the ring over which the coefficients937of ``self`` is given as polynomials.938939OUTPUT:940941- ring942943EXAMPLES::944945sage: P.<x,y>=ProjectiveSpace(QQ,1)946sage: H=Hom(P,P)947sage: f=H([3/5*x^2,6*y^2])948sage: f.base_ring()949Rational Field950951::952953sage: R.<t>=PolynomialRing(ZZ,1)954sage: P.<x,y>=ProjectiveSpace(R,1)955sage: H=Hom(P,P)956sage: f=H([3*x^2,y^2])957sage: f.base_ring()958Multivariate Polynomial Ring in t over Integer Ring959"""960return(self.domain().base_ring())961962def coordinate_ring(self):963r"""964Returns the coordinate ring of the ambient projective space965the multivariable polynomial ring over the base ring966967OUTPUT:968969- ring970971EXAMPLES::972973sage: P.<x,y>=ProjectiveSpace(QQ,1)974sage: H=Hom(P,P)975sage: f=H([3/5*x^2,6*y^2])976sage: f.coordinate_ring()977Multivariate Polynomial Ring in x, y over Rational Field978979::980981sage: R.<t>=PolynomialRing(ZZ,1)982sage: P.<x,y>=ProjectiveSpace(R,1)983sage: H=Hom(P,P)984sage: f=H([3*x^2,y^2])985sage: f.coordinate_ring()986Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring987in t over Integer Ring988"""989return(self._polys[0].parent())990991def change_ring(self,R, check=True):992r"""993Returns a new :class:`SchemeMorphism_polynomial` which is ``self`` coerced to `R`. If ``check``994is ``True``, then the initialization checks are performed.995996INPUT:997998- ``R`` -- ring9991000- ``check`` -- Boolean10011002OUTPUT:10031004- element of the coordinate ring of the domain10051006EXAMPLES::10071008sage: P.<x,y>=ProjectiveSpace(ZZ,1)1009sage: H=Hom(P,P)1010sage: f=H([3*x^2,y^2])1011sage: f.change_ring(GF(3))1012Traceback (most recent call last):1013...1014ValueError: polys (=[0, y^2]) must be of the same degree10151016::10171018sage: P.<x,y,z>=ProjectiveSpace(QQ,2)1019sage: H=Hom(P,P)1020sage: f=H([5/2*x^3 + 3*x*y^2-y^3,3*z^3 + y*x^2, x^3-z^3])1021sage: f.change_ring(GF(3))1022Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 31023Defn: Defined on coordinates by sending (x : y : z) to1024(x^3 - y^3 : x^2*y : x^3 - z^3)10251026::10271028sage: P.<x,y>=ProjectiveSpace(QQ,1)1029sage: X=P.subscheme([5*x^2-y^2])1030sage: H=Hom(X,X)1031sage: f=H([x,y])1032sage: f.change_ring(GF(3))1033Scheme endomorphism of Closed subscheme of Projective Space of dimension10341 over Finite Field of size 3 defined by:1035-x^2 - y^21036Defn: Defined on coordinates by sending (x : y) to1037(x : y)1038"""1039F=self._polys1040S=self.codomain().change_ring(R)1041H=Hom(S,S)1042G=[]1043for i in range(self.codomain().ambient_space().dimension_relative()+1):1044G.append(F[i].change_ring(R))1045return(H(G,check))104610471048############################################################################1049# Rational points on schemes, which we view as morphisms determined1050# by coordinates.1051############################################################################10521053class SchemeMorphism_point(SchemeMorphism):1054"""1055Base class for rational points on schemes.10561057Recall that the `K`-rational points of a scheme `X` over `k` can1058be identified with the set of morphisms `Spec(K) \to X`. In Sage,1059the rational points are implemented by such scheme morphisms.10601061EXAMPLES::10621063sage: from sage.schemes.generic.morphism import SchemeMorphism1064sage: f = SchemeMorphism(Spec(ZZ).Hom(Spec(ZZ)))1065sage: type(f)1066<class 'sage.schemes.generic.morphism.SchemeMorphism'>1067"""1068def _repr_(self):1069r"""1070Return a string representation of ``self``.10711072OUTPUT:10731074String.10751076EXAMPLES::10771078sage: A = AffineSpace(2, QQ)1079sage: a = A(1,2)1080sage: a._repr_()1081'(1, 2)'1082"""1083return self.codomain().ambient_space()._repr_generic_point(self._coords)10841085def _latex_(self):1086r"""1087Return a latex representation of ``self``.10881089OUTPUT:10901091String.10921093EXAMPLES::10941095sage: A = AffineSpace(2, QQ)1096sage: a = A(1,2)1097sage: latex(a) == a._latex_()1098True1099sage: a._latex_()1100'\\left(1, 2\\right)'1101"""1102return self.codomain().ambient_space()._latex_generic_point(self._coords)11031104def __getitem__(self, n):1105"""1106Return the ``n``-th coordinate.11071108OUTPUT:11091110The coordinate values as an element of the base ring.11111112EXAMPLES::11131114sage: A = AffineSpace(2, QQ)1115sage: a = A(1,2)1116sage: a[0]111711118sage: a[1]111921120"""1121return self._coords[n]11221123def __iter__(self):1124"""1125Iterate over the coordinates of the point.11261127OUTPUT:11281129An iterator.11301131EXAMPLES::11321133sage: A = AffineSpace(2, QQ)1134sage: a = A(1,2)1135sage: iter = a.__iter__()1136sage: iter.next()113711138sage: iter.next()113921140sage: list(a)1141[1, 2]1142"""1143return iter(self._coords)11441145def __tuple__(self):1146"""1147Return the coordinates as a tuple.11481149OUTPUT:11501151A tuple.11521153EXAMPLES::11541155sage: A = AffineSpace(2, QQ)1156sage: a = A(1,2)1157sage: tuple(a)1158(1, 2)1159"""1160return self._coords11611162def __len__(self):1163"""1164Return the number of coordinates.11651166OUTPUT:11671168Integer. The number of coordinates used to describe the point.11691170EXAMPLES::11711172sage: A = AffineSpace(2, QQ)1173sage: a = A(1,2)1174sage: len(a)117521176"""1177return len(self._coords)11781179def __cmp__(self, other):1180"""1181Compare two scheme morphisms.11821183INPUT:11841185- ``other`` -- anything. To compare against the scheme1186morphism ``self``.11871188OUTPUT:11891190``+1``, ``0``, or ``-1``.11911192EXAMPLES::11931194sage: A = AffineSpace(2, QQ)1195sage: a = A(1,2)1196sage: b = A(3,4)1197sage: a.__cmp__(b)1198-11199sage: a != b1200True1201"""1202if not isinstance(other, SchemeMorphism_point):1203try:1204other = self.codomain().ambient_space()(other)1205except TypeError:1206return -11207return cmp(self._coords, other._coords)12081209def scheme(self):1210"""1211Return the scheme whose point is represented.12121213OUTPUT:12141215A scheme.12161217EXAMPLES::12181219sage: A = AffineSpace(2, QQ)1220sage: a = A(1,2)1221sage: a.scheme()1222Affine Space of dimension 2 over Rational Field1223"""1224return self.codomain()12251226def change_ring(self,R, check=True):1227r"""1228Returns a new :class:`SchemeMorphism_point` which is self coerced to R. If `check`1229is true, then the initialization checks are performed.12301231INPUT:12321233- ``R`` -- a ring12341235- ``check`` -- Boolean (optional)12361237OUTPUT:12381239- :class:`SchemeMorphism_point`12401241EXAMPLES::12421243sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)1244sage: X=P.subscheme(x^2-y^2)1245sage: X(23,23,1).change_ring(GF(13))1246(10 : 10 : 1)12471248::12491250sage: P.<x,y>=ProjectiveSpace(QQ,1)1251sage: P(-2/3,1).change_ring(CC)1252(-0.666666666666667 : 1.00000000000000)12531254::12551256sage: P.<x,y>=ProjectiveSpace(ZZ,1)1257sage: P(152,113).change_ring(Zp(5))1258(2 + 5^2 + 5^3 + O(5^20) : 3 + 2*5 + 4*5^2 + O(5^20))1259"""1260S=self.codomain().change_ring(R)1261Q=[]1262for i in range(len(self._coords)):1263Q.append(R(self._coords[i]))1264return(S.point(Q,check))12651266def __copy__(self):1267r"""1268Returns a copy of the :class:`SchemeMorphism_point` self coerced to `R`.12691270OUTPUT:12711272- :class:`SchemeMorphism_point`12731274EXAMPLES::12751276sage: P.<x,y>=ProjectiveSpace(ZZ,1)1277sage: Q=P(152,113)1278sage: copy(Q) is Q1279False1280sage: copy(Q) == Q1281True1282"""1283return(self.codomain().point(self._coords,False))128412851286