def iterate_by_length(self, l=1): r""" Returns an iterator over all the words of self of length l. INPUT: - ``l`` - integer (default: 1), the length of the desired words EXAMPLES:: sage: W = Words('ab') sage: list(W.iterate_by_length(1)) [word: a, word: b] sage: list(W.iterate_by_length(2)) [word: aa, word: ab, word: ba, word: bb] sage: list(W.iterate_by_length(3)) [word: aaa, word: aab, word: aba, word: abb, word: baa, word: bab, word: bba, word: bbb] sage: list(W.iterate_by_length('a')) Traceback (most recent call last): ... TypeError: the parameter l (='a') must be an integer """ if not isinstance(l, (int,Integer)): raise TypeError, "the parameter l (=%r) must be an integer"%l #if l == Integer(0): # yield self() for w in xmrange([self.size_of_alphabet()]*l): yield self(map(lambda x: self.alphabet().unrank(x), w))
def iterate_by_length(self, l=1): r""" Returns an iterator over all the words of self of length l. INPUT: - ``l`` - integer (default: 1), the length of the desired words EXAMPLES:: sage: W = Words('ab') sage: list(W.iterate_by_length(1)) [word: a, word: b] sage: list(W.iterate_by_length(2)) [word: aa, word: ab, word: ba, word: bb] sage: list(W.iterate_by_length(3)) [word: aaa, word: aab, word: aba, word: abb, word: baa, word: bab, word: bba, word: bbb] sage: list(W.iterate_by_length('a')) Traceback (most recent call last): ... TypeError: the parameter l (='a') must be an integer """ if not isinstance(l, (int, Integer)): raise TypeError, "the parameter l (=%r) must be an integer" % l #if l == Integer(0): # yield self() for w in xmrange([self.size_of_alphabet()] * l): yield self(map(lambda x: self.alphabet().unrank(x), w))
def units_mod_ideal(I): """ Returns integral elements of the number field representing the images of the global units modulo the ideal ``I``. INPUT: - ``I`` -- number field ideal. OUTPUT: A list of integral elements of the number field representing the images of the global units modulo the ideal ``I``. Elements of the list might be equivalent to each other mod ``I``. EXAMPLES:: sage: from sage.modular.cusps_nf import units_mod_ideal sage: k.<a> = NumberField(x^2 + 1) sage: I = k.ideal(a + 1) sage: units_mod_ideal(I) [1] sage: I = k.ideal(3) sage: units_mod_ideal(I) [1, a, -1, -a] :: sage: from sage.modular.cusps_nf import units_mod_ideal sage: k.<a> = NumberField(x^3 + 11) sage: k.unit_group() Unit group with structure C2 x Z of Number Field in a with defining polynomial x^3 + 11 sage: I = k.ideal(5, a + 1) sage: units_mod_ideal(I) [1, 2*a^2 + 4*a - 1, ...] :: sage: from sage.modular.cusps_nf import units_mod_ideal sage: k.<a> = NumberField(x^4 - x^3 -21*x^2 + 17*x + 133) sage: k.unit_group() Unit group with structure C6 x Z of Number Field in a with defining polynomial x^4 - x^3 - 21*x^2 + 17*x + 133 sage: I = k.ideal(3) sage: U = units_mod_ideal(I) sage: all([U[j].is_unit() and not (U[j] in I) for j in range(len(U))]) True """ k = I.number_field() Uk = k.unit_group() Istar = I.idealstar(2) ulist = Uk.gens_values() elist = [Istar(I.ideallog(u)).order() for u in ulist] from sage.misc.mrange import xmrange from sage.misc.misc import prod return [prod([u**e for u,e in zip(ulist,ei)],k(1)) for ei in xmrange(elist)]
def units_mod_ideal(I): """ Returns integral elements of the number field representing the images of the global units modulo the ideal ``I``. INPUT: - ``I`` -- number field ideal. OUTPUT: A list of integral elements of the number field representing the images of the global units modulo the ideal ``I``. Elements of the list might be equivalent to each other mod ``I``. EXAMPLES:: sage: from sage.modular.cusps_nf import units_mod_ideal sage: k.<a> = NumberField(x^2 + 1) sage: I = k.ideal(a + 1) sage: units_mod_ideal(I) [1] sage: I = k.ideal(3) sage: units_mod_ideal(I) [1, a, -1, -a] :: sage: from sage.modular.cusps_nf import units_mod_ideal sage: k.<a> = NumberField(x^3 + 11) sage: k.unit_group() Unit group with structure C2 x Z of Number Field in a with defining polynomial x^3 + 11 sage: I = k.ideal(5, a + 1) sage: units_mod_ideal(I) [1, 2*a^2 + 4*a - 1, ...] :: sage: from sage.modular.cusps_nf import units_mod_ideal sage: k.<a> = NumberField(x^4 - x^3 -21*x^2 + 17*x + 133) sage: k.unit_group() Unit group with structure C6 x Z of Number Field in a with defining polynomial x^4 - x^3 - 21*x^2 + 17*x + 133 sage: I = k.ideal(3) sage: U = units_mod_ideal(I) sage: all([U[j].is_unit() and not (U[j] in I) for j in range(len(U))]) True """ k = I.number_field() Uk = k.unit_group() Istar = I.idealstar(2) ulist = Uk.gens_values() elist = [Istar(I.ideallog(u)).order() for u in ulist] from sage.misc.mrange import xmrange from sage.misc.all import prod return [k.prod(u**e for u, e in zip(ulist, ei)) for ei in xmrange(elist)]
def parallel_function_combination(point_p_max): r""" Function used in parallel computation, computes rational points lifted. """ rat_points = set() for tupl in xmrange(len_modulo_points): point = [] for k in range(N): # lift all coordinates of given point using chinese remainder theorem L = [ modulo_points[j][tupl[j]][k].lift() for j in range(len_primes - 1) ] L.append(point_p_max[k].lift()) point.append(crt(L, primes_list)) for i in range(num_comp): for j in range(comp_dim_relative[i]): m[i][j] = point[dim_prefix[i] + j] # generating matrix to compute LLL reduction for each component M = [matrix(ZZ, comp_dim_relative[i] + 1, comp_dim_relative[i], m[i]) \ for i in range(num_comp)] A = [M[i].LLL() for i in range(num_comp)] point = [] for i in range(num_comp): point.extend(A[i][1]) # check if all coordinates of this point satisfy height bound bound_satisfied = True for coordinate in point: if coordinate.abs() > bound: bound_satisfied = False break if not bound_satisfied: continue try: rat_points.add( X(point)) # checks if this point lies on X or not except: pass return [list(_) for _ in rat_points]
def parallel_function_combination(point_p_max): r""" Function used in parallel computation, computes rational points lifted. """ rat_points = set() for tupl in xmrange(len_modulo_points): point = [] for k in range(N + 1): # lift all coordinates of given point using chinese remainder theorem L = [ modulo_points[j][tupl[j]][k].lift() for j in range(len_primes - 1) ] L.append(point_p_max[k].lift()) point.append(crt(L, primes_list)) for i in range(N + 1): m[i] = point[i] M = matrix(ZZ, N + 2, N + 1, m) A = M.LLL() point = list(A[1]) # check if all coordinates of this point satisfy height bound bound_satisfied = True for coordinate in point: if coordinate.abs() > bound: bound_satisfied = False break if not bound_satisfied: continue try: pt = X(list(A[1])) except TypeError: pass else: rat_points.add(pt) return [list(_) for _ in rat_points]
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 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 points_of_bounded_height(self,bound, prec=53): r""" Returns an iterator of the points in this product of projective spaces with the absolute heights of the components of at most the given bound. Bound check is strict for the rational field. Requires the base field of this space to be a number field. Uses the Doyle-Krumm algorithm for computing algebraic numbers up to a given height [Doyle-Krumm]_. INPUT: - ``bound`` - a real number - ``prec`` - the precision to use to compute the elements of bounded height for number fields OUTPUT: - an iterator of points in this space .. 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: PP = ProductProjectiveSpaces(QQ, [1, 2]) sage: list(PP.points_of_bounded_height(2)) [(0 : 1 , 0 : 0 : 1), (0 : 1 , 1 : 0 : 1), (0 : 1 , -1 : 0 : 1), (0 : 1 , 0 : 1 : 1), (0 : 1 , 1 : 1 : 1), (0 : 1 , -1 : 1 : 1), (0 : 1 , 0 : -1 : 1), (0 : 1 , 1 : -1 : 1), (0 : 1 , -1 : -1 : 1), (0 : 1 , 0 : 1 : 0), (0 : 1 , 1 : 1 : 0), (0 : 1 , -1 : 1 : 0), (0 : 1 , 1 : 0 : 0), (1 : 1 , 0 : 0 : 1), (1 : 1 , 1 : 0 : 1), (1 : 1 , -1 : 0 : 1), (1 : 1 , 0 : 1 : 1), (1 : 1 , 1 : 1 : 1), (1 : 1 , -1 : 1 : 1), (1 : 1 , 0 : -1 : 1), (1 : 1 , 1 : -1 : 1), (1 : 1 , -1 : -1 : 1), (1 : 1 , 0 : 1 : 0), (1 : 1 , 1 : 1 : 0), (1 : 1 , -1 : 1 : 0), (1 : 1 , 1 : 0 : 0), (-1 : 1 , 0 : 0 : 1), (-1 : 1 , 1 : 0 : 1), (-1 : 1 , -1 : 0 : 1), (-1 : 1 , 0 : 1 : 1), (-1 : 1 , 1 : 1 : 1), (-1 : 1 , -1 : 1 : 1), (-1 : 1 , 0 : -1 : 1), (-1 : 1 , 1 : -1 : 1), (-1 : 1 , -1 : -1 : 1), (-1 : 1 , 0 : 1 : 0), (-1 : 1 , 1 : 1 : 0), (-1 : 1 , -1 : 1 : 0), (-1 : 1 , 1 : 0 : 0), (1 : 0 , 0 : 0 : 1), (1 : 0 , 1 : 0 : 1), (1 : 0 , -1 : 0 : 1), (1 : 0 , 0 : 1 : 1), (1 : 0 , 1 : 1 : 1), (1 : 0 , -1 : 1 : 1), (1 : 0 , 0 : -1 : 1), (1 : 0 , 1 : -1 : 1), (1 : 0 , -1 : -1 : 1), (1 : 0 , 0 : 1 : 0), (1 : 0 , 1 : 1 : 0), (1 : 0 , -1 : 1 : 0), (1 : 0 , 1 : 0 : 0)] :: sage: u = QQ['u'].0 sage: P = ProductProjectiveSpaces([1, 1], NumberField(u^2 - 2, 'v')) sage: list(P.points_of_bounded_height(1.5)) [(0 : 1 , 0 : 1), (0 : 1 , -1 : 1), (0 : 1 , 1 : 1), (0 : 1 , -1/2*v : 1), (0 : 1 , -v : 1), (0 : 1 , 1/2*v : 1), (0 : 1 , v : 1), (0 : 1 , 1 : 0), (-1 : 1 , 0 : 1), (-1 : 1 , -1 : 1), (-1 : 1 , 1 : 1), (-1 : 1 , -1/2*v : 1), (-1 : 1 , -v : 1), (-1 : 1 , 1/2*v : 1), (-1 : 1 , v : 1), (-1 : 1 , 1 : 0), (1 : 1 , 0 : 1), (1 : 1 , -1 : 1), (1 : 1 , 1 : 1), (1 : 1 , -1/2*v : 1), (1 : 1 , -v : 1), (1 : 1 , 1/2*v : 1), (1 : 1 , v : 1), (1 : 1 , 1 : 0), (-1/2*v : 1 , 0 : 1), (-1/2*v : 1 , -1 : 1), (-1/2*v : 1 , 1 : 1), (-1/2*v : 1 , -1/2*v : 1), (-1/2*v : 1 , -v : 1), (-1/2*v : 1 , 1/2*v : 1), (-1/2*v : 1 , v : 1), (-1/2*v : 1 , 1 : 0), (-v : 1 , 0 : 1), (-v : 1 , -1 : 1), (-v : 1 , 1 : 1), (-v : 1 , -1/2*v : 1), (-v : 1 , -v : 1), (-v : 1 , 1/2*v : 1), (-v : 1 , v : 1), (-v : 1 , 1 : 0), (1/2*v : 1 , 0 : 1), (1/2*v : 1 , -1 : 1), (1/2*v : 1 , 1 : 1), (1/2*v : 1 , -1/2*v : 1), (1/2*v : 1 , -v : 1), (1/2*v : 1 , 1/2*v : 1), (1/2*v : 1 , v : 1), (1/2*v : 1 , 1 : 0), (v : 1 , 0 : 1), (v : 1 , -1 : 1), (v : 1 , 1 : 1), (v : 1 , -1/2*v : 1), (v : 1 , -v : 1), (v : 1 , 1/2*v : 1), (v : 1 , v : 1), (v : 1 , 1 : 0), (1 : 0 , 0 : 1), (1 : 0 , -1 : 1), (1 : 0 , 1 : 1), (1 : 0 , -1/2*v : 1), (1 : 0 , -v : 1), (1 : 0 , 1/2*v : 1), (1 : 0 , v : 1), (1 : 0 , 1 : 0)] """ m = self.num_components() comp_points = [list(self._components[i].points_of_bounded_height(bound, prec)) for i in range(m)] indices = xmrange([len(comp_points[i]) for i in range(m)]) return iter([self([comp_points[t][I[t]] for t in range(m)]) for I in indices])
def points_of_bounded_height(self, **kwds): r""" Returns an iterator of the points in this product of projective spaces with the absolute heights of the components of at most the given bound. Bound check is strict for the rational field. Requires the base field of this space to be a number field. 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: - an iterator of points in this space EXAMPLES:: sage: PP = ProductProjectiveSpaces(QQ, [1, 2]) sage: list(PP.points_of_bounded_height(bound=2)) [(0 : 1 , 0 : 0 : 1), (0 : 1 , 1 : 0 : 1), (0 : 1 , -1 : 0 : 1), (0 : 1 , 0 : 1 : 1), (0 : 1 , 1 : 1 : 1), (0 : 1 , -1 : 1 : 1), (0 : 1 , 0 : -1 : 1), (0 : 1 , 1 : -1 : 1), (0 : 1 , -1 : -1 : 1), (0 : 1 , 0 : 1 : 0), (0 : 1 , 1 : 1 : 0), (0 : 1 , -1 : 1 : 0), (0 : 1 , 1 : 0 : 0), (1 : 1 , 0 : 0 : 1), (1 : 1 , 1 : 0 : 1), (1 : 1 , -1 : 0 : 1), (1 : 1 , 0 : 1 : 1), (1 : 1 , 1 : 1 : 1), (1 : 1 , -1 : 1 : 1), (1 : 1 , 0 : -1 : 1), (1 : 1 , 1 : -1 : 1), (1 : 1 , -1 : -1 : 1), (1 : 1 , 0 : 1 : 0), (1 : 1 , 1 : 1 : 0), (1 : 1 , -1 : 1 : 0), (1 : 1 , 1 : 0 : 0), (-1 : 1 , 0 : 0 : 1), (-1 : 1 , 1 : 0 : 1), (-1 : 1 , -1 : 0 : 1), (-1 : 1 , 0 : 1 : 1), (-1 : 1 , 1 : 1 : 1), (-1 : 1 , -1 : 1 : 1), (-1 : 1 , 0 : -1 : 1), (-1 : 1 , 1 : -1 : 1), (-1 : 1 , -1 : -1 : 1), (-1 : 1 , 0 : 1 : 0), (-1 : 1 , 1 : 1 : 0), (-1 : 1 , -1 : 1 : 0), (-1 : 1 , 1 : 0 : 0), (1 : 0 , 0 : 0 : 1), (1 : 0 , 1 : 0 : 1), (1 : 0 , -1 : 0 : 1), (1 : 0 , 0 : 1 : 1), (1 : 0 , 1 : 1 : 1), (1 : 0 , -1 : 1 : 1), (1 : 0 , 0 : -1 : 1), (1 : 0 , 1 : -1 : 1), (1 : 0 , -1 : -1 : 1), (1 : 0 , 0 : 1 : 0), (1 : 0 , 1 : 1 : 0), (1 : 0 , -1 : 1 : 0), (1 : 0 , 1 : 0 : 0)] :: sage: u = QQ['u'].0 sage: P = ProductProjectiveSpaces([1, 1], NumberField(u^2 - 2, 'v')) sage: list(P.points_of_bounded_height(bound=1.5)) [(0 : 1 , 0 : 1), (0 : 1 , -1 : 1), (0 : 1 , 1 : 1), (0 : 1 , -1/2*v : 1), (0 : 1 , -v : 1), (0 : 1 , 1/2*v : 1), (0 : 1 , v : 1), (0 : 1 , 1 : 0), (-1 : 1 , 0 : 1), (-1 : 1 , -1 : 1), (-1 : 1 , 1 : 1), (-1 : 1 , -1/2*v : 1), (-1 : 1 , -v : 1), (-1 : 1 , 1/2*v : 1), (-1 : 1 , v : 1), (-1 : 1 , 1 : 0), (1 : 1 , 0 : 1), (1 : 1 , -1 : 1), (1 : 1 , 1 : 1), (1 : 1 , -1/2*v : 1), (1 : 1 , -v : 1), (1 : 1 , 1/2*v : 1), (1 : 1 , v : 1), (1 : 1 , 1 : 0), (-1/2*v : 1 , 0 : 1), (-1/2*v : 1 , -1 : 1), (-1/2*v : 1 , 1 : 1), (-1/2*v : 1 , -1/2*v : 1), (-1/2*v : 1 , -v : 1), (-1/2*v : 1 , 1/2*v : 1), (-1/2*v : 1 , v : 1), (-1/2*v : 1 , 1 : 0), (-v : 1 , 0 : 1), (-v : 1 , -1 : 1), (-v : 1 , 1 : 1), (-v : 1 , -1/2*v : 1), (-v : 1 , -v : 1), (-v : 1 , 1/2*v : 1), (-v : 1 , v : 1), (-v : 1 , 1 : 0), (1/2*v : 1 , 0 : 1), (1/2*v : 1 , -1 : 1), (1/2*v : 1 , 1 : 1), (1/2*v : 1 , -1/2*v : 1), (1/2*v : 1 , -v : 1), (1/2*v : 1 , 1/2*v : 1), (1/2*v : 1 , v : 1), (1/2*v : 1 , 1 : 0), (v : 1 , 0 : 1), (v : 1 , -1 : 1), (v : 1 , 1 : 1), (v : 1 , -1/2*v : 1), (v : 1 , -v : 1), (v : 1 , 1/2*v : 1), (v : 1 , v : 1), (v : 1 , 1 : 0), (1 : 0 , 0 : 1), (1 : 0 , -1 : 1), (1 : 0 , 1 : 1), (1 : 0 , -1/2*v : 1), (1 : 0 , -v : 1), (1 : 0 , 1/2*v : 1), (1 : 0 , v : 1), (1 : 0 , 1 : 0)] """ B = kwds.pop('bound') tol = kwds.pop('tolerance', 1e-2) prec = kwds.pop('precision', 53) m = self.num_components() comp_points = [list(self._components[i].points_of_bounded_height(bound=B, tolerance=tol, precision=prec)) for i in range(m)] indices = xmrange([len(comp_points[i]) for i in range(m)]) return iter([self([comp_points[t][I[t]] for t in range(m)]) for I in indices])
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)