Enumeration of rational points on product projective schemes - Schemes

Skip to content
Back to top
View this page
Edit this page

# Enumeration of rational points on product projective schemes

Naive algorithms for enumerating rational points over \(\QQ\), number fields or finite fields over general schemes.

Warning

Incorrect results and infinite loops may occur if using a wrong function. (For instance using an affine function for a product projective scheme or a finite field function for a scheme defined over an infinite field.)

EXAMPLES:

Product Projective, over \(\QQ\):

Sage

    sage: PP.<x,y,z> = ProductProjectiveSpaces([1,0], QQ)
    sage: from sage.schemes.product_projective.rational_point import \
    ....:   enum_product_projective_rational_field
    sage: enum_product_projective_rational_field(PP, 3)
    [(-3 : 1 , 1), (-2 : 1 , 1), (-3/2 : 1 , 1),
     (-1 : 1 , 1), (-2/3 : 1 , 1), (-1/2 : 1 , 1),
     (-1/3 : 1 , 1), (0 : 1 , 1), (1/3 : 1 , 1),
     (1/2 : 1 , 1), (2/3 : 1 , 1), (1 : 0 , 1),
     (1 : 1 , 1), (3/2 : 1 , 1), (2 : 1 , 1),
     (3 : 1 , 1)]

Python

    >>> from sage.all import *
    >>> PP = ProductProjectiveSpaces([Integer(1),Integer(0)], QQ, names=('x', 'y', 'z',)); (x, y, z,) = PP._first_ngens(3)
    >>> from sage.schemes.product_projective.rational_point import   enum_product_projective_rational_field
    >>> enum_product_projective_rational_field(PP, Integer(3))
    [(-3 : 1 , 1), (-2 : 1 , 1), (-3/2 : 1 , 1),
     (-1 : 1 , 1), (-2/3 : 1 , 1), (-1/2 : 1 , 1),
     (-1/3 : 1 , 1), (0 : 1 , 1), (1/3 : 1 , 1),
     (1/2 : 1 , 1), (2/3 : 1 , 1), (1 : 0 , 1),
     (1 : 1 , 1), (3/2 : 1 , 1), (2 : 1 , 1),
     (3 : 1 , 1)]

Product projective over finite field:

Sage

    sage: P1.<x,y,a,b> = ProductProjectiveSpaces([1, 1], GF(7))
    sage: X = P1.subscheme([2*x + 3*y])
    sage: from sage.schemes.product_projective.rational_point import \
    ....:   enum_product_projective_finite_field
    sage: enum_product_projective_finite_field(X)
    [(2 : 1 , 0 : 1), (2 : 1 , 1 : 0), (2 : 1 , 1 : 1),
     (2 : 1 , 2 : 1), (2 : 1 , 3 : 1), (2 : 1 , 4 : 1),
     (2 : 1 , 5 : 1), (2 : 1 , 6 : 1)]

[Python]

    >>> from sage.all import *
    >>> P1 = ProductProjectiveSpaces([Integer(1), Integer(1)], GF(Integer(7)), names=('x', 'y', 'a', 'b',)); (x, y, a, b,) = P1._first_ngens(4)
    >>> X = P1.subscheme([Integer(2)*x + Integer(3)*y])
    >>> from sage.schemes.product_projective.rational_point import   enum_product_projective_finite_field
    >>> enum_product_projective_finite_field(X)
    [(2 : 1 , 0 : 1), (2 : 1 , 1 : 0), (2 : 1 , 1 : 1),
     (2 : 1 , 2 : 1), (2 : 1 , 3 : 1), (2 : 1 , 4 : 1),
     (2 : 1 , 5 : 1), (2 : 1 , 6 : 1)]

AUTHORS:

- Volker Braun and Ben Hutz (2014): initial version

- Raghukul Raman (2018): code cleanup and added support for rational fields

sage.schemes.product_projective.rational_point.enum_product_projective_finite_field(X)

  Enumerates projective points on scheme `X` defined over a finite field.

  INPUT:

  - `X` – a scheme defined over a finite field or a set of abstract rational points of such a scheme

  OUTPUT:

  A list containing the projective points of `X` over the finite field, sorted.

  EXAMPLES:

  Sage

      sage: PP.<x,y,z,w> = ProductProjectiveSpaces([1, 1], GF(3))
      sage: from sage.schemes.product_projective.rational_point import \
      ....:   enum_product_projective_finite_field
      sage: enum_product_projective_finite_field(PP)
      [(0 : 1 , 0 : 1), (0 : 1 , 1 : 0), (0 : 1 , 1 : 1),
       (0 : 1 , 2 : 1), (1 : 0 , 0 : 1), (1 : 0 , 1 : 0),
       (1 : 0 , 1 : 1), (1 : 0 , 2 : 1), (1 : 1 , 0 : 1),
       (1 : 1 , 1 : 0), (1 : 1 , 1 : 1), (1 : 1 , 2 : 1),
       (2 : 1 , 0 : 1), (2 : 1 , 1 : 0), (2 : 1 , 1 : 1),
       (2 : 1 , 2 : 1)]

  Python

      >>> from sage.all import *
      >>> PP = ProductProjectiveSpaces([Integer(1), Integer(1)], GF(Integer(3)), names=('x', 'y', 'z', 'w',)); (x, y, z, w,) = PP._first_ngens(4)
      >>> from sage.schemes.product_projective.rational_point import   enum_product_projective_finite_field
      >>> enum_product_projective_finite_field(PP)
      [(0 : 1 , 0 : 1), (0 : 1 , 1 : 0), (0 : 1 , 1 : 1),
       (0 : 1 , 2 : 1), (1 : 0 , 0 : 1), (1 : 0 , 1 : 0),
       (1 : 0 , 1 : 1), (1 : 0 , 2 : 1), (1 : 1 , 0 : 1),
       (1 : 1 , 1 : 0), (1 : 1 , 1 : 1), (1 : 1 , 2 : 1),
       (2 : 1 , 0 : 1), (2 : 1 , 1 : 0), (2 : 1 , 1 : 1),
       (2 : 1 , 2 : 1)]

  Sage

      sage: PP.<x0,x1,x2,x3> = ProductProjectiveSpaces([1, 1], GF(17))
      sage: X = PP.subscheme([x0^2 + 2*x1^2])
      sage: from sage.schemes.product_projective.rational_point import \
      ....:   enum_product_projective_finite_field
      sage: len(enum_product_projective_finite_field(X))
      36

  [Python]

      >>> from sage.all import *
      >>> PP = ProductProjectiveSpaces([Integer(1), Integer(1)], GF(Integer(17)), names=('x0', 'x1', 'x2', 'x3',)); (x0, x1, x2, x3,) = PP._first_ngens(4)
      >>> X = PP.subscheme([x0**Integer(2) + Integer(2)*x1**Integer(2)])
      >>> from sage.schemes.product_projective.rational_point import   enum_product_projective_finite_field
      >>> len(enum_product_projective_finite_field(X))
      36

sage.schemes.product_projective.rational_point.enum_product_projective_number_field(X, **kwds)

  Enumerates product projective points on scheme `X` defined over a number field.

  Simply checks all of the points of absolute height of at most `B` and adds those that are on the scheme to the list.

  This algorithm computes 2 lists: L containing elements x in \(K\) such that H_k(x) <= B, and a list L’ containing elements x in \(K\) that, due to floating point issues, may be slightly larger then the bound. This can be controlled by lowering the tolerance.

  ALGORITHM:

  This is an implementation of the revised algorithm (Algorithm 4) in [DK2013]. Algorithm 5 is used for imaginary quadratic fields.

  INPUT: keyword arguments:

  - `bound` – a real number

  - `tolerance` – a rational number in (0,1] used in Doyle-Krumm algorithm-4

  - `precision` – the precision to use for computing the elements of bounded height of number fields

  OUTPUT:

  A list containing the product projective points of `X` of absolute height up to `B`, sorted.

  EXAMPLES:

  Sage

      sage: # needs sage.rings.number_field
      sage: u = QQ['u'].0
      sage: K = NumberField(u^2 + 2, 'v')
      sage: PP.<x,y,z,w> = ProductProjectiveSpaces([1, 1], K)
      sage: X = PP.subscheme([x^2 + 2*y^2])
      sage: from sage.schemes.product_projective.rational_point import \
      ....:   enum_product_projective_number_field
      sage: enum_product_projective_number_field(X, bound=1.5)
      [(-v : 1 , -1 : 1), (-v : 1 , -v : 1), (-v : 1 , -1/2*v : 1),
       (-v : 1 , 0 : 1), (-v : 1 , 1/2*v : 1), (-v : 1 , v : 1),
       (-v : 1 , 1 : 0), (-v : 1 , 1 : 1), (v : 1 , -1 : 1),
       (v : 1 , -v : 1), (v : 1 , -1/2*v : 1), (v : 1 , 0 : 1),
       (v : 1 , 1/2*v : 1), (v : 1 , v : 1), (v : 1 , 1 : 0),
       (v : 1 , 1 : 1)]

  Python

      >>> from sage.all import *
      >>> # needs sage.rings.number_field
      >>> u = QQ['u'].gen(0)
      >>> K = NumberField(u**Integer(2) + Integer(2), 'v')
      >>> PP = ProductProjectiveSpaces([Integer(1), Integer(1)], K, names=('x', 'y', 'z', 'w',)); (x, y, z, w,) = PP._first_ngens(4)
      >>> X = PP.subscheme([x**Integer(2) + Integer(2)*y**Integer(2)])
      >>> from sage.schemes.product_projective.rational_point import   enum_product_projective_number_field
      >>> enum_product_projective_number_field(X, bound=RealNumber('1.5'))
      [(-v : 1 , -1 : 1), (-v : 1 , -v : 1), (-v : 1 , -1/2*v : 1),
       (-v : 1 , 0 : 1), (-v : 1 , 1/2*v : 1), (-v : 1 , v : 1),
       (-v : 1 , 1 : 0), (-v : 1 , 1 : 1), (v : 1 , -1 : 1),
       (v : 1 , -v : 1), (v : 1 , -1/2*v : 1), (v : 1 , 0 : 1),
       (v : 1 , 1/2*v : 1), (v : 1 , v : 1), (v : 1 , 1 : 0),
       (v : 1 , 1 : 1)]

sage.schemes.product_projective.rational_point.enum_product_projective_rational_field(X, B)

  Enumerate projective, rational points on scheme `X` of height up to bound `B`.

  INPUT:

  - `X` – a scheme or set of abstract rational points of a scheme

  - `B` – positive integer bound

  OUTPUT:

  A list containing the product projective points of `X` of height up to `B`, sorted.

  EXAMPLES:

  Sage

      sage: PP.<x0,x1,x2,x3,x4> = ProductProjectiveSpaces([1, 2], QQ)
      sage: from sage.schemes.product_projective.rational_point import \
      ....:   enum_product_projective_rational_field
      sage: enum_product_projective_rational_field(PP, 1)
      [(-1 : 1 , -1 : -1 : 1), (-1 : 1 , -1 : 0 : 1), (-1 : 1 , -1 : 1 : 0),
       (-1 : 1 , -1 : 1 : 1), (-1 : 1 , 0 : -1 : 1), (-1 : 1 , 0 : 0 : 1),
       (-1 : 1 , 0 : 1 : 0), (-1 : 1 , 0 : 1 : 1), (-1 : 1 , 1 : -1 : 1),
       (-1 : 1 , 1 : 0 : 0), (-1 : 1 , 1 : 0 : 1), (-1 : 1 , 1 : 1 : 0),
       (-1 : 1 , 1 : 1 : 1), (0 : 1 , -1 : -1 : 1), (0 : 1 , -1 : 0 : 1),
       (0 : 1 , -1 : 1 : 0), (0 : 1 , -1 : 1 : 1), (0 : 1 , 0 : -1 : 1),
       (0 : 1 , 0 : 0 : 1), (0 : 1 , 0 : 1 : 0), (0 : 1 , 0 : 1 : 1),
       (0 : 1 , 1 : -1 : 1), (0 : 1 , 1 : 0 : 0), (0 : 1 , 1 : 0 : 1),
       (0 : 1 , 1 : 1 : 0), (0 : 1 , 1 : 1 : 1), (1 : 0 , -1 : -1 : 1),
       (1 : 0 , -1 : 0 : 1), (1 : 0 , -1 : 1 : 0), (1 : 0 , -1 : 1 : 1),
       (1 : 0 , 0 : -1 : 1), (1 : 0 , 0 : 0 : 1), (1 : 0 , 0 : 1 : 0),
       (1 : 0 , 0 : 1 : 1), (1 : 0 , 1 : -1 : 1), (1 : 0 , 1 : 0 : 0),
       (1 : 0 , 1 : 0 : 1), (1 : 0 , 1 : 1 : 0), (1 : 0 , 1 : 1 : 1),
       (1 : 1 , -1 : -1 : 1), (1 : 1 , -1 : 0 : 1), (1 : 1 , -1 : 1 : 0),
       (1 : 1 , -1 : 1 : 1), (1 : 1 , 0 : -1 : 1), (1 : 1 , 0 : 0 : 1),
       (1 : 1 , 0 : 1 : 0), (1 : 1 , 0 : 1 : 1), (1 : 1 , 1 : -1 : 1),
       (1 : 1 , 1 : 0 : 0), (1 : 1 , 1 : 0 : 1), (1 : 1 , 1 : 1 : 0),
       (1 : 1 , 1 : 1 : 1)]

  Python

      >>> from sage.all import *
      >>> PP = ProductProjectiveSpaces([Integer(1), Integer(2)], QQ, names=('x0', 'x1', 'x2', 'x3', 'x4',)); (x0, x1, x2, x3, x4,) = PP._first_ngens(5)
      >>> from sage.schemes.product_projective.rational_point import   enum_product_projective_rational_field
      >>> enum_product_projective_rational_field(PP, Integer(1))
      [(-1 : 1 , -1 : -1 : 1), (-1 : 1 , -1 : 0 : 1), (-1 : 1 , -1 : 1 : 0),
       (-1 : 1 , -1 : 1 : 1), (-1 : 1 , 0 : -1 : 1), (-1 : 1 , 0 : 0 : 1),
       (-1 : 1 , 0 : 1 : 0), (-1 : 1 , 0 : 1 : 1), (-1 : 1 , 1 : -1 : 1),
       (-1 : 1 , 1 : 0 : 0), (-1 : 1 , 1 : 0 : 1), (-1 : 1 , 1 : 1 : 0),
       (-1 : 1 , 1 : 1 : 1), (0 : 1 , -1 : -1 : 1), (0 : 1 , -1 : 0 : 1),
       (0 : 1 , -1 : 1 : 0), (0 : 1 , -1 : 1 : 1), (0 : 1 , 0 : -1 : 1),
       (0 : 1 , 0 : 0 : 1), (0 : 1 , 0 : 1 : 0), (0 : 1 , 0 : 1 : 1),
       (0 : 1 , 1 : -1 : 1), (0 : 1 , 1 : 0 : 0), (0 : 1 , 1 : 0 : 1),
       (0 : 1 , 1 : 1 : 0), (0 : 1 , 1 : 1 : 1), (1 : 0 , -1 : -1 : 1),
       (1 : 0 , -1 : 0 : 1), (1 : 0 , -1 : 1 : 0), (1 : 0 , -1 : 1 : 1),
       (1 : 0 , 0 : -1 : 1), (1 : 0 , 0 : 0 : 1), (1 : 0 , 0 : 1 : 0),
       (1 : 0 , 0 : 1 : 1), (1 : 0 , 1 : -1 : 1), (1 : 0 , 1 : 0 : 0),
       (1 : 0 , 1 : 0 : 1), (1 : 0 , 1 : 1 : 0), (1 : 0 , 1 : 1 : 1),
       (1 : 1 , -1 : -1 : 1), (1 : 1 , -1 : 0 : 1), (1 : 1 , -1 : 1 : 0),
       (1 : 1 , -1 : 1 : 1), (1 : 1 , 0 : -1 : 1), (1 : 1 , 0 : 0 : 1),
       (1 : 1 , 0 : 1 : 0), (1 : 1 , 0 : 1 : 1), (1 : 1 , 1 : -1 : 1),
       (1 : 1 , 1 : 0 : 0), (1 : 1 , 1 : 0 : 1), (1 : 1 , 1 : 1 : 0),
       (1 : 1 , 1 : 1 : 1)]

  Sage

      sage: PP.<x,y,z,u,v> = ProductProjectiveSpaces([2, 1], QQ)
      sage: X = PP.subscheme([x^2 + x*y + y*z, u*u - v*u])
      sage: from sage.schemes.product_projective.rational_point import \
      ....:   enum_product_projective_rational_field
      sage: enum_product_projective_rational_field(X, 4)
      [(-2 : 4 : 1 , 0 : 1), (-2 : 4 : 1 , 1 : 1), (-1 : 1 : 0 , 0 : 1),
       (-1 : 1 : 0 , 1 : 1), (-2/3 : -4/3 : 1 , 0 : 1), (-2/3 : -4/3 : 1 , 1 : 1),
       (-1/2 : -1/2 : 1 , 0 : 1), (-1/2 : -1/2 : 1 , 1 : 1),
       (0 : 0 : 1 , 0 : 1), (0 : 0 : 1 , 1 : 1), (0 : 1 : 0 , 0 : 1),
       (0 : 1 : 0 , 1 : 1), (1 : -1/2 : 1 , 0 : 1), (1 : -1/2 : 1 , 1 : 1)]

  [Python]

      >>> from sage.all import *
      >>> PP = ProductProjectiveSpaces([Integer(2), Integer(1)], QQ, names=('x', 'y', 'z', 'u', 'v',)); (x, y, z, u, v,) = PP._first_ngens(5)
      >>> X = PP.subscheme([x**Integer(2) + x*y + y*z, u*u - v*u])
      >>> from sage.schemes.product_projective.rational_point import   enum_product_projective_rational_field
      >>> enum_product_projective_rational_field(X, Integer(4))
      [(-2 : 4 : 1 , 0 : 1), (-2 : 4 : 1 , 1 : 1), (-1 : 1 : 0 , 0 : 1),
       (-1 : 1 : 0 , 1 : 1), (-2/3 : -4/3 : 1 , 0 : 1), (-2/3 : -4/3 : 1 , 1 : 1),
       (-1/2 : -1/2 : 1 , 0 : 1), (-1/2 : -1/2 : 1 , 1 : 1),
       (0 : 0 : 1 , 0 : 1), (0 : 0 : 1 , 1 : 1), (0 : 1 : 0 , 0 : 1),
       (0 : 1 : 0 , 1 : 1), (1 : -1/2 : 1 , 0 : 1), (1 : -1/2 : 1 , 1 : 1)]

sage.schemes.product_projective.rational_point.sieve(X, bound)

  Return the list of all rational points on scheme `X` of height up to `bound`.

  ALGORITHM:

  Main idea behind the algorithm is to find points modulo primes and then reconstruct them using chinese remainder theorem. We compute the points modulo primes parallelly and then lift them via chinese remainder theorem in parallel. The LLL reduction algorithm is applied to each component of the points, and finally the result is merged and converted to a point on the subscheme.

  For the algorithm to work correctly, sufficient primes need to be chosen, these are determined using the bounds dependent on the bound given in [Hutz2015].

  INPUT:

  - `X` – a scheme with ambient space defined over a product of projective spaces

  - `bound` – positive integer bound

  OUTPUT:

  A list containing the rational points of `X` of height up to `bound`, sorted

  EXAMPLES:

  Sage

      sage: from sage.schemes.product_projective.rational_point import sieve
      sage: PP.<x,y,z,u,v> = ProductProjectiveSpaces([2, 1], QQ)
      sage: X = PP.subscheme([x^2 + y^2 - x*z, u*u - v*u])
      sage: sieve(X, 2)                                                               # needs sage.libs.singular
      [(0 : 0 : 1 , 0 : 1), (0 : 0 : 1 , 1 : 1), (1/2 : -1/2 : 1 , 0 : 1),
       (1/2 : -1/2 : 1 , 1 : 1), (1/2 : 1/2 : 1 , 0 : 1), (1/2 : 1/2 : 1 , 1 : 1),
       (1 : 0 : 1 , 0 : 1), (1 : 0 : 1 , 1 : 1)]

  Python

      >>> from sage.all import *
      >>> from sage.schemes.product_projective.rational_point import sieve
      >>> PP = ProductProjectiveSpaces([Integer(2), Integer(1)], QQ, names=('x', 'y', 'z', 'u', 'v',)); (x, y, z, u, v,) = PP._first_ngens(5)
      >>> X = PP.subscheme([x**Integer(2) + y**Integer(2) - x*z, u*u - v*u])
      >>> sieve(X, Integer(2))                                                               # needs sage.libs.singular
      [(0 : 0 : 1 , 0 : 1), (0 : 0 : 1 , 1 : 1), (1/2 : -1/2 : 1 , 0 : 1),
       (1/2 : -1/2 : 1 , 1 : 1), (1/2 : 1/2 : 1 , 0 : 1), (1/2 : 1/2 : 1 , 1 : 1),
       (1 : 0 : 1 , 0 : 1), (1 : 0 : 1 , 1 : 1)]