Path: blob/master/src/sage/schemes/projective/projective_point.py
8820 views
r"""1Points on projective varieties23Scheme morphism for points on projective varieties4567AUTHORS:89- David Kohel, William Stein1011- William Stein (2006-02-11): fixed bug where P(0,0,0) was allowed as12a projective point.1314- Volker Braun (2011-08-08): Renamed classes, more documentation, misc15cleanups.1617- Ben Hutz (June 2012) added support for projective ring;18(March 2013) iteration functionality and new directory structure19for affine/projective, height functionality20"""2122# Historical note: in trac #11599, V.B. renamed23# * _point_morphism_class -> _morphism24# * _homset_class -> _point_homset2526#*****************************************************************************27# Copyright (C) 2011 Volker Braun <[email protected]>28# Copyright (C) 2006 David Kohel <[email protected]>29# Copyright (C) 2006 William Stein <[email protected]>30#31# Distributed under the terms of the GNU General Public License (GPL)32# as published by the Free Software Foundation; either version 2 of33# the License, or (at your option) any later version.34# http://www.gnu.org/licenses/35#*****************************************************************************3637from sage.categories.number_fields import NumberFields38_NumberFields = NumberFields()39from sage.rings.infinity import infinity40from sage.rings.arith import gcd, lcm, is_prime41from sage.rings.integer_ring import ZZ42from sage.rings.number_field.order import is_NumberFieldOrder43from sage.rings.padics.all import Qp44from sage.rings.quotient_ring import QuotientRing_generic45from sage.rings.rational_field import QQ46from sage.rings.real_mpfr import RealField, RR47from copy import copy48from sage.schemes.generic.morphism import (SchemeMorphism,49is_SchemeMorphism,50SchemeMorphism_point)51from sage.structure.element import AdditiveGroupElement52from sage.structure.sequence import Sequence53545556#*******************************************************************57# Projective varieties58#*******************************************************************59class SchemeMorphism_point_projective_ring(SchemeMorphism_point):60"""61A rational point of projective space over a ring.6263INPUT:6465- ``X`` -- a homset of a subscheme of an ambient projective space over a field `K`6667- ``v`` -- a list or tuple of coordinates in `K`6869- ``check`` -- boolean (optional, default:``True``). Whether to check the input for consistency.7071EXAMPLES::7273sage: P = ProjectiveSpace(2, ZZ)74sage: P(2,3,4)75(2 : 3 : 4)7677"""7879def __init__(self, X, v, check=True):80"""81The Python constructor.8283EXAMPLES::8485sage: P = ProjectiveSpace(2, QQ)86sage: P(2, 3/5, 4)87(1/2 : 3/20 : 1)8889::9091sage: P = ProjectiveSpace(1, ZZ)92sage: P([0, 1])93(0 : 1)9495::9697sage: P = ProjectiveSpace(1, ZZ)98sage: P([0, 0, 1])99Traceback (most recent call last):100...101TypeError: v (=[0, 0, 1]) must have 2 components102103::104105sage: P = ProjectiveSpace(3, QQ)106sage: P(0,0,0,0)107Traceback (most recent call last):108...109ValueError: [0, 0, 0, 0] does not define a valid point since all entries are 0110111::112113It is possible to avoid the possibly time consuming checks, but be careful!!114115sage: P = ProjectiveSpace(3, QQ)116sage: P.point([0,0,0,0],check=False)117(0 : 0 : 0 : 0)118119::120121sage: P.<x, y, z> = ProjectiveSpace(2, ZZ)122sage: X=P.subscheme([x^2-y*z])123sage: X([2,2,2])124(2 : 2 : 2)125"""126SchemeMorphism.__init__(self, X)127if check:128from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field129d = X.codomain().ambient_space().ngens()130if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field):131v = list(v)132elif v is infinity:133v = [0] * (d)134v[1] = 1135if not isinstance(v,(list,tuple)):136raise TypeError("Argument v (= %s) must be a scheme point, list, or tuple."%str(v))137if len(v) != d and len(v) != d-1:138raise TypeError("v (=%s) must have %s components"%(v, d))139140R = X.value_ring()141v = Sequence(v, R)142if len(v) == d-1: # very common special case143v.append(1)144145n = len(v)146all_zero = True147for i in range(n):148last = n-1-i149if v[last]:150all_zero = False151break152if all_zero:153raise ValueError("%s does not define a valid point since all entries are 0"%repr(v))154155X.extended_codomain()._check_satisfies_equations(v)156157if isinstance(X.codomain().base_ring(), QuotientRing_generic):158lift_coords = [P.lift() for P in v]159else:160lift_coords = v161v = Sequence(lift_coords)162163self._coords = v164165def __eq__(self,right):166"""167Tests the proejctive equality of two points.168169INPUT:170171- ``right`` - a point on projective space172173OUTPUT:174175- Boolean - True if ``self`` and ``right`` define the same point. False otherwise.176177Examples::178179sage: PS=ProjectiveSpace(ZZ,1,'x')180sage: P=PS([1,2])181sage: Q=PS([2,4])182sage: P==Q183True184185::186187sage: PS=ProjectiveSpace(ZZ,1,'x')188sage: P=PS([1,2])189sage: Q=PS([1,0])190sage: P==Q191False192193::194195sage: PS=ProjectiveSpace(Zp(5),1,'x')196sage: P=PS([0,1])197sage: P==0198True199200::201202sage: R.<t>=PolynomialRing(QQ)203sage: PS=ProjectiveSpace(R,1,'x')204sage: P=PS([t,1+t^2])205sage: Q=PS([t^2, t+t^3])206sage: P==Q207True208209::210211sage: PS=ProjectiveSpace(ZZ,2,'x')212sage: P=PS([0,1,2])213sage: P==0214False215216::217218sage: PS=ProjectiveSpace(ZZ,1,'x')219sage: P=PS([2,1])220sage: PS2=ProjectiveSpace(Zp(7),1,'x')221sage: Q=PS2([2,1])222sage: P==Q223False224225::226227sage: PS=ProjectiveSpace(ZZ.quo(6),2,'x')228sage: P=PS([2,4,1])229sage: Q=PS([0,1,3])230sage: P==Q231False232233::234235sage: R.<z>=PolynomialRing(QQ)236sage: K.<t>=NumberField(z^2+5)237sage: OK=K.ring_of_integers()238sage: t=OK.gen(1)239sage: PS.<x,y>=ProjectiveSpace(OK,1)240sage: P=PS(2,1+t)241sage: Q=PS(1-t,3)242sage: P==Q243True244245"""246if not isinstance(right, SchemeMorphism_point):247try:248right = self.codomain()(right)249except TypeError:250return False251if self.codomain()!=right.codomain():252return False253n=len(self._coords)254for i in range(0,n):255for j in range(i+1,n):256if self._coords[i]*right._coords[j] != self._coords[j]*right._coords[i]:257return False258return True259260def __ne__(self,right):261"""262Tests the proejctive equality of two points.263264INPUT:265266- ``right`` - a point on projective space267268OUTPUT:269270- Boolean - True if ``self`` and ``right`` define different points. False otherwise.271272Examples::273274sage: PS=ProjectiveSpace(ZZ,1,'x')275sage: P=PS([1,2])276sage: Q=PS([2,4])277sage: P!=Q278False279280::281282sage: PS=ProjectiveSpace(ZZ,1,'x')283sage: P=PS([1,2])284sage: Q=PS([1,0])285sage: P!=Q286True287288::289290sage: PS=ProjectiveSpace(Zp(5),1,'x')291sage: P=PS([0,1])292sage: P!=0293False294295::296297sage: R.<t>=PolynomialRing(QQ)298sage: PS=ProjectiveSpace(R,1,'x')299sage: P=PS([t,1+t^2])300sage: Q=PS([t^2, t+t^3])301sage: P!=Q302False303304::305306sage: PS=ProjectiveSpace(ZZ,2,'x')307sage: P=PS([0,1,2])308sage: P!=0309True310311::312313sage: PS=ProjectiveSpace(ZZ,1,'x')314sage: P=PS([2,1])315sage: PS2=ProjectiveSpace(Zp(7),1,'x')316sage: Q=PS2([2,1])317sage: P!=Q318True319320::321322sage: PS=ProjectiveSpace(ZZ.quo(6),2,'x')323sage: P=PS([2,4,1])324sage: Q=PS([0,1,3])325sage: P!=Q326True327"""328if not isinstance(right, SchemeMorphism_point):329try:330right = self.codomain()(right)331except TypeError:332return True333if self.codomain()!=right.codomain():334return True335n=len(self._coords)336for i in range(0,n):337for j in range(i+1,n):338if self._coords[i]*right._coords[j] != self._coords[j]*right._coords[i]:339return True340return False341342def scale_by(self,t):343"""344Scale the coordinates of the point ``self`` by `t`. A ``TypeError`` occurs if345the point is not in the base_ring of the codomain after scaling.346347INPUT:348349- ``t`` -- a ring element350351OUTPUT:352353- None.354355EXAMPLES::356357sage: R.<t>=PolynomialRing(QQ)358sage: P=ProjectiveSpace(R,2,'x')359sage: p=P([3/5*t^3,6*t, t])360sage: p.scale_by(1/t); p361(3/5*t^2 : 6 : 1)362363::364365sage: R.<t>=PolynomialRing(QQ)366sage: S=R.quo(R.ideal(t^3))367sage: P.<x,y,z>=ProjectiveSpace(S,2)368sage: Q=P(t,1,1)369sage: Q.scale_by(t);Q370(tbar^2 : tbar : tbar)371372::373374sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)375sage: Q=P(2,2,2)376sage: Q.scale_by(1/2);Q377(1 : 1 : 1)378"""379if t==0: #what if R(t) == 0 ?380raise ValueError("Cannot scale by 0")381R=self.codomain().base_ring()382if isinstance(R, QuotientRing_generic):383phi=R.coerce_map_from(self.codomain().ambient_space().base_ring())384for i in range(self.codomain().ambient_space().dimension_relative()+1):385self._coords[i]=phi(self._coords[i]*t).lift()386else:387for i in range(self.codomain().ambient_space().dimension_relative()+1):388self._coords[i]=R(self._coords[i]*t)389390def normalize_coordinates(self):391"""392Removes the gcd from the coordinates of ``self`` (including `-1`).393394.. WARNING:: The gcd will depend on the base ring.395396OUTPUT:397398- None.399400EXAMPLES::401402sage: P = ProjectiveSpace(ZZ,2,'x')403sage: p = P([-5,-15,-20])404sage: p.normalize_coordinates(); p405(1 : 3 : 4)406407::408409sage: P = ProjectiveSpace(Zp(7),2,'x')410sage: p = P([-5,-15,-2])411sage: p.normalize_coordinates(); p412(5 + O(7^20) : 1 + 2*7 + O(7^20) : 2 + O(7^20))413414::415416sage: R.<t> = PolynomialRing(QQ)417sage: P = ProjectiveSpace(R,2,'x')418sage: p = P([3/5*t^3,6*t, t])419sage: p.normalize_coordinates(); p420(3/5*t^2 : 6 : 1)421422::423424sage: P.<x,y> = ProjectiveSpace(Zmod(20),1)425sage: Q = P(4,8)426sage: Q.normalize_coordinates()427sage: Q428(1 : 2)429430::431432sage: R.<t> = PolynomialRing(QQ,1)433sage: S = R.quotient_ring(R.ideal(t^3))434sage: P.<x,y> = ProjectiveSpace(S,1)435sage: Q = P(t,t^2)436sage: Q.normalize_coordinates()437sage: Q438(1 : t)439440Since the base ring is a polynomial ring over a field, only the441gcd `c` is removed. ::442443sage: R.<c> = PolynomialRing(QQ)444sage: P = ProjectiveSpace(R,1)445sage: Q = P(2*c,4*c)446sage: Q.normalize_coordinates();Q447(2 : 4)448449A polynomial ring over a ring gives the more intuitive result. ::450451sage: R.<c> = PolynomialRing(ZZ)452sage: P = ProjectiveSpace(R,1)453sage: Q = P(2*c,4*c)454sage: Q.normalize_coordinates();Q455(1 : 2)456"""457R=self.codomain().base_ring()458GCD = R(gcd(self[0],self[1]))459index=2460if self[0]>0 or self[1] >0:461neg=0462else:463neg=1464while GCD!=1 and index < len(self._coords):465if self[index]>0:466neg=0467GCD=R(gcd(GCD,self[index]))468index+=1469if isinstance(R,(QuotientRing_generic)):470R=R.cover_ring()471GCD=GCD.lift()472if GCD != 1:473if neg==1:474self.scale_by(R(-1)/GCD)475else:476self.scale_by(R(1)/GCD)477else:478if neg==1:479self.scale_by(R(-1))480481def dehomogenize(self,n):482r"""483Dehomogenizes at the nth coordinate484485INPUT:486487- ``n`` -- non-negative integer488489OUTPUT:490491- :class:`SchemeMorphism_point_affine`492493EXAMPLES::494495sage: P.<x,y,z>=ProjectiveSpace(QQ,2)496sage: X=P.subscheme(x^2-y^2);497sage: Q=X(23,23,46)498sage: Q.dehomogenize(2)499(1/2, 1/2)500501::502503sage: R.<t>=PolynomialRing(QQ)504sage: S=R.quo(R.ideal(t^3))505sage: P.<x,y,z>=ProjectiveSpace(S,2)506sage: Q=P(t,1,1)507sage: Q.dehomogenize(1)508(tbar, 1)509510::511512sage: P.<x,y,z>=ProjectiveSpace(GF(5),2)513sage: Q=P(1,3,1)514sage: Q.dehomogenize(0)515(3, 1)516517::518519sage: P.<x,y,z>=ProjectiveSpace(GF(5),2)520sage: Q=P(1,3,0)521sage: Q.dehomogenize(2)522Traceback (most recent call last):523...524ValueError: Can't dehomogenize at 0 coordinate.525"""526if self[n]==0:527raise ValueError("Can't dehomogenize at 0 coordinate.")528PS=self.codomain()529A=PS.affine_patch(n)530Q=[]531for i in range(0,PS.ambient_space().dimension_relative()+1):532if i !=n:533Q.append(self[i]/self[n])534return(A.point(Q))535536def nth_iterate(self,f,n,normalize=False):537r"""538For a map ``self`` and a point `P` in ``self.domain()``539this function returns the nth iterate of `P` by ``self``. If ``normalize==True``,540then the coordinates are automatically normalized.541542INPUT:543544- ``f`` -- a SchmemMorphism_polynomial with ``self`` in ``f.domain()``545546- ``n`` -- a positive integer.547548- ``normalize`` -- Boolean (optional Default: ``False``)549550OUTPUT:551552- A point in ``self.codomain()``553554EXAMPLES::555556sage: P.<x,y>=ProjectiveSpace(ZZ,1)557sage: H=Hom(P,P)558sage: f=H([x^2+y^2,2*y^2])559sage: P(1,1).nth_iterate(f,4)560(32768 : 32768)561562::563564sage: P.<x,y>=ProjectiveSpace(ZZ,1)565sage: H=Hom(P,P)566sage: f=H([x^2+y^2,2*y^2])567sage: P(1,1).nth_iterate(f,4,1)568(1 : 1)569570::571572sage: R.<t>=PolynomialRing(QQ)573sage: P.<x,y,z>=ProjectiveSpace(R,2)574sage: H=Hom(P,P)575sage: f=H([x^2+t*y^2,(2-t)*y^2,z^2])576sage: P(2+t,7,t).nth_iterate(f,2)577(t^4 + 2507*t^3 - 6787*t^2 + 10028*t + 16 : -2401*t^3 + 14406*t^2 -57828812*t + 19208 : t^4)579580::581582sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)583sage: X=P.subscheme(x^2-y^2)584sage: H=Hom(X,X)585sage: f=H([x^2,y^2,z^2])586sage: X(2,2,3).nth_iterate(f,3)587(256 : 256 : 6561)588589.. TODO:: Is there a more efficient way to do this?590"""591if self.codomain()!=f.domain():592raise TypeError("Point is not defined over domain of function")593if f.domain() != f.codomain():594raise TypeError("Domain and Codomain of function not equal")595try:596n=ZZ(n)597except TypeError:598raise TypeError("Iterate number must be an integer")599if n <0:600raise TypeError("Must be a forward orbit")601if n==0:602return(self)603else:604Q=f(self)605if normalize==True:606Q.normalize_coordinates()607for i in range(2,n+1):608Q=f(Q)609if normalize==True:610Q.normalize_coordinates()611return(Q)612613def orbit(self,f,N,**kwds):614r"""615Returns the orbit of `P` by ``self``. If `n` is an integer it returns `[P,self(P),\ldots,self^n(P)]`.616If `n` is a list or tuple `n=[m,k]` it returns `[self^m(P),\ldots,self^k(P)`].617Automatically normalize the points if ``normalize=True``. Perform the checks on point initialization if618``check=True``619620INPUT:621622- ``f`` -- a :class:`SchemeMorphism_polynomial` with ``self`` in ``f.domain()``623624- ``N`` -- a non-negative integer or list or tuple of two non-negative integers625626kwds:627628- ``check`` -- boolean (optional - default: ``True``)629630- ``normalize`` -- boolean (optional - default: ``False``)631632633OUTPUT:634635- a list of points in ``self.codomain()``636637EXAMPLES::638639sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)640sage: H=Hom(P,P)641sage: f=H([x^2+y^2,y^2-z^2,2*z^2])642sage: P(1,2,1).orbit(f,3)643[(1 : 2 : 1), (5 : 3 : 2), (34 : 5 : 8), (1181 : -39 : 128)]644645::646647sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)648sage: H=Hom(P,P)649sage: f=H([x^2+y^2,y^2-z^2,2*z^2])650sage: P(1,2,1).orbit(f,[2,4])651[(34 : 5 : 8), (1181 : -39 : 128), (1396282 : -14863 : 32768)]652653::654655sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)656sage: X=P.subscheme(x^2-y^2)657sage: H=Hom(X,X)658sage: f=H([x^2,y^2,x*z])659sage: X(2,2,3).orbit(f,3,normalize=True)660[(2 : 2 : 3), (2 : 2 : 3), (2 : 2 : 3), (2 : 2 : 3)]661662::663664sage: P.<x,y>=ProjectiveSpace(QQ,1)665sage: H=Hom(P,P)666sage: f=H([x^2+y^2,y^2])667sage: P.point([1,2],False).orbit(f,4,check=False)668[(1 : 2), (5 : 4), (41 : 16), (1937 : 256), (3817505 : 65536)]669"""670if (isinstance(N,(list,tuple))==False):671N=[0,N]672try:673N[0]=ZZ(N[0])674N[1]=ZZ(N[1])675except TypeError:676raise TypeError("Orbit bounds must be integers")677if N[0]<0 or N[1] <0:678raise TypeError("Orbit bounds must be non-negative")679if N[0] > N[1]:680return([])681682Q=copy(self)683check = kwds.pop("check",True)684normalize = kwds.pop("normalize",False)685686if normalize==True:687Q.normalize_coordinates()688for i in range(1,N[0]+1):689Q=f(Q,check)690if normalize==True:691Q.normalize_coordinates()692Orb=[Q]693for i in range(N[0]+1,N[1]+1):694Q=f(Q,check)695if normalize==True:696Q.normalize_coordinates()697Orb.append(Q)698return(Orb)699700def green_function(self, G,v, **kwds):701r"""702Evaluates the local Green's function at the place ``v`` for ``self`` with ``N`` terms of the series703or, in dimension 1, to within the specified error bound. Defaults to ``N=10`` if no kwds provided704705Use ``v=0`` for the archimedean place. Must be over `\ZZ` or `\QQ`.706707ALGORITHM:708709See Exercise 5.29 and Figure 5.6 of ``The Arithmetic of Dynamics Systems``, Joseph H. Silverman, Springer, GTM 241, 2007.710711INPUT:712713- ``G`` - an endomorphism of self.codomain()714715- ``v`` - non-negative integer. a place, use v=0 for the archimedean place716717kwds:718719- ``N`` - positive integer. number of terms of the series to use720721- ``prec`` - positive integer, float point or p-adic precision, default: 100722723- ``error_bound`` - a positive real number724725OUTPUT:726727- a real number728729Examples::730731sage: P.<x,y>=ProjectiveSpace(QQ,1)732sage: H=Hom(P,P)733sage: f=H([x^2+y^2,x*y]);734sage: Q=P(5,1)735sage: f.green_function(Q,0,N=30)7361.6460930159932946233759277576737738::739740sage: P.<x,y>=ProjectiveSpace(QQ,1)741sage: H=Hom(P,P)742sage: f=H([x^2+y^2,x*y]);743sage: Q=P(5,1)744sage: Q.green_function(f,0,N=200,prec=200)7451.6460930160038721802875250367738355497198064992657997569827746747.. TODO::748749error bounds for dimension > 1750"""751N = kwds.get('N', None) #Get number of iterates (if entered)752err = kwds.get('error_bound', None) #Get error bound (if entered)753prec = kwds.get('prec', 100) #Get precision (if entered)754R=RealField(prec)755756if not (v == 0 or is_prime(v)):757raise ValueError("Invalid valuation (=%s) entered."%v)758if v == 0:759K = R760else:761K = Qp(v, prec)762763#Coerce all polynomials in F into polynomials with coefficients in K764F=G.change_ring(K,False)765d = F.degree()766D=F.codomain().ambient_space().dimension_relative()767768if err is not None:769if D!=1:770raise NotImplementedError("error bounds only for dimension 1")771err = R(err)772if not err>0:773raise ValueError, "Error bound (=%s) must be positive."%err774775#if doing error estimates, compute needed number of iterates776res = F.resultant()777778#compute maximum coefficient of polynomials of F779C = R(G.global_height(prec))780781if v == 0:782log_fact = R(0)783for i in range(2*d+1):784log_fact += R(i+1).log()785B = max((R(res.abs()) - R(2*d).log() - (2*d-1)*C - log_fact).log().abs(), (C + R(d+1).log()).abs())786else:787B = max(R(res.abs()).log() - ((2*d-1)*C).abs(), C.abs())788N = R(B/(err*(d-1))).log(d).abs().ceil()789790elif N is None:791N=10 #default is to do 10 iterations792793#Coerce the coordinates into Q_v794self.normalize_coordinates()795if self.codomain().base_ring()==QQ:796self.clear_denominators()797P=self.change_ring(K,False)798799#START GREEN FUNCTION CALCULATION800801g = R(0)802803for i in range(N+1):804m = -1805806#compute the maximum absolute value of entries of a, and where it occurs807for n in range(D+1):808a_v = R(P[n].abs())809if a_v > m:810j = n811m = a_v812813#add to Greens function814g += (1/R(d))**(i)*R(m).log()815816#normalize coordinates and evaluate817P.scale_by(1/P[j])818P = F(P,False)819820return g821822def canonical_height(self,F, **kwds):823r"""824Evaluates the canonical height of ``self`` with respect to ``F``. Must be over `\ZZ` or `\QQ`.825Specify either the number of terms of the series to evaluate or, in dimension 1, the error bound826required.827828ALGORITHM:829830The sum of the Green's function at the archimedean place and the places of bad reduction.831832INPUT:833834- ``P`` - a projective point835836kwds:837838- ``badprimes`` - a list of primes of bad reduction839840- ``N`` - positive integer. number of terms of the series to use in the local green functions841842- ``prec`` - positive integer, float point or p-adic precision843844- ``error_bound`` - a positive real number845846OUTPUT:847848- a real number849850EXAMPLES::851852sage: P.<x,y>=ProjectiveSpace(ZZ,1)853sage: H=Hom(P,P)854sage: f=H([x^2+y^2,2*x*y]);855sage: Q=P(2,1)856sage: f.canonical_height(f(Q))8572.1965476757927038111992627081858sage: f.canonical_height(Q)8591.0979353871245941198040174712860861Notice that preperiodic points may not be exactly 0. ::862863sage: P.<x,y>=ProjectiveSpace(QQ,1)864sage: H=Hom(P,P)865sage: f=H([x^2-29/16*y^2,y^2]);866sage: Q=P(5,4)867sage: f.canonical_height(Q,N=30)8681.4989058602918874235863427216e-9869870::871872sage: P.<x,y,z>=ProjectiveSpace(QQ,2)873sage: X=P.subscheme(x^2-y^2);874sage: H=Hom(X,X)875sage: f=H([x^2,y^2,30*z^2]);876sage: Q=X([4,4,1])877sage: f.canonical_height(Q,badprimes=[2,3,5],prec=200)8782.7054056208276961889784303469356774912979228770208655455481879"""880881badprimes = kwds.pop("badprimes",None)882883if badprimes is None:884badprimes=F.primes_of_bad_reduction(0)885886h=self.green_function(F,0,**kwds) #arch Green function887for v in badprimes:888h+=self.green_function(F,v,**kwds) #non-arch Green functions889890return h891892def global_height(self, prec=None):893r"""894Returns the logarithmic height of the points. Must be over `\ZZ` or `\QQ`.895896INPUT:897898- ``prec`` -- desired floating point precision (default:899default RealField precision).900901OUTPUT:902903- a real number904905EXAMPLES::906907sage: P.<x,y,z>=ProjectiveSpace(QQ,2)908sage: Q=P.point([4,4,1/30])909sage: Q.global_height()9104.78749174278205911912::913914sage: P.<x,y,z>=ProjectiveSpace(ZZ,2)915sage: Q=P([4,1,30])916sage: Q.global_height()9173.40119738166216918919::920921sage: R.<x>=PolynomialRing(QQ)922sage: k.<w>=NumberField(x^2+5)923sage: A=ProjectiveSpace(k,2,'z')924sage: A([3,5*w+1,1]).global_height(prec=100)9252.4181409534757389986565376694926927.. TODO::928929p-adic heights930931"""932if self.domain().base_ring() in _NumberFields or is_NumberFieldOrder(self.domain().base_ring()):933return(max([self[i].global_height(prec) for i in range(self.codomain().ambient_space().dimension_relative()+1)]))934else:935raise NotImplementedError("Must be over a Numberfield or a Numberfield Order")936937938def multiplier(self,f,n,check=True):939r"""940Returns the multiplier of the projective point ``self`` of period `n` by the function `f`.941`f` must be an endomorphism of projective space942943INPUT:944945- ``f`` - a endomorphism of ``self.codomain()``946947- ``n`` - a positive integer, the period of ``self``948949- ``check`` -- check if ``P`` is periodic of period ``n``, Default:True950951OUTPUT:952953- a square matrix of size ``self.codomain().dimension_relative()`` in the ``base_ring`` of ``self``954955EXAMPLES::956957sage: P.<x,y,z,w>=ProjectiveSpace(QQ,3)958sage: H=Hom(P,P)959sage: f=H([x^2,y^2,4*w^2,4*z^2]);960sage: Q=P.point([4,4,1,1],False);961sage: Q.multiplier(f,1)962[ 2 0 -8]963[ 0 2 -8]964[ 0 0 -2]965"""966return(f.multiplier(self,n,check))967968class SchemeMorphism_point_projective_field(SchemeMorphism_point_projective_ring):969"""970A rational point of projective space over a field.971972INPUT:973974- ``X`` -- a homset of a subscheme of an ambient projective space975over a field `K`976977- ``v`` -- a list or tuple of coordinates in `K`978979- ``check`` -- boolean (optional, default:``True``). Whether to980check the input for consistency.981982EXAMPLES::983984sage: P = ProjectiveSpace(3, RR)985sage: P(2,3,4,5)986(0.400000000000000 : 0.600000000000000 : 0.800000000000000 : 1.00000000000000)987"""988989def __init__(self, X, v, check=True):990"""991The Python constructor.992993See :class:`SchemeMorphism_point_projective_ring` for details.994995This function still normalized points so that the rightmost non-zero coordinate is 1. The is to maintain current functionality with current996implementations of curves in projectives space (plane, connic, elliptic, etc). The class:`SchemeMorphism_point_projective_ring` is for general use.997998EXAMPLES::9991000sage: P = ProjectiveSpace(2, QQ)1001sage: P(2, 3/5, 4)1002(1/2 : 3/20 : 1)10031004::10051006sage: P = ProjectiveSpace(3, QQ)1007sage: P(0,0,0,0)1008Traceback (most recent call last):1009...1010ValueError: [0, 0, 0, 0] does not define a valid point since all entries are 010111012::10131014sage: P.<x, y, z> = ProjectiveSpace(2, QQ)1015sage: X=P.subscheme([x^2-y*z])1016sage: X([2,2,2])1017(1 : 1 : 1)1018"""1019SchemeMorphism.__init__(self, X)1020if check:1021from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field1022d = X.codomain().ambient_space().ngens()1023if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field):1024v = list(v)1025elif v is infinity:1026v = [0] * (d)1027v[1] = 11028if not isinstance(v,(list,tuple)):1029raise TypeError("Argument v (= %s) must be a scheme point, list, or tuple."%str(v))1030if len(v) != d and len(v) != d-1:1031raise TypeError("v (=%s) must have %s components"%(v, d))10321033R = X.value_ring()1034v = Sequence(v, R)1035if len(v) == d-1: # very common special case1036v.append(1)10371038n = len(v)1039all_zero = True1040for i in range(n):1041last = n-1-i1042if v[last]:1043all_zero = False1044c = v[last]1045if c == R.one():1046break1047for j in range(last):1048v[j] /= c1049v[last] = R.one()1050break1051if all_zero:1052raise ValueError("%s does not define a valid point since all entries are 0"%repr(v))10531054X.extended_codomain()._check_satisfies_equations(v)10551056self._coords = v10571058def normalize_coordinates(self):1059r"""1060Normalizes ``self`` so that the last non-zero coordinate is `1`.10611062OUTPUT: None.10631064EXAMPLES::10651066sage: P.<x,y,z>=ProjectiveSpace(GF(5),2)1067sage: Q=P.point([1,3,0],false);Q1068(1 : 3 : 0)1069sage: Q.normalize_coordinates();Q1070(2 : 1 : 0)10711072::10731074sage: P.<x,y,z>=ProjectiveSpace(QQ,2)1075sage: X=P.subscheme(x^2-y^2);1076sage: Q=X.point([23,23,46], false);Q1077(23 : 23 : 46)1078sage: Q.normalize_coordinates();Q1079(1/2 : 1/2 : 1)1080"""1081index=self.codomain().ambient_space().dimension_relative()1082while self[index]==0:1083index-=11084self.scale_by(1/self[index])108510861087def clear_denominators(self):1088r"""1089scales by the least common multiple of the denominators.10901091OUTPUT: None.10921093EXAMPLES::10941095sage: R.<t>=PolynomialRing(QQ)1096sage: P.<x,y,z>=ProjectiveSpace(FractionField(R),2)1097sage: Q=P([t,3/t^2,1])1098sage: Q.clear_denominators(); Q1099(t^3 : 3 : t^2)11001101::11021103sage: R.<x>=PolynomialRing(QQ)1104sage: K.<w>=NumberField(x^2-3)1105sage: P.<x,y,z>=ProjectiveSpace(K,2)1106sage: Q=P([1/w,3,0])1107sage: Q.clear_denominators(); Q1108(w : 9 : 0)11091110::11111112sage: P.<x,y,z>=ProjectiveSpace(QQ,2)1113sage: X=P.subscheme(x^2-y^2);1114sage: Q=X([1/2,1/2,1]);1115sage: Q.clear_denominators(); Q1116(1 : 1 : 2)1117"""1118self.scale_by(lcm([self[i].denominator() for i in range(self.codomain().ambient_space().dimension_relative())]))11191120class SchemeMorphism_point_projective_finite_field(SchemeMorphism_point_projective_field):11211122def __hash__(self):1123r"""1124Returns the integer hash of ``self``112511261127OUTPUT:11281129- integer11301131EXAMPLES::11321133sage: P.<x,y,z>=ProjectiveSpace(GF(5),2)1134sage: hash(P(2,1,2))11354111361137::11381139sage: P.<x,y,z>=ProjectiveSpace(GF(7),2)1140sage: X=P.subscheme(x^2-y^2)1141sage: hash(X(1,1,2))11428111431144::11451146sage: P.<x,y>=ProjectiveSpace(GF(13),1)1147sage: hash(P(3,4))11481711491150::11511152sage: P.<x,y>=ProjectiveSpace(GF(13^3,'t'),1)1153sage: hash(P(3,4))115422011155"""1156p=self.codomain().base_ring().order()1157N=self.codomain().ambient_space().dimension_relative()1158return sum(hash(self[i])*p**i for i in range(N+1))11591160def orbit_structure(self,f):1161r"""1162Every points is preperiodic over a finite field. This funtion returns the pair `[m,n]` where `m` is the1163preperiod and `n` the period of the point `P` by ``self``.11641165INPUT:11661167- ``f`` -- a :class:`ScemeMorphism_polynomial` with ``self`` in ``f.domain()``11681169OUTPUT:11701171- a list `[m,n]` of integers11721173EXAMPLES::11741175sage: P.<x,y,z>=ProjectiveSpace(GF(5),2)1176sage: H=Hom(P,P)1177sage: f=H([x^2+y^2,y^2,z^2 + y*z])1178sage: P(1,0,1).orbit_structure(f)1179[0, 1]11801181::11821183sage: P.<x,y,z>=ProjectiveSpace(GF(17),2)1184sage: X=P.subscheme(x^2-y^2)1185sage: H=Hom(X,X)1186sage: f=H([x^2,y^2,z^2])1187sage: X(1,1,2).orbit_structure(f)1188[3, 1]11891190::11911192sage: R.<t> = GF(13^3)1193sage: P.<x,y>=ProjectiveSpace(R,1)1194sage: H=Hom(P,P)1195sage: f=H([x^2-y^2,y^2])1196sage: P(t,4).orbit_structure(f)1197[11, 6]1198"""1199Orbit=[]1200index=11201P=copy(self)1202P.normalize_coordinates()1203F=copy(f)1204F.normalize_coordinates()1205while not P in Orbit:1206Orbit.append(P)1207P=F(P)1208P.normalize_coordinates()1209index+=11210I=Orbit.index(P)1211return([I,index-I-1])12121213#*******************************************************************1214# Abelian varieties1215#*******************************************************************1216class SchemeMorphism_point_abelian_variety_field(AdditiveGroupElement, SchemeMorphism_point_projective_field):1217"""1218A rational point of an abelian variety over a field.12191220EXAMPLES::12211222sage: E = EllipticCurve([0,0,1,-1,0])1223sage: origin = E(0)1224sage: origin.domain()1225Spectrum of Rational Field1226sage: origin.codomain()1227Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field1228"""1229pass1230123112321233