Esempio n. 1
0
def enum_product_projective_finite_field(X):
    r"""
    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: 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)]

    ::

        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
    """
    if (is_Scheme(X)):
        if (not is_ProductProjectiveSpaces(X.ambient_space())):
            raise TypeError(
                "ambient space must be product of projective space over the rational field"
            )
        X = X(X.base_ring())
    else:
        if (not is_ProductProjectiveSpaces(X.codomain().ambient_space())):
            raise TypeError(
                "codomain must be product of projective space over the rational field"
            )

    R = X.codomain().ambient_space()
    pts = []

    for P in R.rational_points():
        try:
            pts.append(X(P))
        except TypeError:
            pass
    pts.sort()

    return pts
Esempio n. 2
0
File: point.py Progetto: ye-man/sage
    def multiplicity(self):
        r"""
        Return the multiplicity of this point on its codomain.

        This uses the subscheme implementation of multiplicity. This point must be a point
        on a subscheme of a product of projective spaces.

        OUTPUT: an integer.

        EXAMPLES::

            sage: PP.<x,y,z,w,u,v,t> = ProductProjectiveSpaces(QQ, [3,2])
            sage: X = PP.subscheme([x^8*t - y^8*t + z^5*w^3*v])
            sage: Q1 = X([1,1,0,0,-1,-1,1])
            sage: Q1.multiplicity()
            1
            sage: Q2 = X([0,0,0,1,0,1,1])
            sage: Q2.multiplicity()
            5
            sage: Q3 = X([0,0,0,1,1,0,0])
            sage: Q3.multiplicity()
            6
        """
        from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
        if is_ProductProjectiveSpaces(self.codomain()):
            raise TypeError(
                "this point must be a point on a subscheme of a product of projective spaces"
            )
        return self.codomain().multiplicity(self)
Esempio n. 3
0
File: point.py Progetto: ye-man/sage
    def intersection_multiplicity(self, X):
        r"""
        Return the intersection multiplicity of the codomain of this point and subscheme ``X`` at this point.

        This uses the subscheme implementation of intersection_multiplicity. This point must be a point
        on a subscheme of a product of projective spaces.

        INPUT:

        - ``X`` -- a subscheme in the same ambient space as the codomain of this point.

        OUTPUT: An integer.

        EXAMPLES::

            sage: PP.<x,y,z,u,v> = ProductProjectiveSpaces(QQ, [2,1])
            sage: X = PP.subscheme([y^2*z^3*u - x^5*v])
            sage: Y = PP.subscheme([u^3 - v^3, x - y])
            sage: Q = X([0,0,1,1,1])
            sage: Q.intersection_multiplicity(Y)
            2
        """
        from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
        if is_ProductProjectiveSpaces(self.codomain()):
            raise TypeError(
                "this point must be a point on a subscheme of a product of projective spaces"
            )
        return self.codomain().intersection_multiplicity(X, self)
Esempio n. 4
0
    def multiplicity(self):
        r"""
        Return the multiplicity of this point on its codomain.

        This uses the subscheme implementation of multiplicity. This point must be a point
        on a subscheme of a product of projective spaces.

        OUTPUT: an integer.

        EXAMPLES::

            sage: PP.<x,y,z,w,u,v,t> = ProductProjectiveSpaces(QQ, [3,2])
            sage: X = PP.subscheme([x^8*t - y^8*t + z^5*w^3*v])
            sage: Q1 = X([1,1,0,0,-1,-1,1])
            sage: Q1.multiplicity()
            1
            sage: Q2 = X([0,0,0,1,0,1,1])
            sage: Q2.multiplicity()
            5
            sage: Q3 = X([0,0,0,1,1,0,0])
            sage: Q3.multiplicity()
            6
        """
        from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
        if is_ProductProjectiveSpaces(self.codomain()):
            raise TypeError("this point must be a point on a subscheme of a product of projective spaces")
        return self.codomain().multiplicity(self)
Esempio n. 5
0
    def intersection_multiplicity(self, X):
        r"""
        Return the intersection multiplicity of the codomain of this point and subscheme ``X`` at this point.

        This uses the subscheme implementation of intersection_multiplicity. This point must be a point
        on a subscheme of a product of projective spaces.

        INPUT:

        - ``X`` -- a subscheme in the same ambient space as the codomain of this point.

        OUTPUT: An integer.

        EXAMPLES::

            sage: PP.<x,y,z,u,v> = ProductProjectiveSpaces(QQ, [2,1])
            sage: X = PP.subscheme([y^2*z^3*u - x^5*v])
            sage: Y = PP.subscheme([u^3 - v^3, x - y])
            sage: Q = X([0,0,1,1,1])
            sage: Q.intersection_multiplicity(Y)
            2
        """
        from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
        if is_ProductProjectiveSpaces(self.codomain()):
            raise TypeError("this point must be a point on a subscheme of a product of projective spaces")
        return self.codomain().intersection_multiplicity(X, self)
Esempio n. 6
0
    def __init__(self, parent, polys, check=True):
        r"""
        The Python constructor.

        INPUT:

        - ``parent`` -- Homset

        - ``polys`` -- anything that defines a point in the class

        - ``check`` -- Boolean. Whether or not to perform input checks
          (Default:`` True``)

        EXAMPLES::

            sage: T.<x,y,z,w,u> = ProductProjectiveSpaces([2,1],QQ)
            sage: H = T.Hom(T)
            sage: H([x^2*u,y^2*w,z^2*u,w^2,u^2])
            Scheme endomorphism of Product of projective spaces P^2 x P^1 over Rational Field
              Defn: Defined by sending (x : y : z , w : u) to 
                    (x^2*u : y^2*w : z^2*u , w^2 : u^2).

        ::

            sage: T.<x,y,z,w,u> = ProductProjectiveSpaces([2,1],QQ)
            sage: H = T.Hom(T)
            sage: H([x^2*u,y^2*w,z^2*u,w^2,u*z])
            Traceback (most recent call last):
            ...
            TypeError: polys (=[x^2*u, y^2*w, z^2*u, w^2, z*u]) must be
            multi-homogeneous of the same degrees (by component)
        """
        if check:
            #check multi-homogeneous
            #if self is a subscheme, we may need the lift of the polynomials
            try:
                polys[0].exponents()
            except AttributeError:
                polys = [f.lift() for f in polys]

            target = parent.codomain().ambient_space()
            from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
            if is_ProductProjectiveSpaces(target):
                splitpolys = target._factors(polys)
                for m in range(len(splitpolys)):
                    d = target._degree(splitpolys[m][0])
                    if not all(d == target._degree(f) for f in splitpolys[m]):
                        raise TypeError(
                            "polys (=%s) must be multi-homogeneous of the same degrees (by component)"
                            % polys)
            else:
                #we are mapping into some other kind of space
                target._validate(polys)

        SchemeMorphism_polynomial.__init__(self, parent, polys, check)
Esempio n. 7
0
    def __init__(self, parent, polys, check = True):
        r"""
        The Python constructor.

        INPUT:

        - ``parent`` -- Homset

        - ``polys`` -- anything that defines a point in the class

        - ``check`` -- Boolean. Whether or not to perform input checks
          (Default:`` True``)

        EXAMPLES::

            sage: T.<x,y,z,w,u> = ProductProjectiveSpaces([2,1],QQ)
            sage: H = T.Hom(T)
            sage: H([x^2*u,y^2*w,z^2*u,w^2,u^2])
            Scheme endomorphism of Product of projective spaces P^2 x P^1 over Rational Field
              Defn: Defined by sending (x : y : z , w : u) to 
                    (x^2*u : y^2*w : z^2*u , w^2 : u^2).

        ::

            sage: T.<x,y,z,w,u> = ProductProjectiveSpaces([2,1],QQ)
            sage: H = T.Hom(T)
            sage: H([x^2*u,y^2*w,z^2*u,w^2,u*z])
            Traceback (most recent call last):
            ...
            TypeError: polys (=[x^2*u, y^2*w, z^2*u, w^2, z*u]) must be
            multi-homogeneous of the same degrees (by component)
        """
        if check:
            #check multi-homogeneous
            #if self is a subscheme, we may need the lift of the polynomials
            try:
                polys[0].exponents()
            except AttributeError:
                polys = [f.lift() for f in polys]

            target = parent.codomain().ambient_space()
            from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
            if is_ProductProjectiveSpaces(target):
                splitpolys = target._factors(polys)
                for m in range(len(splitpolys)):
                    d = target._degree(splitpolys[m][0])
                    if not all(d == target._degree(f) for f in splitpolys[m]):
                        raise  TypeError("polys (=%s) must be multi-homogeneous of the same degrees (by component)"%polys)
            else:
                #we are mapping into some other kind of space
                target._validate(polys)

        SchemeMorphism_polynomial.__init__(self, parent, polys, check)
Esempio n. 8
0
    def cyclegraph(self):
        r"""
        Return the digraph of all orbits of this morphism mod `p`.

        OUTPUT: a digraph

        EXAMPLES::

            sage: P.<a,b,c,d> = ProductProjectiveSpaces(GF(3), [1,1])
            sage: f = DynamicalSystem_projective([a^2,b^2,c^2,d^2], domain=P)
            sage: f.cyclegraph()
            Looped digraph on 16 vertices

        ::

            sage: P.<a,b,c,d> = ProductProjectiveSpaces(GF(5), [1,1])
            sage: f = DynamicalSystem_projective([a^2,b^2,c,d], domain=P)
            sage: f.cyclegraph()
            Looped digraph on 36 vertices

        ::

            sage: P.<a,b,c,d,e> = ProductProjectiveSpaces(GF(2), [1,2])
            sage: f = DynamicalSystem_projective([a^2,b^2,c,d,e], domain=P)
            sage: f.cyclegraph()
            Looped digraph on 21 vertices

        .. TODO:: Dynamical systems for subschemes of product projective spaces needs work.
                  Thus this is not implemented for subschemes.
        """
        V = []
        E = []
        from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
        if is_ProductProjectiveSpaces(self.domain()) == True:
            for P in self.domain():
                V.append(str(P))
                Q = self(P)
                E.append([str(Q)])
        else:
            raise NotImplementedError(
                "Cyclegraph for product projective spaces not implemented for subschemes"
            )
        from sage.graphs.digraph import DiGraph
        g = DiGraph(dict(zip(V, E)), loops=True)
        return g
Esempio n. 9
0
    def points(self, B=0, prec=53):
        r"""
        Return some or all rational points of a projective scheme.

        Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound
        are returned. For a zero-dimensional subscheme, all points are returned regardless of whether the base
        ring is a field or not.

        INPUT:

        - `B` -- integer (optional, default=0). The bound for the
          coordinates.
        - ``prec`` - the precision to use to compute the elements of bounded height for number fields.

        OUTPUT:

        - a list of rational points of a projective scheme.

        .. WARNING::

           In the current implementation, the output of the [Doyle-Krumm]_ algorithm
           cannot be guaranteed to be correct due to the necessity of floating point
           computations. In some cases, the default 53-bit precision is
           considerably lower than would be required for the algorithm to
           generate correct output.

        EXAMPLES::

            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1, 1], QQ)
            sage: X = P.subscheme([x - y, z^2 - 2*w^2])
            sage: X(P.base_ring()).points()
            []

        ::

            sage: u = QQ['u'].0
            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1,1], NumberField(u^2 - 2, 'v'))
            sage: X = P.subscheme([x^2 - y^2, z^2 - 2*w^2])
            sage: X(P.base_ring()).points()
            [(-1 : 1 , -v : 1), (1 : 1 , v : 1), (1 : 1 , -v : 1), (-1 : 1 , v : 1)]

        ::

            sage: u = QQ['u'].0
            sage: K = NumberField(u^2 + 1, 'v')
            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1, 1], K)
            sage: P(K).points(1)
            [(0 : 1 , 0 : 1), (0 : 1 , v : 1), (0 : 1 , -1 : 1), (0 : 1 , -v : 1), (0 : 1 , 1 : 1),
            (0 : 1 , 1 : 0), (v : 1 , 0 : 1), (v : 1 , v : 1), (v : 1 , -1 : 1), (v : 1 , -v : 1),
            (v : 1 , 1 : 1), (v : 1 , 1 : 0), (-1 : 1 , 0 : 1), (-1 : 1 , v : 1), (-1 : 1 , -1 : 1),
            (-1 : 1 , -v : 1), (-1 : 1 , 1 : 1), (-1 : 1 , 1 : 0), (-v : 1 , 0 : 1), (-v : 1 , v : 1),
            (-v : 1 , -1 : 1), (-v : 1 , -v : 1), (-v : 1 , 1 : 1), (-v : 1 , 1 : 0), (1 : 1 , 0 : 1),
            (1 : 1 , v : 1), (1 : 1 , -1 : 1), (1 : 1 , -v : 1), (1 : 1 , 1 : 1), (1 : 1 , 1 : 0),
            (1 : 0 , 0 : 1), (1 : 0 , v : 1), (1 : 0 , -1 : 1), (1 : 0 , -v : 1), (1 : 0 , 1 : 1),
            (1 : 0 , 1 : 0)]

        ::

            sage: P.<x,y,z,u,v> = ProductProjectiveSpaces([2, 1], GF(3))
            sage: P(P.base_ring()).points()
            [(0 : 0 : 1 , 0 : 1), (1 : 0 : 1 , 0 : 1), (2 : 0 : 1 , 0 : 1), (0 : 1 : 1 , 0 : 1), (1 : 1 : 1 , 0 : 1),
            (2 : 1 : 1 , 0 : 1), (0 : 2 : 1 , 0 : 1), (1 : 2 : 1 , 0 : 1), (2 : 2 : 1 , 0 : 1), (0 : 1 : 0 , 0 : 1),
            (1 : 1 : 0 , 0 : 1), (2 : 1 : 0 , 0 : 1), (1 : 0 : 0 , 0 : 1), (0 : 0 : 1 , 1 : 1), (1 : 0 : 1 , 1 : 1),
            (2 : 0 : 1 , 1 : 1), (0 : 1 : 1 , 1 : 1), (1 : 1 : 1 , 1 : 1), (2 : 1 : 1 , 1 : 1), (0 : 2 : 1 , 1 : 1),
            (1 : 2 : 1 , 1 : 1), (2 : 2 : 1 , 1 : 1), (0 : 1 : 0 , 1 : 1), (1 : 1 : 0 , 1 : 1), (2 : 1 : 0 , 1 : 1),
            (1 : 0 : 0 , 1 : 1), (0 : 0 : 1 , 2 : 1), (1 : 0 : 1 , 2 : 1), (2 : 0 : 1 , 2 : 1), (0 : 1 : 1 , 2 : 1),
            (1 : 1 : 1 , 2 : 1), (2 : 1 : 1 , 2 : 1), (0 : 2 : 1 , 2 : 1), (1 : 2 : 1 , 2 : 1), (2 : 2 : 1 , 2 : 1),
            (0 : 1 : 0 , 2 : 1), (1 : 1 : 0 , 2 : 1), (2 : 1 : 0 , 2 : 1), (1 : 0 : 0 , 2 : 1), (0 : 0 : 1 , 1 : 0),
            (1 : 0 : 1 , 1 : 0), (2 : 0 : 1 , 1 : 0), (0 : 1 : 1 , 1 : 0), (1 : 1 : 1 , 1 : 0), (2 : 1 : 1 , 1 : 0),
            (0 : 2 : 1 , 1 : 0), (1 : 2 : 1 , 1 : 0), (2 : 2 : 1 , 1 : 0), (0 : 1 : 0 , 1 : 0), (1 : 1 : 0 , 1 : 0),
            (2 : 1 : 0 , 1 : 0), (1 : 0 : 0 , 1 : 0)]
        """
        X = self.codomain()

        from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
        if not is_ProductProjectiveSpaces(X) and X.base_ring() in Fields():
            # no points
            if X.dimension() == -1:
                return []
            # if X is zero-dimensional
            if X.dimension() == 0:
                points = set()
                # find points from all possible affine patches
                for I in xmrange([n + 1 for n in X.ambient_space().dimension_relative_components()]):
                    [Y,phi] = X.affine_patch(I, True)
                    aff_points = Y.rational_points()
                    for PP in aff_points:
                        points.add(phi(PP))
                return list(points)
        R = self.value_ring()
        points = []
        if R in NumberFields():
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified"%B)
            for P in X.ambient_space().points_of_bounded_height(B, prec):
                try:
                    points.append(X(P))
                except TypeError:
                    pass
            return points
        if is_FiniteField(R):
            for P in X.ambient_space().rational_points():
                try:
                    points.append(X(P))
                except TypeError:
                    pass
            return points
        else:
            raise TypeError("unable to enumerate points over %s"%R)
Esempio n. 10
0
def enum_product_projective_rational_field(X, B):
    r"""
    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`` -- a positive integer bound

    OUTPUT:

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

    EXAMPLES::

        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)]

    ::

        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)]
    """
    if(is_Scheme(X)):
        if (not is_ProductProjectiveSpaces(X.ambient_space())):
            raise TypeError("ambient space must be product of projective space over the rational field")
        X = X(X.base_ring())
    else:
        if (not is_ProductProjectiveSpaces(X.codomain().ambient_space())):
            raise TypeError("codomain must be product of projective space over the rational field")

    R = X.codomain().ambient_space()
    m = R.num_components()
    iters = [ R[i].points_of_bounded_height(bound=B) for i in range(m) ]
    dim = [R[i].dimension_relative() + 1 for i in range(m)]
    
    dim_prefix = [0, dim[0]] # prefixes dim list
    for i in range(1, len(dim)):
        dim_prefix.append(dim_prefix[i] + dim[i])

    pts = []
    P = []
    for i in range(m):
        pt = next(iters[i])
        for j in range(dim[i]):
            P.append(pt[j]) # initial value of P

    try: # add the initial point
        pts.append(X(P))
    except TypeError:
        pass

    i = 0
    while i < m:
        try:
            pt = next(iters[i])
            for j in range(dim[i]):
                P[dim_prefix[i] + j] = pt[j]
            try:
                pts.append(X(P))
            except TypeError:
                pass
            i = 0
        except StopIteration:
            iters[i] = R[i].points_of_bounded_height(bound=B)
            pt = next(iters[i]) # reset
            for j in range(dim[i]):
                P[dim_prefix[i] + j] = pt[j]
            i += 1
    pts.sort()

    return pts
Esempio n. 11
0
def enum_product_projective_number_field(X, **kwds):
    r"""
    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:

    kwds:

    - ``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: 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)]
    """
    B = kwds.pop('bound')
    tol = kwds.pop('tolerance', 1e-2)
    prec = kwds.pop('precision', 53)

    if(is_Scheme(X)):
        if (not is_ProductProjectiveSpaces(X.ambient_space())):
            raise TypeError("ambient space must be product of projective space over the rational field")
        X = X(X.base_ring())
    else:
        if (not is_ProductProjectiveSpaces(X.codomain().ambient_space())):
            raise TypeError("codomain must be product of projective space over the rational field")

    R = X.codomain().ambient_space()

    pts = []

    for P in R.points_of_bounded_height(bound=B, tolerance=tol, precision=prec):
        try:
            pts.append(X(P))
        except TypeError:
            pass
    pts.sort()
    return pts
Esempio n. 12
0
    def points(self, **kwds):
        r"""
        Return some or all rational points of a projective scheme.

        Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound
        are returned. For a zero-dimensional subscheme, all points are returned regardless of whether the base
        ring is a field or not.

        For number fields, this uses the
        Doyle-Krumm algorithm 4 (algorithm 5 for imaginary quadratic) for
        computing algebraic numbers up to a given height [DK2013]_ or
        uses the chinese remainder theorem and points modulo primes
        for larger bounds.

        The algorithm requires floating point arithmetic, so the user is
        allowed to specify the precision for such calculations.
        Additionally, due to floating point issues, points
        slightly larger than the bound may be returned. This can be controlled
        by lowering the tolerance.


        INPUT:

        - ``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.

        - ``algorithm`` - either 'sieve' or 'enumerate' algorithms can be used over `QQ`. If
          not specified, enumerate is used only for small height bounds.

        OUTPUT:

        - a list of rational points of a projective scheme

        EXAMPLES::

            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1, 1], QQ)
            sage: X = P.subscheme([x - y, z^2 - 2*w^2])
            sage: X(P.base_ring()).points()
            []

        ::

            sage: u = QQ['u'].0
            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1,1], NumberField(u^2 - 2, 'v'))
            sage: X = P.subscheme([x^2 - y^2, z^2 - 2*w^2])
            sage: sorted(X(P.base_ring()).points())
            [(-1 : 1 , -v : 1), (-1 : 1 , v : 1), (1 : 1 , -v : 1), (1 : 1 , v : 1)]

        ::

            sage: u = QQ['u'].0
            sage: K = NumberField(u^2 + 1, 'v')
            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1, 1], K)
            sage: P(K).points(bound=1)
            [(-1 : 1 , -1 : 1), (-1 : 1 , -v : 1), (-1 : 1 , 0 : 1), (-1 : 1 , v : 1),
            (-1 : 1 , 1 : 0), (-1 : 1 , 1 : 1), (-v : 1 , -1 : 1), (-v : 1 , -v : 1),
            (-v : 1 , 0 : 1), (-v : 1 , v : 1), (-v : 1 , 1 : 0), (-v : 1 , 1 : 1),
            (0 : 1 , -1 : 1), (0 : 1 , -v : 1), (0 : 1 , 0 : 1), (0 : 1 , v : 1),
            (0 : 1 , 1 : 0), (0 : 1 , 1 : 1), (v : 1 , -1 : 1), (v : 1 , -v : 1),
            (v : 1 , 0 : 1), (v : 1 , v : 1), (v : 1 , 1 : 0), (v : 1 , 1 : 1),
            (1 : 0 , -1 : 1), (1 : 0 , -v : 1), (1 : 0 , 0 : 1), (1 : 0 , v : 1),
            (1 : 0 , 1 : 0), (1 : 0 , 1 : 1), (1 : 1 , -1 : 1), (1 : 1 , -v : 1),
            (1 : 1 , 0 : 1), (1 : 1 , v : 1), (1 : 1 , 1 : 0), (1 : 1 , 1 : 1)]

        ::

            sage: P.<x,y,z,u,v> = ProductProjectiveSpaces([2, 1], GF(3))
            sage: P(P.base_ring()).points()
            [(0 : 0 : 1 , 0 : 1), (0 : 0 : 1 , 1 : 0), (0 : 0 : 1 , 1 : 1), (0 : 0 : 1 , 2 : 1),
            (0 : 1 : 0 , 0 : 1), (0 : 1 : 0 , 1 : 0), (0 : 1 : 0 , 1 : 1), (0 : 1 : 0 , 2 : 1),
            (0 : 1 : 1 , 0 : 1), (0 : 1 : 1 , 1 : 0), (0 : 1 : 1 , 1 : 1), (0 : 1 : 1 , 2 : 1),
            (0 : 2 : 1 , 0 : 1), (0 : 2 : 1 , 1 : 0), (0 : 2 : 1 , 1 : 1), (0 : 2 : 1 , 2 : 1),
            (1 : 0 : 0 , 0 : 1), (1 : 0 : 0 , 1 : 0), (1 : 0 : 0 , 1 : 1), (1 : 0 : 0 , 2 : 1),
            (1 : 0 : 1 , 0 : 1), (1 : 0 : 1 , 1 : 0), (1 : 0 : 1 , 1 : 1), (1 : 0 : 1 , 2 : 1),
            (1 : 1 : 0 , 0 : 1), (1 : 1 : 0 , 1 : 0), (1 : 1 : 0 , 1 : 1), (1 : 1 : 0 , 2 : 1),
            (1 : 1 : 1 , 0 : 1), (1 : 1 : 1 , 1 : 0), (1 : 1 : 1 , 1 : 1), (1 : 1 : 1 , 2 : 1), 
            (1 : 2 : 1 , 0 : 1), (1 : 2 : 1 , 1 : 0), (1 : 2 : 1 , 1 : 1), (1 : 2 : 1 , 2 : 1),
            (2 : 0 : 1 , 0 : 1), (2 : 0 : 1 , 1 : 0), (2 : 0 : 1 , 1 : 1), (2 : 0 : 1 , 2 : 1),
            (2 : 1 : 0 , 0 : 1), (2 : 1 : 0 , 1 : 0), (2 : 1 : 0 , 1 : 1), (2 : 1 : 0 , 2 : 1),
            (2 : 1 : 1 , 0 : 1), (2 : 1 : 1 , 1 : 0), (2 : 1 : 1 , 1 : 1), (2 : 1 : 1 , 2 : 1),
            (2 : 2 : 1 , 0 : 1), (2 : 2 : 1 , 1 : 0), (2 : 2 : 1 , 1 : 1), (2 : 2 : 1 , 2 : 1)]

        ::

            sage: PP.<x,y,z,u,v> = ProductProjectiveSpaces([2,1], QQ)
            sage: X = PP.subscheme([x + y, u*u-v*u])
            sage: X.rational_points(bound=2)
            [(-2 : 2 : 1 , 0 : 1),
             (-2 : 2 : 1 , 1 : 1),
             (-1 : 1 : 0 , 0 : 1),
             (-1 : 1 : 0 , 1 : 1),
             (-1 : 1 : 1 , 0 : 1),
             (-1 : 1 : 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),
             (1/2 : -1/2 : 1 , 0 : 1),
             (1/2 : -1/2 : 1 , 1 : 1),
             (1 : -1 : 1 , 0 : 1),
             (1 : -1 : 1 , 1 : 1),
             (2 : -2 : 1 , 0 : 1),
             (2 : -2 : 1 , 1 : 1)]

        better to enumerate with low codimension::

            sage: PP.<x,y,z,u,v,a,b,c> = ProductProjectiveSpaces([2,1,2], QQ)
            sage: X = PP.subscheme([x*u^2*a, b*z*u*v,z*v^2*c ])
            sage: len(X.rational_points(bound=1, algorithm='enumerate'))
            232
         """
        B = kwds.pop('bound', 0)
        X = self.codomain()

        from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
        if not is_ProductProjectiveSpaces(X) and X.base_ring() in Fields():
            # no points
            if X.dimension() == -1:
                return []
            # if X is zero-dimensional
            if X.dimension() == 0:
                points = set()
                # find points from all possible affine patches
                for I in xmrange([n + 1 for n in X.ambient_space().dimension_relative_components()]):
                    [Y,phi] = X.affine_patch(I, True)
                    aff_points = Y.rational_points()
                    for PP in aff_points:
                        points.add(phi(PP))
                return list(points)
        R = self.value_ring()
        points = []
        if is_RationalField(R):
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified"%B)
            alg = kwds.pop('algorithm', None)
            if alg is None:
                # sieve should only be called for subschemes and if the bound is not very small
                N = prod([k+1 for k in X.ambient_space().dimension_relative_components()])
                if isinstance(X, AlgebraicScheme_subscheme) and B**N > 5000:
                    from sage.schemes.product_projective.rational_point import sieve
                    return sieve(X, B)
                else:
                    from sage.schemes.product_projective.rational_point import enum_product_projective_rational_field
                    return enum_product_projective_rational_field(self, B)
            elif alg == 'sieve':
                from sage.schemes.product_projective.rational_point import sieve
                return sieve(X, B)
            elif alg == 'enumerate':
                from sage.schemes.product_projective.rational_point import enum_product_projective_rational_field
                return enum_product_projective_rational_field(self, B)
            else:
                raise ValueError("algorithm must be 'sieve' or 'enumerate'")
        elif R in NumberFields():
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified"%B)
            from sage.schemes.product_projective.rational_point import enum_product_projective_number_field
            return enum_product_projective_number_field(self, bound=B)
        elif is_FiniteField(R):
            from sage.schemes.product_projective.rational_point import enum_product_projective_finite_field
            return enum_product_projective_finite_field(self)
        else:
            raise TypeError("unable to enumerate points over %s" % R)
Esempio n. 13
0
    def _coerce_map_from_(self, other):
        r"""
        Return true if ``other`` canonically coerces to ``self``.

        EXAMPLES::

            sage: R.<t> = QQ[]
            sage: P = ProjectiveSpace(QQ, 1, 'x')
            sage: P2 = ProjectiveSpace(R, 1, 'x')
            sage: P2(R)._coerce_map_from_(P(QQ))
            True
            sage: P(QQ)._coerce_map_from_(P2(R))
            False

        ::

            sage: P = ProjectiveSpace(QQ, 1, 'x')
            sage: P2 = ProjectiveSpace(CC, 1, 'y')
            sage: P2(CC)._coerce_map_from_(P(QQ))
            False

        ::

            sage: A.<x,y,z> = AffineSpace(QQ, 3)
            sage: H = A.subscheme(z)
            sage: L = A.subscheme([z, y+z])
            sage: A(QQ)._coerce_map_from_(H(QQ))
            True
            sage: H(QQ)._coerce_map_from_(L(QQ))
            True
            sage: L(QQ).has_coerce_map_from(H(QQ))
            False
            sage: A(CC)._coerce_map_from_(H(QQ))
            True
            sage: H(CC)._coerce_map_from_(L(RR))
            True

        ::

            sage: A.<x,y,z> = AffineSpace(QQ, 3)
            sage: A2.<u,v> = AffineSpace(QQ, 2)
            sage: A(QQ).has_coerce_map_from(A2(QQ))
            False

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: P.<u,v,w> = ProjectiveSpace(QQ, 2)
            sage: A(QQ).has_coerce_map_from(P(QQ))
            False

        ::

            sage: A = AffineSpace(QQ, 1)
            sage: A(QQ)._coerce_map_from_(ZZ)
            True

        ::

            sage: PS = ProjectiveSpace(ZZ, 1, 'x')
            sage: PS2 = ProjectiveSpace(Zp(7), 1, 'x')
            sage: PS(ZZ).has_coerce_map_from(PS2(Zp(7)))
            False
            sage: PS2(Zp(7)).has_coerce_map_from(PS(ZZ))
            True

        ::

            sage: PP1 = ProductProjectiveSpaces(ZZ, [2,1], 'x')
            sage: PP1(QQ)._coerce_map_from_(PP1(ZZ))
            True
            sage: PP2 = ProductProjectiveSpaces(QQ, [1,2], 'x')
            sage: PP2(QQ)._coerce_map_from_(PP1(ZZ))
            False
            sage: PP3 = ProductProjectiveSpaces(QQ, [2,1], 'y')
            sage: PP3(QQ)._coerce_map_from_(PP1(ZZ))
            False

        ::

            sage: K.<w> = QuadraticField(2)
            sage: A.<x,y,z> = AffineSpace(QQ, 3)
            sage: H = A.subscheme(z)
            sage: A(K).has_coerce_map_from(H(QQ))
            True

        TESTS::

            sage: P.<x,y> = ProjectiveSpace(QQ, 1)
            sage: X = P. subscheme ([x-y])
            sage: P(1,1) == X(1,1)
            True

        ::

            sage: A = AffineSpace(QQ, 1, 'x')
            sage: AC = AffineSpace(CC, 1, 'x')
            sage: A(3/2) == AC(3/2)
            True

        ::

            sage: A = AffineSpace(QQ, 1)
            sage: A(0) == 0
            True
        """
        target = self.codomain()
        #ring elements can be coerced to a space if we're affine dimension 1
        #and the base rings are coercible
        if isinstance(other, CommutativeRing):
            try:
                from sage.schemes.affine.affine_space import is_AffineSpace
                if is_AffineSpace(target.ambient_space())\
                  and target.ambient_space().dimension_relative() == 1:
                    return target.base_ring().has_coerce_map_from(other)
                else:
                    return False
            except AttributeError:  #no .ambient_space
                return False
        elif isinstance(other, SchemeHomset_points):
            #we are converting between scheme points
            from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme
            source = other.codomain()
            if isinstance(target, AlgebraicScheme_subscheme):
                #subscheme coerce when there is containment
                if not isinstance(source, AlgebraicScheme_subscheme):
                    return False
                if target.ambient_space() == source.ambient_space():
                    if all([
                            g in source.defining_ideal()
                            for g in target.defining_polynomials()
                    ]):
                        return self.domain().coordinate_ring(
                        ).has_coerce_map_from(other.domain().coordinate_ring())
            else:
                #if the target is an ambient space, we can coerce if the base rings coerce
                #and they are the same type: affine, projective, etc and have the same
                #variable names
                from sage.schemes.projective.projective_space import is_ProjectiveSpace
                from sage.schemes.affine.affine_space import is_AffineSpace
                from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
                try:
                    ta = target.ambient_space()
                    sa = source.ambient_space()
                except AttributeError:  #no .ambient_space
                    return False
                #for projective and affine varieties, we check dimension
                #and matching variable names
                if (is_ProjectiveSpace(ta) and is_ProjectiveSpace(sa))\
                  or (is_AffineSpace(ta) and is_AffineSpace(sa)):
                    if (ta.variable_names() == sa.variable_names()):
                        return self.domain().coordinate_ring(
                        ).has_coerce_map_from(other.domain().coordinate_ring())
                    else:
                        return False
                #for products of projective spaces, we check dimension of
                #components and matching variable names
                elif (is_ProductProjectiveSpaces(ta)
                      and is_ProductProjectiveSpaces(sa)):
                    if (ta.dimension_relative_components() == sa.dimension_relative_components()) \
                      and (ta.variable_names() == sa.variable_names()):
                        return self.domain().coordinate_ring(
                        ).has_coerce_map_from(other.domain().coordinate_ring())
                    else:
                        return False
Esempio n. 14
0
    def points(self, **kwds):
        r"""
        Return some or all rational points of a projective scheme.

        Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound
        are returned. For a zero-dimensional subscheme, all points are returned regardless of whether the base
        ring is a field or not.

        For number fields, this uses the
        Doyle-Krumm algorithm 4 (algorithm 5 for imaginary quadratic) for
        computing algebraic numbers up to a given height [Doyle-Krumm]_.

        The algorithm requires floating point arithmetic, so the user is
        allowed to specify the precision for such calculations.
        Additionally, due to floating point issues, points
        slightly larger than the bound may be returned. This can be controlled
        by lowering the tolerance.


        INPUT:

        - ``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 of rational points of a projective scheme

        EXAMPLES::

            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1, 1], QQ)
            sage: X = P.subscheme([x - y, z^2 - 2*w^2])
            sage: X(P.base_ring()).points()
            []

        ::

            sage: u = QQ['u'].0
            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1,1], NumberField(u^2 - 2, 'v'))
            sage: X = P.subscheme([x^2 - y^2, z^2 - 2*w^2])
            sage: X(P.base_ring()).points()
            [(-1 : 1 , -v : 1), (1 : 1 , v : 1), (1 : 1 , -v : 1), (-1 : 1 , v : 1)]

        ::

            sage: u = QQ['u'].0
            sage: K = NumberField(u^2 + 1, 'v')
            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1, 1], K)
            sage: P(K).points(bound=1)
            [(0 : 1 , 0 : 1), (0 : 1 , v : 1), (0 : 1 , -1 : 1), (0 : 1 , -v : 1), (0 : 1 , 1 : 1),
            (0 : 1 , 1 : 0), (v : 1 , 0 : 1), (v : 1 , v : 1), (v : 1 , -1 : 1), (v : 1 , -v : 1),
            (v : 1 , 1 : 1), (v : 1 , 1 : 0), (-1 : 1 , 0 : 1), (-1 : 1 , v : 1), (-1 : 1 , -1 : 1),
            (-1 : 1 , -v : 1), (-1 : 1 , 1 : 1), (-1 : 1 , 1 : 0), (-v : 1 , 0 : 1), (-v : 1 , v : 1),
            (-v : 1 , -1 : 1), (-v : 1 , -v : 1), (-v : 1 , 1 : 1), (-v : 1 , 1 : 0), (1 : 1 , 0 : 1),
            (1 : 1 , v : 1), (1 : 1 , -1 : 1), (1 : 1 , -v : 1), (1 : 1 , 1 : 1), (1 : 1 , 1 : 0),
            (1 : 0 , 0 : 1), (1 : 0 , v : 1), (1 : 0 , -1 : 1), (1 : 0 , -v : 1), (1 : 0 , 1 : 1),
            (1 : 0 , 1 : 0)]

        ::

            sage: P.<x,y,z,u,v> = ProductProjectiveSpaces([2, 1], GF(3))
            sage: P(P.base_ring()).points()
            [(0 : 0 : 1 , 0 : 1), (1 : 0 : 1 , 0 : 1), (2 : 0 : 1 , 0 : 1), (0 : 1 : 1 , 0 : 1), (1 : 1 : 1 , 0 : 1),
            (2 : 1 : 1 , 0 : 1), (0 : 2 : 1 , 0 : 1), (1 : 2 : 1 , 0 : 1), (2 : 2 : 1 , 0 : 1), (0 : 1 : 0 , 0 : 1),
            (1 : 1 : 0 , 0 : 1), (2 : 1 : 0 , 0 : 1), (1 : 0 : 0 , 0 : 1), (0 : 0 : 1 , 1 : 1), (1 : 0 : 1 , 1 : 1),
            (2 : 0 : 1 , 1 : 1), (0 : 1 : 1 , 1 : 1), (1 : 1 : 1 , 1 : 1), (2 : 1 : 1 , 1 : 1), (0 : 2 : 1 , 1 : 1),
            (1 : 2 : 1 , 1 : 1), (2 : 2 : 1 , 1 : 1), (0 : 1 : 0 , 1 : 1), (1 : 1 : 0 , 1 : 1), (2 : 1 : 0 , 1 : 1),
            (1 : 0 : 0 , 1 : 1), (0 : 0 : 1 , 2 : 1), (1 : 0 : 1 , 2 : 1), (2 : 0 : 1 , 2 : 1), (0 : 1 : 1 , 2 : 1),
            (1 : 1 : 1 , 2 : 1), (2 : 1 : 1 , 2 : 1), (0 : 2 : 1 , 2 : 1), (1 : 2 : 1 , 2 : 1), (2 : 2 : 1 , 2 : 1),
            (0 : 1 : 0 , 2 : 1), (1 : 1 : 0 , 2 : 1), (2 : 1 : 0 , 2 : 1), (1 : 0 : 0 , 2 : 1), (0 : 0 : 1 , 1 : 0),
            (1 : 0 : 1 , 1 : 0), (2 : 0 : 1 , 1 : 0), (0 : 1 : 1 , 1 : 0), (1 : 1 : 1 , 1 : 0), (2 : 1 : 1 , 1 : 0),
            (0 : 2 : 1 , 1 : 0), (1 : 2 : 1 , 1 : 0), (2 : 2 : 1 , 1 : 0), (0 : 1 : 0 , 1 : 0), (1 : 1 : 0 , 1 : 0),
            (2 : 1 : 0 , 1 : 0), (1 : 0 : 0 , 1 : 0)]
        """
        B = kwds.pop('bound', 0)
        tol = kwds.pop('tolerance', 1e-2)
        prec = kwds.pop('precision', 53)

        X = self.codomain()

        from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
        if not is_ProductProjectiveSpaces(X) and X.base_ring() in Fields():
            # no points
            if X.dimension() == -1:
                return []
            # if X is zero-dimensional
            if X.dimension() == 0:
                points = set()
                # find points from all possible affine patches
                for I in xmrange([
                        n + 1 for n in
                        X.ambient_space().dimension_relative_components()
                ]):
                    [Y, phi] = X.affine_patch(I, True)
                    aff_points = Y.rational_points()
                    for PP in aff_points:
                        points.add(phi(PP))
                return list(points)
        R = self.value_ring()
        points = []
        if R in NumberFields():
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified" %
                                B)
            for P in X.ambient_space().points_of_bounded_height(
                    bound=B, tolerance=tol, precision=prec):
                try:
                    points.append(X(P))
                except TypeError:
                    pass
            return points
        if is_FiniteField(R):
            for P in X.ambient_space().rational_points():
                try:
                    points.append(X(P))
                except TypeError:
                    pass
            return points
        else:
            raise TypeError("unable to enumerate points over %s" % R)
Esempio n. 15
0
    def points(self, B=0, prec=53):
        r"""
        Return some or all rational points of a projective scheme.

        Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound
        are returned. For a zero-dimensional subscheme, all points are returned regardless of whether the base
        ring is a field or not.

        INPUT:

        - `B` -- integer (optional, default=0). The bound for the
          coordinates.
        - ``prec`` - the precision to use to compute the elements of bounded height for number fields.

        OUTPUT:

        - a list of rational points of a projective scheme.

        .. WARNING::

           In the current implementation, the output of the [Doyle-Krumm]_ algorithm
           cannot be guaranteed to be correct due to the necessity of floating point
           computations. In some cases, the default 53-bit precision is
           considerably lower than would be required for the algorithm to
           generate correct output.

        EXAMPLES::

            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1, 1], QQ)
            sage: X = P.subscheme([x - y, z^2 - 2*w^2])
            sage: X(P.base_ring()).points()
            []

        ::

            sage: u = QQ['u'].0
            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1,1], NumberField(u^2 - 2, 'v'))
            sage: X = P.subscheme([x^2 - y^2, z^2 - 2*w^2])
            sage: X(P.base_ring()).points()
            [(-1 : 1 , -v : 1), (1 : 1 , v : 1), (1 : 1 , -v : 1), (-1 : 1 , v : 1)]

        ::

            sage: u = QQ['u'].0
            sage: K = NumberField(u^2 + 1, 'v')
            sage: P.<x,y,z,w> = ProductProjectiveSpaces([1, 1], K)
            sage: P(K).points(1)
            [(0 : 1 , 0 : 1), (0 : 1 , v : 1), (0 : 1 , -1 : 1), (0 : 1 , -v : 1), (0 : 1 , 1 : 1),
            (0 : 1 , 1 : 0), (v : 1 , 0 : 1), (v : 1 , v : 1), (v : 1 , -1 : 1), (v : 1 , -v : 1),
            (v : 1 , 1 : 1), (v : 1 , 1 : 0), (-1 : 1 , 0 : 1), (-1 : 1 , v : 1), (-1 : 1 , -1 : 1),
            (-1 : 1 , -v : 1), (-1 : 1 , 1 : 1), (-1 : 1 , 1 : 0), (-v : 1 , 0 : 1), (-v : 1 , v : 1),
            (-v : 1 , -1 : 1), (-v : 1 , -v : 1), (-v : 1 , 1 : 1), (-v : 1 , 1 : 0), (1 : 1 , 0 : 1),
            (1 : 1 , v : 1), (1 : 1 , -1 : 1), (1 : 1 , -v : 1), (1 : 1 , 1 : 1), (1 : 1 , 1 : 0),
            (1 : 0 , 0 : 1), (1 : 0 , v : 1), (1 : 0 , -1 : 1), (1 : 0 , -v : 1), (1 : 0 , 1 : 1),
            (1 : 0 , 1 : 0)]

        ::

            sage: P.<x,y,z,u,v> = ProductProjectiveSpaces([2, 1], GF(3))
            sage: P(P.base_ring()).points()
            [(0 : 0 : 1 , 0 : 1), (1 : 0 : 1 , 0 : 1), (2 : 0 : 1 , 0 : 1), (0 : 1 : 1 , 0 : 1), (1 : 1 : 1 , 0 : 1),
            (2 : 1 : 1 , 0 : 1), (0 : 2 : 1 , 0 : 1), (1 : 2 : 1 , 0 : 1), (2 : 2 : 1 , 0 : 1), (0 : 1 : 0 , 0 : 1),
            (1 : 1 : 0 , 0 : 1), (2 : 1 : 0 , 0 : 1), (1 : 0 : 0 , 0 : 1), (0 : 0 : 1 , 1 : 1), (1 : 0 : 1 , 1 : 1),
            (2 : 0 : 1 , 1 : 1), (0 : 1 : 1 , 1 : 1), (1 : 1 : 1 , 1 : 1), (2 : 1 : 1 , 1 : 1), (0 : 2 : 1 , 1 : 1),
            (1 : 2 : 1 , 1 : 1), (2 : 2 : 1 , 1 : 1), (0 : 1 : 0 , 1 : 1), (1 : 1 : 0 , 1 : 1), (2 : 1 : 0 , 1 : 1),
            (1 : 0 : 0 , 1 : 1), (0 : 0 : 1 , 2 : 1), (1 : 0 : 1 , 2 : 1), (2 : 0 : 1 , 2 : 1), (0 : 1 : 1 , 2 : 1),
            (1 : 1 : 1 , 2 : 1), (2 : 1 : 1 , 2 : 1), (0 : 2 : 1 , 2 : 1), (1 : 2 : 1 , 2 : 1), (2 : 2 : 1 , 2 : 1),
            (0 : 1 : 0 , 2 : 1), (1 : 1 : 0 , 2 : 1), (2 : 1 : 0 , 2 : 1), (1 : 0 : 0 , 2 : 1), (0 : 0 : 1 , 1 : 0),
            (1 : 0 : 1 , 1 : 0), (2 : 0 : 1 , 1 : 0), (0 : 1 : 1 , 1 : 0), (1 : 1 : 1 , 1 : 0), (2 : 1 : 1 , 1 : 0),
            (0 : 2 : 1 , 1 : 0), (1 : 2 : 1 , 1 : 0), (2 : 2 : 1 , 1 : 0), (0 : 1 : 0 , 1 : 0), (1 : 1 : 0 , 1 : 0),
            (2 : 1 : 0 , 1 : 0), (1 : 0 : 0 , 1 : 0)]
        """
        X = self.codomain()

        from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
        if not is_ProductProjectiveSpaces(X) and X.base_ring() in Fields():
            # no points
            if X.dimension() == -1:
                return []
            # if X is zero-dimensional
            if X.dimension() == 0:
                points = set()
                # find points from all possible affine patches
                for I in xmrange([
                        n + 1 for n in
                        X.ambient_space().dimension_relative_components()
                ]):
                    [Y, phi] = X.affine_patch(I, True)
                    aff_points = Y.rational_points()
                    for PP in aff_points:
                        points.add(phi(PP))
                return list(points)
        R = self.value_ring()
        points = []
        if R in NumberFields():
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified" %
                                B)
            for P in X.ambient_space().points_of_bounded_height(B, prec):
                try:
                    points.append(X(P))
                except TypeError:
                    pass
            return points
        if is_FiniteField(R):
            for P in X.ambient_space().rational_points():
                try:
                    points.append(X(P))
                except TypeError:
                    pass
            return points
        else:
            raise TypeError("unable to enumerate points over %s" % R)