Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/libs/ratpoints.pyx
4049 views
1
r"""
2
Hyperelliptic Curve Point Finding, via ratpoints.
3
4
"""
5
6
cdef int process(long x, long z, mpz_t y, void *info0, int *quit):
7
# ratpoints calls this function when it finds a point [x : y : z]
8
# info0 is the pointer passed to ratpoints originally
9
# if quit[0] is set to a nonzero value, ratpoints will abort immediately
10
cdef point_list *plist = <point_list *> info0
11
cdef long i
12
if plist.array_size == plist.num_points:
13
i = plist.array_size
14
plist.array_size *= 2
15
plist.xes = <long *> sage_realloc(plist.xes, plist.array_size * sizeof(long))
16
plist.ys = <mpz_t *> sage_realloc(plist.ys, plist.array_size * sizeof(mpz_t))
17
plist.zs = <long *> sage_realloc(plist.zs, plist.array_size * sizeof(long))
18
while i < plist.array_size:
19
mpz_init(plist.ys[i])
20
i += 1
21
plist.xes[plist.num_points] = x
22
mpz_set(plist.ys[plist.num_points], y)
23
plist.zs[plist.num_points] = z
24
plist.num_points += 1
25
if plist.max_num_points > 0:
26
if plist.max_num_points == plist.num_points:
27
quit[0] = -1
28
return 1 # weight for counting the points
29
30
def ratpoints(list coeffs, long H, verbose=False, long max=0):
31
"""
32
Access the ratpoints library to find points on the hyperelliptic curve:
33
34
`y^2 = a_n x^n + \cdots + a_1 x + a_0.`
35
36
INPUT::
37
38
coeffs -- list of integer coefficients a_0, a_1, ..., a_n
39
40
H -- the bound for the denominator and the absolute value of the
41
numerator of the x-coordinate
42
43
verbose -- if True, ratpoints will print comments about its progress
44
45
max -- maximum number of points to find (if 0, find all of them)
46
47
OUTPUT::
48
49
The points output by this program are points in (1, ceil(n/2), 1)-weighted
50
projective space. If n is even, then the associated homogeneous equation is
51
`y^2 = a_n x^n + \cdots + a_1 x z^{n-1} + a_0 z^n` while if n is odd, it is
52
`y^2 = a_n x^n z + \cdots + a_1 x z^n + a_0 z^{n+1}`.
53
54
EXAMPLE::
55
56
sage: from sage.libs.ratpoints import ratpoints
57
sage: for x,y,z in ratpoints([1..6], 200):
58
... print -1*y^2 + 1*z^6 + 2*x*z^5 + 3*x^2*z^4 + 4*x^3*z^3 + 5*x^4*z^2 + 6*x^5*z
59
0
60
0
61
0
62
0
63
0
64
0
65
0
66
sage: for x,y,z in ratpoints([1..5], 200):
67
... print -1*y^2 + 1*z^4 + 2*x*z^3 + 3*x^2*z^2 + 4*x^3*z + 5*x^4
68
0
69
0
70
0
71
0
72
0
73
0
74
0
75
0
76
77
sage: for x,y,z in ratpoints([1..200], 1000):
78
... print x,y,z
79
1 0 0
80
0 1 1
81
0 -1 1
82
201 25353012004564588029934064107520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 200
83
201 -25353012004564588029934064107520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 200
84
85
86
"""
87
cdef ratpoints_args args
88
cdef long i, total, verby
89
cdef Integer sage_int, s_x, s_y, s_z
90
cdef point_list *plist
91
92
coeffs = [Integer(a) for a in coeffs]
93
94
verby = ~0 if verbose else 0
95
96
args.degree = len(coeffs)-1
97
98
args.cof = <mpz_t *> sage_malloc((args.degree+1) * sizeof(mpz_t))
99
# example uses RATPOINTS_MAX_DEGREE -- necessary?
100
args.domain = <ratpoints_interval *> sage_malloc(2*args.degree * sizeof(ratpoints_interval))
101
plist = <point_list *> sage_malloc(sizeof(point_list))
102
if max == 0:
103
plist.array_size = 64
104
else:
105
plist.array_size = max
106
plist.xes = <long *> sage_malloc(plist.array_size * sizeof(long))
107
plist.ys = <mpz_t *> sage_malloc(plist.array_size * sizeof(mpz_t))
108
for i from 0 <= i < plist.array_size:
109
mpz_init(plist.ys[i])
110
plist.zs = <long *> sage_malloc(plist.array_size * sizeof(long))
111
plist.num_points = 0
112
plist.max_num_points = max
113
114
args.height = H
115
args.num_inter = 0
116
args.b_low = 1
117
args.b_high = H
118
args.sp1 = RATPOINTS_DEFAULT_SP1
119
args.sp2 = RATPOINTS_DEFAULT_SP2
120
args.array_size = RATPOINTS_ARRAY_SIZE
121
args.sturm = RATPOINTS_DEFAULT_STURM
122
args.num_primes = RATPOINTS_DEFAULT_NUM_PRIMES
123
args.max_forbidden = RATPOINTS_DEFAULT_MAX_FORBIDDEN
124
args.flags = (RATPOINTS_VERBOSE & verby)
125
126
for i from 0 <= i <= args.degree:
127
mpz_init(args.cof[i])
128
sage_int = <Integer> coeffs[i]
129
mpz_set(args.cof[i], sage_int.value)
130
131
sig_on()
132
total = find_points(&args, process, <void *>plist)
133
sig_off()
134
if total == RATPOINTS_NON_SQUAREFREE:
135
raise RuntimeError('Polynomial must be square-free')
136
if total == RATPOINTS_BAD_ARGS:
137
raise RuntimeError('Bad arguments to ratpoints')
138
139
for i from 0 <= i <= args.degree:
140
mpz_clear(args.cof[i])
141
142
sage_free(args.cof)
143
sage_free(args.domain)
144
145
cdef list L = []
146
for i from 0 <= i < plist.num_points:
147
s_x = Integer(0)
148
s_y = Integer(0)
149
s_z = Integer(0)
150
mpz_set_si(s_x.value, plist.xes[i])
151
mpz_set(s_y.value, plist.ys[i])
152
mpz_set_si(s_z.value, plist.zs[i])
153
L.append((s_x,s_y,s_z))
154
155
for i from 0 <= i < plist.array_size:
156
mpz_clear(plist.ys[i])
157
sage_free(plist.xes)
158
sage_free(plist.ys)
159
sage_free(plist.zs)
160
sage_free(plist)
161
162
return L
163
164
cdef int process_exists_only(long x, long z, mpz_t y, void *info0, int *quit):
165
cdef info_struct_exists_only *info_s = <info_struct_exists_only *>info0
166
cdef Integer YY
167
if info_s.verbose:
168
YY = Integer(0); mpz_set(YY.value, y)
169
print 'Found point [ %d : %d : %d ], quitting'%(x,YY,z)
170
quit[0] = -1
171
return 1
172
173
cdef int ratpoints_mpz_exists_only(mpz_t *coeffs, long H, int degree, bint verbose) except -1:
174
"""
175
Direct call to ratpoints to search for existence only.
176
177
WARNING - The coefficient array will be modified by ratpoints.
178
"""
179
cdef ratpoints_args args
180
cdef info_struct_exists_only info_s
181
cdef long total, verby = ~0 if verbose else 0
182
info_s.verbose = verbose
183
assert degree <= RATPOINTS_MAX_DEGREE
184
args.degree = degree
185
args.cof = coeffs
186
args.domain = <ratpoints_interval *> sage_malloc(2*args.degree * sizeof(ratpoints_interval))
187
args.height = H
188
args.num_inter = 0
189
args.b_low = 1
190
args.b_high = H
191
args.sp1 = RATPOINTS_DEFAULT_SP1
192
args.sp2 = RATPOINTS_DEFAULT_SP2
193
args.array_size = RATPOINTS_ARRAY_SIZE
194
args.sturm = RATPOINTS_DEFAULT_STURM
195
args.num_primes = RATPOINTS_DEFAULT_NUM_PRIMES
196
args.max_forbidden = RATPOINTS_DEFAULT_MAX_FORBIDDEN
197
args.flags = (RATPOINTS_VERBOSE & verby)
198
sig_on()
199
total = find_points(&args, process_exists_only, <void *>(&info_s))
200
sig_off()
201
sage_free(args.domain)
202
if total == RATPOINTS_NON_SQUAREFREE:
203
raise RuntimeError('Polynomial must be square-free')
204
if total == RATPOINTS_BAD_ARGS:
205
raise RuntimeError('Bad arguments to ratpoints')
206
return 1 if (total > 0) else 0
207
208
209
210
211
212