version 1.1, 2001/10/02 11:17:11 |
version 1.2, 2002/09/11 07:27:05 |
|
|
if (typ(z)!=t_VEC) err(elliper1); |
if (typ(z)!=t_VEC) err(elliper1); |
} |
} |
|
|
long |
void |
checkell(GEN e) |
checkell(GEN e) |
{ |
{ |
long lx=lg(e); |
long lx=lg(e); |
if (typ(e)!=t_VEC || lx<14) err(elliper1); |
if (typ(e)!=t_VEC || lx<14) err(elliper1); |
return lx; |
|
} |
} |
|
|
void |
void |
Line 142 smallinitell0(GEN x, GEN y) |
|
Line 141 smallinitell0(GEN x, GEN y) |
|
GEN |
GEN |
smallinitell(GEN x) |
smallinitell(GEN x) |
{ |
{ |
ulong av = avma; |
gpmem_t av = avma; |
GEN y = cgetg(14,t_VEC); |
GEN y = cgetg(14,t_VEC); |
smallinitell0(x,y); return gerepilecopy(av,y); |
smallinitell0(x,y); return gerepilecopy(av,y); |
} |
} |
Line 162 ellinit0(GEN x, long flag,long prec) |
|
Line 161 ellinit0(GEN x, long flag,long prec) |
|
void |
void |
ellprint(GEN e) |
ellprint(GEN e) |
{ |
{ |
long av = avma; |
gpmem_t av = avma; |
long vx = fetch_var(); |
long vx = fetch_var(); |
long vy = fetch_var(); |
long vy = fetch_var(); |
GEN z = cgetg(3,t_VEC); |
GEN z = cgetg(3,t_VEC); |
|
|
err(talker, "not an elliptic curve in ellprint"); |
err(talker, "not an elliptic curve in ellprint"); |
z[1] = lpolx[vx]; name_var(vx, "X"); |
z[1] = lpolx[vx]; name_var(vx, "X"); |
z[2] = lpolx[vy]; name_var(vy, "Y"); |
z[2] = lpolx[vy]; name_var(vy, "Y"); |
fprintferr("%Z = %Z\n", ellLHS(e, z), ellRHS(e, polx[vx])); |
fprintferr("%Z - (%Z)\n", ellLHS(e, z), ellRHS(e, polx[vx])); |
(void)delete_var(); |
(void)delete_var(); |
(void)delete_var(); avma = av; |
(void)delete_var(); avma = av; |
} |
} |
|
|
do_padic_agm(GEN *ptx1, GEN a1, GEN b1, GEN p) |
do_padic_agm(GEN *ptx1, GEN a1, GEN b1, GEN p) |
{ |
{ |
GEN p1,r1,a,b,x,bmod1, bmod = modii((GEN)b1[4],p), x1 = *ptx1; |
GEN p1,r1,a,b,x,bmod1, bmod = modii((GEN)b1[4],p), x1 = *ptx1; |
|
long mi; |
|
|
if (!x1) x1 = gmul2n(gsub(a1,b1),-2); |
if (!x1) x1 = gmul2n(gsub(a1,b1),-2); |
|
mi = min(precp(a1),precp(b1)); |
for(;;) |
for(;;) |
{ |
{ |
a=a1; b=b1; x=x1; |
a=a1; b=b1; x=x1; |
b1=gsqrt(gmul(a,b),0); bmod1=modii((GEN)b1[4],p); |
b1=gprec(gsqrt(gmul(a,b),0),mi); bmod1=modii((GEN)b1[4],p); |
if (!egalii(bmod1,bmod)) b1 = gneg_i(b1); |
if (!egalii(bmod1,bmod)) b1 = gneg_i(b1); |
a1=gmul2n(gadd(gadd(a,b),gmul2n(b1,1)),-2); |
a1=gprec(gmul2n(gadd(gadd(a,b),gmul2n(b1,1)),-2),mi); |
r1=gsub(a1,b1); |
r1=gsub(a1,b1); |
|
if (gcmp0(r1)) {x1=x; break;} |
p1=gsqrt(gdiv(gadd(x,r1),x),0); |
p1=gsqrt(gdiv(gadd(x,r1),x),0); |
if (! gcmp1(modii((GEN)p1[4],p))) p1 = gneg_i(p1); |
if (! gcmp1(modii((GEN)p1[4],p))) p1 = gneg_i(p1); |
x1=gmul(x,gsqr(gmul2n(gaddsg(1,p1),-1))); |
x1=gmul(x,gsqr(gmul2n(gaddsg(1,p1),-1))); |
if (gcmp0(r1)) break; |
|
} |
} |
*ptx1 = x1; return ginv(gmul2n(a1,2)); |
*ptx1 = x1; return ginv(gmul2n(a1,2)); |
} |
} |
Line 227 padic_initell(GEN y, GEN p, long prec) |
|
Line 228 padic_initell(GEN y, GEN p, long prec) |
|
GEN b2,b4,c4,c6,p1,p2,w,pv,a1,b1,x1,u2,q,e0,e1; |
GEN b2,b4,c4,c6,p1,p2,w,pv,a1,b1,x1,u2,q,e0,e1; |
long i,alpha; |
long i,alpha; |
|
|
if (valp(y[13]) >= 0) /* p | j */ |
q=gadd(gun,ggrandocp(p,prec)); |
|
for (i=1; i<=13; i++) y[i]=lmul(q,(GEN)y[i]); |
|
if (gcmp0((GEN)y[13]) || valp((GEN)y[13]) >= 0) /* p | j */ |
err(talker,"valuation of j must be negative in p-adic ellinit"); |
err(talker,"valuation of j must be negative in p-adic ellinit"); |
if (egalii(p,gdeux)) |
if (egalii(p,gdeux)) |
err(impl,"initell for 2-adic numbers"); /* pv=stoi(4); */ |
{ |
|
pv=stoi(4); |
|
err(impl,"initell for 2-adic numbers"); |
|
} |
|
else pv=p; |
|
|
pv=p; q=ggrandocp(p,prec); |
|
for (i=1; i<=5; i++) y[i]=ladd(q,(GEN)y[i]); |
|
b2= (GEN)y[6]; |
b2= (GEN)y[6]; |
b4= (GEN)y[7]; |
b4= (GEN)y[7]; |
c4= (GEN)y[10]; |
c4= (GEN)y[10]; |
Line 275 padic_initell(GEN y, GEN p, long prec) |
|
Line 280 padic_initell(GEN y, GEN p, long prec) |
|
y[19]=zero; return y; |
y[19]=zero; return y; |
} |
} |
|
|
|
/* mis pour debugger do_padic_agm. On peut enlever quand on veut */ |
|
|
|
GEN |
|
dopad(GEN a, GEN b, GEN pv) |
|
{ |
|
GEN x1=NULL; |
|
|
|
return ginv(gmul2n(do_padic_agm(&x1,a,b,pv),2)); |
|
} |
|
|
static int |
static int |
invcmp(GEN x, GEN y) { return -gcmp(x,y); } |
invcmp(GEN x, GEN y) { return -gcmp(x,y); } |
|
|
Line 355 initell0(GEN x, long prec) |
|
Line 370 initell0(GEN x, long prec) |
|
GEN |
GEN |
initell(GEN x, long prec) |
initell(GEN x, long prec) |
{ |
{ |
ulong av = avma; |
gpmem_t av = avma; |
return gerepilecopy(av, initell0(x,prec)); |
return gerepilecopy(av, initell0(x,prec)); |
} |
} |
|
|
GEN |
GEN |
coordch(GEN e, GEN ch) |
_coordch(GEN e, GEN u, GEN r, GEN s, GEN t) |
{ |
{ |
GEN y,p1,p2,v,v2,v3,v4,v6,r,s,t,u; |
GEN y, p1, p2, v, v2, v3, v4, v6; |
long i,lx = checkell(e); |
long i, lx = lg(e); |
ulong av = avma; |
gpmem_t av = avma; |
|
|
checkch(ch); |
y = cgetg(lx,t_VEC); |
u=(GEN)ch[1]; r=(GEN)ch[2]; s=(GEN)ch[3]; t=(GEN)ch[4]; |
v = ginv(u); v2 = gsqr(v); v3 = gmul(v,v2);v4 = gsqr(v2); v6 = gsqr(v3); |
y=cgetg(lx,t_VEC); |
|
v=ginv(u); v2=gsqr(v); v3=gmul(v,v2);v4=gsqr(v2); v6=gsqr(v3); |
|
y[1] = lmul(v,gadd((GEN)e[1],gmul2n(s,1))); |
y[1] = lmul(v,gadd((GEN)e[1],gmul2n(s,1))); |
y[2] = lmul(v2,gsub(gadd((GEN)e[2],gmulsg(3,r)),gmul(s,gadd((GEN)e[1],s)))); |
y[2] = lmul(v2,gsub(gadd((GEN)e[2],gmulsg(3,r)),gmul(s,gadd((GEN)e[1],s)))); |
p2 = ellLHS0(e,r); |
p2 = ellLHS0(e,r); |
Line 388 coordch(GEN e, GEN ch) |
|
Line 401 coordch(GEN e, GEN ch) |
|
y[11] = lmul(v6,(GEN)e[11]); |
y[11] = lmul(v6,(GEN)e[11]); |
y[12] = lmul(gsqr(v6),(GEN)e[12]); |
y[12] = lmul(gsqr(v6),(GEN)e[12]); |
y[13] = e[13]; |
y[13] = e[13]; |
if (lx>14) |
if (lx > 14) |
{ |
{ |
p1=(GEN)e[14]; |
p1 = (GEN)e[14]; |
if (gcmp0(p1)) |
if (gcmp0(p1)) |
{ |
{ |
y[14] = y[15] = y[16] = y[17] = y[18] = y[19] = zero; |
y[14] = y[15] = y[16] = y[17] = y[18] = y[19] = zero; |
} |
} |
|
else if (typ(e[1])==t_PADIC) |
|
{ |
|
y[14] = (long)_vec( gmul(v2, gsub((GEN)p1[1],r)) ); |
|
y[15] = lmul((GEN)e[15], gsqr(u)); |
|
y[16] = lmul((GEN)e[16], u); |
|
y[17] = e[17]; |
|
y[18] = e[18]; /* FIXME: how do q and w change ? */ |
|
y[19] = zero; |
|
} |
else |
else |
{ |
{ |
if (typ(e[1])==t_PADIC) |
p2 = cgetg(4,t_COL); |
{ |
for (i=1; i<=3; i++) p2[i] = lmul(v2, gsub((GEN)p1[i],r)); |
p2=cgetg(2,t_VEC); p2[1]=lmul(v2,gsub((GEN)p1[1],r)); |
y[14] = (long)p2; |
y[14]=(long)p2; |
y[15] = lmul((GEN)e[15], u); |
y[15]=lmul(gsqr(u),(GEN)e[15]); |
y[16] = lmul((GEN)e[16], u); |
y[16]=lmul(u,(GEN)e[16]); |
y[17] = ldiv((GEN)e[17], u); |
/* FIXME: how do q and w change ??? */ |
y[18] = ldiv((GEN)e[18], u); |
y[17]=e[17]; |
y[19] = lmul((GEN)e[19], gsqr(u)); |
y[18]=e[18]; |
|
y[19]=zero; |
|
} |
|
else |
|
{ |
|
p2=cgetg(4,t_COL); |
|
for (i=1; i<=3; i++) p2[i]=lmul(v2,gsub((GEN)p1[i],r)); |
|
y[14]=(long)p2; |
|
y[15]=lmul(u,(GEN)e[15]); |
|
y[16]=lmul(u,(GEN)e[16]); |
|
y[17]=ldiv((GEN)e[17],u); |
|
y[18]=ldiv((GEN)e[18],u); |
|
y[19]=lmul(gsqr(u),(GEN)e[19]); |
|
} |
|
} |
} |
} |
} |
return gerepilecopy(av,y); |
return gerepilecopy(av,y); |
} |
} |
|
|
|
GEN |
|
coordch(GEN e, GEN ch) |
|
{ |
|
checkch(ch); checkell(e); |
|
return _coordch(e, (GEN)ch[1], (GEN)ch[2], (GEN)ch[3], (GEN)ch[4]); |
|
} |
|
|
static GEN |
static GEN |
pointch0(GEN x, GEN v2, GEN v3, GEN mor, GEN s, GEN t) |
pointch0(GEN x, GEN v2, GEN v3, GEN mor, GEN s, GEN t) |
{ |
{ |
Line 431 pointch0(GEN x, GEN v2, GEN v3, GEN mor, GEN s, GEN t) |
|
Line 446 pointch0(GEN x, GEN v2, GEN v3, GEN mor, GEN s, GEN t) |
|
|
|
if (lg(x) < 3) return x; |
if (lg(x) < 3) return x; |
|
|
z = cgetg(3,t_VEC); p1=gadd((GEN)x[1],mor); |
z = cgetg(3,t_VEC); p1 = gadd((GEN)x[1],mor); |
z[1] = lmul(v2,p1); |
z[1] = lmul(v2, p1); |
z[2] = lmul(v3,gsub((GEN)x[2],gadd(gmul(s,p1),t))); |
z[2] = lmul(v3, gsub((GEN)x[2], gadd(gmul(s,p1),t))); |
return z; |
return z; |
} |
} |
|
|
|
|
pointch(GEN x, GEN ch) |
pointch(GEN x, GEN ch) |
{ |
{ |
GEN y,v,v2,v3,mor,r,s,t,u; |
GEN y,v,v2,v3,mor,r,s,t,u; |
long tx,lx=lg(x),i; |
long tx, i, lx = lg(x); |
ulong av = avma; |
gpmem_t av = avma; |
|
|
checkpt(x); checkch(ch); |
checkpt(x); checkch(ch); |
if (lx < 2) return gcopy(x); |
if (lx < 2) return gcopy(x); |
u=(GEN)ch[1]; r=(GEN)ch[2]; s=(GEN)ch[3]; t=(GEN)ch[4]; |
u = (GEN)ch[1]; |
tx=typ(x[1]); v=ginv(u); v2=gsqr(v); v3=gmul(v,v2); mor=gneg_i(r); |
r = (GEN)ch[2]; |
|
s = (GEN)ch[3]; |
|
t = (GEN)ch[4]; |
|
v = ginv(u); v2 = gsqr(v); v3 = gmul(v,v2); |
|
mor = gneg_i(r); |
|
tx = typ(x[1]); |
if (is_matvec_t(tx)) |
if (is_matvec_t(tx)) |
{ |
{ |
y=cgetg(lx,tx); |
y = cgetg(lx,tx); |
for (i=1; i<lx; i++) |
for (i=1; i<lx; i++) |
y[i]=(long) pointch0((GEN)x[i],v2,v3,mor,s,t); |
y[i] = (long)pointch0((GEN)x[i],v2,v3,mor,s,t); |
} |
} |
else |
else |
y = pointch0(x,v2,v3,mor,s,t); |
y = pointch0(x,v2,v3,mor,s,t); |
|
|
oncurve(GEN e, GEN z) |
oncurve(GEN e, GEN z) |
{ |
{ |
GEN p1,p2,x; |
GEN p1,p2,x; |
long av=avma,p,q; |
long p, q; |
|
gpmem_t av=avma; |
|
|
checksell(e); checkpt(z); if (lg(z)<3) return 1; /* oo */ |
checksell(e); checkpt(z); if (lg(z)<3) return 1; /* oo */ |
p1 = ellLHS(e,z); |
p1 = ellLHS(e,z); |
|
|
addell(GEN e, GEN z1, GEN z2) |
addell(GEN e, GEN z1, GEN z2) |
{ |
{ |
GEN p1,p2,x,y,x1,x2,y1,y2; |
GEN p1,p2,x,y,x1,x2,y1,y2; |
long av=avma,tetpil; |
gpmem_t av=avma, tetpil; |
|
|
checksell(e); checkpt(z1); checkpt(z2); |
checksell(e); checkpt(z1); checkpt(z2); |
if (lg(z1)<3) return gcopy(z2); |
if (lg(z1)<3) return gcopy(z2); |
Line 531 invell(GEN e, GEN z) |
|
Line 552 invell(GEN e, GEN z) |
|
GEN |
GEN |
subell(GEN e, GEN z1, GEN z2) |
subell(GEN e, GEN z1, GEN z2) |
{ |
{ |
long av=avma,tetpil; |
gpmem_t av=avma, tetpil; |
|
|
checksell(e); checkpt(z2); |
checksell(e); checkpt(z2); |
z2=invell(e,z2); tetpil=avma; |
z2=invell(e,z2); tetpil=avma; |
Line 541 subell(GEN e, GEN z1, GEN z2) |
|
Line 562 subell(GEN e, GEN z1, GEN z2) |
|
GEN |
GEN |
ordell(GEN e, GEN x, long prec) |
ordell(GEN e, GEN x, long prec) |
{ |
{ |
long av=avma,td,i,lx,tx=typ(x); |
long td, i, lx, tx=typ(x); |
|
gpmem_t av=avma; |
GEN D,a,b,d,pd,p1,y; |
GEN D,a,b,d,pd,p1,y; |
|
|
checksell(e); |
checksell(e); |
|
|
CM_powell(GEN e, GEN z, GEN n) |
CM_powell(GEN e, GEN z, GEN n) |
{ |
{ |
GEN x,y,p0,p1,q0,q1,p2,q2,z1,z2,pol,grdx; |
GEN x,y,p0,p1,q0,q1,p2,q2,z1,z2,pol,grdx; |
long av=avma,tetpil,ln,ep,vn; |
long ln, ep, vn; |
|
gpmem_t av=avma, tetpil; |
|
|
if (lg(z)<3) return gcopy(z); |
if (lg(z)<3) return gcopy(z); |
pol=(GEN)n[1]; |
pol=(GEN)n[1]; |
Line 623 CM_powell(GEN e, GEN z, GEN n) |
|
Line 646 CM_powell(GEN e, GEN z, GEN n) |
|
GEN ss=gzero; |
GEN ss=gzero; |
do |
do |
{ |
{ |
ep=(-valp(z2))>>1; ss=gadd(ss,gmul((GEN)z2[2],gpuigs(polx[0],ep))); |
ep=(-valp(z2))>>1; ss=gadd(ss,gmul((GEN)z2[2],gpowgs(polx[0],ep))); |
z2=gsub(z2,gmul((GEN)z2[2],gpuigs(z1,ep))); |
z2=gsub(z2,gmul((GEN)z2[2],gpowgs(z1,ep))); |
} |
} |
while (valp(z2)<=0); |
while (valp(z2)<=0); |
p2=gadd(p0,gmul(ss,p1)); p0=p1; p1=p2; |
p2=gadd(p0,gmul(ss,p1)); p0=p1; p1=p2; |
|
|
powell(GEN e, GEN z, GEN n) |
powell(GEN e, GEN z, GEN n) |
{ |
{ |
GEN y; |
GEN y; |
long av=avma,i,j,tetpil,s; |
long i, j, s; |
|
gpmem_t av=avma, tetpil; |
ulong m; |
ulong m; |
|
|
checksell(e); checkpt(z); |
checksell(e); checkpt(z); |
Line 679 mathell(GEN e, GEN x, long prec) |
|
Line 703 mathell(GEN e, GEN x, long prec) |
|
{ |
{ |
GEN y,p1,p2, *pdiag; |
GEN y,p1,p2, *pdiag; |
long lx=lg(x),i,j,tx=typ(x); |
long lx=lg(x),i,j,tx=typ(x); |
ulong av = avma; |
gpmem_t av = avma; |
|
|
if (!is_vec_t(tx)) err(elliper1); |
if (!is_vec_t(tx)) err(elliper1); |
lx=lg(x); y=cgetg(lx,t_MAT); pdiag=(GEN*) new_chunk(lx); |
lx=lg(x); y=cgetg(lx,t_MAT); pdiag=(GEN*) new_chunk(lx); |
Line 704 mathell(GEN e, GEN x, long prec) |
|
Line 728 mathell(GEN e, GEN x, long prec) |
|
static GEN |
static GEN |
bilhells(GEN e, GEN z1, GEN z2, GEN h2, long prec) |
bilhells(GEN e, GEN z1, GEN z2, GEN h2, long prec) |
{ |
{ |
long lz1=lg(z1),tx,av=avma,tetpil,i; |
long lz1=lg(z1), tx, i; |
|
gpmem_t av=avma, tetpil; |
GEN y,p1,p2; |
GEN y,p1,p2; |
|
|
if (lz1==1) return cgetg(1,typ(z1)); |
if (lz1==1) return cgetg(1,typ(z1)); |
|
|
bilhell(GEN e, GEN z1, GEN z2, long prec) |
bilhell(GEN e, GEN z1, GEN z2, long prec) |
{ |
{ |
GEN p1,h2; |
GEN p1,h2; |
long av=avma,tetpil,tz1=typ(z1),tz2=typ(z2); |
long tz1=typ(z1), tz2=typ(z2); |
|
gpmem_t av=avma, tetpil; |
|
|
if (!is_matvec_t(tz1) || !is_matvec_t(tz2)) err(elliper1); |
if (!is_matvec_t(tz1) || !is_matvec_t(tz2)) err(elliper1); |
if (lg(z1)==1) return cgetg(1,tz1); |
if (lg(z1)==1) return cgetg(1,tz1); |
Line 775 new_coords(GEN e, GEN x, GEN *pta, GEN *ptb, long prec |
|
Line 801 new_coords(GEN e, GEN x, GEN *pta, GEN *ptb, long prec |
|
GEN |
GEN |
zell(GEN e, GEN z, long prec) |
zell(GEN e, GEN z, long prec) |
{ |
{ |
long av=avma,ty,sw,fl; |
long ty, sw, fl; |
|
gpmem_t av=avma; |
GEN t,u,p1,p2,a,b,x1,u2,D = (GEN)e[12]; |
GEN t,u,p1,p2,a,b,x1,u2,D = (GEN)e[12]; |
|
|
checkbell(e); |
checkbell(e); |
Line 857 zell(GEN e, GEN z, long prec) |
|
Line 884 zell(GEN e, GEN z, long prec) |
|
return gerepileupto(av,t); |
return gerepileupto(av,t); |
} |
} |
|
|
|
typedef struct { |
|
GEN w1,w2; /* original basis for L = <w1,w2> */ |
|
GEN W1,W2,tau; /* new basis for L = <W1,W2> = W2 <1,tau> */ |
|
GEN a,b,c,d; /* tau in F = h/Sl2, tau = g.t, g=[a,b;c,d] in SL(2,Z) */ |
|
GEN x,y; /* z/w2 defined mod <1,tau> --> z + x tau + y reduced mod <1,tau> */ |
|
} SL2_red; |
|
|
/* compute gamma in SL_2(Z) and t'=gamma(t) so that t' is in the usual |
/* compute gamma in SL_2(Z) and t'=gamma(t) so that t' is in the usual |
fundamental domain. Internal function no check, no garbage. */ |
fundamental domain. Internal function no check, no garbage. */ |
static GEN |
static void |
getgamma(GEN *ptt) |
set_gamma(SL2_red *T) |
{ |
{ |
GEN t = *ptt,a,b,c,d,n,m,p1,p2,run; |
GEN t = T->tau,a,b,c,d,n,m,p1,run; |
|
|
run = gsub(realun(DEFAULTPREC), gpuigs(stoi(10),-8)); |
run = gsub(realun(DEFAULTPREC), gpowgs(stoi(10),-8)); |
a=d=gun; b=c=gzero; |
a = d = gun; |
|
b = c = gzero; |
for(;;) |
for(;;) |
{ |
{ |
n = ground(greal(t)); |
n = ground(greal(t)); |
Line 880 getgamma(GEN *ptt) |
|
Line 915 getgamma(GEN *ptt) |
|
p1=negi(c); c=a; a=p1; |
p1=negi(c); c=a; a=p1; |
p1=negi(d); d=b; b=p1; |
p1=negi(d); d=b; b=p1; |
} |
} |
m=cgetg(3,t_MAT); *ptt = t; |
T->a = a; T->b = b; |
p1=cgetg(3,t_COL); m[1]=(long)p1; |
T->c = c; T->d = d; |
p2=cgetg(3,t_COL); m[2]=(long)p2; |
|
p1[1]=(long)a; p2[1]=(long)b; |
|
p1[2]=(long)c; p2[2]=(long)d; return m; |
|
} |
} |
|
|
static GEN |
#define swap(x,y) { GEN _t=x; x=y; y=_t; } |
get_tau(GEN *ptom1, GEN *ptom2, GEN *ptga) |
|
|
/* swap w1, w2 so that Im(t := w1/w2) > 0. Set tau = representative of t in |
|
* the standard fundamental domain, and g in Sl_2, such that tau = g.t */ |
|
static void |
|
red_modSL2(SL2_red *T) |
{ |
{ |
GEN om1 = *ptom1, om2 = *ptom2, tau = gdiv(om1,om2); |
long s; |
long s = gsigne(gimag(tau)); |
T->tau = gdiv(T->w1,T->w2); |
if (!s) |
s = gsigne(gimag(T->tau)); |
err(talker,"omega1 and omega2 R-linearly dependent in elliptic function"); |
if (!s) err(talker,"w1 and w2 R-linearly dependent in elliptic function"); |
if (s < 0) { *ptom1=om2; *ptom2=om1; tau=ginv(tau); } |
if (s < 0) { swap(T->w1, T->w2); T->tau=ginv(T->tau); } |
*ptga = getgamma(&tau); return tau; |
set_gamma(T); |
|
/* update lattice */ |
|
T->W1 = gadd(gmul(T->a,T->w1), gmul(T->b,T->w2)); |
|
T->W2 = gadd(gmul(T->c,T->w1), gmul(T->d,T->w2)); |
|
T->tau = gdiv(T->W1, T->W2); |
} |
} |
|
|
static int |
static int |
get_periods(GEN e, GEN *om1, GEN *om2) |
get_periods(GEN e, SL2_red *T) |
{ |
{ |
long tx = typ(e); |
long tx = typ(e); |
if (is_vec_t(tx)) |
if (is_vec_t(tx)) |
switch(lg(e)) |
switch(lg(e)) |
{ |
{ |
case 3: *om1=(GEN)e[1]; *om2=(GEN)e[2]; return 1; |
case 3: T->w1=(GEN)e[1]; T->w2=(GEN)e[2]; red_modSL2(T); return 1; |
case 20: *om1=(GEN)e[16]; *om2=(GEN)e[15]; return 1; |
case 20: T->w1=(GEN)e[16]; T->w2=(GEN)e[15];red_modSL2(T); return 1; |
} |
} |
return 0; |
return 0; |
} |
} |
|
|
extern GEN PiI2(long prec); |
static GEN |
|
check_real(GEN q) |
|
{ |
|
return (typ(q) == t_COMPLEX && gcmp0((GEN)q[2]))? (GEN)q[1]: q; |
|
} |
|
|
/* computes the numerical values of eisenstein series. k is equal to a positive |
|
even integer. If k=4 or 6, computes g2 or g3. If k=2, or k>6 even, |
|
compute (2iPi/om2)^k*(1+2/zeta(1-k)*sum(n>=1,n^(k-1)q^n/(1-q^n)) with no |
|
constant factor. */ |
|
GEN |
GEN |
elleisnum(GEN om, long k, long flag, long prec) |
_elleisnum(SL2_red *T, long k, long prec) |
{ |
{ |
long av=avma,lim,av1; |
gpmem_t lim, av; |
GEN om1,om2,p1,pii2,tau,q,y,qn,ga,court,asub = NULL; /* gcc -Wall */ |
GEN p1,pii2,q,y,qn,n; |
|
|
if (k%2 || k<=0) err(talker,"k not a positive even integer in elleisnum"); |
|
if (!get_periods(om, &om1, &om2)) err(typeer,"elleisnum"); |
|
pii2 = PiI2(prec); |
pii2 = PiI2(prec); |
tau = get_tau(&om1,&om2, &ga); |
q = gexp(gmul(pii2,T->tau), prec); |
if (k==2) asub=gdiv(gmul(pii2,mulsi(12,gcoeff(ga,2,1))),om2); |
q = check_real(q); |
om2=gadd(gmul(gcoeff(ga,2,1),om1),gmul(gcoeff(ga,2,2),om2)); |
y = gzero; n = utoi(1); |
if (k==2) asub=gdiv(asub,om2); |
av = avma; lim = stack_lim(av,1); qn = gun; n[2] = 0; |
q=gexp(gmul(pii2,tau),prec); |
|
y=gzero; court=stoi(3); |
|
av1=avma; lim=stack_lim(av1,1); qn=gun; court[2]=0; |
|
for(;;) |
for(;;) |
{ |
{ |
court[2]++; qn=gmul(q,qn); |
n[2]++; qn = gmul(q,qn); |
p1=gdiv(gmul(gpuigs(court,k-1),qn),gsub(gun,qn)); |
p1 = gdiv(gmul(gpowgs(n,k-1),qn), gsub(gun,qn)); |
y=gadd(y,p1); |
|
if (gcmp0(p1) || gexpo(p1) <= - bit_accuracy(prec) - 5) break; |
if (gcmp0(p1) || gexpo(p1) <= - bit_accuracy(prec) - 5) break; |
if (low_stack(lim, stack_lim(av1,1))) |
y = gadd(y, p1); |
|
if (low_stack(lim, stack_lim(av,1))) |
{ |
{ |
GEN *gptr[2]; gptr[0]=&y; gptr[1]=&qn; |
GEN *gptr[2]; gptr[0]=&y; gptr[1]=&qn; |
if(DEBUGMEM>1) err(warnmem,"elleisnum"); |
if(DEBUGMEM>1) err(warnmem,"elleisnum"); |
gerepilemany(av1,gptr,2); |
gerepilemany(av,gptr,2); |
} |
} |
} |
} |
|
y = gadd(gun, gmul(y, gdiv(gdeux, gzeta(stoi(1-k),prec)))); /* = E_k(tau) */ |
|
|
y=gadd(gun,gmul(gdiv(gdeux,gzeta(stoi(1-k),prec)),y)); |
y = gmul(y, gpowgs(gdiv(pii2,T->W2),k)); |
p1=gpuigs(gdiv(pii2,om2),k); |
return check_real(y); |
y = gmul(p1,y); |
|
if (k==2) y=gsub(y,asub); |
|
else if (k==4 && flag) y=gdivgs(y,12); |
|
else if (k==6 && flag) y=gdivgs(y,216); |
|
return gerepileupto(av,y); |
|
} |
} |
|
|
/* compute eta1, eta2 */ |
/* Return (2iPi)^k E_k(L) = (2iPi/w2)^k E_k(tau), with L = <w1,w2>, k > 0 even |
|
* E_k(tau) = 1 + 2/zeta(1-k) * sum(n>=1, n^(k-1) q^n/(1-q^n)) |
|
* If flag is != 0 and k=4 or 6, compute g2 = E4/12 or g3 = E6/216 resp. */ |
GEN |
GEN |
elleta(GEN om, long prec) |
elleisnum(GEN om, long k, long flag, long prec) |
{ |
{ |
long av=avma; |
gpmem_t av = avma; |
|
GEN p1, y; |
|
SL2_red T; |
|
|
|
if (k&1 || k<=0) err(talker,"k not a positive even integer in elleisnum"); |
|
if (!get_periods(om, &T)) err(typeer,"elleisnum"); |
|
y = _elleisnum(&T, k, prec); |
|
if (k==2 && signe(T.c)) |
|
{ |
|
p1 = gmul(PiI2(prec), mulsi(12, T.c)); |
|
y = gsub(y, gdiv(p1, gmul(T.w2, T.W2))); |
|
} |
|
else if (k==4 && flag) y = gdivgs(y, 12); |
|
else if (k==6 && flag) y = gdivgs(y,216); |
|
return gerepileupto(av,y); |
|
} |
|
|
|
static GEN |
|
_elleta(SL2_red *T, long prec) |
|
{ |
GEN e2,y1,y2,y; |
GEN e2,y1,y2,y; |
|
|
e2 = gdivgs(elleisnum(om,2,0,prec),12); |
e2 = gdivgs(_elleisnum(T,2,prec),12); |
y2 = gmul((GEN)om[2],e2); |
y2 = gmul(T->W2, e2); |
y1 = gadd(gdiv(PiI2(prec),(GEN)om[2]), gmul((GEN)om[1],e2)); |
y1 = gadd(gdiv(PiI2(prec), T->W2), gmul(T->W1,e2)); |
y = cgetg(3,t_VEC); |
y = cgetg(3,t_VEC); |
y[1] = lneg(y1); |
y[1] = lneg(y1); |
y[2] = lneg(y2); return gerepileupto(av, y); |
y[2] = lneg(y2); return y; |
} |
} |
|
|
/* computes the numerical value of wp(z | om1 Z + om2 Z), |
/* compute eta1, eta2 */ |
If flall=1, compute also wp'. Reduce to the fundamental domain first. */ |
GEN |
|
elleta(GEN om, long prec) |
|
{ |
|
gpmem_t av = avma; |
|
SL2_red T; |
|
if (!get_periods(om, &T)) err(typeer,"elleta"); |
|
return gerepileupto(av, _elleta(&T,prec)); |
|
} |
|
|
static GEN |
static GEN |
weipellnumall(GEN om1, GEN om2, GEN z, long flall, long prec) |
reduce_z(GEN z, long prec, SL2_red *T) |
{ |
{ |
long av=avma,tetpil,lim,av1,toadd; |
GEN Z = gdiv(z, T->W2); |
GEN p1,pii2,pii4,a,tau,q,u,y,yp,u1,u2,qn,v,ga; |
long t = typ(z); |
|
|
pii2 = PiI2(prec); |
if (!is_scalar_t(t) || t == t_INTMOD || t == t_PADIC || t == t_POLMOD) |
tau = get_tau(&om1,&om2, &ga); |
err(typeer,"reduction mod SL2 (reduce_z)"); |
om2=gadd(gmul(gcoeff(ga,2,1),om1),gmul(gcoeff(ga,2,2),om2)); |
T->x = ground(gdiv(gimag(Z), gimag(T->tau))); |
z=gdiv(z,om2); |
Z = gsub(Z, gmul(T->x,T->tau)); |
a=ground(gdiv(gimag(z),gimag(tau))); z=gsub(z,gmul(a,tau)); |
T->y = ground(greal(Z)); |
a=ground(greal(z)); z=gsub(z,a); |
Z = gsub(Z, T->y); |
if (gcmp0(z) || gexpo(z) < 5 - bit_accuracy(prec)) |
if (gcmp0(Z) || gexpo(Z) < 5 - bit_accuracy(prec)) Z = NULL; /* z in L */ |
{ |
return Z; |
avma=av; v=cgetg(2,t_VEC); v[1]=zero; return v; |
} |
} |
|
|
|
q=gexp(gmul(pii2,tau),prec); |
/* computes the numerical value of wp(z | L), L = om1 Z + om2 Z |
u=gexp(gmul(pii2,z),prec); |
* return NULL if z in L. If flall=1, compute also wp' */ |
u1=gsub(gun,u); u2=gsqr(u1); |
static GEN |
y=gadd(gdivgs(gun,12),gdiv(u,u2)); |
weipellnumall(SL2_red *T, GEN z, long flall, long prec) |
if (flall) yp=gdiv(gadd(gun,u),gmul(u1,u2)); |
{ |
toadd=(long)ceil(9.065*gtodouble(gimag(z))); |
long toadd; |
|
gpmem_t av=avma, lim, av1; |
|
GEN p1,pii2,q,u,y,yp,u1,u2,qn,v; |
|
|
av1=avma; lim=stack_lim(av1,1); qn=q; |
z = reduce_z(z,prec, T); |
|
if (!z) return NULL; |
|
|
|
/* Now L,z normalized to <1,tau>. z in fund. domain of <1, tau> */ |
|
pii2 = PiI2(prec); |
|
q = gexp(gmul(pii2,T->tau),prec); |
|
u = gexp(gmul(pii2,z),prec); |
|
u1= gsub(gun,u); u2=gsqr(u1); |
|
y = gadd(ginv(utoi(12)), gdiv(u,u2)); |
|
if (flall) yp = gdiv(gadd(gun,u), gmul(u1,u2)); |
|
toadd = (long)ceil(9.065*gtodouble(gimag(z))); |
|
|
|
av1 = avma; lim = stack_lim(av1,1); qn = q; |
for(;;) |
for(;;) |
{ |
{ |
GEN p2,qnu,qnu1,qnu2,qnu3,qnu4; |
GEN qnu,qnu1,qnu2,qnu3,qnu4; |
|
|
qnu=gmul(qn,u); qnu1=gsub(gun,qnu); qnu2=gsqr(qnu1); |
qnu = gmul(qn,u); /* q^n u */ |
qnu3=gsub(qn,u); qnu4=gsqr(qnu3); |
qnu1 = gsub(gun,qnu); /* 1 - q^n u */ |
p1=gsub(gmul(u,gadd(ginv(qnu2),ginv(qnu4))), |
qnu2 = gsqr(qnu1); /* (1 - q^n u)^2 */ |
gmul2n(ginv(gsqr(gsub(gun,qn))),1)); |
qnu3 = gsub(qn,u); /* q^n - u */ |
p1=gmul(qn,p1); |
qnu4 = gsqr(qnu3); /* (q^n - u)^2 */ |
y=gadd(y,p1); |
p1 = gsub(gmul(u, gadd(ginv(qnu2),ginv(qnu4))), |
|
gmul2n(ginv(gsqr(gsub(gun,qn))), 1)); |
|
y = gadd(y, gmul(qn,p1)); |
if (flall) |
if (flall) |
{ |
{ |
p2=gadd(gdiv(gadd(gun,qnu),gmul(qnu1,qnu2)), |
p1 = gadd(gdiv(gadd(gun,qnu),gmul(qnu1,qnu2)), |
gdiv(gadd(qn,u),gmul(qnu3,qnu4))); |
gdiv(gadd(qn,u),gmul(qnu3,qnu4))); |
p2=gmul(qn,p2); |
|
yp=gadd(yp,p2); |
yp = gadd(yp, gmul(qn,p1)); |
} |
} |
qn=gmul(q,qn); |
qn = gmul(q,qn); |
if (gexpo(qn) <= - bit_accuracy(prec) - 5 - toadd) break; |
if (gexpo(qn) <= - bit_accuracy(prec) - 5 - toadd) break; |
if (low_stack(lim, stack_lim(av1,1))) |
if (low_stack(lim, stack_lim(av1,1))) |
{ |
{ |
Line 1025 weipellnumall(GEN om1, GEN om2, GEN z, long flall, lon |
|
Line 1100 weipellnumall(GEN om1, GEN om2, GEN z, long flall, lon |
|
} |
} |
} |
} |
|
|
pii2=gdiv(pii2,om2); |
u1 = gdiv(pii2, T->W2); |
pii4=gsqr(pii2); |
u2 = gsqr(u1); |
y = gmul(pii4,y); |
y = gmul(u2,y); /* y *= (2i pi / w2)^2 */ |
if (flall) yp=gmul(u,gmul(gmul(pii4,pii2),yp)); |
if (flall) |
tetpil=avma; |
{ |
if (flall) { v=cgetg(3,t_VEC); v[1]=lcopy(y); v[2]=lmul2n(yp,-1); } |
yp = gmul(u, gmul(gmul(u1,u2),yp));/* yp *= u (2i pi / w2)^3 */ |
else v=gcopy(y); |
v = cgetg(3,t_VEC); |
return gerepile(av,tetpil,v); |
v[1] = (long)y; |
|
v[2] = lmul2n(yp,-1); |
|
} |
|
else v = y; |
|
return gerepilecopy(av, v); |
} |
} |
|
|
GEN |
GEN |
ellzeta(GEN om, GEN z, long prec) |
ellzeta(GEN om, GEN z, long prec) |
{ |
{ |
long av=avma,tetpil,lim,av1,toadd; |
long toadd; |
GEN zinit,om1,om2,p1,pii2,tau,q,u,y,u1,qn,ga,x1,x2,et; |
gpmem_t av=avma, lim, av1; |
|
GEN Z,p1,pii2,q,u,y,u1,qn,et; |
|
SL2_red T; |
|
|
if (!get_periods(om, &om1, &om2)) err(typeer,"ellzeta"); |
if (!get_periods(om, &T)) err(typeer,"ellzeta"); |
pii2 = PiI2(prec); |
Z = reduce_z(z, prec, &T); |
tau = get_tau(&om1,&om2, &ga); |
|
om2=gadd(gmul(gcoeff(ga,2,1),om1),gmul(gcoeff(ga,2,2),om2)); |
|
om1=gmul(tau,om2); om=cgetg(3,t_VEC); om[1]=(long)om1; om[2]=(long)om2; |
|
z=gdiv(z,om2); |
|
|
|
x1=ground(gdiv(gimag(z),gimag(tau))); z=gsub(z,gmul(x1,tau)); |
et = _elleta(&T,prec); |
x2=ground(greal(z)); z=gsub(z,x2); zinit=gmul(z,om2); |
et = gadd(gmul(T.x,(GEN)et[1]), gmul(T.y,(GEN)et[2])); |
et=elleta(om,prec); |
if (!Z) return gerepileupto(av, gadd(ginv(z),et)); /* FIXME ??? */ |
et=gadd(gmul(x1,(GEN)et[1]),gmul(x2,(GEN)et[2])); |
|
if (gcmp0(z) || gexpo(z) < 5 - bit_accuracy(prec)) |
pii2 = PiI2(prec); |
{ |
q=gexp(gmul(pii2,T.tau),prec); |
p1=ginv(zinit); tetpil=avma; return gerepile(av,tetpil,gadd(p1,et)); |
u=gexp(gmul(pii2,Z),prec); |
} |
|
q=gexp(gmul(pii2,tau),prec); |
|
u=gexp(gmul(pii2,z),prec); |
|
u1=gsub(u,gun); |
u1=gsub(u,gun); |
y=gdiv(gmul(gsqr(om2),elleisnum(om,2,0,prec)),pii2); |
y=gdiv(gmul(gsqr(T.W2),_elleisnum(&T,2,prec)),pii2); |
y=gadd(ghalf,gdivgs(gmul(z,y),-12)); |
y=gadd(ghalf,gdivgs(gmul(Z,y),-12)); |
y=gadd(y,ginv(u1)); |
y=gadd(y,ginv(u1)); |
toadd=(long)ceil(9.065*gtodouble(gimag(z))); |
toadd=(long)ceil(9.065*gtodouble(gimag(Z))); |
av1=avma; lim=stack_lim(av1,1); qn=q; |
av1=avma; lim=stack_lim(av1,1); qn=q; |
for(;;) |
for(;;) |
{ |
{ |
Line 1079 ellzeta(GEN om, GEN z, long prec) |
|
Line 1153 ellzeta(GEN om, GEN z, long prec) |
|
} |
} |
} |
} |
|
|
y=gmul(gdiv(pii2,om2),y); |
y=gmul(gdiv(pii2,T.W2),y); |
tetpil=avma; |
return gerepileupto(av, gadd(y,et)); |
return gerepile(av,tetpil,gadd(y,et)); |
|
} |
} |
|
|
/* if flag=0, return ellsigma, otherwise return log(ellsigma) */ |
/* if flag=0, return ellsigma, otherwise return log(ellsigma) */ |
GEN |
GEN |
ellsigma(GEN om, GEN z, long flag, long prec) |
ellsigma(GEN w, GEN z, long flag, long prec) |
{ |
{ |
long av=avma,lim,av1,toadd; |
long toadd; |
GEN zinit,om1,om2,p1,pii2,tau,q,u,y,y1,u1,qn,ga,negu,uinv,x1,x2,et,etnew,uhalf; |
gpmem_t av=avma, lim, av1; |
|
GEN Z,zinit,p1,pii2,q,u,y,y1,u1,qn,negu,uinv,et,etnew,uhalf; |
int doprod = (flag >= 2); |
int doprod = (flag >= 2); |
int dolog = (flag & 1); |
int dolog = (flag & 1); |
|
SL2_red T; |
|
|
if (!get_periods(om, &om1, &om2)) err(typeer,"ellsigmaprod"); |
if (!get_periods(w, &T)) err(typeer,"ellsigma"); |
pii2 = PiI2(prec); |
Z = reduce_z(z, prec, &T); |
tau = get_tau(&om1,&om2, &ga); |
|
om2=gadd(gmul(gcoeff(ga,2,1),om1),gmul(gcoeff(ga,2,2),om2)); |
|
om1=gmul(tau,om2); om=cgetg(3,t_VEC); om[1]=(long)om1; om[2]=(long)om2; |
|
z=gdiv(z,om2); |
|
|
|
x1=ground(gdiv(gimag(z),gimag(tau))); z=gsub(z,gmul(x1,tau)); |
et = _elleta(&T, prec); |
x2=ground(greal(z)); z=gsub(z,x2); zinit=gmul(z,om2); |
etnew = gadd(gmul(T.x,(GEN)et[1]), gmul(T.y,(GEN)et[2])); |
et=elleta(om,prec); |
zinit = Z? gmul(Z,T.W2): gzero; |
etnew=gadd(gmul(x1,(GEN)et[1]),gmul(x2,(GEN)et[2])); |
p1 = gadd(zinit, gmul2n(gadd(gmul(T.x,T.W1),gmul(T.y,T.W2)),-1)); |
etnew=gmul(etnew,gadd(gmul2n(gadd(gmul(x1,om1),gmul(x2,om2)),-1),zinit)); |
etnew = gmul(etnew, p1); |
if (mpodd(x1) || mpodd(x2)) etnew=gadd(etnew,gmul2n(pii2,-1)); |
pii2 = PiI2(prec); |
if (gexpo(z) < 5 - bit_accuracy(prec)) |
if (mpodd(T.x) || mpodd(T.y)) etnew = gadd(etnew, gmul2n(pii2,-1)); |
{ |
if (!Z) |
if (dolog) |
{ /* FIXME ??? */ |
return gerepileupto(av, gadd(etnew,glog(zinit,prec))); |
if (dolog) Z = gadd(etnew, glog(z,prec)); |
else |
else Z = gmul(gexp(etnew,prec), z); |
return gerepileupto(av, gmul(gexp(etnew,prec),zinit)); |
return gerepileupto(av, Z); |
} |
} |
|
|
y1 = gadd(etnew,gmul2n(gmul(gmul(z,zinit),(GEN)et[2]),-1)); |
y1 = gadd(etnew,gmul2n(gmul(gmul(Z,zinit),(GEN)et[2]),-1)); |
|
|
/* 9.065 = 2*Pi/log(2) */ |
/* 9.065 = 2*Pi/log(2) */ |
toadd = (long)ceil(9.065*fabs(gtodouble(gimag(z)))); |
toadd = (long)ceil(9.065*fabs(gtodouble(gimag(Z)))); |
uhalf = gexp(gmul(gmul2n(pii2,-1),z),prec); |
uhalf = gexp(gmul(gmul2n(pii2,-1),Z),prec); |
u = gsqr(uhalf); |
u = gsqr(uhalf); |
if (doprod) |
if (doprod) |
{ /* use product */ |
{ /* use product */ |
q=gexp(gmul(pii2,tau),prec); |
q=gexp(gmul(pii2,T.tau),prec); |
uinv=ginv(u); |
uinv=ginv(u); |
u1=gsub(uhalf,ginv(uhalf)); |
u1=gsub(uhalf,ginv(uhalf)); |
y=gdiv(gmul(om2,u1),pii2); |
y=gdiv(gmul(T.W2,u1),pii2); |
av1=avma; lim=stack_lim(av1,1); qn=q; |
av1=avma; lim=stack_lim(av1,1); qn=q; |
negu=stoi(-1); |
negu=stoi(-1); |
for(;;) |
for(;;) |
Line 1147 ellsigma(GEN om, GEN z, long flag, long prec) |
|
Line 1218 ellsigma(GEN om, GEN z, long flag, long prec) |
|
{ /* use sum */ |
{ /* use sum */ |
GEN q8,qn2,urn,urninv; |
GEN q8,qn2,urn,urninv; |
long n; |
long n; |
q8=gexp(gmul2n(gmul(pii2,tau),-3),prec); |
q8=gexp(gmul2n(gmul(pii2,T.tau),-3),prec); |
q=gpuigs(q8,8); |
q=gpowgs(q8,8); |
u=gneg_i(u); uinv=ginv(u); |
u=gneg_i(u); uinv=ginv(u); |
y=gzero; |
y=gzero; |
av1=avma; lim=stack_lim(av1,1); qn=q; qn2=gun; |
av1=avma; lim=stack_lim(av1,1); qn=q; qn2=gun; |
Line 1169 ellsigma(GEN om, GEN z, long flag, long prec) |
|
Line 1240 ellsigma(GEN om, GEN z, long flag, long prec) |
|
} |
} |
} |
} |
|
|
p1=gmul(q8,gmul(gdiv(gdiv((GEN)om[2],pii2),gpuigs(trueeta(tau,prec),3)),y)); |
p1=gmul(q8,gmul(gdiv(gdiv(T.W2,pii2),gpowgs(trueeta(T.tau,prec),3)),y)); |
} |
} |
|
|
if (dolog) |
if (dolog) |
Line 1181 ellsigma(GEN om, GEN z, long flag, long prec) |
|
Line 1252 ellsigma(GEN om, GEN z, long flag, long prec) |
|
GEN |
GEN |
pointell(GEN e, GEN z, long prec) |
pointell(GEN e, GEN z, long prec) |
{ |
{ |
long av=avma,tetpil; |
gpmem_t av = avma; |
GEN y,yp,v,p1; |
GEN v; |
|
SL2_red T; |
|
|
checkbell(e); |
checkbell(e); (void)get_periods(e, &T); |
p1=weipellnumall((GEN)e[16],(GEN)e[15],z,1,prec); |
v = weipellnumall(&T,z,1,prec); |
if (lg(p1)==2) { avma=av; v=cgetg(2,t_VEC); v[1]=zero; return v; } |
if (!v) { avma = av; return _vec(gzero); } |
y = gsub((GEN)p1[1], gdivgs((GEN)e[6],12)); |
v[1] = lsub((GEN)v[1], gdivgs((GEN)e[6],12)); |
yp = gsub((GEN)p1[2], gmul2n(ellLHS0(e,y),-1)); |
v[2] = lsub((GEN)v[2], gmul2n(ellLHS0(e,(GEN)v[1]),-1)); |
tetpil=avma; v=cgetg(3,t_VEC); v[1]=lcopy(y); v[2]=lcopy(yp); |
return gerepilecopy(av, v); |
return gerepile(av,tetpil,v); |
|
} |
} |
|
|
GEN |
static GEN |
weipell(GEN e, long prec) |
_weipell(GEN c4, GEN c6, long PREC) |
{ |
{ |
long av1,tetpil,precres,i,k,l; |
long i, k, l, precres = 2*PREC; |
GEN res,p1,s,t; |
gpmem_t av1, tetpil; |
|
GEN P,p1,s,t, res = cgetg(precres+2,t_SER); |
|
|
checkell(e); precres = 2*prec+2; |
|
res=cgetg(precres,t_SER); |
|
res[1] = evalsigne(1) | evalvalp(-2) | evalvarn(0); |
res[1] = evalsigne(1) | evalvalp(-2) | evalvarn(0); |
if (!prec) { setsigne(res,0); return res; } |
if (!PREC) { setsigne(res,0); return res; } |
for (i=3; i<precres; i+=2) res[i]=zero; |
|
switch(prec) |
P = res + 2; |
|
for (i=1; i<precres; i+=2) P[i]=zero; |
|
switch(PREC) |
{ |
{ |
default: res[8]=ldivgs((GEN)e[11],6048); |
default:P[6] = ldivgs(c6,6048); |
case 3: res[6]=ldivgs((GEN)e[10],240); |
case 3: P[4] = ldivgs(c4, 240); |
case 2: res[4]=zero; |
case 2: P[2] = zero; |
case 1: res[2]=un; |
case 1: P[0] = un; |
case 0: break; |
case 0: break; |
} |
} |
for (k=4; k<prec; k++) |
for (k=4; k<PREC; k++) |
{ |
{ |
av1 = avma; |
av1 = avma; |
s = k&1? gzero: gsqr((GEN)res[k+2]); |
s = k&1? gzero: gsqr((GEN)P[k]); |
t = gzero; |
t = gzero; |
for (l=2; l+l<k; l++) |
for (l=2; l+l<k; l++) |
t = gadd(t, gmul((GEN)res[(l+1)<<1],(GEN)res[(k-l+1)<<1])); |
t = gadd(t, gmul((GEN)P[l<<1],(GEN)P[(k-l)<<1])); |
p1=gmulsg(3,gadd(s,gmul2n(t,1))); |
p1 = gmulsg(3,gadd(s,gmul2n(t,1))); |
tetpil=avma; |
tetpil = avma; |
p1=gdivgs(p1,(k-3)*(2*k+1)); |
p1 = gdivgs(p1, (k-3)*(2*k+1)); |
res[(k+1)<<1] = lpile(av1,tetpil,p1); |
P[k<<1] = lpile(av1,tetpil, p1); |
} |
} |
return res; |
return res; |
} |
} |
|
|
GEN |
GEN |
ellwp0(GEN om, GEN z, long flag, long prec, long PREC) |
weipell(GEN e, long PREC) |
{ |
{ |
GEN v,om1,om2; |
GEN c4 = (GEN)e[10]; |
long av = avma; |
GEN c6 = (GEN)e[11]; |
|
checkell(e); return _weipell(c4,c6,PREC); |
|
} |
|
|
if (z==NULL) return weipell(om,PREC); |
GEN |
|
weipell0(GEN e, long prec, long PREC) |
|
{ |
|
GEN c4,c6; |
|
|
|
if (lg(e) > 3) |
|
{ |
|
checkell(e); |
|
c4 = (GEN)e[10]; |
|
c6 = (GEN)e[11]; |
|
} |
|
else |
|
{ |
|
c4 = elleisnum(e, 4, 0, prec); |
|
c6 = elleisnum(e, 6, 0, prec); c6 = gneg(c6); |
|
} |
|
return _weipell(c4,c6,PREC); |
|
} |
|
|
|
/* assume x a t_POL */ |
|
int |
|
is_simple_var(GEN x) |
|
{ |
|
return (degpol(x) == 1 && gcmp0((GEN)x[2]) && gcmp1((GEN)x[3])); |
|
} |
|
|
|
GEN |
|
ellwp0(GEN w, GEN z, long flag, long prec, long PREC) |
|
{ |
|
GEN v; |
|
gpmem_t av = avma; |
|
SL2_red T; |
|
|
|
if (!z) return weipell0(w,prec,PREC); |
if (typ(z)==t_POL) |
if (typ(z)==t_POL) |
{ |
{ |
if (lgef(z) != 4 || !gcmp0((GEN)z[2]) || !gcmp1((GEN)z[3])) |
if (!is_simple_var(z)) err(talker,"expecting a simple variable in ellwp"); |
err(talker,"expecting a simple variable in ellwp"); |
v = weipell0(w,prec,PREC); setvarn(v, varn(z)); |
v = weipell(om,PREC); setvarn(v, varn(z)); |
|
return v; |
return v; |
} |
} |
if (!get_periods(om, &om1, &om2)) err(typeer,"ellwp"); |
if (!get_periods(w, &T)) err(typeer,"ellwp"); |
switch(flag) |
switch(flag) |
{ |
{ |
case 0: v=weipellnumall(om1,om2,z,0,prec); |
case 0: v = weipellnumall(&T,z,0,prec); |
if (typ(v)==t_VEC && lg(v)==2) { avma=av; v=gpuigs(z,-2); } |
if (!v) { avma = av; v = gpowgs(z,-2); } |
return v; |
return v; |
case 1: v=weipellnumall(om1,om2,z,1,prec); |
case 1: v = weipellnumall(&T,z,1,prec); |
if (typ(v)==t_VEC && lg(v)==2) |
if (!v) |
{ |
{ |
GEN p1 = gmul2n(gpuigs(z,3),1); |
GEN p1 = gmul2n(gpowgs(z,3),1); |
long tetpil=avma; |
gpmem_t tetpil = avma; |
v=cgetg(3,t_VEC); |
v = cgetg(3,t_VEC); |
v[1]=lpuigs(z,-2); |
v[1] = lpuigs(z,-2); |
v[2]=lneg(p1); return gerepile(av,tetpil,v); |
v[2] = lneg(p1); return gerepile(av,tetpil,v); |
} |
} |
return v; |
return v; |
case 2: return pointell(om,z,prec); |
case 2: return pointell(w,z,prec); |
default: err(flagerr,"ellwp"); return NULL; |
default: err(flagerr,"ellwp"); return NULL; |
} |
} |
} |
} |
Line 1266 ellwp0(GEN om, GEN z, long flag, long prec, long PREC) |
|
Line 1372 ellwp0(GEN om, GEN z, long flag, long prec, long PREC) |
|
static GEN |
static GEN |
_a_2(GEN e) |
_a_2(GEN e) |
{ |
{ |
long av = avma; |
gpmem_t av = avma; |
GEN unmodp = gmodulss(1,8); |
GEN unmodp = gmodulss(1,8); |
ulong e6 = itos((GEN)gmul(unmodp,(GEN)e[6])[2]); |
ulong e6 = itos((GEN)gmul(unmodp,(GEN)e[6])[2]); |
ulong e8 = itos((GEN)gmul(unmodp,(GEN)e[8])[2]); |
ulong e8 = itos((GEN)gmul(unmodp,(GEN)e[8])[2]); |
Line 1282 apell2_intern(GEN e, ulong p) |
|
Line 1388 apell2_intern(GEN e, ulong p) |
|
if (p == 2) return _a_2(e); |
if (p == 2) return _a_2(e); |
else |
else |
{ |
{ |
ulong av = avma, i; |
ulong i; |
|
gpmem_t av = avma; |
GEN unmodp = gmodulss(1,p); |
GEN unmodp = gmodulss(1,p); |
ulong e6 = itos((GEN)gmul(unmodp,(GEN)e[6])[2]); |
ulong e6 = itos((GEN)gmul(unmodp,(GEN)e[6])[2]); |
ulong e8 = itos((GEN)gmul(unmodp,(GEN)e[8])[2]); |
ulong e8 = itos((GEN)gmul(unmodp,(GEN)e[8])[2]); |
Line 1337 multi_invmod(GEN x, GEN p) |
|
Line 1444 multi_invmod(GEN x, GEN p) |
|
static GEN |
static GEN |
addsell(GEN e, GEN z1, GEN z2, GEN p) |
addsell(GEN e, GEN z1, GEN z2, GEN p) |
{ |
{ |
GEN p1,p2,x,x1,x2,y,y1,y2; |
GEN z,p1,p2,x,x1,x2,y,y1,y2; |
long av = avma; |
gpmem_t av; |
|
|
if (!z1) return z2; |
if (!z1) return z2; |
if (!z2) return z1; |
if (!z2) return z1; |
|
|
x1 = (GEN)z1[1]; y1 = (GEN)z1[2]; |
x1 = (GEN)z1[1]; y1 = (GEN)z1[2]; |
x2 = (GEN)z2[1]; y2 = (GEN)z2[2]; |
x2 = (GEN)z2[1]; y2 = (GEN)z2[2]; |
|
z = cgetg(3, t_VEC); av = avma; |
p2 = subii(x2, x1); |
p2 = subii(x2, x1); |
if (p2 == gzero) |
if (p2 == gzero) |
{ |
{ |
Line 1356 addsell(GEN e, GEN z1, GEN z2, GEN p) |
|
Line 1464 addsell(GEN e, GEN z1, GEN z2, GEN p) |
|
else p1 = subii(y2,y1); |
else p1 = subii(y2,y1); |
p1 = mulii(p1, mpinvmod(p2, p)); |
p1 = mulii(p1, mpinvmod(p2, p)); |
p1 = resii(p1, p); |
p1 = resii(p1, p); |
x = subii(sqri(p1), addii(x1,x2)); x = modii(x,p); |
x = subii(sqri(p1), addii(x1,x2)); |
y = negi(addii(y1, mulii(p1,subii(x,x1)))); |
y = negi(addii(y1, mulii(p1,subii(x,x1)))); |
avma = av; p1 = cgetg(3,t_VEC); |
x = modii(x,p); |
p1[1] = licopy(x); |
y = modii(y,p); avma = av; |
p1[2] = lmodii(y, p); return p1; |
z[1] = licopy(x); |
|
z[2] = licopy(y); return z; |
} |
} |
|
|
/* z1 <-- z1 + z2 */ |
/* z1 <-- z1 + z2 */ |
Line 1387 addsell_part2(GEN e, GEN z1, GEN z2, GEN p, GEN p2inv) |
|
Line 1496 addsell_part2(GEN e, GEN z1, GEN z2, GEN p, GEN p2inv) |
|
} |
} |
|
|
static GEN |
static GEN |
|
negsell(GEN f) |
|
{ |
|
GEN g = cgetg(3, t_VEC); |
|
g[1] = f[1]; |
|
g[2] = lnegi((GEN)f[2]); |
|
return g; |
|
} |
|
|
|
static GEN |
powsell(GEN e, GEN z, GEN n, GEN p) |
powsell(GEN e, GEN z, GEN n, GEN p) |
{ |
{ |
GEN y; |
GEN y; |
Line 1396 powsell(GEN e, GEN z, GEN n, GEN p) |
|
Line 1514 powsell(GEN e, GEN z, GEN n, GEN p) |
|
if (!s || !z) return NULL; |
if (!s || !z) return NULL; |
if (s < 0) |
if (s < 0) |
{ |
{ |
n = negi(n); y = cgetg(3,t_VEC); |
z = negsell(z); |
y[2] = lnegi((GEN)z[2]); |
n = negi(n); |
y[1] = z[1]; z = y; |
|
} |
} |
if (is_pm1(n)) return z; |
if (is_pm1(n)) return z; |
|
|
Line 1417 powsell(GEN e, GEN z, GEN n, GEN p) |
|
Line 1534 powsell(GEN e, GEN z, GEN n, GEN p) |
|
return addsell(e,y,z,p); |
return addsell(e,y,z,p); |
} |
} |
|
|
|
/* assume H.f = 0, return exact order of f */ |
|
static GEN |
|
exact_order(GEN H, GEN f, GEN cp4, GEN p) |
|
{ |
|
GEN P, e, g, h = H, fa = decomp(H); |
|
long i, j, l; |
|
|
|
P = (GEN)fa[1]; l = lg(P); |
|
e = (GEN)fa[2]; |
|
for (i=1; i<l; i++) |
|
for (j=itos((GEN)e[i]); j; j--) |
|
{ |
|
g = diviiexact(h,(GEN)P[i]); |
|
if (powsell(cp4,f,g,p)) break; |
|
h = g; |
|
} |
|
return h; |
|
} |
|
|
/* make sure *x has lgefint >= k */ |
/* make sure *x has lgefint >= k */ |
static void |
static void |
_fix(GEN x, long k) |
_fix(GEN x, long k) |
Line 1425 _fix(GEN x, long k) |
|
Line 1561 _fix(GEN x, long k) |
|
if (lgefint(y) < k) { GEN p1 = cgeti(k); affii(y,p1); *x = (long)p1; } |
if (lgefint(y) < k) { GEN p1 = cgeti(k); affii(y,p1); *x = (long)p1; } |
} |
} |
|
|
/* low word of integer x */ |
/* compute a_p using Shanks/Mestre + Montgomery's trick. Assume p > 457 */ |
#define _low(x) (__x=(GEN)x, __x[lgefint(__x)-1]) |
|
|
|
/* compute a_p using Shanks/Mestre + Montgomery's trick. Assume p > 20, say */ |
|
GEN |
GEN |
apell1(GEN e, GEN p) |
apell1(GEN e, GEN p) |
{ |
{ |
long *tx, *ty, *ti, av = avma, av2,pfinal,i,j,j2,s,flc,flcc,x,nb; |
long *tx, *ty, *ti, pfinal, i, j, s, k, k1, x, nb; |
GEN p1,p2,p3,h,mfh,f,fh,fg,pordmin,u,v,p1p,p2p,acon,bcon,c4,c6,cp4,pts; |
gpmem_t av = avma, av2; |
GEN __x; |
GEN p1,h,mfh,f,fh,fg,pordmin,u,v,p1p,p2p,A,B,c4,c6,cp4,pts; |
|
|
if (DEBUGLEVEL) timer2(); |
|
p1 = gmodulsg(1,p); |
|
c4 = gdivgs(gmul(p1,(GEN)e[10]), -48); |
|
c6 = gdivgs(gmul(p1,(GEN)e[11]), -864); |
|
pordmin = gceil(gmul2n(gsqrt(p,DEFAULTPREC),2)); |
|
p1p = addsi(1,p); p2p = shifti(p1p,1); |
|
x=0; flcc=0; flc = kronecker((GEN)c6[2],p); |
|
u=c6; acon=gzero; bcon=gun; h=p1p; |
|
tx = ty = ti = NULL; /* gcc -Wall */ |
tx = ty = ti = NULL; /* gcc -Wall */ |
|
|
|
if (DEBUGLEVEL) (void)timer2(); |
|
c4 = gmod(gdivgs((GEN)e[10], -48), p); |
|
c6 = gmod(gdivgs((GEN)e[11], -864), p); |
|
pordmin = gceil(gmul2n(gsqrt(p,DEFAULTPREC),2)); /* ceil( sqrt(4p) ) */ |
|
p1p = addsi(1,p); |
|
p2p = shifti(p1p,1); |
|
x = 0; u = c6; k1 = 0; k = kronecker(c6, p); |
|
A = gzero; B = gun; h = p1p; |
for(;;) |
for(;;) |
{ |
{ |
while (flc==flcc || !flc) |
while (k == k1 || !k) |
{ |
{ |
x++; |
x++; |
u = gadd(c6, gmulsg(x, gaddgs(c4,x*x))); |
u = modii(addii(c6, mulsi(x, addii(c4, mulss(x,x)))), p); |
flc = kronecker((GEN)u[2],p); |
k = kronecker(u, p); |
} |
} |
flcc = flc; |
k1 = k; |
|
|
f = cgetg(3,t_VEC); |
f = cgetg(3,t_VEC); |
f[1] = (long)lift_intern(gmulsg(x,u)); |
f[1] = lmodii(mulsi(x,u), p); |
f[2] = (long)lift_intern(gsqr(u)); |
f[2] = lmodii(sqri(u), p); |
cp4 = lift_intern(gmul(c4, (GEN)f[2])); |
cp4 = modii(mulii(c4, (GEN)f[2]), p); |
fh = powsell(cp4,f,h,p); |
fh = powsell(cp4,f,h,p); |
s = itos(gceil(gsqrt(gdiv(pordmin,bcon),DEFAULTPREC))) >> 1; |
s = itos(gceil(gsqrt(gdiv(pordmin,B),DEFAULTPREC))) >> 1; |
nb = min(128, s >> 1); |
|
/* look for h s.t f^h = 0 */ |
/* look for h s.t f^h = 0 */ |
if (bcon == gun) |
if (B == gun) |
{ /* first time: initialize */ |
{ /* first time: initialize */ |
tx = newbloc(s+1); |
tx = newbloc(s+1); |
ty = newbloc(s+1); |
ty = newbloc(s+1); |
ti = newbloc(s+1); |
ti = newbloc(s+1); |
} |
} |
else f = powsell(cp4,f,bcon,p); /* F */ |
else f = powsell(cp4,f,B,p); /* F = B.f */ |
*tx = evaltyp(t_VECSMALL) | evallg(s+1); |
*tx = evaltyp(t_VECSMALL) | evallg(s+1); |
if (!fh) goto FOUND; |
if (!fh) goto FOUND; |
|
|
p1 = gcopy(fh); |
p1 = gcopy(fh); |
pts = new_chunk(nb+1); |
if (s < 3) |
|
{ /* we're nearly done: naive search */ |
|
GEN q1 = p1, mf = negsell(f); /* -F */ |
|
for (i=1;; i++) |
|
{ |
|
p1 = addsell(cp4,p1, f,p); /* h.f + i.F */ |
|
if (!p1) { h = addii(h, mulsi( i,B)); goto FOUND; } |
|
q1 = addsell(cp4,q1,mf,p); /* h.f - i.F */ |
|
if (!q1) { h = addii(h, mulsi(-i,B)); goto FOUND; } |
|
} |
|
} |
|
/* Baby Step/Giant Step */ |
|
nb = min(128, s >> 1); /* > 0. Will do nb pts at a time: faster inverse */ |
|
pts = cgetg(nb+1, t_VEC); |
j = lgefint(p); |
j = lgefint(p); |
for (i=1; i<=nb; i++) |
for (i=1; i<=nb; i++) |
{ /* baby steps */ |
{ /* baby steps */ |
pts[i] = (long)p1; /* h.f + (i-1).F */ |
pts[i] = (long)p1; /* h.f + (i-1).F */ |
_fix(p1+1, j); tx[i] = _low((GEN)p1[1]); |
_fix(p1+1, j); tx[i] = modBIL((GEN)p1[1]); |
_fix(p1+2, j); ty[i] = _low((GEN)p1[2]); |
_fix(p1+2, j); ty[i] = modBIL((GEN)p1[2]); |
p1 = addsell(cp4,p1,f,p); /* h.f + i.F */ |
p1 = addsell(cp4,p1,f,p); /* h.f + i.F */ |
if (!p1) { h = addii(h, mulsi(i,bcon)); goto FOUND; } |
if (!p1) { h = addii(h, mulsi(i,B)); goto FOUND; } |
} |
} |
mfh = dummycopy(fh); |
mfh = negsell(fh); |
mfh[2] = lnegi((GEN)mfh[2]); |
fg = addsell(cp4,p1,mfh,p); /* h.f + nb.F - h.f = nb.F */ |
fg = addsell(cp4,p1,mfh,p); /* nb.F */ |
if (!fg) { h = mulsi(nb,B); goto FOUND; } |
if (!fg) { h = mulsi(nb,bcon); goto FOUND; } |
|
u = cgetg(nb+1, t_VEC); |
u = cgetg(nb+1, t_VEC); |
av2 = avma; /* more baby steps, nb points at a time */ |
av2 = avma; /* more baby steps, nb points at a time */ |
while (i <= s) |
while (i <= s) |
Line 1499 apell1(GEN e, GEN p) |
|
Line 1644 apell1(GEN e, GEN p) |
|
if (u[j] == zero) /* sum = 0 or doubling */ |
if (u[j] == zero) /* sum = 0 or doubling */ |
{ |
{ |
long k = i+j-2; |
long k = i+j-2; |
if (egalii((GEN)p1[2],(GEN)fg[2])) k -= 2*nb; /* fg = p1 */ |
if (egalii((GEN)p1[2],(GEN)fg[2])) k -= 2*nb; /* fg == p1 */ |
h = addii(h, mulsi(k,bcon)); |
h = addii(h, mulsi(k,B)); goto FOUND; |
goto FOUND; |
|
} |
} |
} |
} |
v = multi_invmod(u, p); |
v = multi_invmod(u, p); |
Line 1510 apell1(GEN e, GEN p) |
|
Line 1654 apell1(GEN e, GEN p) |
|
{ |
{ |
p1 = (GEN)pts[j]; |
p1 = (GEN)pts[j]; |
addsell_part2(cp4,p1,fg,p, (GEN)v[j]); |
addsell_part2(cp4,p1,fg,p, (GEN)v[j]); |
tx[i] = _low((GEN)p1[1]); |
tx[i] = modBIL((GEN)p1[1]); |
ty[i] = _low((GEN)p1[2]); |
ty[i] = modBIL((GEN)p1[2]); |
} |
} |
avma = av2; |
avma = av2; |
} |
} |
p1 = addsell(cp4,(GEN)pts[j-1],mfh,p); /* = f^(s-1) */ |
p1 = addsell(cp4,(GEN)pts[j-1],mfh,p); /* = (s-1).F */ |
|
if (!p1) { h = mulsi(s-1,B); goto FOUND; } |
if (DEBUGLEVEL) msgtimer("[apell1] baby steps, s = %ld",s); |
if (DEBUGLEVEL) msgtimer("[apell1] baby steps, s = %ld",s); |
|
|
/* giant steps: fg = f^s */ |
/* giant steps: fg = s.F */ |
fg = addsell(cp4,p1,f,p); |
fg = addsell(cp4,p1,f,p); |
if (!fg) { h = addii(h, mulsi(s,bcon)); goto FOUND; } |
if (!fg) { h = mulsi(s,B); goto FOUND; } |
pfinal = _low(p); av2 = avma; |
pfinal = modBIL(p); av2 = avma; |
|
|
p1 = gen_sort(tx, cmp_IND | cmp_C, NULL); |
p1 = gen_sort(tx, cmp_IND | cmp_C, NULL); |
for (i=1; i<=s; i++) ti[i] = tx[p1[i]]; |
for (i=1; i<=s; i++) ti[i] = tx[p1[i]]; |
Line 1531 apell1(GEN e, GEN p) |
|
Line 1676 apell1(GEN e, GEN p) |
|
avma = av2; |
avma = av2; |
|
|
gaffect(fg, (GEN)pts[1]); |
gaffect(fg, (GEN)pts[1]); |
for (j=2; j<=nb; j++) /* pts = first nb multiples of fg */ |
for (j=2; j<=nb; j++) /* pts[j] = j.fg = (s*j).F */ |
gaffect(addsell(cp4,(GEN)pts[j-1],fg,p), (GEN)pts[j]); |
{ |
|
p1 = addsell(cp4,(GEN)pts[j-1],fg,p); |
|
if (!p1) { h = mulii(mulss(s,j), B); goto FOUND; } |
|
gaffect(p1, (GEN)pts[j]); |
|
} |
/* replace fg by nb.fg since we do nb points at a time */ |
/* replace fg by nb.fg since we do nb points at a time */ |
avma = av2; |
avma = av2; |
fg = gcopy((GEN)pts[nb]); |
fg = gcopy((GEN)pts[nb]); |
Line 1542 apell1(GEN e, GEN p) |
|
Line 1691 apell1(GEN e, GEN p) |
|
{ |
{ |
GEN ftest = (GEN)pts[j]; |
GEN ftest = (GEN)pts[j]; |
ulong m, l = 1, r = s+1; |
ulong m, l = 1, r = s+1; |
long k, k2; |
long k, k2, j2; |
|
|
avma = av2; |
avma = av2; |
k = _low((GEN)ftest[1]); |
k = modBIL((GEN)ftest[1]); |
while (l<r) |
while (l<r) |
{ |
{ |
m = (l+r) >> 1; |
m = (l+r) >> 1; |
Line 1554 apell1(GEN e, GEN p) |
|
Line 1703 apell1(GEN e, GEN p) |
|
if (r <= (ulong)s && tx[r] == k) |
if (r <= (ulong)s && tx[r] == k) |
{ |
{ |
while (tx[r] == k && r) r--; |
while (tx[r] == k && r) r--; |
k2 = _low((GEN)ftest[2]); |
k2 = modBIL((GEN)ftest[2]); |
for (r++; tx[r] == k && r <= (ulong)s; r++) |
for (r++; tx[r] == k && r <= (ulong)s; r++) |
if (ty[r] == k2 || ty[r] == pfinal - k2) |
if (ty[r] == k2 || ty[r] == pfinal - k2) |
{ /* [h+j2] f == ± ftest (= [i.s] f)? */ |
{ /* [h+j2] f == ± ftest (= [i.s] f)? */ |
if (DEBUGLEVEL) msgtimer("[apell1] giant steps, i = %ld",i); |
|
j2 = ti[r] - 1; |
j2 = ti[r] - 1; |
|
if (DEBUGLEVEL) msgtimer("[apell1] giant steps, i = %ld",i); |
p1 = addsell(cp4, powsell(cp4,f,stoi(j2),p),fh,p); |
p1 = addsell(cp4, powsell(cp4,f,stoi(j2),p),fh,p); |
if (egalii((GEN)p1[1], (GEN)ftest[1])) |
if (egalii((GEN)p1[1], (GEN)ftest[1])) |
{ |
{ |
if (egalii((GEN)p1[2], (GEN)ftest[2])) i = -i; |
if (egalii((GEN)p1[2], (GEN)ftest[2])) i = -i; |
h = addii(h, mulii(addis(mulss(s,i), j2), bcon)); |
h = addii(h, mulii(addis(mulss(s,i), j2), B)); |
goto FOUND; |
goto FOUND; |
} |
} |
} |
} |
} |
} |
if (++j > nb) |
if (++j > nb) |
{ /* compute next nb points */ |
{ /* compute next nb points */ |
long save = 0; /* gcc -Wall */ |
long save = 0; /* gcc -Wall */; |
for (j=1; j<=nb; j++) |
for (j=1; j<=nb; j++) |
{ |
{ |
p1 = (GEN)pts[j]; |
p1 = (GEN)pts[j]; |
Line 1590 apell1(GEN e, GEN p) |
|
Line 1739 apell1(GEN e, GEN p) |
|
} |
} |
} |
} |
|
|
FOUND: /* success, found a point of exponent h */ |
FOUND: /* found a point of exponent h */ |
p2 = decomp(h); p1=(GEN)p2[1]; p2=(GEN)p2[2]; |
h = exact_order(h, f,cp4,p); |
for (i=1; i<lg(p1); i++) |
/* now h is the exact order, and divides E(Fp) = A (mod B) */ |
for (j=itos((GEN)p2[i]); j; j--) |
if (B == gun) B = h; |
{ |
|
p3 = divii(h,(GEN)p1[i]); |
|
if (powsell(cp4,f,p3,p)) break; |
|
h = p3; |
|
} |
|
/* now h is the exact order */ |
|
if (bcon == gun) bcon = h; |
|
else |
else |
{ |
{ |
p1 = chinois(gmodulcp(acon,bcon), gmodulsg(0,h)); |
p1 = chinois(gmodulcp(A,B), gmodulsg(0,h)); |
acon = (GEN)p1[2]; |
A = (GEN)p1[2]; |
bcon = (GEN)p1[1]; |
B = (GEN)p1[1]; |
} |
} |
|
|
i = (cmpii(bcon, pordmin) < 0); |
i = (cmpii(B, pordmin) < 0); |
if (i) acon = centermod(subii(p2p,acon), bcon); |
if (i) A = centermod(subii(p2p,A), B); |
p1 = ground(gdiv(gsub(p1p,acon),bcon)); |
p1 = diviiround(gsub(p1p,A), B); |
h = addii(acon, mulii(p1,bcon)); |
h = addii(A, mulii(p1,B)); |
|
/* h = A mod B, closest lift to p+1 */ |
if (!i) break; |
if (!i) break; |
} |
} |
gunclone(tx); |
gunclone(tx); |
gunclone(ty); |
gunclone(ty); |
gunclone(ti); |
gunclone(ti); |
p1 = (flc==1)? subii(p1p,h): subii(h,p1p); |
p1 = (k==1)? subii(p1p,h): subii(h,p1p); |
return gerepileupto(av,p1); |
return gerepileuptoint(av,p1); |
} |
} |
|
|
typedef struct |
typedef struct |
Line 1667 powssell1(long e, long p, long n, sellpt *p1, sellpt * |
|
Line 1810 powssell1(long e, long p, long n, sellpt *p1, sellpt * |
|
} |
} |
} |
} |
|
|
|
/* assume H.f = 0, return exact order of f, cf. exact_order */ |
|
static long |
|
sexact_order(long H, sellpt *f, long cp4, long p) |
|
{ |
|
GEN P, e, fa = decomp(stoi(H)); |
|
long h = H, g, pp; |
|
long i, j, l; |
|
sellpt fh; |
|
|
|
P = (GEN)fa[1]; l = lg(P); |
|
e = (GEN)fa[2]; |
|
for (i=1; i<l; i++) |
|
{ |
|
pp = itos((GEN)P[i]); |
|
for (j=itos((GEN)e[i]); j; j--) |
|
{ |
|
g = h / pp; |
|
powssell1(cp4, p, g, f, &fh); |
|
if (!fh.isnull) break; |
|
h = g; |
|
} |
|
} |
|
return h; |
|
} |
|
|
typedef struct |
typedef struct |
{ |
{ |
long x,y,i; |
long x,y,i; |
Line 1682 compare_multiples(multiple *a, multiple *b) |
|
Line 1850 compare_multiples(multiple *a, multiple *b) |
|
static GEN |
static GEN |
apell0(GEN e, long p) |
apell0(GEN e, long p) |
{ |
{ |
GEN p1,p2; |
|
sellpt f,fh,fg,ftest,f2; |
sellpt f,fh,fg,ftest,f2; |
long pordmin,u,p1p,p2p,acon,bcon,c4,c6,cp4; |
long pordmin,u,p1p,p2p,A,B,c4,c6,cp4; |
long av,i,j,s,flc,flcc,x,q,h,p3,l,r,m; |
long i, s, k, k1, x, q, h, l, r, m; |
|
gpmem_t av; |
multiple *table; |
multiple *table; |
|
|
if (p < 99) return apell2_intern(e,(ulong)p); |
if (p < 99) return apell2_intern(e,(ulong)p); |
|
table = NULL; /* gcc -Wall */ |
|
|
av = avma; p1 = gmodulss(1,p); |
av = avma; |
c4 = itos((GEN)gdivgs(gmul(p1,(GEN)e[10]), -48)[2]); |
c4 = itos( gmodgs(gdivgs((GEN)e[10], -48), p) ); |
c6 = itos((GEN)gdivgs(gmul(p1,(GEN)e[11]), -864)[2]); |
c6 = itos( gmodgs(gdivgs((GEN)e[11], -864), p) ); |
pordmin = (long)(1 + 4*sqrt((float)p)); |
pordmin = (long)(1 + 4*sqrt((float)p)); |
p1p = p+1; p2p = p1p << 1; |
p1p = p+1; |
x=0; flcc=0; flc = kross(c6, p); |
p2p = p1p << 1; |
u=c6; acon=0; bcon=1; h=p1p; |
x = 0; u = c6; k1 = 0; k = kross(c6, p); |
table = NULL; /* gcc -Wall */ |
A = 0; B = 1; h = p1p; |
for(;;) |
for(;;) |
{ |
{ |
while (flc==flcc || !flc) |
while (k == k1 || !k) |
{ |
{ |
x++; |
x++; |
u = addssmod(c6, mulssmod(x, c4+mulssmod(x,x,p), p), p); |
u = addssmod(c6, mulssmod(x, c4+mulssmod(x,x,p), p), p); |
flc = kross(u,p); |
k = kross(u,p); |
} |
} |
flcc = flc; |
k1 = k; |
f.isnull = 0; |
f.isnull = 0; |
f.x = mulssmod(x, u, p); |
f.x = mulssmod(x, u, p); |
f.y = mulssmod(u, u, p); |
f.y = mulssmod(u, u, p); |
cp4 = mulssmod(c4, f.y, p); |
cp4 = mulssmod(c4, f.y, p); |
powssell1(cp4, p, h, &f, &fh); |
powssell1(cp4, p, h, &f, &fh); |
s = (long) (sqrt(((float)pordmin)/bcon) / 2); |
s = (long) (sqrt(((float)pordmin)/B) / 2); |
if (!s) s=1; |
if (!s) s=1; |
if (bcon==1) |
if (B==1) |
{ |
{ |
table = (multiple *) gpmalloc((s+1)*sizeof(multiple)); |
table = (multiple *) gpmalloc((s+1)*sizeof(multiple)); |
f2 = f; |
f2 = f; |
} |
} |
else powssell1(cp4, p, bcon, &f, &f2); |
else powssell1(cp4, p, B, &f, &f2); |
for (i=0; i < s; i++) |
for (i=0; i < s; i++) |
{ |
{ |
if (fh.isnull) { h += bcon*i; goto FOUND; } |
if (fh.isnull) { h += B*i; goto FOUND; } |
table[i].x = fh.x; |
table[i].x = fh.x; |
table[i].y = fh.y; |
table[i].y = fh.y; |
table[i].i = i; |
table[i].i = i; |
Line 1742 apell0(GEN e, long p) |
|
Line 1911 apell0(GEN e, long p) |
|
if (r < s && table[r].x == ftest.x) break; |
if (r < s && table[r].x == ftest.x) break; |
addsell1(cp4, p, &ftest, &fg); |
addsell1(cp4, p, &ftest, &fg); |
} |
} |
h += table[r].i * bcon; |
h += table[r].i * B; |
if (table[r].y == ftest.y) i = -i; |
if (table[r].y == ftest.y) i = -i; |
h += s * i * bcon; |
h += s * i * B; |
|
|
FOUND: |
FOUND: |
p2=decomp(stoi(h)); p1=(GEN)p2[1]; p2=(GEN)p2[2]; |
h = sexact_order(h, &f, cp4, p); |
for (i=1; i < lg(p1); i++) |
if (B == 1) B = h; |
for (j = mael(p2,i,2); j; j--) |
|
{ |
|
p3 = h / mael(p1,i,2); |
|
powssell1(cp4, p, p3, &f, &fh); |
|
if (!fh.isnull) break; |
|
h = p3; |
|
} |
|
if (bcon == 1) bcon = h; |
|
else |
else |
{ |
{ |
p1 = chinois(gmodulss(acon,bcon), gmodulss(0,h)); |
GEN p1 = chinois(gmodulss(A,B), gmodulss(0,h)); |
acon = itos((GEN)p1[2]); |
A = itos((GEN)p1[2]); |
if (is_bigint(p1[1])) { h = acon; break; } |
if (is_bigint(p1[1])) { h = A; break; } |
bcon = itos((GEN)p1[1]); |
B = itos((GEN)p1[1]); |
} |
} |
|
|
i = (bcon < pordmin); |
i = (B < pordmin); |
if (i) |
if (i) |
{ |
{ |
acon = (p2p - acon) % bcon; |
A = (p2p - A) % B; |
if ((acon << 1) > bcon) acon -= bcon; |
if ((A << 1) > B) A -= B; |
} |
} |
q = ((ulong)(p2p + bcon - (acon << 1))) / (bcon << 1); |
q = ((ulong)(p2p + B - (A << 1))) / (B << 1); |
h = acon + q*bcon; |
h = A + q*B; |
avma = av; if (!i) break; |
avma = av; if (!i) break; |
} |
} |
free(table); return stoi((flc==1)? p1p-h: h-p1p); |
free(table); return stoi(k==1? p1p-h: h-p1p); |
} |
} |
|
|
GEN |
GEN |
Line 1785 apell(GEN e, GEN p) |
|
Line 1946 apell(GEN e, GEN p) |
|
if (typ(p)!=t_INT || signe(p)<0) err(talker,"not a prime in apell"); |
if (typ(p)!=t_INT || signe(p)<0) err(talker,"not a prime in apell"); |
if (gdivise((GEN)e[12],p)) /* e[12] may be an intmod */ |
if (gdivise((GEN)e[12],p)) /* e[12] may be an intmod */ |
{ |
{ |
long av = avma,s; |
long s; |
|
gpmem_t av = avma; |
GEN p0 = egalii(p,gdeux)? stoi(8): p; |
GEN p0 = egalii(p,gdeux)? stoi(8): p; |
GEN c6 = gmul((GEN)e[11],gmodulsg(1,p0)); |
GEN c6 = gmul((GEN)e[11],gmodulsg(1,p0)); |
s = kronecker(lift_intern(c6),p); avma=av; |
s = kronecker(lift_intern(c6),p); avma=av; |
|
|
anell(GEN e, long n) |
anell(GEN e, long n) |
{ |
{ |
long tab[4]={0,1,1,-1}; /* p prime; (-1/p) = tab[p&3]. tab[0] is not used */ |
long tab[4]={0,1,1,-1}; /* p prime; (-1/p) = tab[p&3]. tab[0] is not used */ |
long p, i, m, av, tetpil; |
long p, i, m; |
|
gpmem_t av, tetpil; |
GEN p1,p2,an; |
GEN p1,p2,an; |
|
|
checkell(e); |
checkell(e); |
Line 1873 anell(GEN e, long n) |
|
Line 2036 anell(GEN e, long n) |
|
GEN |
GEN |
akell(GEN e, GEN n) |
akell(GEN e, GEN n) |
{ |
{ |
long i,j,ex,av=avma; |
long i, j, ex; |
|
gpmem_t av=avma; |
GEN p1,p2,ap,u,v,w,y,pl; |
GEN p1,p2,ap,u,v,w,y,pl; |
|
|
checkell(e); |
checkell(e); |
Line 1908 akell(GEN e, GEN n) |
|
Line 2072 akell(GEN e, GEN n) |
|
GEN |
GEN |
hell(GEN e, GEN a, long prec) |
hell(GEN e, GEN a, long prec) |
{ |
{ |
long av=avma,tetpil,n; |
long n; |
|
gpmem_t av=avma, tetpil; |
GEN p1,p2,y,z,q,pi2surw,pi2isurw,qn,ps; |
GEN p1,p2,y,z,q,pi2surw,pi2isurw,qn,ps; |
|
|
checkbell(e); |
checkbell(e); |
Line 1951 hells(GEN e, GEN x, long prec) |
|
Line 2116 hells(GEN e, GEN x, long prec) |
|
return mu; |
return mu; |
} |
} |
|
|
|
/* [1,0,0,0] */ |
|
static GEN |
|
init_ch() { |
|
GEN v = cgetg(5,t_VEC); |
|
v[1] = un; v[2] = v[3] = v[4] = zero; return v; |
|
} |
|
|
GEN |
GEN |
hell2(GEN e, GEN x, long prec) |
hell2(GEN e, GEN x, long prec) |
{ |
{ |
GEN ep,e3,ro,p1,p2,mu,d,xp; |
GEN ep,e3,ro,p1,p2,mu,d,xp; |
long av=avma,tetpil,lx,lc,i,j,tx; |
long lx, lc, i, j, tx; |
|
gpmem_t av=avma, tetpil; |
|
|
if (!oncurve(e,x)) err(heller1); |
if (!oncurve(e,x)) err(heller1); |
d=(GEN)e[12]; ro=(GEN)e[14]; e3=(gsigne(d) < 0)?(GEN)ro[1]:(GEN)ro[3]; |
d=(GEN)e[12]; ro=(GEN)e[14]; e3=(gsigne(d) < 0)?(GEN)ro[1]:(GEN)ro[3]; |
p1=cgetg(5,t_VEC); p1[1]=un; p1[2]=laddgs(gfloor(e3),-1); |
p1 = init_ch(); p1[2] = laddgs(gfloor(e3),-1); |
p1[3]=p1[4]=zero; ep=coordch(e,p1); xp=pointch(x,p1); |
ep = coordch(e,p1); |
|
xp = pointch(x,p1); |
tx=typ(x[1]); lx=lg(x); |
tx=typ(x[1]); lx=lg(x); |
if (!is_matvec_t(tx)) |
if (!is_matvec_t(tx)) |
{ |
{ |
Line 2016 hell0(GEN e, GEN z, long prec) |
|
Line 2190 hell0(GEN e, GEN z, long prec) |
|
static GEN |
static GEN |
ghell0(GEN e, GEN a, long flag, long prec) |
ghell0(GEN e, GEN a, long flag, long prec) |
{ |
{ |
long av=avma,lx,i,n,n2,grandn,tx=typ(a); |
long lx, i, n, n2, grandn, tx=typ(a); |
|
gpmem_t av=avma; |
GEN p,p1,p2,x,y,z,phi2,psi2,psi3,logdep; |
GEN p,p1,p2,x,y,z,phi2,psi2,psi3,logdep; |
|
|
checkbell(e); if (!is_matvec_t(tx)) err(elliper1); |
checkbell(e); if (!is_matvec_t(tx)) err(elliper1); |
Line 2106 static long ellrootno_all(GEN e, GEN p, GEN* ptcond); |
|
Line 2281 static long ellrootno_all(GEN e, GEN p, GEN* ptcond); |
|
GEN |
GEN |
lseriesell(GEN e, GEN s, GEN A, long prec) |
lseriesell(GEN e, GEN s, GEN A, long prec) |
{ |
{ |
long av=avma,av1,tetpil,lim,l,n,eps,flun; |
long l, n, eps, flun; |
|
gpmem_t av=avma, av1, tetpil, lim; |
GEN z,p1,p2,cg,cg1,v,cga,cgb,s2,ns,gs,N; |
GEN z,p1,p2,cg,cg1,v,cga,cgb,s2,ns,gs,N; |
|
|
if (!A) A = gun; |
if (!A) A = gun; |
Line 2118 lseriesell(GEN e, GEN s, GEN A, long prec) |
|
Line 2294 lseriesell(GEN e, GEN s, GEN A, long prec) |
|
} |
} |
flun = gcmp1(A) && gcmp1(s); |
flun = gcmp1(A) && gcmp1(s); |
eps = ellrootno_all(e,gun,&N); |
eps = ellrootno_all(e,gun,&N); |
if (flun && eps<0) { z=cgetr(prec); affsr(0,z); return z; } |
if (flun && eps < 0) return realzero(prec); |
|
|
cg1=mppi(prec); setexpo(cg1,2); cg=divrr(cg1,gsqrt(N,prec)); |
cg1=mppi(prec); setexpo(cg1,2); cg=divrr(cg1,gsqrt(N,prec)); |
cga=gmul(cg,A); cgb=gdiv(cg,A); |
cga=gmul(cg,A); cgb=gdiv(cg,A); |
l=(long)((pariC2*(prec-2) + fabs(gtodouble(s)-1.)*log(rtodbl(cga))) |
l=(long)((pariC2*(prec-2) + fabs(gtodouble(s)-1.)*log(rtodbl(cga))) |
/ rtodbl(cgb)+1); |
/ rtodbl(cgb)+1); |
v = anell(e, min((ulong)l,TEMPMAX)); |
v = anell(e, min((ulong)l,TEMPMAX)); |
s2 = ns = NULL; /* gcc -Wall */ |
s2 = ns = NULL; /* gcc -Wall */ |
if (!flun) { s2=gsubsg(2,s); ns=gpui(cg,gsubgs(gmul2n(s,1),2),prec); } |
if (!flun) { s2=gsubsg(2,s); ns=gpow(cg,gsubgs(gmul2n(s,1),2),prec); } |
z=gzero; |
z=gzero; |
if (typ(s)==t_INT) |
if (typ(s)==t_INT) |
{ |
{ |
Line 2136 lseriesell(GEN e, GEN s, GEN A, long prec) |
|
Line 2313 lseriesell(GEN e, GEN s, GEN A, long prec) |
|
av1=avma; lim=stack_lim(av1,1); |
av1=avma; lim=stack_lim(av1,1); |
for (n=1; n<=l; n++) |
for (n=1; n<=l; n++) |
{ |
{ |
p1=gdiv(incgam4(s,gmulsg(n,cga),gs,prec),gpui(stoi(n),s,prec)); |
p1=gdiv(incgam4(s,gmulsg(n,cga),gs,prec),gpow(stoi(n),s,prec)); |
p2=flun? p1: gdiv(gmul(ns,incgam(s2,gmulsg(n,cgb),prec)), |
p2=flun? p1: gdiv(gmul(ns,incgam(s2,gmulsg(n,cgb),prec)), |
gpui(stoi(n),s2,prec)); |
gpow(stoi(n),s2,prec)); |
if (eps<0) p2=gneg_i(p2); |
if (eps<0) p2=gneg_i(p2); |
z = gadd(z, gmul(gadd(p1,p2), |
z = gadd(z, gmul(gadd(p1,p2), |
((ulong)n<=TEMPMAX)? (GEN)v[n]: akell(e,stoi(n)))); |
((ulong)n<=TEMPMAX)? (GEN)v[n]: akell(e,stoi(n)))); |
Line 2177 lseriesell(GEN e, GEN s, GEN A, long prec) |
|
Line 2354 lseriesell(GEN e, GEN s, GEN A, long prec) |
|
Uses Tate's algorithm (Anvers IV). Given the remarks at the bottom of |
Uses Tate's algorithm (Anvers IV). Given the remarks at the bottom of |
page 46, the "long" algorithm is used for p < 4 only. */ |
page 46, the "long" algorithm is used for p < 4 only. */ |
static void cumule(GEN *vtotal, GEN *e, GEN u, GEN r, GEN s, GEN t); |
static void cumule(GEN *vtotal, GEN *e, GEN u, GEN r, GEN s, GEN t); |
static void cumule1(GEN *vtotal, GEN *e, GEN v2); |
static void cumulev(GEN *vtotal, GEN u, GEN r, GEN s, GEN t); |
|
|
static GEN |
static GEN |
localreduction_result(long av, long f, long kod, long c, GEN v) |
localred_result(long f, long kod, long c, GEN v) |
{ |
{ |
long tetpil = avma; |
GEN z = cgetg(5, t_VEC); |
GEN result = cgetg(5, t_VEC); |
z[1] = lstoi(f); |
result[1] = lstoi(f); result[2] = lstoi(kod); |
z[2] = lstoi(kod); |
result[3] = lcopy(v); result[4] = lstoi(c); |
z[3] = lcopy(v); |
return gerepile(av,tetpil, result); |
z[4] = lstoi(c); return z; |
} |
} |
|
|
/* ici, p != 2 et p != 3 */ |
/* Here p > 3. e assumed integral */ |
static GEN |
static GEN |
localreduction_carac_not23(GEN e, GEN p) |
localred_carac_p(GEN e, GEN p, int minim) |
{ |
{ |
long av = avma, k, f, kod, c, nuj, nudelta; |
long k, f, kod, c, nuj, nudelta; |
GEN pk, p2k, a2prime, a3prime; |
GEN p2, v = init_ch(); |
GEN p2, r = gzero, s = gzero, t = gzero, v; |
GEN c4, c6, delta, tri; |
GEN c4, c6, delta, unmodp, xun, tri, var, p4k, p6k; |
|
|
|
nudelta = ggval((GEN)e[12], p); |
c4 = (GEN)e[10]; |
v = cgetg(5,t_VEC); v[1] = un; v[2] = v[3] = v[4] = zero; |
c6 = (GEN)e[11]; |
nuj = gcmp0((GEN)e[13])? 0: - ggval((GEN)e[13], p); |
delta = (GEN)e[12]; |
|
nuj = gcmp0((GEN)e[13])? 0: - ggval((GEN)e[13], p); |
|
nudelta = ggval(delta, p); |
k = (nuj > 0 ? nudelta - nuj : nudelta) / 12; |
k = (nuj > 0 ? nudelta - nuj : nudelta) / 12; |
c4 = (GEN)e[10]; c6 = (GEN)e[11]; delta = (GEN)e[12]; |
if (k <= 0) |
if (k > 0) /* modele non minimal */ |
|
{ |
{ |
pk = gpuigs(p, k); |
if (minim) return v; |
if (mpodd((GEN)e[1])) |
} |
s = shifti(subii(pk, (GEN)e[1]), -1); |
else |
else |
{ /* model not minimal */ |
s = negi(shifti((GEN)e[1], -1)); |
GEN pk = gpowgs(p,k), p2k = sqri(pk), p4k = sqri(p2k), p6k = mulii(p4k,p2k); |
p2k = sqri(pk); |
GEN r, s, t; |
p4k = sqri(p2k); |
|
p6k = mulii(p4k, p2k); |
|
|
|
a2prime = subii((GEN)e[2], mulii(s, addii((GEN)e[1], s))); |
s = negi((GEN)e[1]); |
switch(smodis(a2prime, 3)) |
if (mpodd(s)) s = addii(s, pk); |
|
s = shifti(s, -1); |
|
|
|
r = subii(mulii(s, addii((GEN)e[1], s)), (GEN)e[2]); /* - a_2' */ |
|
switch(smodis(r, 3)) |
{ |
{ |
case 0: r = negi(divis(a2prime, 3)); break; |
default: break; /* 0 */ |
case 1: r = divis(subii(p2k, a2prime), 3); break; |
case 1: r = addii(r, p2k); break; |
case 2: r = negi(divis(addii(a2prime, p2k), 3)); break; |
case 2: r = subii(r, p2k); break; |
} |
} |
a3prime = ellLHS0_i(e,r); |
r = divis(r, 3); |
if (mpodd(a3prime)) |
|
t = shifti(subii(mulii(pk, p2k), a3prime), -1); |
t = negi(ellLHS0_i(e,r)); /* - a_3' */ |
else |
if (mpodd(t)) t = addii(t, mulii(pk, p2k)); |
t = negi(shifti(a3prime, -1)); |
t = shifti(t, -1); |
v[1] = (long)pk; v[2] = (long)r; v[3] = (long)s; v[4] = (long)t; |
|
|
v[1] = (long)pk; |
|
v[2] = (long)r; |
|
v[3] = (long)s; |
|
v[4] = (long)t; |
|
if (minim) return v; |
|
|
nudelta -= 12 * k; |
nudelta -= 12 * k; |
c4 = divii(c4, p4k); c6 = divii(c6, p6k); |
c4 = diviiexact(c4, p4k); |
delta = divii(delta, sqri(p6k)); |
c6 = diviiexact(c6, p6k); |
|
delta = diviiexact(delta, sqri(p6k)); |
} |
} |
|
|
if (nuj > 0) switch(nudelta - nuj) |
if (nuj > 0) switch(nudelta - nuj) |
{ |
{ |
case 0: f = 1; kod = 4+nuj; /* Inu */ |
case 0: f = 1; kod = 4+nuj; /* Inu */ |
Line 2244 localreduction_carac_not23(GEN e, GEN p) |
|
Line 2431 localreduction_carac_not23(GEN e, GEN p) |
|
break; |
break; |
case 6: f = 2; kod = -4-nuj; /* Inu* */ |
case 6: f = 2; kod = -4-nuj; /* Inu* */ |
if (nuj & 1) |
if (nuj & 1) |
c = 3 + kronecker(divii(mulii(c6, delta),gpuigs(p, 9+nuj)), p); |
c = 3 + kronecker(divii(mulii(c6, delta),gpowgs(p, 9+nuj)), p); |
else |
else |
c = 3 + kronecker(divii(delta, gpuigs(p, 6+nuj)), p); |
c = 3 + kronecker(divii(delta, gpowgs(p, 6+nuj)), p); |
break; |
break; |
default: err(bugparier,"localred (nu_delta - nu_j != 0,6)"); |
default: err(bugparier,"localred (nu_delta - nu_j != 0,6)"); |
return NULL; /* not reached */ |
return NULL; /* not reached */ |
} |
} |
else switch(nudelta) |
else switch(nudelta) |
{ |
{ |
case 0: f = 0; kod = 1; c = 1; break; /* I0, regulier */ |
case 0: f = 0; kod = 1; c = 1; break; /* I0, regular */ |
case 2: f = 2; kod = 2; c = 1; break; /* II */ |
case 2: f = 2; kod = 2; c = 1; break; /* II */ |
case 3: f = 2; kod = 3; c = 2; break; /* III */ |
case 3: f = 2; kod = 3; c = 2; break; /* III */ |
case 4: f = 2; kod = 4; /* IV */ |
case 4: f = 2; kod = 4; /* IV */ |
c = 2 + kronecker(gdiv(mulis(c6, -6), sqri(p)), p); |
c = 2 + kronecker(divii(mulis(c6, -6), sqri(p)), p); |
break; |
break; |
case 6: f = 2; kod = -1; /* I0* */ |
case 6: f = 2; kod = -1; /* I0* */ |
p2 = sqri(p); |
p2 = sqri(p); |
unmodp = gmodulsg(1,p); |
/* x^3 - 3c4/p^2 x - 2c6/p^3 */ |
var = gmul(unmodp,polx[0]); |
tri = coefs_to_pol(4, gun, gzero, |
tri = gsub(gsqr(var),gmul(divii(gmulsg(3, c4), p2),unmodp)); |
negi(divii(gmul2n(c6,1), mulii(p2,p))), |
tri = gsub(gmul(tri, var), |
negi(divii(gmulsg(3, c4), p2))); |
gmul(divii(gmul2n(c6,1), mulii(p2,p)),unmodp)); |
c = 1 + FpX_nbroots(tri, p); |
xun = gmodulcp(var,tri); |
|
c = lgef(ggcd((GEN)(gsub(gpui(xun,p,0),xun))[2], tri)) - 2; |
|
break; |
break; |
case 8: f = 2; kod = -4; /* IV* */ |
case 8: f = 2; kod = -4; /* IV* */ |
c = 2 + kronecker(gdiv(mulis(c6,-6), gpuigs(p,4)), p); |
c = 2 + kronecker(gdiv(mulis(c6,-6), gpowgs(p,4)), p); |
break; |
break; |
case 9: f = 2; kod = -3; c = 2; break; /* III* */ |
case 9: f = 2; kod = -3; c = 2; break; /* III* */ |
case 10: f = 2; kod = -2; c = 1; break; /* II* */ |
case 10: f = 2; kod = -2; c = 1; break; /* II* */ |
default: err(bugparier,"localred"); |
default: err(bugparier,"localred"); |
return NULL; /* not reached */ |
return NULL; /* not reached */ |
} |
} |
return localreduction_result(av,f,kod,c,v); |
return localred_result(f, kod, c, v); |
} |
} |
|
|
/* renvoie a_{ k,l } avec les notations de Tate */ |
/* return a_{ k,l } in Tate's notation */ |
static int |
static int |
aux(GEN ak, int p, int l) |
aux(GEN ak, int p, int l) |
{ |
{ |
long av = avma, pl = p, res; |
gpmem_t av = avma; |
while (--l) pl *= p; |
long res = smodis(divis(ak, u_pow(p, l)), p); |
res = smodis(divis(ak, pl), p); |
|
avma = av; return res; |
avma = av; return res; |
} |
} |
|
|
static int |
static int |
aux2(GEN ak, int p, GEN pl) |
aux2(GEN ak, int p, GEN pl) |
{ |
{ |
long av = avma, res; |
gpmem_t av = avma; |
res = smodis(divii(ak, pl), p); |
long res = smodis(divii(ak, pl), p); |
avma = av; |
avma = av; return res; |
return res; |
|
} |
} |
|
|
/* renvoie le nombre de racines distinctes du polynome XXX + aXX + bX + c |
/* number of distinct roots of X^3 + aX^2 + bX + c modulo p |
* modulo p s'il y a une racine multiple, elle est renvoyee dans *mult |
* if there's a multiple root, put it un *mult */ |
*/ |
|
static int |
static int |
numroots3(int a, int b, int c, int p, int *mult) |
numroots3(int a, int b, int c, int p, int *mult) |
{ |
{ |
Line 2317 numroots3(int a, int b, int c, int p, int *mult) |
|
Line 2499 numroots3(int a, int b, int c, int p, int *mult) |
|
} |
} |
} |
} |
|
|
/* idem pour aXX +bX + c */ |
/* same for aX^2 +bX + c */ |
static int |
static int |
numroots2(int a, int b, int c, int p, int *mult) |
numroots2(int a, int b, int c, int p, int *mult) |
{ |
{ |
Line 2325 numroots2(int a, int b, int c, int p, int *mult) |
|
Line 2507 numroots2(int a, int b, int c, int p, int *mult) |
|
else { *mult = a * b; return (b * b - a * c) % 3 ? 2 : 1; } |
else { *mult = a * b; return (b * b - a * c) % 3 ? 2 : 1; } |
} |
} |
|
|
/* ici, p1 = 2 ou p1 = 3 */ |
/* p = 2 or 3 */ |
static GEN |
static GEN |
localreduction_carac_23(GEN e, GEN p1) |
localred_carac_23(GEN e, long p, int minim) |
{ |
{ |
long av = avma, p, c, nu, nudelta; |
long c, nu, nudelta; |
int a21, a42, a63, a32, a64, theroot, al, be, ga; |
int a21, a42, a63, a32, a64, theroot, al, be, ga, p2, p3, p4; |
GEN pk, p2k, pk1, p4, p6; |
GEN pk, p2k, pk1; |
GEN p2, p3, r = gzero, s = gzero, t = gzero, v; |
GEN r, s, t, v; |
|
|
nudelta = ggval((GEN)e[12], p1); |
nudelta = ggval((GEN)e[12], stoi(p)); |
v = cgetg(5,t_VEC); v[1] = un; v[2] = v[3] = v[4] = zero; |
v = init_ch(); |
|
|
for(;;) |
for (;;) |
{ |
{ |
if (!nudelta) |
if (!nudelta) |
return localreduction_result(av, 0, 1, 1, v); |
return localred_result(0, 1, 1, v); |
/* I0 */ |
/* I0 */ |
p = itos(p1); |
if (smodis((GEN)e[6], p)) /* p \nmid b2 */ |
if (!divise((GEN)e[6], p1)) |
|
{ |
{ |
if (smodis(negi((GEN)e[11]), p == 2 ? 8 : 3) == 1) |
if (smodis(negi((GEN)e[11]), p == 2 ? 8 : 3) == 1) |
c = nudelta; |
c = nudelta; |
else |
else |
c = 2 - (nudelta & 1); |
c = 2 - (nudelta & 1); |
return localreduction_result(av, 1, 4 + nudelta, c, v); |
return localred_result(1, 4 + nudelta, c, v); |
} |
} |
/* Inu */ |
/* Inu */ |
if (p == 2) |
if (p == 2) |
{ |
{ |
r = modis((GEN)e[4], 2); |
r = modis((GEN)e[4], 2); |
s = modis(addii(r, (GEN)e[2]), 2); |
s = modis(addii(r, (GEN)e[2]), 2); |
if (signe(r)) t = modis(addii(addii((GEN)e[4], (GEN)e[5]), s), 2); |
if (signe(r)) |
else t = modis((GEN)e[5], 2); |
t = modis(addii(addii((GEN)e[4], (GEN)e[5]), s), 2); |
|
else |
|
t = modis((GEN)e[5], 2); |
} |
} |
else /* p == 3 */ |
else /* p == 3 */ |
{ |
{ |
Line 2365 localreduction_carac_23(GEN e, GEN p1) |
|
Line 2548 localreduction_carac_23(GEN e, GEN p1) |
|
s = modis((GEN)e[1], 3); |
s = modis((GEN)e[1], 3); |
t = modis(ellLHS0_i(e,r), 3); |
t = modis(ellLHS0_i(e,r), 3); |
} |
} |
cumule(&v, &e, gun, r, s, t); /* p | a1, a2, a3, a4 et a6 */ |
cumule(&v, &e, gun, r, s, t); /* p | (a1, a2, a3, a4, a6) */ |
p2 = stoi(p*p); |
p2 = p * p; |
if (!divise((GEN)e[5], p2)) |
if (smodis((GEN)e[5], p2)) |
return localreduction_result(av, nudelta, 2, 1, v); |
return localred_result(nudelta, 2, 1, v); |
/* II */ |
/* II */ |
p3 = stoi(p*p*p); |
p3 = p2 * p; |
if (!divise((GEN)e[9], p3)) |
if (smodis((GEN)e[9], p3)) |
return localreduction_result(av, nudelta - 1, 3, 2, v); |
return localred_result(nudelta - 1, 3, 2, v); |
/* III */ |
/* III */ |
if (!divise((GEN)e[8], p3)) |
if (smodis((GEN)e[8], p3)) |
{ |
{ |
if (smodis((GEN)e[8], (p==2)? 32: 27) == p*p) |
if (smodis((GEN)e[8], (p==2)? 32: 27) == p2) |
c = 3; |
c = 3; |
else |
else |
c = 1; |
c = 1; |
return localreduction_result(av, nudelta - 2, 4, c, v); |
return localred_result(nudelta - 2, 4, c, v); |
} |
} |
/* IV */ |
/* IV */ |
|
|
/* now for the last five cases... */ |
if (smodis((GEN)e[5], p3)) |
|
|
if (!divise((GEN)e[5], p3)) |
|
cumule(&v, &e, gun, gzero, gzero, p == 2? gdeux: modis((GEN)e[3], 9)); |
cumule(&v, &e, gun, gzero, gzero, p == 2? gdeux: modis((GEN)e[3], 9)); |
/* p | a1, a2; p^2 | a3, a4; p^3 | a6 */ |
/* p | a1, a2; p^2 | a3, a4; p^3 | a6 */ |
a21 = aux((GEN)e[2], p, 1); a42 = aux((GEN)e[4], p, 2); |
a21 = aux((GEN)e[2], p, 1); |
|
a42 = aux((GEN)e[4], p, 2); |
a63 = aux((GEN)e[5], p, 3); |
a63 = aux((GEN)e[5], p, 3); |
switch (numroots3(a21, a42, a63, p, &theroot)) |
switch (numroots3(a21, a42, a63, p, &theroot)) |
{ |
{ |
case 3: |
case 3: |
if (p == 2) |
if (p == 2) |
c = 1 + (a63 == 0) + ((a21 + a42 + a63) & 1); |
c = 1 + (a63 == 0) + ((a21 + a42 + a63) & 1); |
else |
else |
c = 1 + (a63 == 0) + (((1 + a21 + a42 + a63) % 3) == 0) |
c = 1 + (a63 == 0) + (((1 + a21 + a42 + a63) % 3) == 0) |
+ (((1 - a21 + a42 - a63) % 3) == 0); |
+ (((1 - a21 + a42 - a63) % 3) == 0); |
return localreduction_result(av, nudelta - 4, -1, c, v); |
return localred_result(nudelta - 4, -1, c, v); |
/* I0* */ |
/* I0* */ |
case 2: /* calcul de nu */ |
case 2: /* compute nu */ |
if (theroot) cumule(&v, &e, gun, stoi(theroot * p), gzero, gzero); |
if (theroot) cumule(&v, &e, gun, stoi(theroot * p), gzero, gzero); |
/* p | a1; p^2 | a2, a3; p^3 | a4; p^4 | a6 */ |
/* p | a1; p^2 | a2, a3; p^3 | a4; p^4 | a6 */ |
nu = 1; |
nu = 1; |
pk = p2; |
pk = stoi(p2); |
p2k = stoi(p * p * p * p); |
p2k = stoi(p2 * p2); |
for(;;) |
for(;;) |
{ |
{ |
if (numroots2(al = 1, be = aux2((GEN)e[3], p, pk), |
be = aux2((GEN)e[3], p, pk); |
ga = -aux2((GEN)e[5], p, p2k), p, &theroot) == 2) |
ga = -aux2((GEN)e[5], p, p2k); |
break; |
al = 1; |
if (theroot) cumule(&v, &e, gun, gzero, gzero, mulsi(theroot,pk)); |
if (numroots2(al, be, ga, p, &theroot) == 2) break; |
pk1 = pk; pk = mulsi(p, pk); p2k = mulsi(p, p2k); |
if (theroot) cumule(&v, &e, gun, gzero, gzero, mulsi(theroot,pk)); |
nu++; |
pk1 = pk; |
if (numroots2(al = a21, be = aux2((GEN)e[4], p, pk), |
pk = mulsi(p, pk); |
ga = aux2((GEN)e[5], p, p2k), p, &theroot) == 2) |
p2k = mulsi(p, p2k); nu++; |
break; |
|
if (theroot) cumule(&v, &e, gun, mulsi(theroot, pk1), gzero, gzero); |
al = a21; |
p2k = mulsi(p, p2k); |
be = aux2((GEN)e[4], p, pk); |
nu++; |
ga = aux2((GEN)e[5], p, p2k); |
} |
if (numroots2(al, be, ga, p, &theroot) == 2) break; |
if (p == 2) |
if (theroot) cumule(&v, &e, gun, mulsi(theroot, pk1), gzero, gzero); |
c = 4 - 2 * (ga & 1); |
p2k = mulsi(p, p2k); nu++; |
else |
} |
c = 3 + kross(be * be - al * ga, 3); |
if (p == 2) |
return localreduction_result(av, nudelta - 4 - nu, -4 - nu, c, v); |
c = 4 - 2 * (ga & 1); |
/* Inu* */ |
else |
|
c = 3 + kross(be * be - al * ga, 3); |
|
return localred_result(nudelta - 4 - nu, -4 - nu, c, v); |
|
/* Inu* */ |
case 1: |
case 1: |
if (theroot) cumule(&v, &e, gun, stoi(theroot * p), gzero, gzero); |
if (theroot) cumule(&v, &e, gun, stoi(theroot * p), gzero, gzero); |
/* p | a1; p^2 | a2, a3; p^3 | a4; p^4 | a6 */ |
/* p | a1; p^2 | a2, a3; p^3 | a4; p^4 | a6 */ |
a32 = aux((GEN)e[3], p, 2); a64 = aux((GEN)e[5], p, 4); |
a32 = aux((GEN)e[3], p, 2); |
if (numroots2(1, a32, -a64, p, &theroot) == 2) |
a64 = aux((GEN)e[5], p, 4); |
{ |
if (numroots2(1, a32, -a64, p, &theroot) == 2) |
if (p == 2) |
{ |
c = 3 - 2 * a64; |
if (p == 2) |
else |
c = 3 - 2 * a64; |
c = 2 + kross(a32 * a32 + a64, 3); |
else |
return localreduction_result(av, nudelta - 6, -4, c, v); |
c = 2 + kross(a32 * a32 + a64, 3); |
} |
return localred_result(nudelta - 6, -4, c, v); |
/* IV* */ |
} |
if (theroot) cumule(&v, &e, gun, gzero, gzero, stoi(theroot*p*p)); |
/* IV* */ |
/* p | a1; p^2 | a2; p^3 | a3, a4; p^5 | a6 */ |
if (theroot) cumule(&v, &e, gun, gzero, gzero, stoi(theroot*p*p)); |
p4 = sqri(p2); |
/* p | a1; p^2 | a2; p^3 | a3, a4; p^5 | a6 */ |
if (!divise((GEN)e[4], p4)) |
p4 = p2 * p2; |
return localreduction_result(av, nudelta - 7, -3, 2, v); |
if (smodis((GEN)e[4], p4)) |
/* III* */ |
return localred_result(nudelta - 7, -3, 2, v); |
p6 = mulii(p4, p2); |
/* III* */ |
if (!divise((GEN)e[5], p6)) |
|
return localreduction_result(av, nudelta - 8, -2, 1, v); |
if (smodis((GEN)e[5], p4 * p2)) |
/* II* */ |
return localred_result(nudelta - 8, -2, 1, v); |
cumule(&v, &e, p1, gzero, gzero, gzero); /* non minimal, on repart |
/* II* */ |
pour un tour */ |
cumule(&v, &e, stoi(p), gzero, gzero, gzero); /* not minimal */ |
nudelta -= 12; |
nudelta -= 12; |
} |
} |
} |
} |
/* Not reached */ |
/* Not reached */ |
} |
} |
|
|
|
static GEN |
|
localred(GEN e, GEN p, int minim) |
|
{ |
|
if (gcmpgs(p, 3) > 0) /* p != 2,3 */ |
|
return localred_carac_p(e,p, minim); |
|
else |
|
{ |
|
GEN z = localred_carac_23(e,itos(p), minim); |
|
return minim? (GEN)z[3]: z; |
|
} |
|
} |
|
|
GEN |
GEN |
localreduction(GEN e, GEN p1) |
localreduction(GEN e, GEN p) |
{ |
{ |
|
gpmem_t av = avma; |
checkell(e); |
checkell(e); |
if (typ(e[12]) != t_INT) |
if (typ(e[12]) != t_INT) |
err(talker,"not an integral curve in localreduction"); |
err(talker,"not an integral curve in localreduction"); |
if (gcmpgs(p1, 3) > 0) /* p different de 2 ou 3 */ |
return gerepileupto(av, localred(e, p, 0)); |
return localreduction_carac_not23(e,p1); |
|
else |
|
return localreduction_carac_23(e,p1); |
|
} |
} |
|
|
#if 0 |
static GEN |
/* Calcul de toutes les fibres non elliptiques d'une courbe sur Z. |
ell_to_small(GEN E) |
* Etant donne une courbe elliptique sous forme longue e, dont les coefficients |
|
* sont entiers, renvoie une matrice dont les lignes sont de la forme |
|
* [p, fp, kodp, cp]. Il y a une ligne par diviseur premier du discriminant. |
|
*/ |
|
GEN |
|
globaltatealgo(GEN e) |
|
{ |
{ |
long k, l,av; |
long i; |
GEN p1, p2, p3, p4, prims, result; |
GEN e; |
|
if (lg(E) <= 14) return E; |
|
e = cgetg(14,t_VEC); |
|
for (i = 1; i < 14; i++) e[i] = E[i]; |
|
return e; |
|
} |
|
|
|
static GEN |
|
ellintegralmodel(GEN e) |
|
{ |
|
GEN a = cgetg(6,t_VEC), v, prims, d, u; |
|
long i, l, k; |
|
|
checkell(e); |
checkell(e); |
prims = decomp((GEN)e[12]); |
for (i = 1; i < 6; i++) |
l = lg(p1 = (GEN)prims[1]); |
{ |
p2 = (GEN)prims[2]; |
a[i] = e[i]; |
if ((long)prims == avma) cgiv(prims); |
switch(typ(a[i])) |
result = cgetg(5, t_MAT); |
{ |
result[1] = (long)p1; |
case t_INT: case t_FRAC: case t_FRACN: break; |
result[2] = (long)p2; |
default: err(talker, "not a rational curve in ellintegralmodel"); |
result[3] = (long)(p3 = cgetg(l, t_COL)); |
} |
for (k = 1; k < l; k++) p3[k] = lgeti(3); |
} |
result[4] = (long)(p4 = cgetg(l, t_COL)); |
/* a = [a1, a2, a3, a4, a6] */ |
for (k = 1; k < l; k++) p4[k] = lgeti(3); |
d = denom(a); |
av = avma; |
prims = (GEN)auxdecomp(d, 0)[1]; /* partial factorization */ |
|
if (is_pm1(d)) return NULL; |
|
|
|
l = lg(prims); u = gun; |
for (k = 1; k < l; k++) |
for (k = 1; k < l; k++) |
{ |
{ |
GEN q = localreduction(e, (GEN)p1[k]); |
GEN p = (GEN)prims[k]; |
affii((GEN)q[1],(GEN)p2[k]); |
int n = 0, m; |
affii((GEN)q[2],(GEN)p3[k]); |
for (i = 1; i < 6; i++) |
affii((GEN)q[4],(GEN)p4[k]); |
if (!gcmp0((GEN)a[i])) |
avma = av; |
{ |
|
int r = (i == 5)? 6: i; /* a5 is missing */ |
|
m = r * n + ggval((GEN)a[i], p); |
|
while (m < 0) { n++; m += r; } |
|
} |
|
u = mulii(u, gpowgs(p, n)); |
} |
} |
return result; |
v = init_ch(); v[1] = linv(u); return v; |
} |
} |
#endif |
|
|
|
/* Algorithme de reduction d'une courbe sur Q a sa forme standard. Etant |
static void |
* donne une courbe elliptique sous forme longue e, dont les coefficients |
standard_model(GEN e, GEN *pv) |
* sont rationnels, renvoie son [N, [u, r, s, t], c], ou N est le conducteur |
{ |
* arithmetique de e, [u, r, s, t] est le changement de variables qui reduit |
GEN r, s, t; |
* e a sa forme minimale globale dans laquelle a1 et a3 valent 0 ou 1, et a2 |
s = gdiventgs((GEN)e[1], -2); |
* vaut -1, 0 ou 1 et tel que u est un rationnel positif. Enfin c est le |
r = gdiventgs(gaddgs(gsub(gsub((GEN)e[2], gmul(s,(GEN)e[1])), gsqr(s)), 1), -3); |
* produit des nombres de Tamagawa locaux cp. |
t = gdiventgs(ellLHS0(e,r), -2); |
*/ |
cumulev(pv, gun, r, s, t); |
|
} |
|
|
GEN |
GEN |
globalreduction(GEN e1) |
ellminimalmodel(GEN E, GEN *ptv) |
{ |
{ |
long i, k, l, m, tetpil, av = avma; |
gpmem_t av = avma; |
GEN p1, c = gun, prims, result, N = gun, u = gun, r, s, t; |
GEN c4, c6, e, v, prims; |
GEN v = cgetg(5, t_VEC), a = cgetg(7, t_VEC), e = cgetg(20, t_VEC); |
long l, k; |
|
|
checkell(e1); |
v = ellintegralmodel(E); |
for (i = 1; i < 5; i++) a[i] = e1[i]; a[5] = zero; a[6] = e1[5]; |
e = ell_to_small(E); |
prims = decomp(denom(a)); |
if (v) e = coordch(e, v); else v = init_ch(); |
p1 = (GEN)prims[1]; l = lg(p1); |
c4 = (GEN)e[10]; |
|
c6 = (GEN)e[11]; |
|
prims = (GEN)decomp(mppgcd(c4,c6))[1]; |
|
l = lg(prims); |
for (k = 1; k < l; k++) |
for (k = 1; k < l; k++) |
{ |
{ |
int n = 0; |
GEN w = localred(e, (GEN)prims[k], 1); |
for (i = 1; i < 7; i++) |
if (!gcmp1((GEN)w[1])) |
if (!gcmp0((GEN)a[i])) |
cumule(&v, &e, (GEN)w[1], (GEN)w[2], (GEN)w[3], (GEN)w[4]); |
{ |
|
m = i * n + ggval((GEN)a[i], (GEN)p1[k]); |
|
while (m < 0) { n++; m += i; } |
|
} |
|
u = gmul(u, gpuigs((GEN)p1[k], n)); |
|
} |
} |
v[1] = linv(u); v[2] = v[3] = v[4] = zero; |
standard_model(e, &v); |
for (i = 1; i < 14; i++) e[i] = e1[i]; |
e = coordch(E, v); |
for (; i < 20; i++) e[i] = zero; |
if (ptv) { gerepileall(av, 2, &e, &v); *ptv = v; } |
if (!gcmp1(u)) e = coordch(e, v); |
else e = gerepileupto(av, e); |
prims = decomp((GEN)e[12]); |
return e; |
l = lg(p1 = (GEN)prims[1]); |
} |
for (k = (signe(e[12]) < 0) + 1; k < l; k++) |
|
|
/* Reduction of a rational curve E to its standard minimal model |
|
* (a1,a3 = 0 or 1, a2 = -1, 0 or 1). |
|
* |
|
* Return [N, [u,r,s,t], c], where |
|
* N = arithmetic conductor of E |
|
* c = product of the local Tamagawa numbers cp |
|
* [u, r, s, t] = the change of variable reducing E to its minimal model, |
|
* with u > 0 */ |
|
GEN |
|
globalreduction(GEN E) |
|
{ |
|
long k, l; |
|
gpmem_t av = avma; |
|
GEN c, prims, result, N, v, e; |
|
|
|
v = ellintegralmodel(E); |
|
e = ell_to_small(E); |
|
if (v) e = coordch(e, v); else v = init_ch(); |
|
|
|
prims = (GEN)decomp(absi((GEN)e[12]))[1]; |
|
l = lg(prims); c = N = gun; |
|
for (k = 1; k < l; k++) |
{ |
{ |
GEN q = localreduction(e, (GEN)p1[k]); |
GEN p = (GEN)prims[k]; |
GEN v1 = (GEN)q[3]; |
GEN q = localreduction(e, p); |
N = mulii(N, gpui((GEN)p1[k],(GEN)q[1],0)); |
GEN w = (GEN)q[3]; |
|
N = mulii(N, powgi(p, (GEN)q[1])); |
c = mulii(c, (GEN)q[4]); |
c = mulii(c, (GEN)q[4]); |
if (!gcmp1((GEN)v1[1])) cumule1(&v, &e, v1); |
if (!gcmp1((GEN)w[1])) |
|
cumule(&v, &e, (GEN)w[1], (GEN)w[2], (GEN)w[3], (GEN)w[4]); |
} |
} |
s = gdiventgs((GEN)e[1], -2); |
standard_model(e, &v); |
r = gdiventgs(gaddgs(gsub(gsub((GEN)e[2], gmul(s,(GEN)e[1])), gsqr(s)), 1), -3); |
result = cgetg(4, t_VEC); |
t = gdiventgs(ellLHS0(e,r), -2); |
result[1] = (long)N; |
cumule(&v, &e, gun, r, s, t); |
result[2] = (long)v; |
tetpil = avma; |
result[3] = (long)c; return gerepilecopy(av, result); |
result = cgetg(4, t_VEC); result[1] = lcopy(N); result[2] = lcopy(v); |
|
result[3] = lcopy(c); |
|
return gerepile(av, tetpil, result); |
|
} |
} |
|
|
/* cumule les effets de plusieurs chgts de variable. On traite a part les cas |
/* accumulate the effects of variable changes [u,r,s,t] and [U,R,S,T]. |
* particuliers frequents, tels que soit u = 1, soit r' = s' = t' = 0 |
* Frequent special cases: (U = 1) or (r = s = t = 0) */ |
*/ |
|
static void |
static void |
cumulev(GEN *vtotal, GEN u, GEN r, GEN s, GEN t) |
cumulev(GEN *vtotal, GEN u, GEN r, GEN s, GEN t) |
{ |
{ |
long av = avma, tetpil; |
GEN U,R,S,T,UU,RR,SS,TT, v = *vtotal, w = cgetg(5, t_VEC); |
GEN temp, v = *vtotal, v3 = cgetg(5, t_VEC); |
gpmem_t av = avma; |
if (gcmp1((GEN)v[1])) |
|
|
U = (GEN)v[1]; |
|
R = (GEN)v[2]; |
|
S = (GEN)v[3]; |
|
T = (GEN)v[4]; |
|
if (gcmp1(U)) |
{ |
{ |
v3[1] = lcopy(u); |
UU = gcopy(u); |
v3[2] = ladd((GEN)v[2], r); |
RR = gadd(R, r); |
v3[3] = ladd((GEN)v[3], s); |
SS = gadd(S, s); av = avma; |
av = avma; |
TT = gerepileupto(av, gadd(T, gadd(t, gmul(S, r)))); |
temp = gadd((GEN)v[4], gmul((GEN)v[3], r)); |
|
tetpil = avma; |
|
v3[4] = lpile(av, tetpil, gadd(temp, t)); |
|
} |
} |
else if (gcmp0(r) && gcmp0(s) && gcmp0(t)) |
else if (gcmp0(r) && gcmp0(s) && gcmp0(t)) |
{ |
{ |
v3[1] = lmul((GEN)v[1], u); |
UU = gmul(U, u); |
v3[2] = lcopy((GEN)v[2]); |
RR = gcopy(R); |
v3[3] = lcopy((GEN)v[3]); |
SS = gcopy(S); |
v3[4] = lcopy((GEN)v[4]); |
TT = gcopy(T); |
} |
} |
else /* cas general */ |
else /* general case */ |
{ |
{ |
v3[1] = lmul((GEN)v[1], u); |
GEN U2 = gsqr(U); |
temp = gsqr((GEN)v[1]); |
UU = gmul(U, u); |
v3[2] = ladd(gmul(temp, r), (GEN)v[2]); |
RR = gadd(R, gmul(U2, r)); |
v3[3] = ladd(gmul((GEN)v[1], s), (GEN)v[3]); |
SS = gadd(S, gmul(U, s)); |
v3[4] = ladd((GEN)v[4], gmul(temp, gadd(gmul((GEN)v[1], t), gmul((GEN)v[3], r)))); |
TT = gadd(T, gmul(U2, gadd(gmul(U, t), gmul(S, r)))); |
|
gerepileall(av, 4, &UU,&RR,&SS,&TT); |
v3 = gerepilecopy(av, v3); |
|
} |
} |
*vtotal = v3; |
w[1] = (long)UU; |
|
w[2] = (long)RR; |
|
w[3] = (long)SS; |
|
w[4] = (long)TT; *vtotal = w; |
} |
} |
|
|
static void |
static void |
cumule(GEN *vtotal, GEN *e, GEN u, GEN r, GEN s, GEN t) |
cumule(GEN *vtotal, GEN *e, GEN u, GEN r, GEN s, GEN t) |
{ |
{ |
long av = avma, tetpil; |
*e = _coordch(*e, u, r, s, t); |
GEN v2 = cgetg(5, t_VEC); |
|
v2[1] = (long)u; v2[2] = (long)r; v2[3] = (long)s; v2[4] = (long)t; |
|
tetpil = avma; |
|
*e = gerepile(av, tetpil, coordch(*e, v2)); |
|
cumulev(vtotal, u, r, s, t); |
cumulev(vtotal, u, r, s, t); |
} |
} |
|
|
static void |
|
cumule1(GEN *vtotal, GEN *e, GEN v2) |
|
{ |
|
*e = coordch(*e, v2); |
|
cumulev(vtotal, (GEN)v2[1], (GEN)v2[2], (GEN)v2[3], (GEN)v2[4]); |
|
} |
|
|
|
/********************************************************************/ |
/********************************************************************/ |
/** **/ |
/** **/ |
/** Parametrisation modulaire **/ |
/** Parametrisation modulaire **/ |
|
|
taniyama(GEN e) |
taniyama(GEN e) |
{ |
{ |
GEN v,w,c,d,s1,s2,s3; |
GEN v,w,c,d,s1,s2,s3; |
long n,m,av=avma,tetpil; |
long n, m; |
|
gpmem_t av=avma, tetpil; |
|
|
checkell(e); v = cgetg(precdl+3,t_SER); |
checkell(e); v = cgetg(precdl+3,t_SER); |
v[1] = evalsigne(1) | evalvalp(-2) | evalvarn(0); |
v[1] = evalsigne(1) | evalvalp(-2) | evalvarn(0); |
v[2] = un; |
v[2] = un; |
c=gtoser(anell(e,precdl+1),0); setvalp(c,1); |
c=gtoser(anell(e,precdl+1),0); setvalp(c,1); |
d=ginv(c); c=gsqr(d); |
d=ginv(c); c=gsqr(d); |
for (n=-3; n<=precdl-4; n++) |
for (n=-3; n<=(long)precdl-4; n++) |
{ |
{ |
if (n!=2) |
if (n!=2) |
{ |
{ |
|
|
orderell(GEN e, GEN p) |
orderell(GEN e, GEN p) |
{ |
{ |
GEN p1; |
GEN p1; |
long av=avma,k; |
long k; |
|
gpmem_t av=avma; |
|
|
checkell(e); checkpt(p); |
checkell(e); checkpt(p); |
k=typ(e[13]); |
k=typ(e[13]); |
Line 2696 orderell(GEN e, GEN p) |
|
Line 2918 orderell(GEN e, GEN p) |
|
avma=av; return gzero; |
avma=av; return gzero; |
} |
} |
|
|
/* one can do much better by factoring denom(D) (see ellglobalred) */ |
|
static GEN |
|
ellintegralmodel(GEN e) |
|
{ |
|
GEN a = cgetg(6,t_VEC), v; |
|
long i; |
|
|
|
for (i=1; i<6; i++) |
|
{ |
|
a[i]=e[i]; |
|
switch(typ(a[i])) |
|
{ |
|
case t_INT: case t_FRAC: case t_FRACN: break; |
|
default: err(talker, "not a rational curve in ellintegralmodel"); |
|
} |
|
} |
|
a = denom(a); if (gcmp1(a)) return NULL; |
|
v = cgetg(5,t_VEC); |
|
v[1]=linv(a); v[2]=v[3]=v[4]=zero; return v; |
|
} |
|
|
|
/* Using Lutz-Nagell */ |
/* Using Lutz-Nagell */ |
|
|
/* p is a polynomial of degree exactly 3 with integral coefficients |
/* p is a polynomial of degree exactly 3 with integral coefficients |
|
|
torsellnagelllutz(GEN e) |
torsellnagelllutz(GEN e) |
{ |
{ |
GEN d,ld,pol,p1,lr,r,v,w,w2,w3; |
GEN d,ld,pol,p1,lr,r,v,w,w2,w3; |
long i,j,nlr,t,t2,k,k2,av=avma; |
long i, j, nlr, t, t2, k, k2; |
|
gpmem_t av=avma; |
|
|
checkell(e); |
|
v = ellintegralmodel(e); |
v = ellintegralmodel(e); |
if (v) e = coordch(e,v); |
if (v) e = coordch(e,v); |
pol = RHSpol(e); |
pol = RHSpol(e); |
Line 2854 torsellnagelllutz(GEN e) |
|
Line 3055 torsellnagelllutz(GEN e) |
|
|
|
/* Using Doud's algorithm */ |
/* Using Doud's algorithm */ |
|
|
/* Input e and n, finds a bound for #Tor */ |
/* finds a bound for #E_tor */ |
static long |
static long |
torsbound(GEN e, long n) |
torsbound(GEN e) |
{ |
{ |
long av = avma, m, b, c, d, prime = 2; |
long m, b, c, prime = 2; |
|
gpmem_t av = avma; |
byteptr p = diffptr; |
byteptr p = diffptr; |
GEN D = (GEN)e[12]; |
GEN D = (GEN)e[12]; |
|
long n = bit_accuracy(lgefint(D)) >> 3; |
|
/* n = number of primes to try ~ 1 prime every 8 bits in D */ |
b = c = m = 0; p++; |
b = c = m = 0; p++; |
while (m<n) |
while (m<n) |
{ |
{ |
d = *p++; if (!d) err(primer1); |
NEXT_PRIME_VIADIFF_CHECK(prime,p); |
prime += d; |
if (smodis(D, prime)) |
if (ggval(D,stoi(prime)) == 0) |
|
{ |
{ |
b = cgcd(b, prime+1 - itos(apell0(e,prime))); |
b = cgcd(b, prime+1 - itos(apell0(e,prime))); |
if (b==c) m++; else {c = b; m = 0;} |
if (b==c) m++; else {c = b; m = 0;} |
Line 2886 _round(GEN x, long *e) |
|
Line 3088 _round(GEN x, long *e) |
|
return y; |
return y; |
} |
} |
|
|
/* Input the curve, a point, and an integer n, returns a point of order n |
/* E the curve, w in C/Lambda ~ E of order n, returns q = pointell(w) as a |
on the curve, or NULL if q is not rational. */ |
* rational point on the curve, or NULL if q is not rational. */ |
static GEN |
static GEN |
torspnt(GEN E, GEN q, long n) |
torspnt(GEN E, GEN w, long n, long prec) |
{ |
{ |
GEN p = cgetg(3,t_VEC); |
GEN p = cgetg(3,t_VEC), q = pointell(E, w, prec); |
long e; |
long e; |
p[1] = lmul2n(_round(gmul2n((GEN)q[1],2), &e),-2); |
p[1] = lmul2n(_round(gmul2n((GEN)q[1],2), &e),-2); |
if (e > -5) return NULL; |
if (e > -5) return NULL; |
Line 2924 best_in_cycle(GEN e, GEN p, long k) |
|
Line 3126 best_in_cycle(GEN e, GEN p, long k) |
|
return (gsigne(d_ellLHS(e,p)) < 0)? invell(e,p): p; |
return (gsigne(d_ellLHS(e,p)) < 0)? invell(e,p): p; |
} |
} |
|
|
|
/* <p,q> = E_tors, possibly NULL (= oo), p,q independant unless NULL |
|
* order p = k, order q = 2 unless NULL */ |
static GEN |
static GEN |
tors(GEN e, long k, GEN p, GEN q, GEN v) |
tors(GEN e, long k, GEN p, GEN q, GEN v) |
{ |
{ |
Line 2939 tors(GEN e, long k, GEN p, GEN q, GEN v) |
|
Line 3143 tors(GEN e, long k, GEN p, GEN q, GEN v) |
|
p = best_in_cycle(e,p,k); |
p = best_in_cycle(e,p,k); |
if (v) |
if (v) |
{ |
{ |
v[1] = linv((GEN)v[1]); |
|
p = pointch(p,v); |
p = pointch(p,v); |
q = pointch(q,v); |
q = pointch(q,v); |
} |
} |
Line 2954 tors(GEN e, long k, GEN p, GEN q, GEN v) |
|
Line 3157 tors(GEN e, long k, GEN p, GEN q, GEN v) |
|
{ |
{ |
p = best_in_cycle(e,p,k); |
p = best_in_cycle(e,p,k); |
if (v) |
if (v) |
{ |
|
v[1] = linv((GEN)v[1]); |
|
p = pointch(p,v); |
p = pointch(p,v); |
} |
|
r = cgetg(4,t_VEC); |
r = cgetg(4,t_VEC); |
r[1] = lstoi(k); p1 = cgetg(2,t_VEC); p1[1] = r[1]; |
r[1] = lstoi(k); p1 = cgetg(2,t_VEC); p1[1] = r[1]; |
r[2] = (long)p1; p1 = cgetg(2,t_VEC); p1[1] = lcopy(p); |
r[2] = (long)p1; p1 = cgetg(2,t_VEC); p1[1] = lcopy(p); |
Line 2977 tors(GEN e, long k, GEN p, GEN q, GEN v) |
|
Line 3177 tors(GEN e, long k, GEN p, GEN q, GEN v) |
|
GEN |
GEN |
torselldoud(GEN e) |
torselldoud(GEN e) |
{ |
{ |
long b,i,ord,av=avma,prec, k = 1; |
long b, i, ord, prec, k = 1; |
GEN v,w1,w22,w1j,w12,p,tor1,tor2; |
gpmem_t av=avma; |
|
GEN v,w,w1,w22,w1j,w12,p,tor1,tor2; |
|
|
checkbell(e); |
checkbell(e); |
v = ellintegralmodel(e); |
v = ellintegralmodel(e); |
if (v) e = coordch(e,v); |
if (v) e = coordch(e,v); |
|
|
b = lgefint((GEN)e[12]) >> 1; /* b = size of sqrt(D) */ |
b = DEFAULTPREC + ((lgefint((GEN)e[12])-2) >> 1); /* b >= size of sqrt(D) */ |
prec = precision((GEN)e[15]); |
w1 = (GEN)e[15]; |
|
prec = precision(w1); |
if (prec < b) err(precer, "torselldoud"); |
if (prec < b) err(precer, "torselldoud"); |
b = max(b, DEFAULTPREC); |
if (b < prec) { prec = b; e = gprec_w(e, b); w1 = (GEN)e[15]; } |
if (b < prec) { prec = b; e = gprec_w(e, b); } |
b = torsbound(e); |
b = torsbound(e,3); |
|
if (b==1) { avma=av; return tors(e,1,NULL,NULL, v); } |
if (b==1) { avma=av; return tors(e,1,NULL,NULL, v); } |
|
if (v) v[1] = linv((GEN)v[1]); |
w22 = gmul2n((GEN)e[16],-1); |
w22 = gmul2n((GEN)e[16],-1); |
w1 = (GEN)e[15]; |
|
if (b % 4) |
if (b % 4) |
{ |
{ /* cyclic of order 1, p, 2p, p <= 5 */ |
p = NULL; |
p = NULL; |
for (i=10; i>1; i--) |
for (i=10; i>1; i--) |
{ |
{ |
if (b%i != 0) continue; |
if (b%i != 0) continue; |
w1j = gdivgs(w1,i); |
w1j = gdivgs(w1,i); |
p = torspnt(e,pointell(e,w1j,prec),i); |
p = torspnt(e,w1j,i,prec); |
if (!p && i%2==0) |
if (!p && i%2==0) |
{ |
{ |
p = torspnt(e,pointell(e,gadd(w22,w1j),prec),i); |
p = torspnt(e,gadd(w22,w1j),i,prec); |
if (!p) p = torspnt(e,pointell(e,gadd(w22,gmul2n(w1j,1)),prec),i); |
if (!p) p = torspnt(e,gadd(w22,gmul2n(w1j,1)),i,prec); |
} |
} |
if (p) { k = i; break; } |
if (p) { k = i; break; } |
} |
} |
Line 3012 torselldoud(GEN e) |
|
Line 3213 torselldoud(GEN e) |
|
} |
} |
|
|
ord = 0; tor1 = tor2 = NULL; |
ord = 0; tor1 = tor2 = NULL; |
w12 = gmul2n((GEN)e[15],-1); |
w12 = gmul2n(w1,-1); |
if ((p = torspnt(e,pointell(e,w12,prec),2))) |
if ((p = torspnt(e,w12,2,prec))) |
{ |
{ |
tor1 = p; ord++; |
tor1 = p; ord++; |
} |
} |
if ((p = torspnt(e,pointell(e,w22,prec),2)) |
w = w22; |
|| (!ord && (p = torspnt(e,pointell(e,gadd(w12,w22),prec),2)))) |
if ((p = torspnt(e,w,2,prec))) |
{ |
{ |
tor2 = p; ord += 2; |
tor2 = p; ord += 2; |
} |
} |
|
if (!ord) |
|
{ |
|
w = gadd(w12,w22); |
|
if ((p = torspnt(e,w,2,prec))) |
|
{ |
|
tor2 = p; ord += 2; |
|
} |
|
} |
|
p = NULL; |
switch(ord) |
switch(ord) |
{ |
{ |
case 0: |
case 0: /* no point of order 2 */ |
for (i=9; i>1; i-=2) |
for (i=9; i>1; i-=2) |
{ |
{ |
if (b%i!=0) continue; |
if (b%i!=0) continue; |
w1j=gdivgs((GEN)e[15],i); |
w1j = gdivgs(w1,i); |
p = torspnt(e,pointell(e,w1j,prec),i); |
p = torspnt(e,w1j,i,prec); |
if (p) { k = i; break; } |
if (p) { k = i; break; } |
} |
} |
break; |
break; |
|
|
case 1: |
case 1: /* 1 point of order 2: w1 / 2 */ |
p = NULL; |
|
for (i=12; i>2; i-=2) |
for (i=12; i>2; i-=2) |
{ |
{ |
if (b%i!=0) continue; |
if (b%i!=0) continue; |
w1j=gdivgs((GEN)e[15],i); |
w1j = gdivgs(w1,i); |
p = torspnt(e,pointell(e,w1j,prec),i); |
p = torspnt(e,w1j,i,prec); |
if (!p && i%4==0) |
if (!p && i%4==0) |
p = torspnt(e,pointell(e,gadd(w22,w1j),prec),i); |
p = torspnt(e,gadd(w22,w1j),i,prec); |
if (p) { k = i; break; } |
if (p) { k = i; break; } |
} |
} |
if (!p) { p = tor1; k = 2; } |
if (!p) { p = tor1; k = 2; } |
break; |
break; |
|
|
case 2: |
case 2: /* 1 point of order 2: w = w2/2 or (w1+w2)/2 */ |
for (i=5; i>1; i-=2) |
for (i=5; i>1; i-=2) |
{ |
{ |
if (b%i!=0) continue; |
if (b%i!=0) continue; |
w1j = gdivgs((GEN)e[15],i); |
w1j = gdivgs(w1,i); |
p = torspnt(e,pointell(e,gadd(w22,w1j),prec),i+i); |
p = torspnt(e,gadd(w,w1j),2*i,prec); |
if (p) { k = 2*i; break; } |
if (p) { k = 2*i; break; } |
} |
} |
if (!p) { p = tor2; k = 2; } |
if (!p) { p = tor2; k = 2; } |
tor2 = NULL; break; |
tor2 = NULL; break; |
|
|
case 3: |
case 3: /* 2 points of order 2: w1/2 and w2/2 */ |
for (i=8; i>2; i-=2) |
for (i=8; i>2; i-=2) |
{ |
{ |
if (b%(2*i)!=0) continue; |
if (b%(2*i)!=0) continue; |
w1j=gdivgs((GEN)e[15],i); |
w1j = gdivgs(w1,i); |
p = torspnt(e,pointell(e,w1j,prec),i); |
p = torspnt(e,w1j,i,prec); |
if (p) { k = i; break; } |
if (p) { k = i; break; } |
} |
} |
if (!p) { p = tor1; k = 2; } |
if (!p) { p = tor1; k = 2; } |
Line 3089 elltors0(GEN e, long flag) |
|
Line 3297 elltors0(GEN e, long flag) |
|
/* par compatibilite */ |
/* par compatibilite */ |
GEN torsell(GEN e) {return torselldoud(e);} |
GEN torsell(GEN e) {return torselldoud(e);} |
|
|
/* LOCAL ROOT NUMBERS, D'APRES HALBERSTADT halberst@math.jussieu.fr */ |
/* LOCAL ROOT NUMBERS, after HALBERSTADT */ |
|
|
/* ici p=2 ou 3 */ |
/* p = 2 or 3 */ |
static long |
static long |
neron(GEN e, GEN p, long* ptkod) |
neron(GEN e, GEN p, long* ptkod) |
{ |
{ |
long av=avma,kod,v4,v6,vd; |
long kod, v4, v6, vd; |
|
gpmem_t av=avma; |
GEN c4, c6, d, nv; |
GEN c4, c6, d, nv; |
|
|
nv=localreduction(e,p); |
nv=localreduction(e,p); |
Line 3196 neron(GEN e, GEN p, long* ptkod) |
|
Line 3405 neron(GEN e, GEN p, long* ptkod) |
|
static long |
static long |
ellrootno_2(GEN e) |
ellrootno_2(GEN e) |
{ |
{ |
long n2,kod,u,v,x1,y1,d1,av=avma,v4,v6,w2; |
long n2, kod, u, v, x1, y1, d1, v4, v6, w2; |
|
gpmem_t av=avma; |
GEN p=gdeux,c4,c6,tmp,p6; |
GEN p=gdeux,c4,c6,tmp,p6; |
|
|
n2=neron(e,p,&kod); c4=(GEN)e[10]; c6=(GEN)e[11]; p6=stoi(64); |
n2=neron(e,p,&kod); c4=(GEN)e[10]; c6=(GEN)e[11]; p6=stoi(64); |
Line 3283 ellrootno_2(GEN e) |
|
Line 3493 ellrootno_2(GEN e) |
|
static long |
static long |
ellrootno_3(GEN e) |
ellrootno_3(GEN e) |
{ |
{ |
long n2,kod,u,v,d1,av=avma,r6,K4,K6,v4; |
long n2, kod, u, v, d1, r6, K4, K6, v4; |
|
gpmem_t av=avma; |
GEN p=stoi(3),c4,c6,tmp,p4; |
GEN p=stoi(3),c4,c6,tmp,p4; |
|
|
n2=neron(e,p,&kod); c4=(GEN)e[10]; c6=(GEN)e[11]; p4=stoi(81); |
n2=neron(e,p,&kod); c4=(GEN)e[10]; c6=(GEN)e[11]; p4=stoi(81); |
Line 3328 ellrootno_3(GEN e) |
|
Line 3539 ellrootno_3(GEN e) |
|
} |
} |
} |
} |
|
|
|
/* assume p > 3 */ |
static long |
static long |
ellrootno_not23(GEN e, GEN p, GEN ex) |
ellrootno_p(GEN e, GEN p, GEN ex) |
{ |
{ |
GEN j; |
GEN j; |
long ep,z; |
long ep,z; |
Line 3346 ellrootno_not23(GEN e, GEN p, GEN ex) |
|
Line 3558 ellrootno_not23(GEN e, GEN p, GEN ex) |
|
static long |
static long |
ellrootno_intern(GEN e, GEN p, GEN ex) |
ellrootno_intern(GEN e, GEN p, GEN ex) |
{ |
{ |
if (cmpis(p,3) > 0) return ellrootno_not23(e,p,ex); |
if (cmpis(p,3) > 0) return ellrootno_p(e,p,ex); |
switch(itos(p)) |
switch(itos(p)) |
{ |
{ |
case 3: return ellrootno_3(e); |
case 3: return ellrootno_3(e); |
Line 3378 ellrootno_all(GEN e, GEN p, GEN* ptcond) |
|
Line 3590 ellrootno_all(GEN e, GEN p, GEN* ptcond) |
|
exs=ggval(cond,p); |
exs=ggval(cond,p); |
if (!exs) return 1; |
if (!exs) return 1; |
} |
} |
if (cmpis(p,3)>0) return ellrootno_not23(e,p,stoi(exs)); |
if (cmpis(p,3)>0) return ellrootno_p(e,p,stoi(exs)); |
switch(itos(p)) |
switch(itos(p)) |
{ |
{ |
case 3: return ellrootno_3(e); |
case 3: return ellrootno_3(e); |
Line 3393 ellrootno_all(GEN e, GEN p, GEN* ptcond) |
|
Line 3605 ellrootno_all(GEN e, GEN p, GEN* ptcond) |
|
long |
long |
ellrootno(GEN e, GEN p) |
ellrootno(GEN e, GEN p) |
{ |
{ |
long av=avma,s; |
long s; |
|
gpmem_t av=avma; |
if (!p) p = gun; |
if (!p) p = gun; |
s=ellrootno_all(e, p, NULL); |
s=ellrootno_all(e, p, NULL); |
avma=av; return s; |
avma=av; return s; |