Morphisms on projective varieties

A morphism of schemes determined by rational functions that define what the morphism does on points in the ambient projective space.

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 (2013-03) iteration functionality and new directory structure for affine/projective, height functionality
  • Brian Stout, Ben Hutz (Nov 2013) - added minimal model functionality
class sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space(parent, polys, check=True)

Bases: sage.schemes.generic.morphism.SchemeMorphism_polynomial

A morphism of schemes determined by rational functions that define what the morphism does on points in the ambient projective space.

EXAMPLES:

sage: R.<x,y> = QQ[]
sage: P1 = ProjectiveSpace(R)
sage: H = P1.Hom(P1)
sage: H([y,2*x])
Scheme endomorphism of Projective Space of dimension 1 over Rational Field
  Defn: Defined on coordinates by sending (x : y) to
        (y : 2*x)

An example of a morphism between projective plane curves (see trac ticket #10297):

sage: P2.<x,y,z> = ProjectiveSpace(QQ,2)
sage: f = x^3+y^3+60*z^3
sage: g = y^2*z-( x^3 - 6400*z^3/3)
sage: C = Curve(f)
sage: E = Curve(g)
sage: xbar,ybar,zbar = C.coordinate_ring().gens()
sage: H = C.Hom(E)
sage: H([zbar,xbar-ybar,-(xbar+ybar)/80])
Scheme morphism:
  From: Projective Curve over Rational Field defined by x^3 + y^3 + 60*z^3
  To:   Projective Curve over Rational Field defined by -x^3 + y^2*z + 6400/3*z^3
  Defn: Defined on coordinates by sending (x : y : z) to
        (z : x - y : -1/80*x - 1/80*y)

A more complicated example:

sage: P2.<x,y,z> = ProjectiveSpace(2,QQ)
sage: P1 = P2.subscheme(x-y)
sage: H12 = P1.Hom(P2)
sage: H12([x^2,x*z, z^2])
Scheme morphism:
  From: Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
  x - y
  To:   Projective Space of dimension 2 over Rational Field
  Defn: Defined on coordinates by sending (x : y : z) to
      (y^2 : y*z : z^2)

We illustrate some error checking:

sage: R.<x,y> = QQ[]
sage: P1 = ProjectiveSpace(R)
sage: H = P1.Hom(P1)
sage: f = H([x-y, x*y])
Traceback (most recent call last):
...
ValueError: polys (=[x - y, x*y]) must be of the same degree

sage: H([x-1, x*y+x])
Traceback (most recent call last):
...
ValueError: polys (=[x - 1, x*y + x]) must be homogeneous

sage: H([exp(x),exp(y)])
Traceback (most recent call last):
...
TypeError: polys (=[e^x, e^y]) must be elements of
Multivariate Polynomial Ring in x, y over Rational Field
canonical_height(P, **kwds)

Evaluates the canonical height of P with respect to self. Must be over \(\ZZ\) or \(\QQ\).

Specify either the number of terms of the series to evaluate or, in dimension 1, the error bound required.

ALGORITHM:

The sum of the Green’s function at the archimedean place and the places of bad reduction.

INPUT:

  • P – a projective point

kwds:

  • badprimes - a list of primes of bad reduction
  • N - positive integer. number of terms of the series to use in the local green functions
  • prec - positive integer, float point or p-adic precision, default: 100
  • error_bound - a positive real number

OUTPUT:

  • a real number

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,2*x*y]);
sage: f.canonical_height(P.point([5,4]),error_bound=0.001)
2.1970553519503404898926835324
sage: f.canonical_height(P.point([2,1]),error_bound=0.001)
1.0984430632822307984974382955

Notice that preperiodic points may not be exactly 0:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2-29/16*y^2,y^2]);
sage: f.canonical_height(P.point([1,4]),N=60)
1.2024186864216154694752186858e-18
sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: X = P.subscheme(x^2-y^2);
sage: H = Hom(X,X)
sage: f = H([x^2,y^2,4*z^2]);
sage: Q = X([4,4,1])
sage: f.canonical_height(Q,badprimes=[2])
0.0013538030870311431824555314882
conjugate(M)

Conjugates self by M, i.e. \(M^{-1} \circ f \circ M\).

If possible the map will be defined over the same space as self. Otherwise, will try to coerce to the base_ring of M.

INPUT:

  • M – a square invertible matrix

OUTPUT:

  • a map from self.domain() to self.codomain().

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.conjugate(matrix([[1,2],[0,1]]))
Scheme endomorphism of Projective Space of dimension 1 over Integer Ring
  Defn: Defined on coordinates by sending (x : y) to
        (x^2 + 4*x*y + 3*y^2 : y^2)
sage: R.<x> = PolynomialRing(QQ)
sage: K.<i> = NumberField(x^2+1)
sage: P.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = Hom(P,P)
sage: f = H([x^3+y^3,y^3])
sage: f.conjugate(matrix([[i,0],[0,-i]]))
Scheme endomorphism of Projective Space of dimension 1 over Integer Ring
  Defn: Defined on coordinates by sending (x : y) to
        (-x^3 + y^3 : -y^3)
sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2,y*z])
sage: f.conjugate(matrix([[1,2,3],[0,1,2],[0,0,1]]))
Scheme endomorphism of Projective Space of dimension 2 over Integer Ring
  Defn: Defined on coordinates by sending (x : y : z) to
        (x^2 + 4*x*y + 3*y^2 + 6*x*z + 9*y*z + 7*z^2 : y^2 + 2*y*z : y*z + 2*z^2)
sage: P.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.conjugate(matrix([[2,0],[0,1/2]]))
Scheme endomorphism of Projective Space of dimension 1 over Multivariate
Polynomial Ring in x, y over Rational Field
  Defn: Defined on coordinates by sending (x : y) to
        (2*x^2 + 1/8*y^2 : 1/2*y^2)
sage: R.<x> = PolynomialRing(QQ)
sage: K.<i> = NumberField(x^2+1)
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([1/3*x^2+1/2*y^2,y^2])
sage: f.conjugate(matrix([[i,0],[0,-i]]))
Scheme endomorphism of Projective Space of dimension 1 over Multivariate
Polynomial Ring in x, y over Number Field in i with defining polynomial
x^2 + 1
  Defn: Defined on coordinates by sending (x : y) to
        ((1/3*i)*x^2 + (1/2*i)*y^2 : (-i)*y^2)
degree()

This function returns the degree of self.

The degree is defined as the degree of the homogeneous polynomials that are the coordinates of self.

OUTPUT:

  • A positive integer

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.degree()
2
sage: P.<x,y,z> = ProjectiveSpace(CC,2)
sage: H = Hom(P,P)
sage: f = H([x^3+y^3,y^2*z,z*x*y])
sage: f.degree()
3
sage: R.<t> = PolynomialRing(QQ)
sage: P.<x,y,z> = ProjectiveSpace(R,2)
sage: H = Hom(P,P)
sage: f = H([x^2+t*y^2,(2-t)*y^2,z^2])
sage: f.degree()
2
sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: X = P.subscheme(x^2-y^2)
sage: H = Hom(X,X)
sage: f = H([x^2,y^2,z^2])
sage: f.degree()
2
dehomogenize(n)

Returns the standard dehomogenization at the nth coordinate \((\frac{self[0]}{self[n]},\frac{self[1]}{self[n]},...)\).

Note that the new function is defined over the fraction field of the base ring of self.

INPUT:

  • n – a nonnegative integer

OUTPUT:

  • SchemeMorphism_polynomial_affine_space (on nth affine patch)

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.dehomogenize(0)
Scheme endomorphism of Affine Space of dimension 1 over Integer Ring
  Defn: Defined on coordinates by sending (x) to
        (x^2/(x^2 + 1))
sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2-z^2,2*z^2])
sage: f.dehomogenize(2)
Scheme endomorphism of Affine Space of dimension 2 over Rational Field
  Defn: Defined on coordinates by sending (x0, x1) to
        (1/2*x0^2 + 1/2*x1^2, 1/2*x1^2 - 1/2)
sage: R.<t> = PolynomialRing(QQ)
sage: P.<x,y,z> = ProjectiveSpace(FractionField(R),2)
sage: H = Hom(P,P)
sage: f = H([x^2+t*y^2,t*y^2-z^2,t*z^2])
sage: f.dehomogenize(2)
Scheme endomorphism of Affine Space of dimension 2 over Fraction Field
of Univariate Polynomial Ring in t over Rational Field
  Defn: Defined on coordinates by sending (x0, x1) to
        (1/t*x0^2 + x1^2, x1^2 - 1/t)
sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: X = P.subscheme(x^2-y^2)
sage: H = Hom(X,X)
sage: f = H([x^2,y^2,x*z])
sage: f.dehomogenize(2)
Scheme endomorphism of Closed subscheme of Affine Space of dimension 2
over Integer Ring defined by:
  x0^2 - x1^2
  Defn: Defined on coordinates by sending (x0, x1) to
        (x1^2/x0, x1^2/x0)
dynatomic_polynomial(period)

For a map \(f:\mathbb{P}^1 \to \mathbb{P}^1\) this function computes the dynatomic polynomial.

The dynatomic polynomial is the analog of the cyclotomic polynomial and its roots are the points of formal period \(period\).

ALGORITHM:

For a positive integer \(n\), let \([F_n,G_n]\) be the coordinates of the \(nth\) iterate of \(f\). Then construct

\[\Phi^{\ast}_n(f)(x,y) = \sum_{d \mid n} (yF_d(x,y) - xG_d(x,y))^{\mu(n/d)}\]

where \(\mu\) is the Moebius function.

For a pair \([m,n]\), let \(f^m = [F_m,G_m]\). Compute

\[\Phi^{\ast}_{m,n}(f)(x,y) = \Phi^{\ast}_n(f)(F_m,G_m)/\Phi^{\ast}_n(f)(F_{m-1},G_{m-1})\]

REFERENCES:

[Hutz]B. Hutz. Efficient determination of rational preperiodic points for endomorphisms of projective space. Arxiv 1210.6246, 2012.
[MoPa]P. Morton and P. Patel. The Galois theory of periodic points of polynomial maps. Proc. London Math. Soc., 68 (1994), 225-263.

INPUT:

  • period – a positive integer or a list/tuple \([m,n]\) where \(m\) is the preperiod and \(n\) is the period

OUTPUT:

  • If possible, a two variable polynomial in the coordinate ring of self. Otherwise a fraction field element of the coordinate ring of self

Todo

Do the division when the base ring is p-adic or a function field so that the output is a polynomial.

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.dynatomic_polynomial(2)
x^2 + x*y + 2*y^2
sage: P.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,x*y])
sage: f.dynatomic_polynomial(4)
2*x^12 + 18*x^10*y^2 + 57*x^8*y^4 + 79*x^6*y^6 + 48*x^4*y^8 + 12*x^2*y^10 + y^12
sage: P.<x,y> = ProjectiveSpace(CC,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,3*x*y])
sage: f.dynatomic_polynomial(3)
13.0000000000000*x^6 + 117.000000000000*x^4*y^2 +
78.0000000000000*x^2*y^4 + y^6
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2-10/9*y^2,y^2])
sage: f.dynatomic_polynomial([2,1])
x^4*y^2 - 11/9*x^2*y^4 - 80/81*y^6
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2-29/16*y^2,y^2])
sage: f.dynatomic_polynomial([2,3])
x^12 - 95/8*x^10*y^2 + 13799/256*x^8*y^4 - 119953/1024*x^6*y^6 +
8198847/65536*x^4*y^8 - 31492431/524288*x^2*y^10 +
172692729/16777216*y^12
sage: P.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = Hom(P,P)
sage: f = H([x^2-y^2,y^2])
sage: f.dynatomic_polynomial([1,2])
x^2 - x*y
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^3-y^3,3*x*y^2])
sage: f.dynatomic_polynomial([0,4])==f.dynatomic_polynomial(4)
True
sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,x*y,z^2])
sage: f.dynatomic_polynomial(2)
Traceback (most recent call last):
...
TypeError: Does not make sense in dimension >1
sage: P.<x,y> = ProjectiveSpace(Qp(5),1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.dynatomic_polynomial(2)
(x^4*y + (2 + O(5^20))*x^2*y^3 - x*y^4 + (2 + O(5^20))*y^5)/(x^2*y -
x*y^2 + y^3)

Todo

It would be nice to get this to actually be a polynomial.

sage: L.<t> = PolynomialRing(QQ)
sage: P.<x,y> = ProjectiveSpace(L,1)
sage: H = Hom(P,P)
sage: f = H([x^2+t*y^2,y^2])
sage: f.dynatomic_polynomial(2)
x^2 + x*y + (t + 1)*y^2
sage: K.<c> = PolynomialRing(ZZ)
sage: P.<x,y> = ProjectiveSpace(K,1)
sage: H = Hom(P,P)
sage: f = H([x^2+ c*y^2,y^2])
sage: f.dynatomic_polynomial([1,2])
x^2 - x*y + (c + 1)*y^2
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.dynatomic_polynomial(2)
x^2 + x*y + 2*y^2
sage: R.<X> = PolynomialRing(QQ)
sage: K.<c> = NumberField(X^2 + X + 2)
sage: PP = P.change_ring(K)
sage: ff = f.change_ring(K)
sage: p = PP((c,1))
sage: ff(ff(p)) == p
True
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,x*y])
sage: f.dynatomic_polynomial([2,2])
x^4 + 4*x^2*y^2 + y^4
sage: R.<X> = PolynomialRing(QQ)
sage: K.<c> = NumberField(X^4 + 4*X^2 + 1)
sage: PP = P.change_ring(K)
sage: ff = f.change_ring(K)
sage: p = PP((c,1))
sage: ff.nth_iterate(p,4) == ff.nth_iterate(p,2)
True
global_height(prec=None)

Returns the maximum of the heights of the coefficients in any of the coordinate functions of self.

INPUT:

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

OUTPUT:

  • a real number

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([1/1331*x^2+1/4000*y^2,210*x*y]);
sage: f.global_height()
8.29404964010203

This function does not automatically normalize:

sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: H = Hom(P,P)
sage: f = H([4*x^2+100*y^2,210*x*y,10000*z^2]);
sage: f.global_height()
9.21034037197618
sage: f.normalize_coordinates()
sage: f.global_height()
8.51719319141624
sage: R.<z> = PolynomialRing(QQ)
sage: K.<w> = NumberField(z^2-2)
sage: O = K.maximal_order()
sage: P.<x,y> = ProjectiveSpace(O,1)
sage: H = Hom(P,P)
sage: f = H([2*x^2 + 3*O(w)*y^2,O(w)*y^2])
sage: f.global_height()
1.44518587894808

Todo

add heights to integer.pyx and remove special case

green_function(P, v, **kwds)

Evaluates the local Green’s function at the place v for P with N terms of the series or, in dimension 1, to within a given error bound.

Use v=0 for the archimedean place. Must be over \(\ZZ\) or \(\QQ\).

ALGORITHM:

See Exercise 5.29 and Figure 5.6 of The Arithmetic of Dynamics Systems, Joseph H. Silverman, Springer, GTM 241, 2007.

INPUT:

  • P - a projective point
  • v - non-negative integer. a place, use v=0 for the archimedean place

kwds:

  • N - positive integer. number of terms of the series to use
  • prec - positive integer, float point or p-adic precision, default: 100
  • error_bound - a positive real number

OUTPUT:

  • a real number

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,x*y])
sage: f.green_function(P.point([5,2],False),0,N=30)
1.7315451844777407992085512000
sage: f.green_function(P.point([2,1],False),0,N=30)
0.86577259223181088325226209926
sage: f.green_function(P.point([1,1],False),0,N=30)
0.43288629610862338612700146098
height_difference_bound(prec=None)

Returns an upper bound on the different bewtween the canonical height of a point with respect to self and the height of the point. self must be a morphism.

ALGORITHM:

Uses a Nullstellensatz argument to compute the constant. For details: B. Hutz, Efficient determination of rational preperiodic points for endomorphisms of projective space, arxiv:1210.6246 (2012).

INPUT:

  • prec - positive integer, float point, default: RealField default

OUTPUT:

  • a real number

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([x^2+y^2,x*y]);
sage: f.height_difference_bound()
1.38629436111989

This function does not automatically normalize.

sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: H = End(P)
sage: f = H([4*x^2+100*y^2,210*x*y,10000*z^2]);
sage: f.height_difference_bound()
11.0020998412042
sage: f.normalize_coordinates()
sage: f.height_difference_bound()
10.7632079329219
is_PGL_minimal(prime_list=None)

Checks if self is a minimal model in its conjugacy class. See [Bruin-Molnar] and [Molnar] for a description of the algorithm.

INPUT:

  • prime_list – list of primes to check minimality, if None, check all places

OUTPUT:

  • Boolean - True if self is minimal, False otherwise.

EXAMPLES:

sage: PS.<X,Y> = ProjectiveSpace(QQ,1)
sage: H = End(PS)
sage: f = H([X^2+3*Y^2,X*Y])
sage: f.is_PGL_minimal()
True
sage: PS.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(PS)
sage: f = H([6*x^2+12*x*y+7*y^2,12*x*y])
sage: f.is_PGL_minimal()
False
sage: PS.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(PS)
sage: f = H([6*x^2+12*x*y+7*y^2,y^2])
sage: f.is_PGL_minimal()
Traceback (most recent call last):
...
TypeError: Affine minimality is only considered for maps not of the form
f or 1/f for a polynomial f.
is_morphism()

returns True if self is a morphism (no common zero of defining polynomials).

The map is a morphism if and only if the ideal generated by the defining polynomials is the unit ideal.

OUTPUT:

  • Boolean

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.is_morphism()
True
sage: P.<x,y,z> = ProjectiveSpace(RR,2)
sage: H = Hom(P,P)
sage: f = H([x*z-y*z,x^2-y^2,z^2])
sage: f.is_morphism()
False
sage: R.<t> = PolynomialRing(GF(5))
sage: P.<x,y,z> = ProjectiveSpace(R,2)
sage: H = Hom(P,P)
sage: f = H([x*z-t*y^2,x^2-y^2,t*z^2])
sage: f.is_morphism()
True
minimal_model(return_transformation=False, prime_list=None)

Given self a scheme morphism on the projective line over the rationals, determine if self is minimal. In particular, determine if self is affine minimal, which is enough to decide if it is minimal or not. See Proposition 2.10 in [Bruin-Molnar].

REFERENCES:

[Bruin-Molnar]N. Bruin and A. Molnar, Minimal models for rational functions in a dynamical setting LMS Journal of Computation and Mathematics, Volume 15 (2012), pp 400-417.
[Molnar]A. Molnar, Fractional Linear Minimal Models of Rational Functions, M.Sc. Thesis.

INPUT:

  • self – scheme morphism on the projective line defined over \(QQ\).

  • return_transformation – a boolean value, default value True. This

    signals a return of the PGL_2 transformation to conjugate self to the calculated minimal model. default: False

  • prime_list – a list of primes, in case one only wants to determine minimality

    at those specific primes.

OUTPUT:

  • a scheme morphism on the projective line which is a minimal model of self.
  • a \(PGL(2,QQ)\) element which conjugates self to a minimal model

EXAMPLES:

sage: PS.<X,Y> = ProjectiveSpace(QQ,1)
sage: H = End(PS)
sage: f = H([X^2+3*Y^2,X*Y])
sage: f.minimal_model(return_transformation=True)
(
Scheme endomorphism of Projective Space of dimension 1 over Rational
Field
  Defn: Defined on coordinates by sending (X : Y) to
        (X^2 + 3*Y^2 : X*Y)
,
[1 0]
[0 1]
)
sage: PS.<X,Y> = ProjectiveSpace(QQ,1)
sage: H = End(PS)
sage: f = H([7365/2*X^4 + 6282*X^3*Y + 4023*X^2*Y^2 + 1146*X*Y^3 + 245/2*Y^4, -12329/2*X^4 - 10506*X^3*Y - 6723*X^2*Y^2 - 1914*X*Y^3 - 409/2*Y^4])
sage: f.minimal_model(return_transformation=True)
(
Scheme endomorphism of Projective Space of dimension 1 over Rational
Field
  Defn: Defined on coordinates by sending (X : Y) to
        (22176*X^4 + 151956*X^3*Y + 390474*X^2*Y^2 + 445956*X*Y^3 +
190999*Y^4 : -12329*X^4 - 84480*X^3*Y - 217080*X^2*Y^2 - 247920*X*Y^3 -
106180*Y^4),
[2 3]
[0 1]
)
sage: PS.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(PS)
sage: f = H([6*x^2+12*x*y+7*y^2,12*x*y])
sage: f.minimal_model()
Scheme endomorphism of Projective Space of dimension 1 over Rational
Field
  Defn: Defined on coordinates by sending (x : y) to
        (x^2 + 12*x*y + 42*y^2 : 2*x*y)
sage: PS.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = End(PS)
sage: f = H([6*x^2+12*x*y+7*y^2,12*x*y + 42*y^2])
sage: g,M=f.minimal_model(return_transformation=True)
sage: f.conjugate(M)==g
True
sage: PS.<X,Y> = ProjectiveSpace(QQ,1)
sage: H = End(PS)
sage: f = H([X+Y,X-3*Y])
sage: f.minimal_model()
Traceback (most recent call last):
...
NotImplementedError: Minimality is only for degree 2 or higher
sage: PS.<X,Y> = ProjectiveSpace(QQ,1)
sage: H = End(PS)
sage: f = H([X^2-Y^2,X^2+X*Y])
sage: f.minimal_model()
Traceback (most recent call last):
...
TypeError: The function is not a morphism
multiplier(P, n, check=True)

Returns the multiplier of self at the \(QQ\)-rational point P of period n. self must be an endomorphism of projective space

INPUT:

  • P - a point on domain of self
  • n - a positive integer, the period of P
  • check – verify that P has period n, Default:True

OUTPUT:

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

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: H = End(P)
sage: f = H([x^2,y^2,4*z^2]);
sage: Q = P.point([4,4,1],False);
sage: f.multiplier(Q,1)
[2 0]
[0 2]
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([7*x^2 - 28*y^2,24*x*y])
sage: f.multiplier(P(2,5),4)
[231361/20736]
sage: P.<x,y> = ProjectiveSpace(CC,1)
sage: H = End(P)
sage: f = H([x^3 - 25*x*y^2 + 12*y^3,12*y^3])
sage: f.multiplier(P(1,1),5)
[0.389017489711935]
sage: P.<x,y> = ProjectiveSpace(RR,1)
sage: H = End(P)
sage: f = H([x^2-2*y^2,y^2])
sage: f.multiplier(P(2,1),1)
[4.00000000000000]
sage: P.<x,y> = ProjectiveSpace(Qp(13),1)
sage: H = End(P)
sage: f = H([x^2-29/16*y^2,y^2])
sage: f.multiplier(P(5,4),3)
[6 + 8*13 + 13^2 + 8*13^3 + 13^4 + 8*13^5 + 13^6 + 8*13^7 + 13^8 +
8*13^9 + 13^10 + 8*13^11 + 13^12 + 8*13^13 + 13^14 + 8*13^15 + 13^16 +
8*13^17 + 13^18 + 8*13^19 + O(13^20)]
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([x^2-y^2,y^2])
sage: f.multiplier(P(0,1),1)
Traceback (most recent call last):
...
ValueError: (0 : 1) is not periodic of period 1

Todo

would be better to keep the dehomogenizations for reuse

normalize_coordinates()

Scales by 1/gcd of the coordinate functions. Also, scales to clear any denominators from the coefficients. This is done in place.

OUTPUT:

  • None.

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([5/4*x^3,5*x*y^2])
sage: f.normalize_coordinates(); f
Scheme endomorphism of Projective Space of dimension 1 over Rational
Field
  Defn: Defined on coordinates by sending (x : y) to
        (x^2 : 4*y^2)
sage: P.<x,y,z> = ProjectiveSpace(GF(7),2)
sage: X = P.subscheme(x^2-y^2)
sage: H = Hom(X,X)
sage: f = H([x^3+x*y^2,x*y^2,x*z^2])
sage: f.normalize_coordinates(); f
Scheme endomorphism of Closed subscheme of Projective Space of dimension
2 over Finite Field of size 7 defined by:
  x^2 - y^2
  Defn: Defined on coordinates by sending (x : y : z) to
        (2*y^2 : y^2 : z^2)

Note

gcd raises an error if the base_ring does not support gcds.

nth_iterate(P, n, normalize=False)

For a map self and a point \(P\) in self.domain() this function returns the nth iterate of \(P\) by self.

If normalize is True, then the coordinates are automatically normalized.

Todo

Is there a more efficient way to do this?

INPUT:

  • P – a point in self.domain()
  • n – a positive integer.
  • normalize - Boolean (optional Default: False)

OUTPUT:

  • A point in self.codomain()

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,2*y^2])
sage: Q = P(1,1)
sage: f.nth_iterate(Q,4)
(32768 : 32768)
sage: P.<x,y> = ProjectiveSpace(ZZ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,2*y^2])
sage: Q = P(1,1)
sage: f.nth_iterate(Q,4,1)
(1 : 1)

Is this the right behavior?

sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: H = Hom(P,P)
sage: f = H([x^2,2*y^2,z^2-x^2])
sage: Q = P(2,7,1)
sage: f.nth_iterate(Q,2)
(-16/7 : -2744 : 1)
sage: R.<t> = PolynomialRing(QQ)
sage: P.<x,y,z> = ProjectiveSpace(R,2)
sage: H = Hom(P,P)
sage: f = H([x^2+t*y^2,(2-t)*y^2,z^2])
sage: Q = P(2+t,7,t)
sage: f.nth_iterate(Q,2)
(t^4 + 2507*t^3 - 6787*t^2 + 10028*t + 16 : -2401*t^3 + 14406*t^2 -
28812*t + 19208 : t^4)
sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: X = P.subscheme(x^2-y^2)
sage: H = Hom(X,X)
sage: f = H([x^2,y^2,z^2])
sage: f.nth_iterate(X(2,2,3),3)
(256 : 256 : 6561)
sage: K.<c> = FunctionField(QQ)
sage: P.<x,y> = ProjectiveSpace(K,1)
sage: H = Hom(P,P)
sage: f = H([x^3-2*x*y^2 - c*y^3,x*y^2])
sage: f.nth_iterate(P(c,1),2)
((c^6 - 9*c^4 + 25*c^2 - c - 21)/(c^2 - 3) : 1)
nth_iterate_map(n)

For a map self this function returns the nth iterate of self as a function on self.domain()

ALGORITHM:

Uses a form of successive squaring to reducing computations.

Todo

This could be improved.

INPUT:

  • n – a positive integer.

OUTPUT:

  • A map between projective spaces

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.nth_iterate_map(2)
Scheme endomorphism of Projective Space of dimension 1 over Rational
Field
  Defn: Defined on coordinates by sending (x : y) to
        (x^4 + 2*x^2*y^2 + 2*y^4 : y^4)
sage: P.<x,y> = ProjectiveSpace(CC,1)
sage: H = Hom(P,P)
sage: f = H([x^2-y^2,x*y])
sage: f.nth_iterate_map(3)
Scheme endomorphism of Projective Space of dimension 1 over Complex
Field with 53 bits of precision
  Defn: Defined on coordinates by sending (x : y) to
        (x^8 + (-7.00000000000000)*x^6*y^2 + 13.0000000000000*x^4*y^4 +
(-7.00000000000000)*x^2*y^6 + y^8 : x^7*y + (-4.00000000000000)*x^5*y^3
+ 4.00000000000000*x^3*y^5 - x*y^7)
sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: H = Hom(P,P)
sage: f = H([x^2-y^2,x*y,z^2+x^2])
sage: f.nth_iterate_map(2)
Scheme endomorphism of Projective Space of dimension 2 over Integer Ring
  Defn: Defined on coordinates by sending (x : y : z) to
        (x^4 - 3*x^2*y^2 + y^4 : x^3*y - x*y^3 : 2*x^4 - 2*x^2*y^2 + y^4
+ 2*x^2*z^2 + z^4)
sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: X = P.subscheme(x*z-y^2)
sage: H = Hom(X,X)
sage: f = H([x^2,x*z,z^2])
sage: f.nth_iterate_map(2)
Scheme endomorphism of Closed subscheme of Projective Space of dimension
2 over Rational Field defined by:
  -y^2 + x*z
  Defn: Defined on coordinates by sending (x : y : z) to
        (x^4 : x^2*z^2 : z^4)
orbit(P, N, **kwds)

Returns the orbit of \(P\) by self. If \(n\) is an integer it returns \([P,self(P),\ldots,self^n(P)]\). If \(n\) is a list or tuple \(n=[m,k]\) it returns \([self^m(P),\ldots,self^k(P)]\). Automatically normalize the points if normalize=True. Perform the checks on point initialize if check=True

INPUT:

  • P – a point in self.domain()
  • n – a non-negative integer or list or tuple of two non-negative integers

kwds:

  • check – boolean (optional - default: True)
  • normalize – boolean (optional - default: False)

OUTPUT:

  • a list of points in self.codomain()

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2-z^2,2*z^2])
sage: f.orbit(P(1,2,1),3)
[(1 : 2 : 1), (5 : 3 : 2), (34 : 5 : 8), (1181 : -39 : 128)]
sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2-z^2,2*z^2])
sage: f.orbit(P(1,2,1),[2,4])
[(34 : 5 : 8), (1181 : -39 : 128), (1396282 : -14863 : 32768)]
sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: X = P.subscheme(x^2-y^2)
sage: H = Hom(X,X)
sage: f = H([x^2,y^2,x*z])
sage: f.orbit(X(2,2,3),3,normalize=True)
[(2 : 2 : 3), (2 : 2 : 3), (2 : 2 : 3), (2 : 2 : 3)]
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2])
sage: f.orbit(P.point([1,2],False),4,check=False)
[(1 : 2), (5 : 4), (41 : 16), (1937 : 256), (3817505 : 65536)]
sage: K.<c> = FunctionField(QQ)
sage: P.<x,y> = ProjectiveSpace(K,1)
sage: H = Hom(P,P)
sage: f = H([x^2+c*y^2,y^2])
sage: f.orbit(P(0,1),3)
[(0 : 1), (c : 1), (c^2 + c : 1), (c^4 + 2*c^3 + c^2 + c : 1)]
possible_periods(**kwds)

Returns the set of possible periods for rational periodic points of self. Must be defined over \(\ZZ\) or \(\QQ\).

ALGORITHM:
Calls self.possible_periods() modulo all primes of good reduction in range prime_bound. Returns the intersection of those lists.

INPUT:

kwds:

  • prime_bound - a list or tuple of two positive integers. Or an integer for the upper bound. (optional)

    default: [1,20].

  • bad_primes - a list or tuple of integer primes, the primes of bad reduction. (optional)

OUTPUT:

  • a list of positive integers.

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([x^2-29/16*y^2,y^2])
sage: f.possible_periods()
[1, 3]
sage: PS.<x,y> = ProjectiveSpace(1,QQ)
sage: H = End(PS)
sage: f = H([5*x^3 - 53*x*y^2 + 24*y^3, 24*y^3])
sage: f.possible_periods(prime_bound=[1,5])
Traceback (most recent call last):
...
ValueError: No primes of good reduction in that range
sage: f.possible_periods(prime_bound=[1,10])
[1, 4, 12]
sage: f.possible_periods(prime_bound=[1,20])
[1, 4]
sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: H = End(P)
sage: f = H([2*x^3 - 50*x*z^2 + 24*z^3,5*y^3 - 53*y*z^2 + 24*z^3,24*z^3])
sage: f.possible_periods(prime_bound=10)
[1, 2, 6, 20, 42, 60, 140, 420]
sage: f.possible_periods(prime_bound=20) # long time
[1, 20]
primes_of_bad_reduction(check=True)

Determines the primes of bad reduction for a map \(self: \mathbb{P}^N \to \mathbb{P}^N\) defined over \(\ZZ\) or \(\QQ\).

If check is True, each prime is verified to be of bad reduction.

ALGORITHM:

\(p\) is a prime of bad reduction if and only if the defining polynomials of self have a common zero. Or stated another way, \(p\) is a prime of bad reducion if and only if the radical of the ideal defined by the defining polynomials of self is not \((x_0,x_1,\ldots,x_N)\). This happens if and only if some power of each \(x_i\) is not in the ideal defined by the defining polynomials of self. This last condition is what is checked. The lcm of the coefficients of the monomials \(x_i\) in a groebner basis is computed. This may return extra primes.

INPUT:

  • check – Boolean (optional - default: True)

OUTPUT:

  • a list of integer primes.

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([1/3*x^2+1/2*y^2,y^2])
sage: print f.primes_of_bad_reduction()
[2, 3]
sage: P.<x,y,z,w> = ProjectiveSpace(QQ,3)
sage: H = Hom(P,P)
sage: f = H([12*x*z-7*y^2,31*x^2-y^2,26*z^2,3*w^2-z*w])
sage: f.primes_of_bad_reduction()
[2, 3, 7, 13, 31]

This is an example where check=False returns extra primes:

sage: P.<x,y,z> = ProjectiveSpace(ZZ,2)
sage: H = Hom(P,P)
sage: f = H([3*x*y^2 + 7*y^3 - 4*y^2*z + 5*z^3, -5*x^3 + x^2*y + y^3 + 2*x^2*z, -2*x^2*y + x*y^2 + y^3 - 4*y^2*z + x*z^2])
sage: f.primes_of_bad_reduction(False)
[2, 5, 37, 2239, 304432717]
sage: f.primes_of_bad_reduction()
[5, 37, 2239, 304432717]
resultant(normalize=False)

Computes the resultant of the defining polynomials of self if self is a map on the projective line.

If normalize is True, then first normalize the coordinate functions with normalize_coordinates().

INPUT:

  • normalize – Boolean (optional - default: False)

OUTPUT:

  • an element of self.codomain().base_ring()

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,6*y^2])
sage: f.resultant()
36
sage: R.<t> = PolynomialRing(GF(17))
sage: P.<x,y> = ProjectiveSpace(R,1)
sage: H = Hom(P,P)
sage: f = H([t*x^2+t*y^2,6*y^2])
sage: f.resultant()
2*t^2
scale_by(t)

Scales each coordinates by a factor of \(t\).

A TypeError occurs if the point is not in the coordinate_ring of the parent after scaling.

INPUT:

  • t – a ring element

OUTPUT:

  • None.

EXAMPLES:

sage: A.<x,y> = ProjectiveSpace(QQ,1)
sage: H = Hom(A,A)
sage: f = H([x^3-2*x*y^2,x^2*y])
sage: f.scale_by(1/x)
sage: f
Scheme endomorphism of Projective Space of dimension 1 over Rational
Field
  Defn: Defined on coordinates by sending (x : y) to
        (x^2 - 2*y^2 : x*y)
sage: R.<t> = PolynomialRing(QQ)
sage: P.<x,y> = ProjectiveSpace(R,1)
sage: H = Hom(P,P)
sage: f = H([3/5*x^2,6*y^2])
sage: f.scale_by(5/3*t); f
Scheme endomorphism of Projective Space of dimension 1 over Univariate
Polynomial Ring in t over Rational Field
  Defn: Defined on coordinates by sending (x : y) to
        (t*x^2 : 10*t*y^2)
sage: P.<x,y,z> = ProjectiveSpace(GF(7),2)
sage: X = P.subscheme(x^2-y^2)
sage: H = Hom(X,X)
sage: f = H([x^2,y^2,z^2])
sage: f.scale_by(x-y);f
Scheme endomorphism of Closed subscheme of Projective Space of dimension
2 over Finite Field of size 7 defined by:
  x^2 - y^2
  Defn: Defined on coordinates by sending (x : y : z) to
        (x*y^2 - y^3 : x*y^2 - y^3 : x*z^2 - y*z^2)
class sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space_field(parent, polys, check=True)

Bases: sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space

The Python constructor.

See SchemeMorphism_polynomial for details.

EXAMPLES:

sage: P1.<x,y> = ProjectiveSpace(QQ,1)
sage: H = P1.Hom(P1)
sage: H([y,2*x])
Scheme endomorphism of Projective Space of dimension 1 over Rational Field
  Defn: Defined on coordinates by sending (x : y) to
        (y : 2*x)
all_rational_preimages(points)

Given a set of rational points in the domain of self, return all the rational pre-images of those points. In others words, all the rational points which have some iterate in the set points. This function repeatedly calls rational_preimages. If the degree is at least two, by Northocott, this is always a finite set. self must be defined over \(\QQ\) and be an endomorphism of projective space. In the examples, the output is sorted because the calculations are done in parallel and the order of the results is not guaranteed.

INPUT:

  • points - a list of rational points in the domain of self

OUTPUT:

  • a list of rational points in the domain of self.

Examples:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([16*x^2 - 29*y^2,16*y^2])
sage: sorted(f.all_rational_preimages([P(-1,4)]))
[(-7/4 : 1), (-5/4 : 1), (-3/4 : 1), (-1/4 : 1), (1/4 : 1), (3/4 : 1),
(5/4 : 1), (7/4 : 1)]
sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: H = End(P)
sage: f = H([76*x^2 - 180*x*y + 45*y^2 + 14*x*z + 45*y*z - 90*z^2, 67*x^2 - 180*x*y - 157*x*z + 90*y*z, -90*z^2])
sage: sorted(f.all_rational_preimages([P(-9,-4,1)]))
[(-9 : -4 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 1), (0 : 4 : 1), (1
: 0 : 1), (1 : 1 : 1), (1 : 2 : 1), (1 : 3 : 1)]
A non-periodic example.
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([x^2 + y^2,2*x*y])
sage: sorted(f.all_rational_preimages([P(17,15)]))
[(1/3 : 1), (3/5 : 1), (5/3 : 1), (3 : 1)]
lift_to_rational_periodic(points_modp, B=None)

Given a list of points in projective space over \(GF(p)\), determine if they lift to \(\QQ\)-rational periodic points. self must be an endomorphism of projective space defined over \(\QQ\)

ALGORITHM:

Use Hensel lifting to find a \(p\)-adic approximation for that rational point. The accuracy needed is determined by the height bound \(B\). Then apply the the LLL algorithm to determine if the lift corresponds to a rational point.

If the point is a point of high multiplicity (multiplier 1) then procedure can be very slow.

INPUT:

  • points_modp - a list or tuple of pairs containing a point in projective space over \(GF(p)\) and the possible period.
  • B - a positive integer - the height bound for a rational preperiodic point. (optional)

OUTPUT:

  • a list of projective points.

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([x^2 - y^2,y^2])
sage: f.lift_to_rational_periodic([[P(0,1).change_ring(GF(7)),4]])
[[(0 : 1), 2]]
There may be multiple points in the lift.
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([-5*x^2 + 4*y^2,4*x*y])
sage: f.lift_to_rational_periodic([[P(1,0).change_ring(GF(3)),1]]) # long time
[[(1 : 0), 1], [(2/3 : 1), 1], [(-2/3 : 1), 1]]
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([16*x^2 - 29*y^2,16*y^2])
sage: f.lift_to_rational_periodic([[P(3,1).change_ring(GF(13)), 3]])
[[(-1/4 : 1), 3]]
sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: H = End(P)
sage: f = H([76*x^2 - 180*x*y + 45*y^2 + 14*x*z + 45*y*z - 90*z^2, 67*x^2 - 180*x*y - 157*x*z + 90*y*z, -90*z^2])
sage: f.lift_to_rational_periodic([[P(14,19,1).change_ring(GF(23)), 9]]) # long time
[[(-9 : -4 : 1), 9]]
rational_periodic_points(**kwds)

Determine the set of rational periodic points for self an endomorphism of projective space. Must be defined over \(\QQ\).

The default parameter values are typically good choices for \(\mathbb{P}^1\). If you are having trouble getting a partiuclar map to finish, try first computing the possible periods, then try various different lifting_prime.

ALGORITHM:

Modulo each prime of good reduction \(p\) determine the set of periodic points modulo \(p\). For each cycle modulo \(p\) compute the set of possible periods (\(mrp^e\)). Take the intersection of the list of possible periods modulo several primes of good reduction to get a possible list of minimal periods of rational periodic points. Take each point modulo \(p\) associated to each of these possible periods and try to lift it to a rational point with a combination of \(p\)-adic approximation and the LLL basis reducion algorithm.

See B. Hutz, Determination of all rational preperiodic points for morphisms of Pn, submitted, 2012.

INPUT:

kwds:

  • prime_bound - a pair (list or tuple) of positive integers that represent the

    limits of primes to use in the reduction step. Or an integer that represents the upper bound. (optional) default: [1,20]

  • lifting_prime - a prime integer. (optional) argument that specifies modulo which prime to try and perform the

    lifting. default: 23

  • periods - a list of positive integers which is the list of possible periods. (optional)

  • bad_primes - a list or tuple of integer primes, the primes of bad reduction. (optional)

OUTPUT:

  • a list of rational points in projective space.

Examples:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([x^2-3/4*y^2,y^2])
sage: sorted(f.rational_periodic_points(prime_bound=20,lifting_prime=7)) # long time
[(-1/2 : 1), (1 : 0), (3/2 : 1)]
sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: H = End(P)
sage: f = H([2*x^3 - 50*x*z^2 + 24*z^3,5*y^3 - 53*y*z^2 + 24*z^3,24*z^3])
sage: sorted(f.rational_periodic_points(prime_bound=[1,20])) # long time
[(-3 : -1 : 1), (-3 : 0 : 1), (-3 : 1 : 1), (-3 : 3 : 1), (-1 : -1 : 1),
(-1 : 0 : 1), (-1 : 1 : 1), (-1 : 3 : 1), (0 : 1 : 0), (1 : -1 : 1), (1
: 0 : 0), (1 : 0 : 1), (1 : 1 : 1), (1 : 3 : 1), (3 : -1 : 1), (3 : 0 :
1), (3 : 1 : 1), (3 : 3 : 1), (5 : -1 : 1), (5 : 0 : 1), (5 : 1 : 1), (5
: 3 : 1)]
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([-5*x^2 + 4*y^2,4*x*y])
sage: sorted(f.rational_periodic_points()) # long time
[(-2 : 1), (-2/3 : 1), (2/3 : 1), (1 : 0), (2 : 1)]

Todo

  • move some of this to Cython so that it is faster especially the possible periods mod \(p\).
  • have the last prime of good redution used also return the list of points instead of getting the information again for all_points.
rational_preimages(Q)

Given a rational point \(Q\) in the domain of self, return all the rational points \(P\) in the domain of self with \(self(P)==Q\). In other words, the set of first pre-images of \(Q\). self must be defined over \(\QQ\) and be an endomorphism of projective space.

ALGORITHM:
Use elimination via groebner bases to find the rational pre-images

INPUT:

  • Q - a rational point in the domain of self.

OUTPUT:

  • a list of rational points in the domain of self.

Examples:

sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([16*x^2 - 29*y^2,16*y^2])
sage: f.rational_preimages(P(-1,4))
[(5/4 : 1), (-5/4 : 1)]
sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
sage: H = End(P)
sage: f = H([76*x^2 - 180*x*y + 45*y^2 + 14*x*z + 45*y*z - 90*z^2, 67*x^2 - 180*x*y - 157*x*z + 90*y*z, -90*z^2])
sage: f.rational_preimages(P(-9,-4,1))
[(0 : 4 : 1)]
A non-periodic example.
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([x^2 + y^2,2*x*y])
sage: f.rational_preimages(P(17,15))
[(5/3 : 1), (3/5 : 1)]
sage: P.<x,y,z,w> = ProjectiveSpace(QQ,3)
sage: H = End(P)
sage: f = H([x^2 - 2*y*w - 3*w^2, -2*x^2 + y^2 - 2*x*z + 4*y*w + 3*w^2, x^2 - y^2 + 2*x*z + z^2 - 2*y*w - w^2, w^2])
sage: f.rational_preimages(P(0,-1,0,1))
[]
sage: P.<x,y> = ProjectiveSpace(QQ,1)
sage: H = End(P)
sage: f = H([x^2 + y^2,2*x*y])
sage: f.rational_preimages([CC.0,1])
Traceback (most recent call last):
...
TypeError: Point must be in codomain of self
rational_preperiodic_graph(**kwds)

Determines the set of rational preperiodic points for self. self must be defined over \(\QQ\) and be an endomorphism of projective space.

ALGORITHM: - Determines the list of possible periods.

  • Determines the rational periodic points from the possible periods.
  • Determines the rational preperiodic points from the rational periodic points by determining rational preimages.

INPUT:

kwds:

  • prime_bound - a pair (list or tuple) of positive integers that represent the

    limits of primes to use in the reduction step. Or an integer that represents the upper bound. (optional) default: [1,20]

  • lifting_prime - a prime integer. (optional) argument that specifies modulo which prime to try and perform the

    lifting. default: 23

  • periods - a list of positive integers which is the list of possible periods. (optional)

  • bad_primes - a list or tuple of integer primes, the primes of bad reduction. (optional)

OUTPUT:

  • a digraph representing the orbits of the rational preperiodic points in projective space.

Examples:

sage: PS.<x,y> = ProjectiveSpace(1,QQ)
sage: H = End(PS)
sage: f = H([7*x^2 - 28*y^2,24*x*y])
sage: f.rational_preperiodic_graph()
Looped digraph on 12 vertices
sage: PS.<x,y> = ProjectiveSpace(1,QQ)
sage: H = End(PS)
sage: f = H([-3/2*x^3 +19/6*x*y^2,y^3])
sage: f.rational_preperiodic_graph(prime_bound=[1,8])
Looped digraph on 12 vertices
sage: PS.<x,y,z> = ProjectiveSpace(2,QQ)
sage: H = End(PS)
sage: f = H([2*x^3 - 50*x*z^2 + 24*z^3,5*y^3 - 53*y*z^2 + 24*z^3,24*z^3])
sage: f.rational_preperiodic_graph(prime_bound=[1,11],lifting_prime=13) # long time
Looped digraph on 30 vertices
rational_preperiodic_points(**kwds)

Determined the set of rational preperiodic points for self. self must be defined over \(\QQ\) and be an endomorphism of projective space.

The default parameter values are typically good choices for \(\mathbb{P}^1\). If you are having trouble getting a partiuclar map to finish, try first computing the possible periods, then try various different lifting_prime.

ALGORITHM:

  • Determines the list of possible periods.
  • Determines the rational periodic points from the possible periods.
  • Determines the rational preperiodic points from the rational periodic points by determining rational preimages.

INPUT:

kwds:

  • prime_bound - a pair (list or tuple) of positive integers that represent the limits of primes to use in the reduction step. Or an integer that represents the upper bound. (optional) default: [1,20]
  • lifting_prime - a prime integer. (optional) argument that specifies modulo which prime to try and perform the lifting. default: 23
  • periods - a list of positive integers which is the list of possible periods. (optional)
  • bad_primes - a list or tuple of integer primes, the primes of bad reduction. (optional)

OUTPUT:

  • a list of rational points in projective space.

Examples:

sage: PS.<x,y> = ProjectiveSpace(1,QQ)
sage: H = End(PS)
sage: f = H([x^2 -y^2,3*x*y])
sage: sorted(f.rational_preperiodic_points())
[(-2 : 1), (-1 : 1), (-1/2 : 1), (0 : 1), (1/2 : 1), (1 : 0), (1 : 1),
(2 : 1)]
sage: PS.<x,y> = ProjectiveSpace(1,QQ)
sage: H = End(PS)
sage: f = H([5*x^3 - 53*x*y^2 + 24*y^3, 24*y^3])
sage: sorted(f.rational_preperiodic_points(prime_bound=10))
[(-1 : 1), (0 : 1), (1 : 0), (1 : 1), (3 : 1)]
sage: PS.<x,y,z> = ProjectiveSpace(2,QQ)
sage: H = End(PS)
sage: f = H([x^2 - 21/16*z^2,y^2-2*z^2,z^2])
sage: sorted(f.rational_preperiodic_points(prime_bound=[1,8],lifting_prime=7,periods=[2])) # long time
[(-5/4 : -2 : 1), (-5/4 : -1 : 1), (-5/4 : 0 : 1), (-5/4 : 1 : 1), (-5/4
: 2 : 1), (-1/4 : -2 : 1), (-1/4 : -1 : 1), (-1/4 : 0 : 1), (-1/4 : 1 :
1), (-1/4 : 2 : 1), (1/4 : -2 : 1), (1/4 : -1 : 1), (1/4 : 0 : 1), (1/4
: 1 : 1), (1/4 : 2 : 1), (5/4 : -2 : 1), (5/4 : -1 : 1), (5/4 : 0 : 1),
(5/4 : 1 : 1), (5/4 : 2 : 1)]
class sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space_finite_field(parent, polys, check=True)

Bases: sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space_field

The Python constructor.

See SchemeMorphism_polynomial for details.

EXAMPLES:

sage: P1.<x,y> = ProjectiveSpace(QQ,1)
sage: H = P1.Hom(P1)
sage: H([y,2*x])
Scheme endomorphism of Projective Space of dimension 1 over Rational Field
  Defn: Defined on coordinates by sending (x : y) to
        (y : 2*x)
cyclegraph()

returns Digraph of all orbits of self mod \(p\).

For subschemes, only points on the subscheme whose image are also on the subscheme are in the digraph.

OUTPUT:

  • a digraph

EXAMPLES:

sage: P.<x,y> = ProjectiveSpace(GF(13),1)
sage: H = Hom(P,P)
sage: f = H([x^2-y^2,y^2])
sage: f.cyclegraph()
Looped digraph on 14 vertices
sage: P.<x,y,z> = ProjectiveSpace(GF(5^2,'t'),2)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2,z^2+y*z])
sage: f.cyclegraph()
Looped digraph on 651 vertices
sage: P.<x,y,z> = ProjectiveSpace(GF(7),2)
sage: X = P.subscheme(x^2-y^2)
sage: H = Hom(X,X)
sage: f = H([x^2,y^2,z^2])
sage: f.cyclegraph()
Looped digraph on 15 vertices
orbit_structure(P)

Every point is preperiodic over a finite field. This funtion returns the pair \([m,n]\) where \(m\) is the preperiod and \(n\) the period of the point P by self.

INPUT:

  • P – a point in self.domain()

OUTPUT:

  • a list \([m,n]\) of integers

EXAMPLES:

sage: P.<x,y,z> = ProjectiveSpace(GF(5),2)
sage: H = Hom(P,P)
sage: f = H([x^2+y^2,y^2,z^2 + y*z])
sage: f.orbit_structure(P(2,1,2))
[0, 6]
sage: P.<x,y,z> = ProjectiveSpace(GF(7),2)
sage: X = P.subscheme(x^2-y^2)
sage: H = Hom(X,X)
sage: f = H([x^2,y^2,z^2])
sage: f.orbit_structure(X(1,1,2))
[0, 2]
sage: P.<x,y> = ProjectiveSpace(GF(13),1)
sage: H = Hom(P,P)
sage: f = H([x^2-y^2,y^2])
sage: f.orbit_structure(P(3,4))
[2, 3]
possible_periods(return_points=False)

Returns the list of possible minimal periods of a periodic point over \(\QQ\) and (optionally) a point in each cycle.

ALGORITHM:

The list comes from: Hutz, Good reduction of periodic points, Illinois Journal of Mathematics 53 (Winter 2009), no. 4, 1109-1126.

INPUT:

  • return_points - Boolean (optional) - a value of True returns the points as well as the possible periods.

OUTPUT:

  • a list of positive integers, or a list of pairs of projective points and periods if flag is 1.

Examples:

sage: P.<x,y> = ProjectiveSpace(GF(23),1)
sage: H = End(P)
sage: f = H([x^2-2*y^2,y^2])
sage: f.possible_periods()
[1, 5, 11, 22, 110]
sage: P.<x,y> = ProjectiveSpace(GF(13),1)
sage: H = End(P)
sage: f = H([x^2-y^2,y^2])
sage: f.possible_periods(True)
[[(1 : 0), 1], [(0 : 1), 2], [(3 : 1), 3], [(3 : 1), 36]]
sage: PS.<x,y,z> = ProjectiveSpace(2,GF(7))
sage: H = End(PS)
sage: f = H([-360*x^3 + 760*x*z^2, y^3 - 604*y*z^2 + 240*z^3, 240*z^3])
sage: f.possible_periods()
[1, 2, 4, 6, 12, 14, 28, 42, 84]

Todo

  • do not reutrn duplicate points
  • check == False to speed up?
  • move to Cython

Previous topic

Points on projective varieties

Next topic

Enumeration of rational points on projective schemes

This Page