Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Testing latest pari + WASM + node.js... and it works?! Wow.

28485 views
License: GPL3
ubuntu2004
1
/* Copyright (C) 2005 The PARI group.
2
3
This file is part of the PARI/GP package.
4
5
PARI/GP is free software; you can redistribute it and/or modify it under the
6
terms of the GNU General Public License as published by the Free Software
7
Foundation; either version 2 of the License, or (at your option) any later
8
version. It is distributed in the hope that it will be useful, but WITHOUT
9
ANY WARRANTY WHATSOEVER.
10
11
Check the License for details. You should have received a copy of it, along
12
with the package; see the file 'COPYING'. If not, write to the Free Software
13
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
14
15
/********************************************************************/
16
/** **/
17
/** INTERFACE TO JOHN CREMONA ELLIPTIC CURVES DATABASE **/
18
/** **/
19
/********************************************************************/
20
#include "pari.h"
21
#include "paripriv.h"
22
23
static long
24
strtoclass(const char *s)
25
{
26
long c=0;
27
while (*s && *s<='9') s++;
28
if (!*s) return -1;
29
while ('a'<=*s && *s<='z') c = 26*c + *(s++)-'a';
30
return c;
31
}
32
33
/*Take a curve name like "100a2" and set
34
* f to the conductor, (100)
35
* c to the isogeny class (in base 26), ("a" or 0)
36
* i to the curve index (2).
37
* return 0 if parse error. */
38
static int
39
ellparsename(const char *s, long *f, long *c, long *i)
40
{
41
long j;
42
*f=-1; *c=-1; *i=-1;
43
if (*s<'0' || *s>'9') return 0;
44
*f=0;
45
for (j=0;j<10 && '0'<=*s && *s<='9';j++)
46
*f=10**f+*(s++)-'0';
47
if (j==10) {*f=-1; return 0;}
48
if (*s<'a' || *s>'z') return !*s;
49
*c=0;
50
for (j=0; j<7 && 'a'<=*s && *s<='z';j++)
51
*c=26**c+*(s++)-'a';
52
if (j==7) {*c=-1; return 0;}
53
if (*s<'0' || *s>'9') return !*s;
54
*i=0;
55
for (j=0; j<10 && '0'<=*s && *s<='9';j++)
56
*i=10**i+*(s++)-'0';
57
if (j==10) {*i=-1; return 0;}
58
return !*s;
59
}
60
61
/* Take an integer and convert it to base 26 */
62
static GEN
63
ellrecode(long x)
64
{
65
GEN str;
66
char *s;
67
long d = 0, n = x;
68
do { d++; n /= 26; } while (n);
69
str = cgetg(nchar2nlong(d+1)+1, t_STR);
70
s = GSTR(str); s[d] = 0;
71
n = x;
72
do { s[--d] = n%26 + 'a'; n /= 26; } while (n);
73
return str;
74
}
75
76
GEN
77
ellconvertname(GEN n)
78
{
79
switch(typ(n))
80
{
81
case t_STR:
82
{
83
long f,i,c;
84
if (!ellparsename(GSTR(n),&f,&c,&i)) pari_err_TYPE("ellconvertname", n);
85
if (f<0 || c<0 || i<0)
86
pari_err_TYPE("ellconvertname [incomplete name]", n);
87
return mkvec3s(f,c,i);
88
}
89
case t_VEC:
90
if (lg(n)==4)
91
{
92
pari_sp av = avma;
93
GEN f=gel(n,1), c=gel(n,2), s=gel(n,3);
94
if (typ(f)!=t_INT || typ(c)!=t_INT || typ(s)!=t_INT)
95
pari_err_TYPE("ellconvertname",n);
96
return gerepilecopy(av, shallowconcat1(mkvec3(f, ellrecode(itos(c)), s)));
97
}
98
/*fall through*/
99
}
100
pari_err_TYPE("ellconvertname",n);
101
return NULL; /*LCOV_EXCL_LINE*/
102
}
103
104
THREAD GEN ellcondfile_cache;
105
THREAD long ellcondfile_cache_cond;
106
107
void
108
pari_init_ellcondfile(void)
109
{
110
ellcondfile_cache = NULL;
111
ellcondfile_cache_cond = -1;
112
}
113
114
static GEN
115
ellcondfile(long n)
116
{
117
if (ellcondfile_cache_cond >= 0 && n == ellcondfile_cache_cond)
118
return gcopy(ellcondfile_cache);
119
else
120
{
121
pari_sp av = avma;
122
char *s = stack_malloc(strlen(pari_datadir) + 12 + 20 + 1);
123
pariFILE *F;
124
GEN V;
125
sprintf(s, "%s/elldata/ell%ld", pari_datadir, n);
126
F = pari_fopengz(s);
127
if (!F) pari_err_FILE("elldata file",s);
128
set_avma(av);
129
V = gp_read_stream(F->file);
130
if (!V || typ(V)!=t_VEC ) pari_err_FILE("elldata file [read]",s);
131
ellcondfile_cache_cond = -1; /* disable cache until update */
132
if (ellcondfile_cache) gunclone(ellcondfile_cache);
133
ellcondfile_cache = gclone(V);
134
ellcondfile_cache_cond = n; /* reenable cache */
135
pari_fclose(F); return V;
136
}
137
}
138
139
/* return the vector of all curves of conductor f */
140
static int cmpi1(GEN x, GEN v) { return cmpii(x, gel(v,1)); }
141
static GEN
142
ellcondlist(long f)
143
{
144
pari_sp av = avma;
145
GEN V = ellcondfile(f/1000);
146
long i = tablesearch(V, utoipos(f), &cmpi1);
147
if (i)
148
{
149
GEN v = gel(V,i);
150
return vecslice(v,2, lg(v)-1);
151
}
152
set_avma(av); return cgetg(1,t_VEC);
153
}
154
155
static GEN
156
ellsearchbyname(GEN V, char *name)
157
{
158
GEN x;
159
long j;
160
for (j=1; j<lg(V); j++)
161
{
162
GEN v = gel(V,j);
163
if (!strcmp(GSTR(gel(v,1)), name)) return v;
164
}
165
x = strtoGENstr(name);
166
pari_err_DOMAIN("ellsearchbyname", "name", "=", x,x);
167
return NULL;/*LCOV_EXCL_LINE*/
168
}
169
170
static GEN
171
ellsearchbyclass(GEN V, long c)
172
{
173
long i,j,n;
174
GEN res;
175
for (n=0,j=1; j<lg(V); j++)
176
if (strtoclass(GSTR(gmael(V,j,1)))==c) n++;
177
res = cgetg(n+1,t_VEC);
178
for (i=1,j=1; j<lg(V); j++)
179
if (strtoclass(GSTR(gmael(V,j,1)))==c) res[i++] = V[j];
180
return res;
181
}
182
183
GEN
184
ellsearch(GEN A)
185
{
186
pari_sp av = avma;
187
long f, c, i;
188
GEN V;
189
if (typ(A)==t_INT) { f = itos(A); c = i = -1; }
190
else if (typ(A)==t_VEC)
191
{
192
long l = lg(A)-1;
193
if (l<1 || l>3)
194
pari_err_TYPE("ellsearch",A);
195
f = gtos(gel(A,1));
196
c = l>=2 ? gtos(gel(A,2)): -1;
197
i = l>=3 ? gtos(gel(A,3)): -1;
198
if (l>=3) A = ellconvertname(A);
199
}
200
else if (typ(A)==t_STR) {
201
if (!ellparsename(GSTR(A),&f,&c,&i))
202
pari_err_TYPE("ellsearch",A);
203
} else {
204
pari_err_TYPE("ellsearch",A);
205
return NULL;/*LCOV_EXCL_LINE*/
206
}
207
if (f <= 0) pari_err_DOMAIN("ellsearch", "conductor", "<=", gen_0,stoi(f));
208
V = ellcondlist(f);
209
if (c >= 0)
210
V = (i < 0)? ellsearchbyclass(V,c): ellsearchbyname(V, GSTR(A));
211
return gerepilecopy(av, V);
212
}
213
214
GEN
215
ellsearchcurve(GEN name)
216
{
217
pari_sp ltop=avma;
218
long f, c, i;
219
if (!ellparsename(GSTR(name),&f,&c,&i)) pari_err_TYPE("ellsearch",name);
220
if (f<0 || c<0 || i<0) pari_err_TYPE("ellsearch [incomplete name]", name);
221
return gerepilecopy(ltop, ellsearchbyname(ellcondlist(f), GSTR(name)));
222
}
223
224
GEN
225
ellidentify(GEN E)
226
{
227
pari_sp ltop=avma;
228
long j;
229
GEN V, M, G, N;
230
checkell_Q(E);
231
G = ellglobalred(E); N = gel(G,1);
232
V = ellcondlist(itos(N));
233
M = ellchangecurve(vecslice(E,1,5),gel(G,2));
234
for (j=1; j<lg(V); j++)
235
if (ZV_equal(gmael(V,j,2), M))
236
return gerepilecopy(ltop, mkvec2(gel(V,j),gel(G,2)));
237
pari_err_BUG("ellidentify [missing curve]");
238
return NULL;/*LCOV_EXCL_LINE*/
239
}
240
241
GEN
242
elldatagenerators(GEN E)
243
{
244
pari_sp ltop=avma;
245
GEN V=ellidentify(E);
246
GEN gens=gmael(V,1,3);
247
GEN W=ellchangepointinv(gens,gel(V,2));
248
return gerepileupto(ltop,W);
249
}
250
251
void
252
forell(void *E, long call(void*, GEN), long a, long b, long flag)
253
{
254
long ca=a/1000, cb=b/1000;
255
long i, j, k;
256
257
if (ca < 0) ca = 0;
258
for(i=ca; i<=cb; i++)
259
{
260
pari_sp ltop=avma;
261
GEN V = ellcondfile(i);
262
for (j=1; j<lg(V); j++)
263
{
264
GEN ells = gel(V,j);
265
long cond= itos(gel(ells,1));
266
267
if (i==ca && cond<a) continue;
268
if (i==cb && cond>b) break;
269
for(k=2; k<lg(ells); k++)
270
{
271
GEN e = gel(ells,k);
272
if (flag) {
273
GEN n = gel(e,1); /* Cremona label */
274
long f, c, x;
275
if (!ellparsename(GSTR(n),&f,&c,&x))
276
pari_err_TYPE("ellconvertname", n);
277
if (x != 1) continue;
278
}
279
if (call(E, e)) return;
280
}
281
}
282
set_avma(ltop);
283
}
284
}
285
286
void
287
forell0(long a, long b, GEN code, long flag)
288
{ EXPRVOID_WRAP(code, forell(EXPR_ARGVOID, a, b, flag)) }
289
290