# Points on projective varieties#

Scheme morphism for points on projective varieties

AUTHORS:

• David Kohel, William Stein

• William Stein (2006-02-11): fixed bug where P(0,0,0) was allowed as a projective point.

• Volker Braun (2011-08-08): Renamed classes, more documentation, misc cleanups.

• Ben Hutz (June 2012) added support for projective ring; (March 2013) iteration functionality and new directory structure for affine/projective, height functionality

class sage.schemes.projective.projective_point.SchemeMorphism_point_abelian_variety_field(X, v, check=True)#

A rational point of an abelian variety over a field.

EXAMPLES:

sage: E = EllipticCurve([0,0,1,-1,0])
sage: origin = E(0)
sage: origin.domain()
Spectrum of Rational Field
sage: origin.codomain()
Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field

class sage.schemes.projective.projective_point.SchemeMorphism_point_projective_field(X, v, check=True)#

A rational point of projective space over a field.

INPUT:

• X – a homset of a subscheme of an ambient projective space over a field $$K$$.

• v – a list or tuple of coordinates in $$K$$.

• check – boolean (optional, default:True). Whether to check the input for consistency.

EXAMPLES:

sage: P = ProjectiveSpace(3, RR)
sage: P(2, 3, 4, 5)
(0.400000000000000 : 0.600000000000000 : 0.800000000000000 : 1.00000000000000)

clear_denominators()#

scales by the least common multiple of the denominators.

OUTPUT: None.

EXAMPLES:

sage: R.<t> = PolynomialRing(QQ)
sage: P.<x,y,z> = ProjectiveSpace(FractionField(R), 2)
sage: Q = P([t, 3/t^2, 1])
sage: Q.clear_denominators(); Q
(t^3 : 3 : t^2)

sage: R.<x> = PolynomialRing(QQ)
sage: K.<w> = NumberField(x^2 - 3)                                          # optional - sage.rings.number_field
sage: P.<x,y,z> = ProjectiveSpace(K, 2)                                     # optional - sage.rings.number_field
sage: Q = P([1/w, 3, 0])                                                    # optional - sage.rings.number_field
sage: Q.clear_denominators(); Q                                             # optional - sage.rings.number_field
(w : 9 : 0)

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: X = P.subscheme(x^2 - y^2)
sage: Q = X([1/2, 1/2, 1])
sage: Q.clear_denominators(); Q
(1 : 1 : 2)

sage: PS.<x,y> = ProjectiveSpace(QQ, 1)
sage: Q = PS.point([1, 2/3], False); Q
(1 : 2/3)
sage: Q.clear_denominators(); Q
(3 : 2)

intersection_multiplicity(X)#

Return the intersection multiplicity of the codomain of this point and X at this point.

This uses the intersection_multiplicity implementations for projective/affine subschemes. This point must be a point of a projective subscheme.

INPUT:

• X – a subscheme in the same ambient space as that of the codomain of this point.

OUTPUT: Integer.

EXAMPLES:

sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: X = P.subscheme([x*z - y^2])
sage: Y = P.subscheme([x^3 - y*w^2 + z*w^2, x*y - z*w])
sage: Q1 = X([1/2, 1/4, 1/8, 1])
sage: Q1.intersection_multiplicity(Y)
1
sage: Q2 = X([0,0,0,1])
sage: Q2.intersection_multiplicity(Y)
5
sage: Q3 = X([0,0,1,0])
sage: Q3.intersection_multiplicity(Y)
6

sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: X = P.subscheme([x^2 - y^2])
sage: Q = P([1,1,1,0])
sage: Q.intersection_multiplicity(X)
Traceback (most recent call last):
...
TypeError: this point must be a point on a projective subscheme

multiplicity()#

Return the multiplicity of this point on its codomain.

Uses the subscheme multiplicity implementation. This point must be a point on a projective subscheme.

OUTPUT: an integer.

EXAMPLES:

sage: P.<x,y,z,w,t> = ProjectiveSpace(QQ, 4)
sage: X = P.subscheme([y^6 - x^3*w^2*t + t^5*w, x^2 - t^2])
sage: Q1 = X([1,0,2,1,1])
sage: Q1.multiplicity()
1
sage: Q2 = X([0,0,-2,1,0])
sage: Q2.multiplicity()
8

normalize_coordinates()#

Normalizes the point so that the last non-zero coordinate is $$1$$.

OUTPUT: None.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(GF(5), 2)                                 # optional - sage.rings.finite_rings
sage: Q = P.point([GF(5)(1), GF(5)(3), GF(5)(0)], False); Q                 # optional - sage.rings.finite_rings
(1 : 3 : 0)
sage: Q.normalize_coordinates(); Q                                          # optional - sage.rings.finite_rings
(2 : 1 : 0)

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: X = P.subscheme(x^2 - y^2);
sage: Q = X.point([23, 23, 46], False); Q
(23 : 23 : 46)
sage: Q.normalize_coordinates(); Q
(1/2 : 1/2 : 1)

class sage.schemes.projective.projective_point.SchemeMorphism_point_projective_finite_field(X, v, check=True)#
class sage.schemes.projective.projective_point.SchemeMorphism_point_projective_ring(X, v, check=True)#

A rational point of projective space over a ring.

INPUT:

• X – a homset of a subscheme of an ambient projective space over a ring $$K$$.

• v – a list or tuple of coordinates in $$K$$.

• check – boolean (optional, default:True). Whether to check the input for consistency.

EXAMPLES:

sage: P = ProjectiveSpace(2, ZZ)
sage: P(2,3,4)
(2 : 3 : 4)

dehomogenize(n)#

Dehomogenizes at the nth coordinate.

INPUT:

• n – non-negative integer.

OUTPUT:

• SchemeMorphism_point_affine.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: X = P.subscheme(x^2 - y^2)
sage: Q = X(23, 23, 46)
sage: Q.dehomogenize(2)
(1/2, 1/2)

sage: R.<t> = PolynomialRing(QQ)
sage: S = R.quo(R.ideal(t^3))
sage: P.<x,y,z> = ProjectiveSpace(S, 2)
sage: Q = P(t, 1, 1)
sage: Q.dehomogenize(1)
(tbar, 1)

sage: P.<x,y,z> = ProjectiveSpace(GF(5), 2)                                 # optional - sage.rings.finite_rings
sage: Q = P(1, 3, 1)                                                        # optional - sage.rings.finite_rings
sage: Q.dehomogenize(0)                                                     # optional - sage.rings.finite_rings
(3, 1)

sage: P.<x,y,z> = ProjectiveSpace(GF(5), 2)                                 # optional - sage.rings.finite_rings
sage: Q = P(1, 3, 0)                                                        # optional - sage.rings.finite_rings
sage: Q.dehomogenize(2)                                                     # optional - sage.rings.finite_rings
Traceback (most recent call last):
...
ValueError: can...t dehomogenize at 0 coordinate

global_height(prec=None)#

Return the absolute logarithmic height of the point.

INPUT:

• prec – desired floating point precision (default: default RealField precision).

OUTPUT:

• a real number.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: Q = P.point([4, 4, 1/30])
sage: Q.global_height()
4.78749174278205

sage: P.<x,y,z> = ProjectiveSpace(ZZ, 2)
sage: Q = P([4, 1, 30])
sage: Q.global_height()
3.40119738166216

sage: R.<x> = PolynomialRing(QQ)
sage: k.<w> = NumberField(x^2 + 5)                                          # optional - sage.rings.number_field
sage: A = ProjectiveSpace(k, 2, 'z')                                        # optional - sage.rings.number_field
sage: A([3, 5*w + 1, 1]).global_height(prec=100)                            # optional - sage.rings.number_field
2.4181409534757389986565376694

sage: P.<x,y,z> = ProjectiveSpace(QQbar, 2)                                 # optional - sage.rings.number_field
sage: Q = P([QQbar(sqrt(3)), QQbar(sqrt(-2)), 1])                           # optional - sage.rings.number_field
sage: Q.global_height()                                                     # optional - sage.rings.number_field
0.549306144334055

sage: K = UniversalCyclotomicField()                                        # optional - sage.rings.number_field
sage: P.<x,y,z> = ProjectiveSpace(K, 2)                                     # optional - sage.rings.number_field
sage: Q = P.point([K(4/3), K.gen(7), K.gen(5)])                             # optional - sage.rings.number_field
sage: Q.global_height()                                                     # optional - sage.rings.number_field
1.38629436111989

is_preperiodic(f, err=0.1, return_period=False)#

Determine if the point is preperiodic with respect to the map f.

This is implemented for both projective space and subschemes. There are two optional keyword arguments: error_bound sets the error_bound used in the canonical height computation and return_period a boolean which controls if the period is returned if the point is preperiodic. If return_period is True and this point is not preperiodic, then $$(0,0)$$ is returned for the period.

ALGORITHM:

We know that a point is preperiodic if and only if it has canonical height zero. However, we can only compute the canonical height up to numerical precision. This function first computes the canonical height of the point to the given error bound. If it is larger than that error bound, then it must not be preperiodic. If it is less than the error bound, then we expect preperiodic. In this case we begin computing the orbit stopping if either we determine the orbit is finite, or the height of the point is large enough that it must be wandering. We can determine the height cutoff by computing the height difference constant, i.e., the bound between the height and the canonical height of a point (which depends only on the map and not the point itself). If the height of the point is larger than the difference bound, then the canonical height cannot be zero so the point cannot be preperiodic.

INPUT:

• f – an endomorphism of this point’s codomain.

kwds:

• err – a positive real number (optional - default: 0.1).

• return_period – boolean (optional - default: False).

OUTPUT:

• boolean – True if preperiodic.

• if return_period is True, then (0,0) if wandering, and (m,n) if preperiod m and period n.

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ, 1)
sage: f = DynamicalSystem_projective([x^3 - 3*x*y^2, y^3], domain=P)
sage: Q = P(-1, 1)
sage: Q.is_preperiodic(f)
True

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: X = P.subscheme(z)
sage: f = DynamicalSystem([x^2 - y^2, y^2, z^2], domain=X)
sage: p = X((-1, 1, 0))
sage: p.is_preperiodic(f, return_period=True)
(0, 2)

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: f = DynamicalSystem_projective([x^2 - 29/16*y^2, y^2], domain=P)
sage: Q = P(1, 4)
sage: Q.is_preperiodic(f, return_period=True)
(1, 3)
sage: Q = P(1, 1)
sage: Q.is_preperiodic(f, return_period=True)
(0, 0)

sage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^2 + 1)                                          # optional - sage.rings.number_field
sage: P.<x,y> = ProjectiveSpace(K, 1)                                       # optional - sage.rings.number_field
sage: f = DynamicalSystem_projective([x^5 + 5/4*x*y^4, y^5], domain=P)      # optional - sage.rings.number_field
sage: Q = P([-1/2*a + 1/2, 1])                                              # optional - sage.rings.number_field
sage: Q.is_preperiodic(f)                                                   # optional - sage.rings.number_field
True
sage: Q = P([a, 1])                                                         # optional - sage.rings.number_field
sage: Q.is_preperiodic(f)                                                   # optional - sage.rings.number_field
False

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: f = DynamicalSystem_projective([
....:         -38/45*x^2 + (2*y - 7/45*z)*x + (-1/2*y^2 - 1/2*y*z + z^2),
....:         -67/90*x^2 + (2*y + z*157/90)*x - y*z,
....:         z^2
....:     ], domain=P)
sage: Q = P([1, 3, 1])
sage: Q.is_preperiodic(f, return_period=True)
(0, 9)

sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: f = DynamicalSystem_projective([
....:         (-y - w)*x + (-13/30*y^2 + 13/30*w*y + w^2),
....:         -1/2*x^2 + (-y + 3/2*w)*x + (-1/3*y^2 + 4/3*w*y),
....:         -3/2*z^2 + 5/2*z*w + w^2,
....:         w^2
....:     ], domain=P)
sage: Q = P([3,0,4/3,1])
sage: Q.is_preperiodic(f, return_period=True)
(2, 24)

sage: from sage.misc.verbose import set_verbose
sage: set_verbose(-1)
sage: P.<x,y,z> = ProjectiveSpace(QQbar, 2)                                 # optional - sage.rings.number_field
sage: f = DynamicalSystem_projective([x^2, QQbar(sqrt(-1))*y^2, z^2],       # optional - sage.rings.number_field sage.symbolic
....:                                domain=P)
sage: Q = P([1, 1, 1])                                                      # optional - sage.rings.number_field sage.symbolic
sage: Q.is_preperiodic(f)                                                   # optional - sage.rings.number_field sage.symbolic
True

sage: set_verbose(-1)
sage: P.<x,y,z> = ProjectiveSpace(QQbar, 2)                                 # optional - sage.rings.number_field
sage: f = DynamicalSystem_projective([x^2, y^2, z^2], domain=P)             # optional - sage.rings.number_field
sage: Q = P([QQbar(sqrt(-1)), 1, 1])                                        # optional - sage.rings.number_field sage.symbolic
sage: Q.is_preperiodic(f)                                                   # optional - sage.rings.number_field sage.symbolic
True

sage: P.<x,y> = ProjectiveSpace(QQ, 1)
sage: f = DynamicalSystem_projective([16*x^2 - 29*y^2, 16*y^2], domain=P)
sage: Q = P(-1,4)
sage: Q.is_preperiodic(f)
True

sage: P.<x,y,z> = ProjectiveSpace(GF(3), 2)                                 # optional - sage.rings.finite_rings
sage: F = DynamicalSystem([x^2 - 2*y^2, y^2, z^2])                          # optional - sage.rings.finite_rings
sage: Q = P(1, 1, 1)                                                        # optional - sage.rings.finite_rings
sage: Q.is_preperiodic(F, return_period=True)                               # optional - sage.rings.finite_rings
(1, 1)

local_height(v, prec=None)#

Returns the maximum of the local height of the coordinates of this point.

INPUT:

• v – a prime or prime ideal of the base ring.

• prec – desired floating point precision (default: default RealField precision).

OUTPUT:

• a real number.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: Q = P.point([4, 4, 1/150], False)
sage: Q.local_height(5)
3.21887582486820

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: Q = P([4, 1, 30])
sage: Q.local_height(2)
0.693147180559945

local_height_arch(i, prec=None)#

Returns the maximum of the local heights at the i-th infinite place of this point.

INPUT:

• i – an integer.

• prec – desired floating point precision (default: default RealField precision).

OUTPUT:

• a real number.

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
sage: Q = P.point([4, 4, 1/150], False)
sage: Q.local_height_arch(0)
1.38629436111989

sage: P.<x,y,z> = ProjectiveSpace(QuadraticField(5, 'w'), 2)                # optional - sage.rings.number_field
sage: Q = P.point([4, 1, 30], False)                                        # optional - sage.rings.number_field
sage: Q.local_height_arch(1)                                                # optional - sage.rings.number_field
3.401197381662155375413236691607

multiplier(f, n, check=True)#

Returns the multiplier of this point of period n by the function f.

f must be an endomorphism of projective space.

INPUT:

• f - a endomorphism of this point’s codomain.

• n - a positive integer, the period of this point.

• check – check if P is periodic of period n, Default:True.

OUTPUT:

• a square matrix of size self.codomain().dimension_relative() in the base_ring of this point.

EXAMPLES:

sage: P.<x,y,z,w> = ProjectiveSpace(QQ, 3)
sage: f = DynamicalSystem_projective([x^2, y^2, 4*w^2, 4*z^2], domain=P)
sage: Q = P.point([4, 4, 1, 1], False)
sage: Q.multiplier(f, 1)
[ 2  0 -8]
[ 0  2 -8]
[ 0  0 -2]

normalize_coordinates()#

Removes the gcd from the coordinates of this point (including $$-1$$).

Warning

The gcd will depend on the base ring.

OUTPUT: None.

EXAMPLES:

sage: P = ProjectiveSpace(ZZ, 2, 'x')
sage: p = P([-5, -15, -20])
sage: p.normalize_coordinates(); p
(1 : 3 : 4)

sage: P = ProjectiveSpace(Zp(7), 2, 'x')                                    # optional - sage.rings.padics
sage: p = P([-5, -15, -2])                                                  # optional - sage.rings.padics
sage: p.normalize_coordinates(); p                                          # optional - sage.rings.padics
(5 + O(7^20) : 1 + 2*7 + O(7^20) : 2 + O(7^20))

sage: R.<t> = PolynomialRing(QQ)
sage: P = ProjectiveSpace(R, 2, 'x')
sage: p = P([3/5*t^3, 6*t, t])
sage: p.normalize_coordinates(); p
(3/5*t^2 : 6 : 1)

sage: P.<x,y> = ProjectiveSpace(Zmod(20), 1)
sage: Q = P(3, 6)
sage: Q.normalize_coordinates()
sage: Q
(1 : 2)


Since the base ring is a polynomial ring over a field, only the gcd $$c$$ is removed.

sage: R.<c> = PolynomialRing(QQ)
sage: P = ProjectiveSpace(R, 1)
sage: Q = P(2*c, 4*c)
sage: Q.normalize_coordinates();Q
(2 : 4)


A polynomial ring over a ring gives the more intuitive result.

sage: R.<c> = PolynomialRing(ZZ)
sage: P = ProjectiveSpace(R, 1)
sage: Q = P(2*c, 4*c)
sage: Q.normalize_coordinates();Q
(1 : 2)

sage: R.<t> = PolynomialRing(QQ, 1)
sage: S = R.quotient_ring(R.ideal(t^3))
sage: P.<x,y> = ProjectiveSpace(S, 1)
sage: Q = P(t + 1, t^2 + t)
sage: Q.normalize_coordinates()
sage: Q
(1 : tbar)

scale_by(t)#

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.

INPUT:

• t – a ring element.

OUTPUT: None.

EXAMPLES:

sage: R.<t> = PolynomialRing(QQ)
sage: P = ProjectiveSpace(R, 2, 'x')
sage: p = P([3/5*t^3, 6*t, t])
sage: p.scale_by(1/t); p
(3/5*t^2 : 6 : 1)

sage: R.<t> = PolynomialRing(QQ)
sage: S = R.quo(R.ideal(t^3))
sage: P.<x,y,z> = ProjectiveSpace(S, 2)
sage: Q = P(t, 1, 1)
sage: Q.scale_by(t);Q
(tbar^2 : tbar : tbar)

sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: Q = P(2, 2, 2)
sage: Q.scale_by(1/2);Q
(1 : 1 : 1)