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