Testing latest pari + WASM + node.js... and it works?! Wow.
License: GPL3
ubuntu2004
/* Copyright (C) 2005 The PARI group.12This file is part of the PARI/GP package.34PARI/GP is free software; you can redistribute it and/or modify it under the5terms of the GNU General Public License as published by the Free Software6Foundation; either version 2 of the License, or (at your option) any later7version. It is distributed in the hope that it will be useful, but WITHOUT8ANY WARRANTY WHATSOEVER.910Check the License for details. You should have received a copy of it, along11with the package; see the file 'COPYING'. If not, write to the Free Software12Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */1314/********************************************************************/15/** **/16/** INTERFACE TO JOHN CREMONA ELLIPTIC CURVES DATABASE **/17/** **/18/********************************************************************/19#include "pari.h"20#include "paripriv.h"2122static long23strtoclass(const char *s)24{25long c=0;26while (*s && *s<='9') s++;27if (!*s) return -1;28while ('a'<=*s && *s<='z') c = 26*c + *(s++)-'a';29return c;30}3132/*Take a curve name like "100a2" and set33* f to the conductor, (100)34* c to the isogeny class (in base 26), ("a" or 0)35* i to the curve index (2).36* return 0 if parse error. */37static int38ellparsename(const char *s, long *f, long *c, long *i)39{40long j;41*f=-1; *c=-1; *i=-1;42if (*s<'0' || *s>'9') return 0;43*f=0;44for (j=0;j<10 && '0'<=*s && *s<='9';j++)45*f=10**f+*(s++)-'0';46if (j==10) {*f=-1; return 0;}47if (*s<'a' || *s>'z') return !*s;48*c=0;49for (j=0; j<7 && 'a'<=*s && *s<='z';j++)50*c=26**c+*(s++)-'a';51if (j==7) {*c=-1; return 0;}52if (*s<'0' || *s>'9') return !*s;53*i=0;54for (j=0; j<10 && '0'<=*s && *s<='9';j++)55*i=10**i+*(s++)-'0';56if (j==10) {*i=-1; return 0;}57return !*s;58}5960/* Take an integer and convert it to base 26 */61static GEN62ellrecode(long x)63{64GEN str;65char *s;66long d = 0, n = x;67do { d++; n /= 26; } while (n);68str = cgetg(nchar2nlong(d+1)+1, t_STR);69s = GSTR(str); s[d] = 0;70n = x;71do { s[--d] = n%26 + 'a'; n /= 26; } while (n);72return str;73}7475GEN76ellconvertname(GEN n)77{78switch(typ(n))79{80case t_STR:81{82long f,i,c;83if (!ellparsename(GSTR(n),&f,&c,&i)) pari_err_TYPE("ellconvertname", n);84if (f<0 || c<0 || i<0)85pari_err_TYPE("ellconvertname [incomplete name]", n);86return mkvec3s(f,c,i);87}88case t_VEC:89if (lg(n)==4)90{91pari_sp av = avma;92GEN f=gel(n,1), c=gel(n,2), s=gel(n,3);93if (typ(f)!=t_INT || typ(c)!=t_INT || typ(s)!=t_INT)94pari_err_TYPE("ellconvertname",n);95return gerepilecopy(av, shallowconcat1(mkvec3(f, ellrecode(itos(c)), s)));96}97/*fall through*/98}99pari_err_TYPE("ellconvertname",n);100return NULL; /*LCOV_EXCL_LINE*/101}102103THREAD GEN ellcondfile_cache;104THREAD long ellcondfile_cache_cond;105106void107pari_init_ellcondfile(void)108{109ellcondfile_cache = NULL;110ellcondfile_cache_cond = -1;111}112113static GEN114ellcondfile(long n)115{116if (ellcondfile_cache_cond >= 0 && n == ellcondfile_cache_cond)117return gcopy(ellcondfile_cache);118else119{120pari_sp av = avma;121char *s = stack_malloc(strlen(pari_datadir) + 12 + 20 + 1);122pariFILE *F;123GEN V;124sprintf(s, "%s/elldata/ell%ld", pari_datadir, n);125F = pari_fopengz(s);126if (!F) pari_err_FILE("elldata file",s);127set_avma(av);128V = gp_read_stream(F->file);129if (!V || typ(V)!=t_VEC ) pari_err_FILE("elldata file [read]",s);130ellcondfile_cache_cond = -1; /* disable cache until update */131if (ellcondfile_cache) gunclone(ellcondfile_cache);132ellcondfile_cache = gclone(V);133ellcondfile_cache_cond = n; /* reenable cache */134pari_fclose(F); return V;135}136}137138/* return the vector of all curves of conductor f */139static int cmpi1(GEN x, GEN v) { return cmpii(x, gel(v,1)); }140static GEN141ellcondlist(long f)142{143pari_sp av = avma;144GEN V = ellcondfile(f/1000);145long i = tablesearch(V, utoipos(f), &cmpi1);146if (i)147{148GEN v = gel(V,i);149return vecslice(v,2, lg(v)-1);150}151set_avma(av); return cgetg(1,t_VEC);152}153154static GEN155ellsearchbyname(GEN V, char *name)156{157GEN x;158long j;159for (j=1; j<lg(V); j++)160{161GEN v = gel(V,j);162if (!strcmp(GSTR(gel(v,1)), name)) return v;163}164x = strtoGENstr(name);165pari_err_DOMAIN("ellsearchbyname", "name", "=", x,x);166return NULL;/*LCOV_EXCL_LINE*/167}168169static GEN170ellsearchbyclass(GEN V, long c)171{172long i,j,n;173GEN res;174for (n=0,j=1; j<lg(V); j++)175if (strtoclass(GSTR(gmael(V,j,1)))==c) n++;176res = cgetg(n+1,t_VEC);177for (i=1,j=1; j<lg(V); j++)178if (strtoclass(GSTR(gmael(V,j,1)))==c) res[i++] = V[j];179return res;180}181182GEN183ellsearch(GEN A)184{185pari_sp av = avma;186long f, c, i;187GEN V;188if (typ(A)==t_INT) { f = itos(A); c = i = -1; }189else if (typ(A)==t_VEC)190{191long l = lg(A)-1;192if (l<1 || l>3)193pari_err_TYPE("ellsearch",A);194f = gtos(gel(A,1));195c = l>=2 ? gtos(gel(A,2)): -1;196i = l>=3 ? gtos(gel(A,3)): -1;197if (l>=3) A = ellconvertname(A);198}199else if (typ(A)==t_STR) {200if (!ellparsename(GSTR(A),&f,&c,&i))201pari_err_TYPE("ellsearch",A);202} else {203pari_err_TYPE("ellsearch",A);204return NULL;/*LCOV_EXCL_LINE*/205}206if (f <= 0) pari_err_DOMAIN("ellsearch", "conductor", "<=", gen_0,stoi(f));207V = ellcondlist(f);208if (c >= 0)209V = (i < 0)? ellsearchbyclass(V,c): ellsearchbyname(V, GSTR(A));210return gerepilecopy(av, V);211}212213GEN214ellsearchcurve(GEN name)215{216pari_sp ltop=avma;217long f, c, i;218if (!ellparsename(GSTR(name),&f,&c,&i)) pari_err_TYPE("ellsearch",name);219if (f<0 || c<0 || i<0) pari_err_TYPE("ellsearch [incomplete name]", name);220return gerepilecopy(ltop, ellsearchbyname(ellcondlist(f), GSTR(name)));221}222223GEN224ellidentify(GEN E)225{226pari_sp ltop=avma;227long j;228GEN V, M, G, N;229checkell_Q(E);230G = ellglobalred(E); N = gel(G,1);231V = ellcondlist(itos(N));232M = ellchangecurve(vecslice(E,1,5),gel(G,2));233for (j=1; j<lg(V); j++)234if (ZV_equal(gmael(V,j,2), M))235return gerepilecopy(ltop, mkvec2(gel(V,j),gel(G,2)));236pari_err_BUG("ellidentify [missing curve]");237return NULL;/*LCOV_EXCL_LINE*/238}239240GEN241elldatagenerators(GEN E)242{243pari_sp ltop=avma;244GEN V=ellidentify(E);245GEN gens=gmael(V,1,3);246GEN W=ellchangepointinv(gens,gel(V,2));247return gerepileupto(ltop,W);248}249250void251forell(void *E, long call(void*, GEN), long a, long b, long flag)252{253long ca=a/1000, cb=b/1000;254long i, j, k;255256if (ca < 0) ca = 0;257for(i=ca; i<=cb; i++)258{259pari_sp ltop=avma;260GEN V = ellcondfile(i);261for (j=1; j<lg(V); j++)262{263GEN ells = gel(V,j);264long cond= itos(gel(ells,1));265266if (i==ca && cond<a) continue;267if (i==cb && cond>b) break;268for(k=2; k<lg(ells); k++)269{270GEN e = gel(ells,k);271if (flag) {272GEN n = gel(e,1); /* Cremona label */273long f, c, x;274if (!ellparsename(GSTR(n),&f,&c,&x))275pari_err_TYPE("ellconvertname", n);276if (x != 1) continue;277}278if (call(E, e)) return;279}280}281set_avma(ltop);282}283}284285void286forell0(long a, long b, GEN code, long flag)287{ EXPRVOID_WRAP(code, forell(EXPR_ARGVOID, a, b, flag)) }288289290