Path: blob/master/src/sage/schemes/affine/affine_point.py
8820 views
r"""1Points on affine varieties23Scheme morphism for points on affine varieties4567AUTHORS:89- David Kohel, William Stein1011- Volker Braun (2011-08-08): Renamed classes, more documentation, misc12cleanups.1314- Ben Hutz (2013)15"""1617# Historical note: in trac #11599, V.B. renamed18# * _point_morphism_class -> _morphism19# * _homset_class -> _point_homset2021#*****************************************************************************22# Copyright (C) 2011 Volker Braun <[email protected]>23# Copyright (C) 2006 David Kohel <[email protected]>24# Copyright (C) 2006 William Stein <[email protected]>25#26# Distributed under the terms of the GNU General Public License (GPL)27# as published by the Free Software Foundation; either version 2 of28# the License, or (at your option) any later version.29# http://www.gnu.org/licenses/30#*****************************************************************************3132from copy import copy33from sage.categories.number_fields import NumberFields34_NumberFields = NumberFields()35from sage.rings.integer_ring import ZZ36from sage.rings.number_field.order import is_NumberFieldOrder37from sage.rings.rational_field import QQ38from sage.rings.real_mpfr import RealField39from sage.schemes.generic.morphism import (SchemeMorphism_point, SchemeMorphism, is_SchemeMorphism)40from sage.structure.sequence import Sequence4142############################################################################43# Rational points on schemes, which we view as morphisms determined44# by coordinates.45############################################################################4647class SchemeMorphism_point_affine(SchemeMorphism_point):48"""49A rational point on an affine scheme.5051INPUT:5253- ``X`` -- a subscheme of an ambient affine space over a ring `R`.5455- ``v`` -- a list/tuple/iterable of coordinates in `R`.5657- ``check`` -- boolean (optional, default:``True``). Whether to58check the input for consistency.5960EXAMPLES::6162sage: A = AffineSpace(2, QQ)63sage: A(1,2)64(1, 2)65"""66def __init__(self, X, v, check=True):67"""68The Python constructor.6970See :class:`SchemeMorphism_point_affine` for details.7172TESTS::7374sage: from sage.schemes.affine.affine_point import SchemeMorphism_point_affine75sage: A3.<x,y,z> = AffineSpace(QQ, 3)76sage: SchemeMorphism_point_affine(A3(QQ), [1,2,3])77(1, 2, 3)78"""79SchemeMorphism.__init__(self, X)80if is_SchemeMorphism(v):81v = list(v)82if check:83# Verify that there are the right number of coords84d = self.codomain().ambient_space().ngens()85if len(v) != d:86raise TypeError("Argument v (=%s) must have %s coordinates."%(v, d))87if not isinstance(v,(list,tuple)):88raise TypeError("Argument v (= %s) must be a scheme point, list, or tuple."%str(v))89# Make sure the coordinates all lie in the appropriate ring90v = Sequence(v, X.value_ring())91# Verify that the point satisfies the equations of X.92X.extended_codomain()._check_satisfies_equations(v)93self._coords = tuple(v)9495def nth_iterate(self,f,n):96r"""97Returns the point `f^n(self)`9899INPUT:100101- ``f`` -- a :class:`SchemeMorphism_polynomial` with ``self`` if ``f.domain()``102- ``n`` -- a positive integer.103104OUTPUT:105106- a point in ``f.codomain()``107108EXAMPLES::109110sage: A.<x,y>=AffineSpace(QQ,2)111sage: H=Hom(A,A)112sage: f=H([(x-2*y^2)/x,3*x*y])113sage: A(9,3).nth_iterate(f,3)114(-104975/13123, -9566667)115116::117118sage: A.<x,y>=AffineSpace(ZZ,2)119sage: X=A.subscheme([x-y^2])120sage: H=Hom(X,X)121sage: f=H([9*y^2,3*y])122sage: X(9,3).nth_iterate(f,4)123(59049, 243)124"""125if self.codomain()!=f.domain():126raise TypeError("Point is not defined over domain of function")127if f.domain() != f.codomain():128raise TypeError("Domain and Codomain of function not equal")129if n==0:130return(self)131else:132Q=f(self)133for i in range(2,n+1):134Q=f(Q)135return(Q)136137def orbit(self,f,N):138r"""139Returns the orbit of self by `f`. If `n` is an integer it returns `[self,f(self),\ldots,f^{n}(self)]`.140141If `n` is a list or tuple `n=[m,k]` it returns `[f^{m}(self),\ldots,f^{k}(self)]`.142143INPUT:144145- ``f`` -- a :class:`SchemeMorphism_polynomial` with ``self`` in ``f.domain()``146- ``n`` -- a non-negative integer or list or tuple of two non-negative integers147148OUTPUT:149150- a list of points in ``f.codomain()``151152EXAMPLES::153154sage: A.<x,y>=AffineSpace(QQ,2)155sage: H=Hom(A,A)156sage: f=H([(x-2*y^2)/x,3*x*y])157sage: A(9,3).orbit(f,3)158[(9, 3), (-1, 81), (13123, -243), (-104975/13123, -9566667)]159160::161162sage: A.<x>=AffineSpace(QQ,1)163sage: H=Hom(A,A)164sage: f=H([(x-2)/x])165sage: A(1/2).orbit(f,[1,3])166[(-3), (5/3), (-1/5)]167168::169170sage: A.<x,y>=AffineSpace(ZZ,2)171sage: X=A.subscheme([x-y^2])172sage: H=Hom(X,X)173sage: f=H([9*y^2,3*y])174sage: X(9,3).orbit(f,(0,4))175[(9, 3), (81, 9), (729, 27), (6561, 81), (59049, 243)]176"""177Q=copy(self)178if type(N)==list or type(N)==tuple:179Bounds=list(N)180else:181Bounds=[0,N]182for i in range(1,Bounds[0]+1):183Q=f(Q)184Orb=[Q]185for i in range(Bounds[0]+1,Bounds[1]+1):186Q=f(Q)187Orb.append(Q)188return(Orb)189190def global_height(self, prec=None):191r"""192Returns the logarithmic height of the point.193194INPUT:195196- ``prec`` -- desired floating point precision (default:197default RealField precision).198199OUTPUT:200201- a real number202203EXAMPLES::204205sage: P.<x,y>=AffineSpace(QQ,2)206sage: Q=P(41,1/12)207sage: Q.global_height()2083.71357206670431209210::211212sage: P=AffineSpace(ZZ,4,'x')213sage: Q=P(3,17,-51,5)214sage: Q.global_height()2153.93182563272433216217::218219sage: R.<x>=PolynomialRing(QQ)220sage: k.<w>=NumberField(x^2+5)221sage: A=AffineSpace(k,2,'z')222sage: A([3,5*w+1]).global_height(prec=100)2232.4181409534757389986565376694224225.. TODO::226227p-adic heights228229add heights to integer.pyx and remove special case230"""231if self.domain().base_ring() == ZZ:232if prec is None:233R = RealField()234else:235R = RealField(prec)236H=max([self[i].abs() for i in range(self.codomain().ambient_space().dimension_relative())])237return(R(max(H,1)).log())238if self.domain().base_ring() in _NumberFields or is_NumberFieldOrder(self.domain().base_ring()):239return(max([self[i].global_height(prec) for i in range(self.codomain().ambient_space().dimension_relative())]))240else:241raise NotImplementedError("Must be over a Numberfield or a Numberfield Order")242243class SchemeMorphism_point_affine_field(SchemeMorphism_point_affine):244pass245246class SchemeMorphism_point_affine_finite_field(SchemeMorphism_point_affine_field):247248def __hash__(self):249r"""250Returns the integer hash of ``self``251252OUTPUT:253254- integer255256EXAMPLES::257258sage: P.<x,y,z>=AffineSpace(GF(5),3)259sage: hash(P(2,1,2))26057261262::263264sage: P.<x,y,z>=AffineSpace(GF(7),3)265sage: X=P.subscheme(x^2-y^2)266sage: hash(X(1,1,2))267106268269::270271sage: P.<x,y>=AffineSpace(GF(13),2)272sage: hash(P(3,4))27355274275::276277sage: P.<x,y>=AffineSpace(GF(13^3,'t'),2)278sage: hash(P(3,4))2798791280"""281p=self.codomain().base_ring().order()282N=self.codomain().ambient_space().dimension_relative()283return sum(hash(self[i])*p**i for i in range(N))284285def orbit_structure(self,f):286r"""287Every points is preperiodic over a finite field. This funtion returns the pair `[m,n]` where `m` is the288preperiod and `n` the period of the point ``self`` by ``f``.289290INPUT:291292- ``P`` -- a point in ``self.domain()``293294OUTPUT:295296- a list `[m,n]` of integers297298EXAMPLES::299300sage: P.<x,y,z>=AffineSpace(GF(5),3)301sage: H=Hom(P,P)302sage: f=H([x^2+y^2,y^2,z^2+y*z])303sage: P(1,1,1).orbit_structure(f)304[0, 6]305306::307308sage: P.<x,y,z>=AffineSpace(GF(7),3)309sage: X=P.subscheme(x^2-y^2)310sage: H=Hom(X,X)311sage: f=H([x^2,y^2,z^2])312sage: X(1,1,2).orbit_structure(f)313[0, 2]314315::316317sage: P.<x,y>=AffineSpace(GF(13),2)318sage: H=Hom(P,P)319sage: f=H([x^2-y^2,y^2])320sage: P(3,4).orbit_structure(f)321[2, 6]322"""323Orbit=[]324index=1325P=copy(self)326F=copy(f)327while not P in Orbit:328Orbit.append(P)329P=F(P)330index+=1331I=Orbit.index(P)332return([I,index-I-1])333334335336