22
22
from math import floor
23
23
24
24
from sage .schemes .projective .projective_space import ProjectiveSpace
25
+ from sage .rings .integer_ring import ZZ
25
26
from sage .rings .rational_field import QQ
26
27
from sage .rings .real_mpfr import RealField
27
28
from sage .rings .number_field .unit_group import UnitGroup
28
- from sage .arith .misc import GCD as gcd
29
+ from sage .arith .misc import gcd
30
+ from sage .arith .functions import lcm
29
31
from sage .matrix .constructor import matrix , column_matrix
30
32
from sage .libs .pari .all import pari
31
33
from sage .modules .free_module_element import vector
32
34
from sage .rings .integer import Integer
33
35
from sage .geometry .polyhedron .constructor import Polyhedron
34
36
35
37
36
- def QQ_points_of_bounded_height ( dim , bound ):
38
+ def ZZ_points_of_bounded_height ( PS , dim , bound ):
37
39
r"""
38
40
Return an iterator of the points in ``self`` of absolute multiplicative
39
41
height of at most ``bound`` in the rational field.
40
42
41
43
INPUT:
42
44
45
+ - ``PS`` -- a projective space
46
+
47
+ - ``dim`` -- a positive integer
48
+
49
+ - ``bound`` -- a positive integer
50
+
51
+ OUTPUT:
52
+
53
+ - an iterator of points of bounded height
54
+
55
+ EXAMPLES:
56
+
57
+ sage: from sage.schemes.projective.proj_bdd_height import ZZ_points_of_bounded_height
58
+ sage: PS = ProjectiveSpace(ZZ, 1)
59
+ sage: sorted(list(ZZ_points_of_bounded_height(PS, 1, 1)))
60
+ [(-1 : -1), (-1 : 0), (-1 : 1), (0 : -1)]
61
+ sage: len(list(ZZ_points_of_bounded_height(PS, 1, 5)))
62
+ 40
63
+ sage: sorted(list(ZZ_points_of_bounded_height(PS, 1, 2)))
64
+ [(-2 : -1), (-2 : 1), (-1 : -2), (-1 : -1),
65
+ (-1 : 0), (-1 : 1), (-1 : 2), (0 : -1)]
66
+ sage: PS = ProjectiveSpace(ZZ, 2)
67
+ sage: sorted(list(ZZ_points_of_bounded_height(PS, 2, 1)))
68
+ [(-1 : -1 : -1), (-1 : -1 : 0), (-1 : -1 : 1), (-1 : 0 : -1),
69
+ (-1 : 0 : 0), (-1 : 0 : 1), (-1 : 1 : -1), (-1 : 1 : 0),
70
+ (-1 : 1 : 1), (0 : -1 : -1), (0 : -1 : 0), (0 : -1 : 1),
71
+ (0 : 0 : -1)]
72
+
73
+ There are no points of negative height::
74
+
75
+ sage: from sage.schemes.projective.proj_bdd_height import ZZ_points_of_bounded_height
76
+ sage: PS = ProjectiveSpace(ZZ, 1)
77
+ sage: list(ZZ_points_of_bounded_height(PS, 1, -3))
78
+ []
79
+ """
80
+ if bound < 1 :
81
+ return iter (set ([]))
82
+
83
+ points_of_bounded_height = set ([])
84
+
85
+ for t in itertools .product (range (- bound , bound + 1 ), repeat = dim + 1 ):
86
+ if gcd (t ) == 1 :
87
+ point = PS (t )
88
+ if point not in points_of_bounded_height :
89
+ points_of_bounded_height .add (point )
90
+ yield point
91
+
92
+
93
+ def QQ_points_of_bounded_height (PS , dim , bound , normalize = False ):
94
+ r"""
95
+ Return an iterator of the points in ``self`` of absolute multiplicative
96
+ height of at most ``bound`` in the rational field.
97
+
98
+ INPUT:
99
+
100
+ - ``PS`` -- a projective space
101
+
43
102
- ``dim`` -- a positive integer
44
103
45
104
- ``bound`` -- a real number
46
105
106
+ - ``normalize`` -- boolean (optional, default: ``False``); whether to
107
+ normalize the coordinates of returned points
108
+
47
109
OUTPUT:
48
110
49
111
- an iterator of points of bounded height
50
112
51
113
EXAMPLES:
52
114
53
115
sage: from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height
54
- sage: sorted(list(QQ_points_of_bounded_height(1, 1)))
116
+ sage: PS = ProjectiveSpace(QQ, 1)
117
+ sage: sorted(list(QQ_points_of_bounded_height(PS, 1, 1)))
55
118
[(-1 : 1), (0 : 1), (1 : 0), (1 : 1)]
56
- sage: len(list(QQ_points_of_bounded_height(1, 5)))
119
+ sage: len(list(QQ_points_of_bounded_height(PS, 1, 5)))
57
120
40
121
+ sage: sorted(list(QQ_points_of_bounded_height(PS, 1, 2)))
122
+ [(-2 : 1), (-1 : 1), (-1/2 : 1), (0 : 1),
123
+ (1/2 : 1), (1 : 0), (1 : 1), (2 : 1)]
124
+ sage: sorted(list(QQ_points_of_bounded_height(PS, 1, 2, normalize=True)))
125
+ [(-2 : 1), (-1 : 1), (-1 : 2), (0 : 1),
126
+ (1 : 0), (1 : 1), (1 : 2), (2 : 1)]
58
127
59
128
There are no points of negative height::
60
129
61
130
sage: from sage.schemes.projective.proj_bdd_height import QQ_points_of_bounded_height
62
- sage: list(QQ_points_of_bounded_height(1, -3))
131
+ sage: PS = ProjectiveSpace(QQ, 1)
132
+ sage: list(QQ_points_of_bounded_height(PS, 1, -3))
63
133
[]
64
134
"""
65
135
if bound < 1 :
66
136
return iter (set ([]))
67
137
68
- PN = ProjectiveSpace (QQ , dim )
69
138
unit_tuples = list (itertools .product ([- 1 , 1 ], repeat = dim ))
70
139
points_of_bounded_height = set ([])
71
140
increasing_tuples = itertools .combinations_with_replacement (range (floor (bound + 1 )), dim + 1 )
72
141
for t in increasing_tuples :
73
142
if gcd (t ) == 1 :
74
143
for p in itertools .permutations (t ):
75
144
for u in unit_tuples :
76
- point = PN ([a * b for a , b in zip (u , p )] + [p [dim ]])
145
+ point = PS ([a * b for a , b in zip (u , p )] + [p [dim ]])
77
146
if point not in points_of_bounded_height :
147
+ if normalize :
148
+ point .scale_by (lcm ([point [i ].denominator () for i in range (dim + 1 )]))
149
+
78
150
points_of_bounded_height .add (point )
79
151
yield point
80
152
81
153
82
- def IQ_points_of_bounded_height (PN , K , dim , bound ):
154
+ def IQ_points_of_bounded_height (PS , K , dim , bound ):
83
155
r"""
84
156
Return an iterator of the points in ``self`` of absolute multiplicative
85
157
height of at most ``bound`` in the imaginary quadratic field ``K``.
86
158
87
159
INPUT:
88
160
89
- - ``PN `` -- a projective space
161
+ - ``PS `` -- a projective space
90
162
91
163
- ``K`` -- a number field
92
164
@@ -147,13 +219,14 @@ def IQ_points_of_bounded_height(PN, K, dim, bound):
147
219
if a == K .ideal (point_coordinates ):
148
220
for p in itertools .permutations (point_coordinates ):
149
221
for u in unit_tuples :
150
- point = PN ([i * j for i , j in zip (u , p )] + [p [dim ]])
222
+ point = PS ([i * j for i , j in zip (u , p )] + [p [dim ]])
223
+
151
224
if point not in points_in_class_a :
152
225
points_in_class_a .add (point )
153
226
yield point
154
227
155
228
156
- def points_of_bounded_height (PN , K , dim , bound , prec = 53 ):
229
+ def points_of_bounded_height (PS , K , dim , bound , prec = 53 ):
157
230
r"""
158
231
Return an iterator of the points in ``K`` with dimension ``dim`` of
159
232
absolute multiplicative height of at most ``bound``.
@@ -164,7 +237,7 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53):
164
237
165
238
INPUT:
166
239
167
- - ``PN `` -- a projective space
240
+ - ``PS `` -- a projective space
168
241
169
242
- ``K`` -- a number field
170
243
@@ -184,8 +257,39 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53):
184
257
sage: x = polygen(ZZ, 'x')
185
258
sage: K.<a> = NumberField(x^3 - 7) # optional - sage.rings.number_field
186
259
sage: P.<x,y,z> = ProjectiveSpace(K, 2) # optional - sage.rings.number_field
187
- sage: len(list(points_of_bounded_height(P, K, 2, 1))) # optional - sage.rings.number_field
188
- 13
260
+ sage: sorted(list(points_of_bounded_height(P, K, 2, 1))) # optional - sage.rings.number_field
261
+ [(0 : 0 : 1), (0 : 1 : 0), (1 : 0 : 0), (0 : -1 : 1), (0 : 1 : 1),
262
+ (-1 : 0 : 1), (1 : 0 : 1), (1 : 1 : 0), (-1 : 1 : 0), (-1 : -1 : 1),
263
+ (-1 : 1 : 1), (1 : -1 : 1), (1 : 1 : 1)]
264
+
265
+ ::
266
+
267
+ sage: R.<x> = QQ[]
268
+ sage: K.<a> = NumberField(3*x^2 + 1)
269
+ sage: O = K.maximal_order()
270
+ sage: P.<z,w> = ProjectiveSpace(O, 1)
271
+ sage: len(list(P.points_of_bounded_height(bound=2)))
272
+ 44
273
+
274
+ ::
275
+
276
+ sage: R.<x> = QQ[]
277
+ sage: K.<a> = NumberField(3*x^2 + 1)
278
+ sage: O = K.maximal_order()
279
+ sage: P.<z,w> = ProjectiveSpace(O, 1)
280
+ sage: sorted(list(P.points_of_bounded_height(bound=1)))
281
+ [(-1 : 1), (-3/2*a - 1/2 : 1), (3/2*a - 1/2 : 1), (0 : 1),
282
+ (-3/2*a + 1/2 : 0), (-3/2*a + 1/2 : 1), (3/2*a + 1/2 : 1), (1 : 1)]
283
+
284
+ ::
285
+
286
+ sage: R.<x> = QQ[]
287
+ sage: K.<z> = NumberField(x^2 - 2)
288
+ sage: R2.<y> = K[]
289
+ sage: L.<w> = K.extension(y^2 - 3)
290
+ sage: P.<a,b> = ProjectiveSpace(L, 1)
291
+ sage: len(list(P.points_of_bounded_height(bound=2)))
292
+ 256
189
293
"""
190
294
if bound < 1 :
191
295
return iter ([])
@@ -344,7 +448,8 @@ def points_of_bounded_height(PN, K, dim, bound, prec=53):
344
448
if log_arch_height <= log_arch_height_bound and a == K .ideal (point_coordinates ):
345
449
for p in itertools .permutations (point_coordinates ):
346
450
for u in unit_tuples :
347
- point = PN ([i * j for i , j in zip (u , p )] + [p [dim ]])
451
+ point = PS ([i * j for i , j in zip (u , p )] + [p [dim ]])
452
+
348
453
if point not in points_in_class_a :
349
454
points_in_class_a .add (point )
350
455
yield point
0 commit comments