Ticket #13130: trac_13130_rings_for_projective_space.patch
File trac_13130_rings_for_projective_space.patch, 41.8 KB (added by , 10 years ago) |
---|
-
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 153 153 Standard comparison function for points on elliptic curves, to 154 154 allow sorting and equality testing. 155 155 156 .. NOTE:: 157 158 ``__eq__`` and ``__ne__`` are implemented in SchemeMorphism_point_projective_ring 159 156 160 EXAMPLES: 157 161 sage: E=EllipticCurve(QQ,[1,1]) 158 162 sage: P=E(0,1) … … 374 378 """ 375 379 Comparison function for points to allow sorting and equality testing. 376 380 381 .. NOTE:: 382 383 ``__eq__`` and ``__ne__`` are implemented in SchemeMorphism_point_projective_field 384 377 385 EXAMPLES:: 378 386 379 387 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 21 21 - William Stein (2006): initial version. 22 22 23 23 - Volker Braun (2011-08-11): significant improvement and refactoring. 24 25 - Ben Hutz (June 2012): added support for projective ring 24 26 """ 25 27 26 28 … … 45 47 from sage.schemes.generic.spec import Spec, is_Spec 46 48 from sage.schemes.generic.morphism import ( 47 49 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 ) 52 52 53 53 54 54 def is_SchemeHomset(H): … … 716 716 sage: SchemeHomset_points_projective_ring(Spec(ZZ), ProjectiveSpace(ZZ,2)) 717 717 Set of rational points of Projective Space of dimension 2 over Integer Ring 718 718 """ 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_ring728 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 NotImplementedError733 734 TESTS::735 736 sage: Hom._element_constructor_(1,2,3)737 Traceback (most recent call last):738 ...739 NotImplementedError740 """741 check = kwds.get('check', True)742 raise NotImplementedError743 719 744 720 def points(self, B=0): 745 721 """ … … 750 726 - `B` -- integer (optional, default=0). The bound for the 751 727 coordinates. 752 728 753 OUTPUT:754 755 This is currently not implemented and will raise ``NotImplementedError``.756 757 729 EXAMPLES:: 758 730 759 731 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)] 765 762 """ 766 raise NotImplementedError # fixed when _element_constructor_ is defined.767 763 R = self.value_ring() 768 764 if R == ZZ: 769 765 if not B > 0: 770 766 raise TypeError, "A positive bound B (= %s) must be specified."%B 771 from sage.schemes.generic.rational_point simport enum_projective_rational_field767 from sage.schemes.generic.rational_point import enum_projective_rational_field 772 768 return enum_projective_rational_field(self,B) 773 769 else: 774 770 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 55 55 56 56 - Volker Braun (2011-08-08): Renamed classes, more documentation, misc 57 57 cleanups. 58 59 - Ben Hutz (June 2012): added support for projective ring 58 60 """ 59 61 60 62 # Historical note: in trac #11599, V.B. renamed … … 73 75 #***************************************************************************** 74 76 75 77 76 from sage.rings.infinity import infinity77 78 from sage.structure.element import AdditiveGroupElement, RingElement, Element, generic_power 78 79 from sage.structure.sequence import Sequence 79 80 from sage.categories.homset import Homset 80 81 from sage.rings.all import is_RingHomomorphism, is_CommutativeRing, Integer 81 82 from point import is_SchemeTopologicalPoint 82 import scheme 83 from sage.rings.infinity import infinity 84 import scheme 85 86 from sage.rings.arith import gcd, lcm 87 from sage.categories.gcd_domains import GcdDomains 88 from sage.rings.quotient_ring import QuotientRing_generic 89 83 90 84 91 85 92 def is_SchemeMorphism(f): … … 705 712 Some checks are performed to make sure the given polynomials 706 713 define a morphism:: 707 714 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 factors715 716 715 sage: f = H([exp(x),exp(y)]) 717 716 Traceback (most recent call last): 718 717 ... … … 745 744 polys = [source_ring(poly) for poly in polys] 746 745 except TypeError: 747 746 raise TypeError, "polys (=%s) must be elements of %s"%(polys,source_ring) 748 from sage.rings.quotient_ring import QuotientRing_generic749 747 if isinstance(source_ring, QuotientRing_generic): 750 748 lift_polys = [f.lift() for f in polys] 751 749 else: 752 750 lift_polys = polys 753 from sage.schemes.generic.projective_space import is_ProjectiveSpace754 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 common757 # zeros758 if isinstance(source_ring, QuotientRing_generic):759 # if the coordinate ring of the domain is a760 # quotient by an ideal, we need to check that the761 # gcd of polys and the generators of the ideal is 1762 gcd_polys = lift_polys + list(source_ring.defining_ideal().gens())763 else:764 # if the domain is affine space, we just need to765 # check the gcd of polys766 gcd_polys = polys767 from sage.rings.arith import gcd768 if gcd(gcd_polys) != 1:769 raise ValueError, "polys (=%s) must not have common factors"%polys770 751 polys = Sequence(lift_polys) 771 polys.set_immutable()772 752 # Todo: check that map is well defined (how?) 773 self._ _polys = polys774 SchemeMorphism.__init__(self, parent) 753 self._polys = polys 754 SchemeMorphism.__init__(self, parent) 775 755 776 756 def defining_polynomials(self): 777 757 """ … … 790 770 sage: H([x^3+y, 1-x-y]).defining_polynomials() 791 771 [x^3 + y, -x - y + 1] 792 772 """ 793 return self._ _polys773 return self._polys 794 774 795 def __call__(self, x ):775 def __call__(self, x,check=True): 796 776 """ 797 777 Apply this morphism to a point in the domain. 798 778 799 779 INPUT: 800 780 801 - ``x`` -- a nythingthat 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. 802 782 803 783 OUTPUT: 804 784 … … 837 817 Traceback (most recent call last): 838 818 ... 839 819 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 840 853 """ 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" 843 859 P = [f(x._coords) for f in self.defining_polynomials()] 844 return self.codomain() (P)860 return self.codomain().point(P,check) 845 861 846 862 847 863 def _repr_defn(self): … … 866 882 o = self.codomain().ambient_space()._repr_generic_point(self.defining_polynomials()) 867 883 return "Defined on coordinates by sending %s to\n%s"%(i,o) 868 884 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 869 908 870 909 class SchemeMorphism_polynomial_affine_space(SchemeMorphism_polynomial): 871 910 """ … … 893 932 """ 894 933 A morphism of schemes determined by rational functions that define 895 934 what the morphism does on points in the ambient projective space. 896 935 897 936 EXAMPLES:: 898 937 899 938 sage: R.<x,y> = QQ[] 900 939 sage: P1 = ProjectiveSpace(R) 901 940 sage: H = P1.Hom(P1) … … 903 942 Scheme endomorphism of Projective Space of dimension 1 over Rational Field 904 943 Defn: Defined on coordinates by sending (x : y) to 905 944 (y : 2*x) 906 945 907 946 An example of a morphism between projective plane curves (see #10297):: 908 947 909 948 sage: P2.<x,y,z> = ProjectiveSpace(QQ,2) 910 949 sage: f = x^3+y^3+60*z^3 911 950 sage: g = y^2*z-( x^3 - 6400*z^3/3) … … 919 958 To: Projective Curve over Rational Field defined by -x^3 + y^2*z + 6400/3*z^3 920 959 Defn: Defined on coordinates by sending (x : y : z) to 921 960 (z : x - y : -1/80*x - 1/80*y) 922 961 923 962 A more complicated example:: 924 963 925 964 sage: P2.<x,y,z> = ProjectiveSpace(2,QQ) 926 965 sage: P1 = P2.subscheme(x-y) 927 966 sage: H12 = P1.Hom(P2) 928 967 sage: H12([x^2,x*z, z^2]) 929 968 Scheme morphism: 930 From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:931 x - y932 To: Projective Space of dimension 2 over Rational Field933 Defn: Defined on coordinates by sending (x : y : z) to969 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 934 973 (y^2 : y*z : z^2) 935 974 936 975 We illustrate some error checking:: 937 976 938 977 sage: R.<x,y> = QQ[] … … 942 981 Traceback (most recent call last): 943 982 ... 944 983 ValueError: polys (=[x - y, x*y]) must be of the same degree 945 984 946 985 sage: H([x-1, x*y+x]) 947 986 Traceback (most recent call last): 948 987 ... 949 988 ValueError: polys (=[x - 1, x*y + x]) must be homogeneous 950 989 951 990 sage: H([exp(x),exp(y)]) 952 991 Traceback (most recent call last): 953 992 ... … … 958 997 def __init__(self, parent, polys, check=True): 959 998 """ 960 999 The Python constructor. 961 1000 962 1001 See :class:`SchemeMorphism_polynomial` for details. 963 1002 964 1003 EXAMPLES:: 965 1004 966 1005 sage: P1.<x,y> = ProjectiveSpace(QQ,1) 967 1006 sage: H = P1.Hom(P1) 968 1007 sage: H([y,2*x]) … … 974 1013 if check: 975 1014 # morphisms from projective space are always given by 976 1015 # homogeneous polynomials of the same degree 977 polys = self.defining_polynomials()978 1016 try: 979 1017 d = polys[0].degree() 980 1018 except AttributeError: … … 984 1022 degs = [f.degree() for f in polys] 985 1023 if not all([d==degs[0] for d in degs[1:]]): 986 1024 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:: 987 1031 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) 988 1189 989 1190 ############################################################################ 990 1191 # Rational points on schemes, which we view as morphisms determined … … 1218 1419 X.extended_codomain()._check_satisfies_equations(v) 1219 1420 self._coords = tuple(v) 1220 1421 1221 1422 1222 1423 #******************************************************************* 1223 1424 # Projective varieties 1224 1425 #******************************************************************* 1225 1426 class SchemeMorphism_point_projective_ring(SchemeMorphism_point): 1226 1427 """ 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:: 1258 1431 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` 1263 1433 1264 1434 - ``v`` -- a list or tuple of coordinates in `K` 1265 1435 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 1269 1438 EXAMPLES:: 1270 1439 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 1282 1444 """ 1445 1283 1446 def __init__(self, X, v, check=True): 1284 1447 """ 1285 1448 The Python constructor. 1286 1449 1287 See :class:`SchemeMorphism_point_projective_field` for details.1450 EXAMPLES:: 1288 1451 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) 1294 1492 """ 1295 1493 SchemeMorphism.__init__(self, X) 1296 1494 if check: … … 1306 1504 "Argument v (= %s) must be a scheme point, list, or tuple."%str(v) 1307 1505 if len(v) != d and len(v) != d-1: 1308 1506 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 1792 class 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 1310 1858 R = X.value_ring() 1311 1859 v = Sequence(v, R) 1312 1860 if len(v) == d-1: # very common special case … … 1327 1875 break 1328 1876 if all_zero: 1329 1877 raise ValueError, "%s does not define a valid point since all entries are 0"%repr(v) 1330 1878 1331 1879 X.extended_codomain()._check_satisfies_equations(v) 1332 1880 1333 1881 self._coords = v 1334 1882 1335 1883 1336 1337 1884 #******************************************************************* 1338 1885 # Abelian varieties 1339 1886 #******************************************************************* … … 1353 1900 """ 1354 1901 pass 1355 1902 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 80 80 from sage.modules.free_module_element import prepare 81 81 82 82 from ambient_space import AmbientSpace 83 import homset 83 from homset import (SchemeHomset_points_projective_ring, SchemeHomset_points_projective_field) 84 84 import morphism 85 85 86 86 … … 145 145 sage: P.coordinate_ring() is R 146 146 True 147 147 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 148 164 Projective spaces are not cached, i.e., there can be several with 149 165 the same base ring and dimension (to facilitate gluing 150 166 constructions). … … 225 241 TypeError otherwise. 226 242 227 243 EXAMPLES:: 228 244 229 245 sage: P = ProjectiveSpace(2, ZZ) 230 246 sage: P._check_satisfies_equations([1, 1, 0]) 231 247 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)) 233 253 True 254 255 :: 256 257 sage: P = ProjectiveSpace(2, ZZ) 234 258 sage: P._check_satisfies_equations([0, 0, 0]) 235 259 Traceback (most recent call last): 236 260 ... 237 261 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)) 239 267 Traceback (most recent call last): 240 268 ... 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]) 243 275 Traceback (most recent call last): 244 276 ... 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 250 278 """ 251 279 if not isinstance(v, (list, tuple)): 252 280 raise TypeError, 'The argument v=%s must be a list or tuple'%v … … 307 335 EXAMPLES:: 308 336 309 337 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) 312 344 sage: P._validate((x*y - z, x)) 313 345 Traceback (most recent call last): 314 346 ... 315 347 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 316 356 """ 357 if not isinstance(polynomials, (list, tuple)): 358 raise TypeError, 'The argument polynomials=%s must be a list or tuple'%polynomials 317 359 for f in polynomials: 318 360 if not f.is_homogeneous(): 319 361 raise TypeError("%s is not a homogeneous polynomial!" % f) … … 511 553 sage: P2._point_homset(Spec(GF(3)), P2) 512 554 Set of rational points of Projective Space of dimension 2 over Finite Field of size 3 513 555 """ 514 return homset.SchemeHomset_points_projective_ring(*args, **kwds)556 return SchemeHomset_points_projective_ring(*args, **kwds) 515 557 516 558 def _point(self, *args, **kwds): 517 559 """ … … 679 721 680 722 OUTPUT: 681 723 682 An ambient affine space with fixed projective_embedding map.724 - An ambient affine space with fixed projective_embedding map. 683 725 684 726 EXAMPLES:: 685 727 … … 731 773 sage: P2._point_homset(Spec(GF(3)), P2) 732 774 Set of rational points of Projective Space of dimension 2 over Finite Field of size 3 733 775 """ 734 return homset.SchemeHomset_points_projective_field(*args, **kwds)776 return SchemeHomset_points_projective_field(*args, **kwds) 735 777 736 778 def _point(self, *args, **kwds): 737 779 """ … … 755 797 Return iterator over the elements of this projective space. 756 798 757 799 Note that iteration is over the decomposition 758 `\ PP^n = \mathbb{A}A^n \cup \PP^n-1`, where800 `\mathbb{P}^n = \mathbb{A}A^n \cup \mathbb{P}^n-1`, where 759 801 `\mathbb{A}A^n` is the `n`-th affine patch and 760 `\ PP^n-1` is the hyperplane at infinity802 `\mathbb{P}^n-1` is the hyperplane at infinity 761 803 `x_n = 0`. 762 804 763 805 EXAMPLES:: … … 867 909 1), (-1/2 : 1 : 1), (1/2 : 1 : 1), (-2 : 1 : 0), (-1 : 1 : 0), (0 : 1 : 868 910 0), (1 : 1 : 0), (2 : 1 : 0), (-1/2 : 1 : 0), (1/2 : 1 : 0), (1 : 0 : 869 911 0)] 912 870 913 871 914 .. note:: 872 915 -
sage/schemes/readme.py
diff --git a/sage/schemes/readme.py b/sage/schemes/readme.py
a b 144 144 :: 145 145 146 146 sage: P( [2, 1+t] ) 147 Traceback (most recent call last): 148 ... 149 NotImplementedError 147 (2 : t + 1 : 1) 150 148 151 149 In fact, we need a test ``R.ideal([2,1+t]) == R.ideal([1])`` in order 152 150 to make this meaningful.