Ticket #13130: trac_13130_rings_for_projective_space.patch

File trac_13130_rings_for_projective_space.patch, 41.8 KB (added by bhutz, 10 years ago)

minor changes from review

  • sage/schemes/elliptic_curves/ell_point.py

    # HG changeset patch
    # User Ben Hutz
    # Date 1342523999 14400
    # Node ID c7b78ae0010ff10e7a4529b1576c01e722df6102
    # Parent  5714ed3eab6a53acc9102d19ffadb4e970c9c331
    Trac 13130: Ring support for projective space points and morphisms
    
    diff --git a/sage/schemes/elliptic_curves/ell_point.py b/sage/schemes/elliptic_curves/ell_point.py
    a b  
    153153        Standard comparison function for points on elliptic curves, to
    154154        allow sorting and equality testing.
    155155
     156        .. NOTE::
     157       
     158            ``__eq__`` and ``__ne__`` are implemented in SchemeMorphism_point_projective_ring
     159
    156160        EXAMPLES:
    157161            sage: E=EllipticCurve(QQ,[1,1])
    158162            sage: P=E(0,1)
     
    374378        """
    375379        Comparison function for points to allow sorting and equality testing.
    376380
     381        .. NOTE::
     382       
     383            ``__eq__`` and ``__ne__`` are implemented in SchemeMorphism_point_projective_field
     384
    377385        EXAMPLES::
    378386
    379387            sage: E = EllipticCurve('45a')
  • sage/schemes/generic/homset.py

    diff --git a/sage/schemes/generic/homset.py b/sage/schemes/generic/homset.py
    a b  
    2121- William Stein (2006): initial version.
    2222
    2323- Volker Braun (2011-08-11): significant improvement and refactoring.
     24
     25- Ben Hutz (June 2012): added support for projective ring
    2426"""
    2527
    2628
     
    4547from sage.schemes.generic.spec import Spec, is_Spec
    4648from sage.schemes.generic.morphism import (
    4749    SchemeMorphism,
    48     SchemeMorphism_structure_map, SchemeMorphism_spec,
    49     SchemeMorphism_point_affine,
    50     SchemeMorphism_point_projective_ring,
    51     SchemeMorphism_point_projective_field )
     50    SchemeMorphism_structure_map,
     51    SchemeMorphism_spec )
    5252
    5353
    5454def is_SchemeHomset(H):
     
    716716        sage: SchemeHomset_points_projective_ring(Spec(ZZ), ProjectiveSpace(ZZ,2))
    717717        Set of rational points of Projective Space of dimension 2 over Integer Ring
    718718    """
    719     def _element_constructor_(self, *v, **kwds):
    720         r"""
    721         The element constructor.
    722        
    723         This is currently not implemented.
    724 
    725         EXAMPLES::
    726 
    727             sage: from sage.schemes.generic.homset import SchemeHomset_points_projective_ring
    728             sage: Hom = SchemeHomset_points_projective_ring(Spec(ZZ), ProjectiveSpace(ZZ,2))
    729             sage: Hom(1,2,3)
    730             Traceback (most recent call last):
    731             ...
    732             NotImplementedError
    733 
    734         TESTS::
    735 
    736             sage: Hom._element_constructor_(1,2,3)
    737             Traceback (most recent call last):
    738             ...
    739             NotImplementedError
    740         """
    741         check = kwds.get('check', True)
    742         raise NotImplementedError
    743719
    744720    def points(self, B=0):
    745721        """
     
    750726        - `B` -- integer (optional, default=0). The bound for the
    751727          coordinates.
    752728
    753         OUTPUT:
    754 
    755         This is currently not implemented and will raise ``NotImplementedError``.
    756 
    757729        EXAMPLES::
    758730
    759731            sage: from sage.schemes.generic.homset import SchemeHomset_points_projective_ring
    760             sage: Hom = SchemeHomset_points_projective_ring(Spec(ZZ), ProjectiveSpace(ZZ,2))
    761             sage: Hom.points(5)
    762             Traceback (most recent call last):
    763             ...
    764             NotImplementedError
     732            sage: H = SchemeHomset_points_projective_ring(Spec(ZZ), ProjectiveSpace(ZZ,2))
     733            sage: H.points(3)
     734            [(0 : 0 : 1), (0 : 1 : -3), (0 : 1 : -2), (0 : 1 : -1), (0 : 1 : 0), (0
     735            : 1 : 1), (0 : 1 : 2), (0 : 1 : 3), (0 : 2 : -3), (0 : 2 : -1), (0 : 2 :
     736            1), (0 : 2 : 3), (0 : 3 : -2), (0 : 3 : -1), (0 : 3 : 1), (0 : 3 : 2),
     737            (1 : -3 : -3), (1 : -3 : -2), (1 : -3 : -1), (1 : -3 : 0), (1 : -3 : 1),
     738            (1 : -3 : 2), (1 : -3 : 3), (1 : -2 : -3), (1 : -2 : -2), (1 : -2 : -1),
     739            (1 : -2 : 0), (1 : -2 : 1), (1 : -2 : 2), (1 : -2 : 3), (1 : -1 : -3),
     740            (1 : -1 : -2), (1 : -1 : -1), (1 : -1 : 0), (1 : -1 : 1), (1 : -1 : 2),
     741            (1 : -1 : 3), (1 : 0 : -3), (1 : 0 : -2), (1 : 0 : -1), (1 : 0 : 0), (1
     742            : 0 : 1), (1 : 0 : 2), (1 : 0 : 3), (1 : 1 : -3), (1 : 1 : -2), (1 : 1 :
     743            -1), (1 : 1 : 0), (1 : 1 : 1), (1 : 1 : 2), (1 : 1 : 3), (1 : 2 : -3),
     744            (1 : 2 : -2), (1 : 2 : -1), (1 : 2 : 0), (1 : 2 : 1), (1 : 2 : 2), (1 :
     745            2 : 3), (1 : 3 : -3), (1 : 3 : -2), (1 : 3 : -1), (1 : 3 : 0), (1 : 3 :
     746            1), (1 : 3 : 2), (1 : 3 : 3), (2 : -3 : -3), (2 : -3 : -2), (2 : -3 :
     747            -1), (2 : -3 : 0), (2 : -3 : 1), (2 : -3 : 2), (2 : -3 : 3), (2 : -2 :
     748            -3), (2 : -2 : -1), (2 : -2 : 1), (2 : -2 : 3), (2 : -1 : -3), (2 : -1 :
     749            -2), (2 : -1 : -1), (2 : -1 : 0), (2 : -1 : 1), (2 : -1 : 2), (2 : -1 :
     750            3), (2 : 0 : -3), (2 : 0 : -1), (2 : 0 : 1), (2 : 0 : 3), (2 : 1 : -3),
     751            (2 : 1 : -2), (2 : 1 : -1), (2 : 1 : 0), (2 : 1 : 1), (2 : 1 : 2), (2 :
     752            1 : 3), (2 : 2 : -3), (2 : 2 : -1), (2 : 2 : 1), (2 : 2 : 3), (2 : 3 :
     753            -3), (2 : 3 : -2), (2 : 3 : -1), (2 : 3 : 0), (2 : 3 : 1), (2 : 3 : 2),
     754            (2 : 3 : 3), (3 : -3 : -2), (3 : -3 : -1), (3 : -3 : 1), (3 : -3 : 2),
     755            (3 : -2 : -3), (3 : -2 : -2), (3 : -2 : -1), (3 : -2 : 0), (3 : -2 : 1),
     756            (3 : -2 : 2), (3 : -2 : 3), (3 : -1 : -3), (3 : -1 : -2), (3 : -1 : -1),
     757            (3 : -1 : 0), (3 : -1 : 1), (3 : -1 : 2), (3 : -1 : 3), (3 : 0 : -2), (3
     758            : 0 : -1), (3 : 0 : 1), (3 : 0 : 2), (3 : 1 : -3), (3 : 1 : -2), (3 : 1
     759            : -1), (3 : 1 : 0), (3 : 1 : 1), (3 : 1 : 2), (3 : 1 : 3), (3 : 2 : -3),
     760            (3 : 2 : -2), (3 : 2 : -1), (3 : 2 : 0), (3 : 2 : 1), (3 : 2 : 2), (3 :
     761            2 : 3), (3 : 3 : -2), (3 : 3 : -1), (3 : 3 : 1), (3 : 3 : 2)]
    765762        """
    766         raise NotImplementedError # fixed when _element_constructor_ is defined.
    767763        R = self.value_ring()
    768764        if R == ZZ:
    769765            if not B > 0:
    770766                raise TypeError, "A positive bound B (= %s) must be specified."%B
    771             from sage.schemes.generic.rational_points import enum_projective_rational_field
     767            from sage.schemes.generic.rational_point import enum_projective_rational_field
    772768            return enum_projective_rational_field(self,B)
    773769        else:
    774770            raise TypeError, "Unable to enumerate points over %s."%R
  • sage/schemes/generic/morphism.py

    diff --git a/sage/schemes/generic/morphism.py b/sage/schemes/generic/morphism.py
    a b  
    5555
    5656- Volker Braun (2011-08-08): Renamed classes, more documentation, misc
    5757  cleanups.
     58 
     59- Ben Hutz (June 2012): added support for projective ring
    5860"""
    5961
    6062# Historical note: in trac #11599, V.B. renamed
     
    7375#*****************************************************************************
    7476
    7577
    76 from sage.rings.infinity import infinity
    7778from sage.structure.element   import AdditiveGroupElement, RingElement, Element, generic_power
    7879from sage.structure.sequence  import Sequence
    7980from sage.categories.homset   import Homset
    8081from sage.rings.all           import is_RingHomomorphism, is_CommutativeRing, Integer
    8182from point                    import is_SchemeTopologicalPoint
    82 import scheme                 
     83from sage.rings.infinity      import infinity
     84import scheme
     85
     86from sage.rings.arith            import gcd, lcm
     87from sage.categories.gcd_domains import GcdDomains
     88from sage.rings.quotient_ring    import QuotientRing_generic
     89
    8390
    8491
    8592def is_SchemeMorphism(f):
     
    705712    Some checks are performed to make sure the given polynomials
    706713    define a morphism::
    707714   
    708         sage: R.<x,y> = QQ[]
    709         sage: P1 = ProjectiveSpace(R)
    710         sage: H = P1.Hom(P1)
    711         sage: f = H([x^2, x*y])
    712         Traceback (most recent call last):
    713         ...
    714         ValueError: polys (=[x^2, x*y]) must not have common factors
    715 
    716715        sage: f = H([exp(x),exp(y)])
    717716        Traceback (most recent call last):
    718717        ...
     
    745744                polys = [source_ring(poly) for poly in polys]
    746745            except TypeError:
    747746                raise TypeError, "polys (=%s) must be elements of %s"%(polys,source_ring)
    748             from sage.rings.quotient_ring import QuotientRing_generic
    749747            if isinstance(source_ring, QuotientRing_generic):
    750748                lift_polys = [f.lift() for f in polys]
    751749            else:
    752750                lift_polys = polys
    753             from sage.schemes.generic.projective_space import is_ProjectiveSpace
    754             if is_ProjectiveSpace(target):
    755                 # if the codomain is a subscheme of projective space,
    756                 # then we need to make sure that polys have no common
    757                 # zeros
    758                 if isinstance(source_ring, QuotientRing_generic):
    759                     # if the coordinate ring of the domain is a
    760                     # quotient by an ideal, we need to check that the
    761                     # gcd of polys and the generators of the ideal is 1
    762                     gcd_polys = lift_polys + list(source_ring.defining_ideal().gens())
    763                 else:
    764                     # if the domain is affine space, we just need to
    765                     # check the gcd of polys
    766                     gcd_polys = polys
    767                 from sage.rings.arith import gcd
    768                 if gcd(gcd_polys) != 1:
    769                     raise ValueError, "polys (=%s) must not have common factors"%polys
    770751            polys = Sequence(lift_polys)
    771             polys.set_immutable()
    772752            # Todo: check that map is well defined (how?)
    773         self.__polys = polys
    774         SchemeMorphism.__init__(self, parent)
     753        self._polys = polys
     754        SchemeMorphism.__init__(self, parent) 
    775755       
    776756    def defining_polynomials(self):
    777757        """
     
    790770            sage: H([x^3+y, 1-x-y]).defining_polynomials()
    791771            [x^3 + y, -x - y + 1]
    792772        """
    793         return self.__polys
     773        return self._polys
    794774
    795     def __call__(self, x):
     775    def __call__(self, x,check=True):
    796776        """
    797777        Apply this morphism to a point in the domain.
    798778
    799779        INPUT:
    800780
    801         - ``x`` -- anything that defines a point in the domain.
     781        - ``x`` -- a point in the domain or a list or tuple that defines a point in the domain.
    802782
    803783        OUTPUT:
    804784
     
    837817            Traceback (most recent call last):
    838818            ...
    839819            TypeError: Argument v (=(0,)) must have 2 coordinates.
     820           
     821        ::
     822       
     823        It is possible to avoid the checks on the resulting point which can be useful for indeterminacies,
     824        but be careful!!
     825       
     826            sage: PS.<x,y>=ProjectiveSpace(QQ,1)
     827            sage: H=Hom(PS,PS)
     828            sage: f=H([x^3,x*y^2])
     829            sage: P=PS(0,1)
     830            sage: f(P,check=False)
     831            (0 : 0)
     832           
     833        ::
     834       
     835            sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)
     836            sage: X=P.subscheme(x^2-y^2);
     837            sage: H=Hom(X,X)
     838            sage: f=H([x^2,y^2,z^2]);
     839            sage: f([4,4,1])
     840            (16 : 16 : 1)
     841       
     842        ::
     843       
     844            sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)
     845            sage: X=P.subscheme(x^2-y^2);
     846            sage: H=Hom(X,X)
     847            sage: f=H([x^2,y^2,z^2]);
     848            sage: f(P([4,4,1]))
     849            Traceback (most recent call last):
     850            ...
     851            TypeError: Point must be in the domain of the function
     852
    840853        """
    841         dom = self.domain()
    842         x = dom(x)
     854        if check:
     855            if not isinstance(x,SchemeMorphism_point):
     856                x = self.domain()(x)
     857            elif x.codomain()!=self.domain():
     858                raise TypeError, "Point must be in the domain of the function"
    843859        P = [f(x._coords) for f in self.defining_polynomials()]
    844         return self.codomain()(P)
     860        return self.codomain().point(P,check)
    845861
    846862
    847863    def _repr_defn(self):
     
    866882        o = self.codomain().ambient_space()._repr_generic_point(self.defining_polynomials())
    867883        return "Defined on coordinates by sending %s to\n%s"%(i,o)
    868884
     885    def __getitem__(self,i):
     886        """
     887        returns the ith poly with self[i]
     888       
     889        INPUT::
     890       
     891        - ``i``- integer
     892       
     893        OTUPUT::
     894       
     895        - element of the coordinate ring of the domain
     896       
     897        Examples::
     898       
     899            sage: P.<x,y>=ProjectiveSpace(QQ,1)
     900            sage: H=Hom(P,P)
     901            sage: f=H([3/5*x^2,6*y^2])
     902            sage: f[1]
     903            6*y^2
     904        """
     905        return(self._polys[i])
     906
     907
    869908
    870909class SchemeMorphism_polynomial_affine_space(SchemeMorphism_polynomial):
    871910    """
     
    893932    """
    894933    A morphism of schemes determined by rational functions that define
    895934    what the morphism does on points in the ambient projective space.
    896 
     935   
    897936    EXAMPLES::
    898 
     937   
    899938        sage: R.<x,y> = QQ[]
    900939        sage: P1 = ProjectiveSpace(R)
    901940        sage: H = P1.Hom(P1)
     
    903942        Scheme endomorphism of Projective Space of dimension 1 over Rational Field
    904943          Defn: Defined on coordinates by sending (x : y) to
    905944                (y : 2*x)
    906 
     945   
    907946    An example of a morphism between projective plane curves (see #10297)::   
    908 
     947   
    909948        sage: P2.<x,y,z> = ProjectiveSpace(QQ,2)
    910949        sage: f = x^3+y^3+60*z^3
    911950        sage: g = y^2*z-( x^3 - 6400*z^3/3)
     
    919958          To:   Projective Curve over Rational Field defined by -x^3 + y^2*z + 6400/3*z^3
    920959          Defn: Defined on coordinates by sending (x : y : z) to
    921960                (z : x - y : -1/80*x - 1/80*y)
    922 
     961   
    923962    A more complicated example::
    924 
     963   
    925964        sage: P2.<x,y,z> = ProjectiveSpace(2,QQ)
    926965        sage: P1 = P2.subscheme(x-y)
    927966        sage: H12 = P1.Hom(P2)
    928967        sage: H12([x^2,x*z, z^2])
    929968        Scheme morphism:
    930         From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
    931         x - y
    932         To:   Projective Space of dimension 2 over Rational Field
    933         Defn: Defined on coordinates by sending (x : y : z) to
     969          From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
     970          x - y
     971          To:   Projective Space of dimension 2 over Rational Field
     972          Defn: Defined on coordinates by sending (x : y : z) to
    934973              (y^2 : y*z : z^2)
    935 
     974   
    936975    We illustrate some error checking::
    937976   
    938977        sage: R.<x,y> = QQ[]
     
    942981        Traceback (most recent call last):
    943982        ...
    944983        ValueError: polys (=[x - y, x*y]) must be of the same degree
    945 
     984   
    946985        sage: H([x-1, x*y+x])
    947986        Traceback (most recent call last):
    948987        ...
    949988        ValueError: polys (=[x - 1, x*y + x]) must be homogeneous
    950 
     989   
    951990        sage: H([exp(x),exp(y)])
    952991        Traceback (most recent call last):
    953992        ...
     
    958997    def __init__(self, parent, polys, check=True):
    959998        """
    960999        The Python constructor.
    961 
     1000       
    9621001        See :class:`SchemeMorphism_polynomial` for details.
    963 
     1002       
    9641003        EXAMPLES::
    965 
     1004       
    9661005            sage: P1.<x,y> = ProjectiveSpace(QQ,1)
    9671006            sage: H = P1.Hom(P1)
    9681007            sage: H([y,2*x])
     
    9741013        if check:
    9751014            # morphisms from projective space are always given by
    9761015            # homogeneous polynomials of the same degree
    977             polys = self.defining_polynomials()
    9781016            try:
    9791017                d = polys[0].degree()
    9801018            except AttributeError:
     
    9841022            degs = [f.degree() for f in polys]
    9851023            if not all([d==degs[0] for d in degs[1:]]):
    9861024                raise ValueError, "polys (=%s) must be of the same degree"%polys
     1025
     1026    def __eq__(self,right):
     1027        """
     1028        Tests the equality of two projective spaces.
     1029
     1030        INPUT::
    9871031       
     1032        - ``right`` - a map on projective space
     1033       
     1034        OUTPUT::
     1035       
     1036        - Boolean - True if ``self`` and ``right`` define the same projective map. False otherwise.
     1037       
     1038        Examples::
     1039
     1040            sage: P1.<x,y> = ProjectiveSpace(RR,1)
     1041            sage: P2.<x,y> = ProjectiveSpace(QQ,1)
     1042            sage: P1==P2
     1043            False
     1044
     1045            ::
     1046
     1047            sage: R.<x,y>=QQ[]
     1048            sage: P1=ProjectiveSpace(R)
     1049            sage: P2.<x,y>=ProjectiveSpace(QQ,1)
     1050            sage: P1==P2
     1051            True
     1052        """
     1053        if not isinstance(right, SchemeMorphism_polynomial):
     1054            return False
     1055        else:
     1056            n=len(self._polys)
     1057            for i in range(0,n):
     1058                for j in range(i+1,n):
     1059                    if self._polys[i]*right._polys[j] != self._polys[j]*right._polys[i]:
     1060                        return False
     1061        return True
     1062
     1063    def __ne__(self,right):
     1064        """
     1065        Tests the inequality of two projective spaces.
     1066
     1067        INPUT::
     1068       
     1069        - ``right`` - a map on projective space
     1070       
     1071        OUTPUT::
     1072       
     1073        - Boolean - True if ``self`` and ``right`` define different projective maps. False otherwise.
     1074       
     1075        Examples::
     1076
     1077            sage: P1.<x,y> = ProjectiveSpace(RR,1)
     1078            sage: P2.<x,y> = ProjectiveSpace(QQ,1)
     1079            sage: P1!=P2
     1080            True
     1081
     1082            ::
     1083
     1084            sage: R.<x,y>=QQ[]
     1085            sage: P1=ProjectiveSpace(R)
     1086            sage: P2.<x,y>=ProjectiveSpace(QQ,1)
     1087            sage: P1!=P2
     1088            False
     1089        """
     1090        if not isinstance(right, SchemeMorphism_polynomial):
     1091            return True
     1092        else:
     1093            n=len(self._polys)
     1094            for i in range(0,n):
     1095                for j in range(i+1,n):
     1096                    if self._polys[i]*right._polys[j] != self._polys[j]*right._polys[i]:
     1097                        return True
     1098        return False
     1099
     1100    def scale_by(self,t):
     1101        """
     1102        Scales each coordiantes by a factor of t. A TypeError occurs if the point is not in the coordinate_ring of the parent after scaling.
     1103       
     1104        INPUT::
     1105       
     1106        - ``t`` - a ring element
     1107       
     1108        OUTPUT::
     1109       
     1110        - None.
     1111       
     1112        Examples::
     1113
     1114            sage: R.<t>=PolynomialRing(QQ)
     1115            sage: P.<x,y>=ProjectiveSpace(R,1)
     1116            sage: H=Hom(P,P)
     1117            sage: f=H([3/5*x^2,6*y^2])
     1118            sage: f.scale_by(5/3*t); f
     1119            Scheme endomorphism of Projective Space of dimension 1 over Univariate
     1120            Polynomial Ring in t over Rational Field
     1121              Defn: Defined on coordinates by sending (x : y) to
     1122                    (t*x^2 : 10*t*y^2)
     1123        """
     1124        if t==0:
     1125            raise ValueError, "Cannot scale by 0"
     1126        R=self.domain().coordinate_ring()
     1127        for i in range(self.codomain().dimension_relative()+1):
     1128            self._polys[i]=R(self._polys[i]*t)
     1129
     1130    def normalize_coordinates(self):
     1131        """
     1132        Scales by 1/gcd of the coordinate functions. Also, scales to clear any denominators from the coefficients.
     1133        This is done in place.
     1134       
     1135        INPUT::
     1136       
     1137        - None.
     1138       
     1139        OUTPUT::
     1140       
     1141        - None.
     1142       
     1143        Examples::
     1144       
     1145            sage: P.<x,y>=ProjectiveSpace(QQ,1)
     1146            sage: H=Hom(P,P)
     1147            sage: f=H([5/4*x^3,5*x*y^2])
     1148            sage: f.normalize_coordinates(); f
     1149            Scheme endomorphism of Projective Space of dimension 1 over Rational
     1150            Field
     1151              Defn: Defined on coordinates by sending (x : y) to
     1152                    (x^2 : 4*y^2)
     1153
     1154        .. NOTE::
     1155       
     1156            -gcd raises an attribute error if the base_ring does not support gcds.
     1157        """
     1158        #computes the gcd of the coordinates as elements of the coordinate_ring and checks if the leading coefficients are all negative
     1159        GCD = gcd(self[0],self[1])
     1160        index=2
     1161        if self[0].lc()>0 or self[1].lc() >0:
     1162            neg=0
     1163        else:
     1164            neg=1
     1165        while GCD!=1 and index < self.codomain().dimension_relative()+1:
     1166            if self[index].lc()>0:
     1167                neg=0
     1168            GCD=gcd(GCD,self[index])
     1169            index+=+1
     1170
     1171        if GCD != 1:
     1172            R=self.domain().base_ring()
     1173            if neg==1:
     1174                self.scale_by(R(-1)/GCD)
     1175            else:
     1176                self.scale_by(R(1)/GCD)
     1177        else:
     1178            if neg==1:
     1179                self.scale_by(-1)
     1180       
     1181        #clears any denominators from the coefficients
     1182        LCM = lcm([self[i].denominator() for i in range(self.codomain().dimension_relative()+1)])
     1183        self.scale_by(LCM)
     1184       
     1185        #scales by 1/gcd of the coefficients.
     1186        GCD = gcd([self[i].content() for i in range(self.codomain().dimension_relative()+1)])
     1187        if GCD!=1:
     1188            self.scale_by(1/GCD)
    9881189
    9891190############################################################################
    9901191# Rational points on schemes, which we view as morphisms determined
     
    12181419            X.extended_codomain()._check_satisfies_equations(v)
    12191420        self._coords = tuple(v)
    12201421
    1221    
     1422
    12221423#*******************************************************************
    12231424# Projective varieties
    12241425#*******************************************************************
    12251426class SchemeMorphism_point_projective_ring(SchemeMorphism_point):
    12261427    """
    1227     A rational point of projective space over a ring (how?).
    1228 
    1229     Currently this is not implemented.
    1230 
    1231     EXAMPLES:
    1232 
    1233         sage: from sage.schemes.generic.morphism import SchemeMorphism_point_projective_ring
    1234         sage: SchemeMorphism_point_projective_ring(None, None)
    1235         Traceback (most recent call last):
    1236         ...
    1237         NotImplementedError
    1238        
    1239     """
    1240     def __init__(self, X, v, check=True):
    1241         """
    1242         The Python constructor
    1243        
    1244         EXAMPLES:
    1245 
    1246             sage: from sage.schemes.generic.morphism import SchemeMorphism_point_projective_ring
    1247             sage: SchemeMorphism_point_projective_ring(None, None)
    1248             Traceback (most recent call last):
    1249             ...
    1250             NotImplementedError
    1251         """
    1252         raise NotImplementedError
    1253 
    1254 
    1255 class SchemeMorphism_point_projective_field(SchemeMorphism_point_projective_ring):
    1256     """
    1257     A rational point of projective space over a field.
     1428    A rational point of projective space over a ring.
     1429               
     1430    INPUT::
    12581431   
    1259     INPUT:
    1260    
    1261     -  ``X`` -- a subscheme of an ambient projective space
    1262        over a field `K`
     1432    -  ``X`` -- a homset of a subscheme of an ambient projective space over a field `K`
    12631433   
    12641434    - ``v`` -- a list or tuple of coordinates in `K`
    12651435   
    1266     - ``check`` -- boolean (optional, default:``True``). Whether to
    1267       check the input for consistency.
    1268    
     1436    - ``check`` -- boolean (optional, default:``True``). Whether to check the input for consistency. 
     1437       
    12691438    EXAMPLES::
    12701439   
    1271         sage: P = ProjectiveSpace(3, RR)
    1272         sage: P(2,3,4,5)
    1273         (0.400000000000000 : 0.600000000000000 : 0.800000000000000 : 1.00000000000000)
    1274 
    1275     Not all homogeneous coordinates are allowed to vanish simultaneously::
    1276    
    1277         sage: P = ProjectiveSpace(3, QQ)
    1278         sage: P(0,0,0,0)
    1279         Traceback (most recent call last):
    1280         ...
    1281         ValueError: [0, 0, 0, 0] does not define a valid point since all entries are 0
     1440        sage: P = ProjectiveSpace(2, ZZ)
     1441        sage: P(2,3,4)
     1442        (2 : 3 : 4)
     1443       
    12821444    """
     1445 
    12831446    def __init__(self, X, v, check=True):
    12841447        """
    12851448        The Python constructor.
    12861449
    1287         See :class:`SchemeMorphism_point_projective_field` for details.
     1450        EXAMPLES::
    12881451       
    1289         EXAMPLES::
    1290 
    1291         sage: P = ProjectiveSpace(2, CDF)
    1292         sage: P(2+I, 3-I, 4+5*I)
    1293         (0.317073170732 - 0.146341463415*I : 0.170731707317 - 0.463414634146*I : 1.0)
     1452            sage: P = ProjectiveSpace(2, QQ)
     1453            sage: P(2, 3/5, 4)
     1454            (1/2 : 3/20 : 1)
     1455       
     1456        ::
     1457       
     1458            sage: P = ProjectiveSpace(1, ZZ)
     1459            sage: P([0, 1])
     1460            (0 : 1)
     1461       
     1462        ::
     1463       
     1464            sage: P = ProjectiveSpace(1, ZZ)
     1465            sage: P([0, 0, 1])
     1466            Traceback (most recent call last):
     1467            ...
     1468            TypeError: v (=[0, 0, 1]) must have 2 components
     1469       
     1470        ::
     1471       
     1472            sage: P = ProjectiveSpace(3, QQ)
     1473            sage: P(0,0,0,0)
     1474            Traceback (most recent call last):
     1475            ...
     1476            ValueError: [0, 0, 0, 0] does not define a valid point since all entries are 0
     1477           
     1478        ::
     1479       
     1480        It is possible to avoid the possibly time consuming checks, but be careful!!
     1481       
     1482            sage: P = ProjectiveSpace(3, QQ)
     1483            sage: P.point([0,0,0,0],check=False)
     1484            (0 : 0 : 0 : 0)
     1485           
     1486        ::
     1487       
     1488            sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
     1489            sage: X=P.subscheme([x^2-y*z])
     1490            sage: X([2,2,2])
     1491            (2 : 2 : 2)
    12941492        """
    12951493        SchemeMorphism.__init__(self, X)
    12961494        if check:
     
    13061504                      "Argument v (= %s) must be a scheme point, list, or tuple."%str(v)
    13071505            if len(v) != d and len(v) != d-1:
    13081506                raise TypeError, "v (=%s) must have %s components"%(v, d)
    1309             #v = Sequence(v, X.base_ring())
     1507       
     1508            R = X.value_ring()
     1509            v = Sequence(v, R)
     1510            if len(v) == d-1:     # very common special case
     1511                v.append(1)
     1512           
     1513            n = len(v)
     1514            all_zero = True
     1515            for i in range(n):
     1516                last = n-1-i
     1517                if v[last]:
     1518                    all_zero = False
     1519                    break
     1520            if all_zero:
     1521                raise ValueError, "%s does not define a valid point since all entries are 0"%repr(v)
     1522       
     1523            X.extended_codomain()._check_satisfies_equations(v)
     1524
     1525            if isinstance(X.codomain().base_ring(), QuotientRing_generic):
     1526                lift_coords = [P.lift() for P in v]
     1527            else:
     1528                lift_coords = v
     1529            v = Sequence(lift_coords)
     1530           
     1531        self._coords = v
     1532       
     1533    def __eq__(self,right):
     1534        """
     1535        Tests the proejctive equality of two points.
     1536       
     1537        INPUT::
     1538       
     1539        - ``right`` - a point on projective space
     1540       
     1541        OUTPUT::
     1542       
     1543        - Boolean - True if ``self`` and ``right`` define the same point. False otherwise.
     1544       
     1545        Examples::
     1546       
     1547            sage: PS=ProjectiveSpace(ZZ,1,'x')
     1548            sage: P=PS([1,2])
     1549            sage: Q=PS([2,4])
     1550            sage: P==Q
     1551            True
     1552       
     1553        ::
     1554       
     1555            sage: PS=ProjectiveSpace(ZZ,1,'x')
     1556            sage: P=PS([1,2])
     1557            sage: Q=PS([1,0])
     1558            sage: P==Q
     1559            False
     1560       
     1561        ::
     1562       
     1563            sage: PS=ProjectiveSpace(Zp(5),1,'x')
     1564            sage: P=PS([0,1])
     1565            sage: P==0
     1566            True
     1567       
     1568        ::
     1569       
     1570            sage: R.<t>=PolynomialRing(QQ)
     1571            sage: PS=ProjectiveSpace(R,1,'x')
     1572            sage: P=PS([t,1+t^2])
     1573            sage: Q=PS([t^2, t+t^3])
     1574            sage: P==Q
     1575            True
     1576           
     1577        ::
     1578       
     1579            sage: PS=ProjectiveSpace(ZZ,2,'x')
     1580            sage: P=PS([0,1,2])
     1581            sage: P==0
     1582            False
     1583
     1584        ::
     1585       
     1586            sage: PS=ProjectiveSpace(ZZ,1,'x')
     1587            sage: P=PS([2,1])
     1588            sage: PS2=ProjectiveSpace(Zp(7),1,'x')
     1589            sage: Q=PS2([2,1])
     1590            sage: P==Q
     1591            False
     1592       
     1593        ::
     1594       
     1595            sage: PS=ProjectiveSpace(ZZ.quo(6),2,'x')
     1596            sage: P=PS([2,4,1])
     1597            sage: Q=PS([0,1,3])
     1598            sage: P==Q
     1599            False
     1600       
     1601        ::
     1602
     1603            sage: R.<z>=PolynomialRing(QQ)
     1604            sage: K.<t>=NumberField(z^2+5)
     1605            sage: OK=K.ring_of_integers()
     1606            sage: t=OK.gen(1)
     1607            sage: PS.<x,y>=ProjectiveSpace(OK,1)
     1608            sage: P=PS(2,1+t)
     1609            sage: Q=PS(1-t,3)
     1610            sage: P==Q
     1611            True
     1612
     1613        """
     1614        if not isinstance(right, SchemeMorphism_point):
     1615            try:
     1616                right = self.codomain()(right)
     1617            except TypeError:
     1618                return False
     1619        if self.codomain()!=right.codomain():
     1620            return False
     1621        n=len(self._coords)
     1622        for i in range(0,n):
     1623            for j in range(i+1,n):
     1624                if self._coords[i]*right._coords[j] != self._coords[j]*right._coords[i]:
     1625                    return False
     1626        return True
     1627
     1628    def __ne__(self,right):
     1629        """
     1630        Tests the proejctive equality of two points.
     1631       
     1632        INPUT::
     1633       
     1634        - ``right`` - a point on projective space
     1635       
     1636        OUTPUT::
     1637       
     1638        - Boolean - True if ``self`` and ``right`` define different points. False otherwise.
     1639       
     1640        Examples::
     1641       
     1642            sage: PS=ProjectiveSpace(ZZ,1,'x')
     1643            sage: P=PS([1,2])
     1644            sage: Q=PS([2,4])
     1645            sage: P!=Q
     1646            False
     1647       
     1648        ::
     1649       
     1650            sage: PS=ProjectiveSpace(ZZ,1,'x')
     1651            sage: P=PS([1,2])
     1652            sage: Q=PS([1,0])
     1653            sage: P!=Q
     1654            True
     1655       
     1656        ::
     1657       
     1658            sage: PS=ProjectiveSpace(Zp(5),1,'x')
     1659            sage: P=PS([0,1])
     1660            sage: P!=0
     1661            False
     1662       
     1663        ::
     1664       
     1665            sage: R.<t>=PolynomialRing(QQ)
     1666            sage: PS=ProjectiveSpace(R,1,'x')
     1667            sage: P=PS([t,1+t^2])
     1668            sage: Q=PS([t^2, t+t^3])
     1669            sage: P!=Q
     1670            False
     1671           
     1672        ::
     1673       
     1674            sage: PS=ProjectiveSpace(ZZ,2,'x')
     1675            sage: P=PS([0,1,2])
     1676            sage: P!=0
     1677            True
     1678
     1679        ::
     1680       
     1681            sage: PS=ProjectiveSpace(ZZ,1,'x')
     1682            sage: P=PS([2,1])
     1683            sage: PS2=ProjectiveSpace(Zp(7),1,'x')
     1684            sage: Q=PS2([2,1])
     1685            sage: P!=Q
     1686            True
     1687       
     1688        ::
     1689       
     1690            sage: PS=ProjectiveSpace(ZZ.quo(6),2,'x')
     1691            sage: P=PS([2,4,1])
     1692            sage: Q=PS([0,1,3])
     1693            sage: P!=Q
     1694            True
     1695        """
     1696        if not isinstance(right, SchemeMorphism_point):
     1697            try:
     1698                right = self.codomain()(right)
     1699            except TypeError:
     1700                return True
     1701        if self.codomain()!=right.codomain():
     1702            return True
     1703        n=len(self._coords)
     1704        for i in range(0,n):
     1705            for j in range(i+1,n):
     1706                if self._coords[i]*right._coords[j] != self._coords[j]*right._coords[i]:
     1707                    return True
     1708        return False
     1709
     1710    def scale_by(self,t):
     1711        """
     1712        Scale the coordinates of the point by t. A TypeError occurs if the point is not in the base_ring of the codomain after scaling.
     1713       
     1714        INPUT::
     1715       
     1716        - ``t`` - a ring element
     1717       
     1718        OUTPUT::
     1719       
     1720        - None.
     1721       
     1722        Examples::
     1723       
     1724            sage: R.<t>=PolynomialRing(QQ)
     1725            sage: P=ProjectiveSpace(R,2,'x')
     1726            sage: p=P([3/5*t^3,6*t, t])
     1727            sage: p.scale_by(1/t); p
     1728            (3/5*t^2 : 6 : 1)
     1729
     1730        """
     1731        if t==0:
     1732            raise ValueError, "Cannot scale by 0"
     1733        R=self.codomain().base_ring()
     1734        for i in range(len(self._coords)):
     1735            self._coords[i]=R(self._coords[i]*t)
     1736               
     1737    def normalize_coordinates(self):
     1738        """
     1739        Removes common factors from the coordinates of self (including -1).
     1740
     1741        INPUT::
     1742       
     1743        - None.
     1744       
     1745        OUTPUT::
     1746       
     1747        - None.
     1748       
     1749        Examples::
     1750       
     1751            sage: P=ProjectiveSpace(ZZ,2,'x')
     1752            sage: p=P([-5,-15,-20])
     1753            sage: p.normalize_coordinates(); p
     1754            (1 : 3 : 4)
     1755       
     1756        ::
     1757       
     1758            sage: P=ProjectiveSpace(Zp(7),2,'x')
     1759            sage: p=P([-5,-15,-2])
     1760            sage: p.normalize_coordinates(); p
     1761            (5 + O(7^20) : 1 + 2*7 + O(7^20) : 2 + O(7^20))
     1762           
     1763        ::
     1764       
     1765            sage: R.<t>=PolynomialRing(QQ)
     1766            sage: P=ProjectiveSpace(R,2,'x')
     1767            sage: p=P([3/5*t^3,6*t, t])
     1768            sage: p.normalize_coordinates(); p
     1769            (3/5*t^2 : 6 : 1)
     1770        """
     1771        R=self.codomain().base_ring()
     1772        GCD = R(gcd(self[0],self[1]))
     1773        index=2
     1774        if self[0]>0 or self[1] >0:
     1775            neg=0
     1776        else:
     1777            neg=1
     1778        while GCD!=1 and index < len(self._coords):
     1779            if self[index]>0:
     1780                neg=0
     1781            GCD=R(gcd(GCD,self[index]))
     1782            index+=+1
     1783        if GCD != 1:
     1784            if neg==1:
     1785                self.scale_by(R(-1)/GCD)
     1786            else:
     1787                self.scale_by(R(1)/GCD)
     1788        else:
     1789            if neg==1:
     1790                self.scale_by(R(-1))
     1791     
     1792class SchemeMorphism_point_projective_field(SchemeMorphism_point_projective_ring):
     1793    """
     1794    A rational point of projective space over a field.
     1795   
     1796    INPUT:
     1797   
     1798    -  ``X`` -- a homset of a subscheme of an ambient projective space
     1799       over a field `K`
     1800   
     1801    - ``v`` -- a list or tuple of coordinates in `K`
     1802   
     1803    - ``check`` -- boolean (optional, default:``True``). Whether to
     1804      check the input for consistency.
     1805   
     1806    EXAMPLES::
     1807   
     1808        sage: P = ProjectiveSpace(3, RR)
     1809        sage: P(2,3,4,5)
     1810        (0.400000000000000 : 0.600000000000000 : 0.800000000000000 : 1.00000000000000)
     1811    """
     1812   
     1813    def __init__(self, X, v, check=True):
     1814        """
     1815        The Python constructor.
     1816       
     1817        See :class:`SchemeMorphism_point_projective_ring` for details.
     1818       
     1819        This function still normalized points so that the rightmost non-zero coordinate is 1. The is to maintain current functionality with current
     1820        implementations of curves in projectives space (plane, connic, elliptic, etc). The class:`SchemeMorphism_point_projective_ring` is for general use.
     1821       
     1822        EXAMPLES::
     1823       
     1824            sage: P = ProjectiveSpace(2, QQ)
     1825            sage: P(2, 3/5, 4)
     1826            (1/2 : 3/20 : 1)
     1827       
     1828        ::
     1829       
     1830            sage: P = ProjectiveSpace(3, QQ)
     1831            sage: P(0,0,0,0)
     1832            Traceback (most recent call last):
     1833            ...
     1834            ValueError: [0, 0, 0, 0] does not define a valid point since all entries are 0
     1835           
     1836        ::
     1837       
     1838            sage: P.<x, y, z> = ProjectiveSpace(2, QQ)
     1839            sage: X=P.subscheme([x^2-y*z])
     1840            sage: X([2,2,2])
     1841            (1 : 1 : 1)
     1842        """
     1843        SchemeMorphism.__init__(self, X)
     1844        if check:
     1845            from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field
     1846            d = X.codomain().ambient_space().ngens()
     1847            if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field):
     1848                v = list(v)
     1849            elif v is infinity:
     1850                v = [0] * (d)
     1851                v[1] = 1
     1852            if not isinstance(v,(list,tuple)):
     1853                raise TypeError, \
     1854                      "Argument v (= %s) must be a scheme point, list, or tuple."%str(v)
     1855            if len(v) != d and len(v) != d-1:
     1856                raise TypeError, "v (=%s) must have %s components"%(v, d)
     1857       
    13101858            R = X.value_ring()
    13111859            v = Sequence(v, R)
    13121860            if len(v) == d-1:     # very common special case
     
    13271875                    break
    13281876            if all_zero:
    13291877                raise ValueError, "%s does not define a valid point since all entries are 0"%repr(v)
    1330 
     1878       
    13311879            X.extended_codomain()._check_satisfies_equations(v)
    13321880               
    13331881        self._coords = v
    13341882
    13351883
    1336 
    13371884#*******************************************************************
    13381885# Abelian varieties
    13391886#*******************************************************************
     
    13531900    """
    13541901    pass
    13551902
    1356 
    1357 
    1358 
  • sage/schemes/generic/projective_space.py

    diff --git a/sage/schemes/generic/projective_space.py b/sage/schemes/generic/projective_space.py
    a b  
    8080from sage.modules.free_module_element import prepare
    8181
    8282from ambient_space import AmbientSpace
    83 import homset
     83from homset import (SchemeHomset_points_projective_ring, SchemeHomset_points_projective_field)
    8484import morphism
    8585
    8686
     
    145145        sage: P.coordinate_ring() is R
    146146        True
    147147   
     148    ::
     149   
     150        sage: ProjectiveSpace(3, Zp(5), 'y')
     151        Projective Space of dimension 3 over 5-adic Ring with capped relative precision 20
     152   
     153    ::
     154   
     155        sage: ProjectiveSpace(2,QQ,'x,y,z')
     156        Projective Space of dimension 2 over Rational Field
     157
     158    ::
     159   
     160        sage: PS.<x,y>=ProjectiveSpace(1,CC)
     161        sage: PS
     162        Projective Space of dimension 1 over Complex Field with 53 bits of precision
     163   
    148164    Projective spaces are not cached, i.e., there can be several with
    149165    the same base ring and dimension (to facilitate gluing
    150166    constructions).
     
    225241        TypeError otherwise.
    226242
    227243        EXAMPLES::
    228 
     244       
    229245            sage: P = ProjectiveSpace(2, ZZ)
    230246            sage: P._check_satisfies_equations([1, 1, 0])
    231247            True
    232             sage: P._check_satisfies_equations((0, 1, 0))
     248       
     249        ::
     250       
     251            sage: P = ProjectiveSpace(1, QQ)
     252            sage: P._check_satisfies_equations((1/2, 0))
    233253            True
     254           
     255        ::
     256       
     257            sage: P = ProjectiveSpace(2, ZZ)
    234258            sage: P._check_satisfies_equations([0, 0, 0])
    235259            Traceback (most recent call last):
    236260            ...
    237261            TypeError: The zero vector is not a point in projective space
    238             sage: P._check_satisfies_equations([1, 2, 3, 4, 5])
     262
     263        ::
     264       
     265            sage: P = ProjectiveSpace(2, ZZ)
     266            sage: P._check_satisfies_equations((1, 0))
    239267            Traceback (most recent call last):
    240268            ...
    241             TypeError: The list v=[1, 2, 3, 4, 5] must have 3 components
    242             sage: P._check_satisfies_equations([1/2, 1, 1])
     269            TypeError: The list v=(1, 0) must have 3 components
     270       
     271        ::
     272       
     273            sage: P = ProjectiveSpace(2, ZZ)
     274            sage: P._check_satisfies_equations([1/2, 0, 1])
    243275            Traceback (most recent call last):
    244276            ...
    245             TypeError: The components of v=[1/2, 1, 1] must be elements of Integer Ring
    246             sage: P._check_satisfies_equations(5)
    247             Traceback (most recent call last):           
    248             ...
    249             TypeError: The argument v=5 must be a list or tuple
     277            TypeError: The components of v=[1/2, 0, 1] must be elements of Integer Ring
    250278        """
    251279        if not isinstance(v, (list, tuple)):
    252280            raise TypeError, 'The argument v=%s must be a list or tuple'%v
     
    307335        EXAMPLES::
    308336
    309337            sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
    310             sage: P._validate((x*y - z^2, x))
    311             (x*y - z^2, x)
     338            sage: P._validate([x*y - z^2, x])
     339            [x*y - z^2, x]
     340       
     341       ::
     342       
     343            sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
    312344            sage: P._validate((x*y - z, x))
    313345            Traceback (most recent call last):
    314346            ...
    315347            TypeError: x*y - z is not a homogeneous polynomial!
     348     
     349      ::
     350     
     351            sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)
     352            sage: P._validate(x*y - z)
     353            Traceback (most recent call last):
     354            ...
     355            TypeError: The argument polynomials=x*y - z must be a list or tuple   
    316356        """
     357        if not isinstance(polynomials, (list, tuple)):
     358            raise TypeError, 'The argument polynomials=%s must be a list or tuple'%polynomials
    317359        for f in polynomials:
    318360            if not f.is_homogeneous():
    319361                raise TypeError("%s is not a homogeneous polynomial!" % f)
     
    511553            sage: P2._point_homset(Spec(GF(3)), P2)
    512554            Set of rational points of Projective Space of dimension 2 over Finite Field of size 3
    513555        """
    514         return homset.SchemeHomset_points_projective_ring(*args, **kwds)
     556        return SchemeHomset_points_projective_ring(*args, **kwds)
    515557
    516558    def _point(self, *args, **kwds):
    517559        """
     
    679721       
    680722        OUTPUT:
    681723
    682         An ambient affine space with fixed projective_embedding map.
     724        - An ambient affine space with fixed projective_embedding map.
    683725       
    684726        EXAMPLES::
    685727       
     
    731773            sage: P2._point_homset(Spec(GF(3)), P2)
    732774            Set of rational points of Projective Space of dimension 2 over Finite Field of size 3
    733775        """
    734         return homset.SchemeHomset_points_projective_field(*args, **kwds)
     776        return SchemeHomset_points_projective_field(*args, **kwds)
    735777
    736778    def _point(self, *args, **kwds):
    737779        """
     
    755797        Return iterator over the elements of this projective space.
    756798       
    757799        Note that iteration is over the decomposition
    758         `\PP^n = \mathbb{A}A^n \cup \PP^n-1`, where
     800        `\mathbb{P}^n = \mathbb{A}A^n \cup \mathbb{P}^n-1`, where
    759801        `\mathbb{A}A^n` is the `n`-th affine patch and
    760         `\PP^n-1` is the hyperplane at infinity
     802        `\mathbb{P}^n-1` is the hyperplane at infinity
    761803        `x_n = 0`.
    762804       
    763805        EXAMPLES::
     
    867909            1), (-1/2 : 1 : 1), (1/2 : 1 : 1), (-2 : 1 : 0), (-1 : 1 : 0), (0 : 1 :
    868910            0), (1 : 1 : 0), (2 : 1 : 0), (-1/2 : 1 : 0), (1/2 : 1 : 0), (1 : 0 :
    869911            0)]
     912
    870913       
    871914        .. note::
    872915
  • sage/schemes/readme.py

    diff --git a/sage/schemes/readme.py b/sage/schemes/readme.py
    a b  
    144144  ::
    145145
    146146        sage: P( [2, 1+t] )
    147         Traceback (most recent call last):
    148         ...
    149         NotImplementedError
     147        (2 : t + 1 : 1)
    150148 
    151149  In fact, we need a test ``R.ideal([2,1+t]) == R.ideal([1])`` in order
    152150  to make this meaningful.