/**************************************************************/ /* */ /* NUMBER FIELDS */ /* */ /**************************************************************/ /* $Id: base1.c,v 1.2 1999/09/23 17:50:55 karim Exp $ */ #include "pari.h" #include "parinf.h" void checkrnf(GEN rnf) { if (typ(rnf)!=t_VEC) err(idealer1); if (lg(rnf)!=12) err(idealer1); } GEN checkbnf(GEN bnf) { if (typ(bnf)!=t_VEC) err(idealer1); switch (lg(bnf)) { case 11: return bnf; case 10: if (typ(bnf[1])==t_POL) err(talker,"please apply bnfinit first"); break; case 7: return checkbnf((GEN)bnf[1]); case 3: if (typ(bnf[2])==t_POLMOD) return checkbnf((GEN)bnf[1]); } err(idealer1); return NULL; /* not reached */ } GEN checknf(GEN nf) { if (typ(nf)==t_POL) err(talker,"please apply nfinit first"); if (typ(nf)!=t_VEC) err(idealer1); switch(lg(nf)) { case 10: return nf; case 11: return checknf((GEN)nf[7]); case 3: if (typ(nf[2]) == t_POLMOD) return checknf((GEN)nf[1]); } err(idealer1); return NULL; /* not reached */ } void checkbnr(GEN bnr) { if (typ(bnr)!=t_VEC || lg(bnr)!=7) err(talker,"incorrect bigray field"); (void)checkbnf((GEN)bnr[1]); } void checkbnrgen(GEN bnr) { checkbnr(bnr); if (lg(bnr[5])<=3) err(talker,"please apply bnrinit(,,1) and not bnrinit(,)"); } GEN check_units(GEN bnf, char *f) { GEN nf, x; bnf = checkbnf(bnf); nf = checknf(bnf); x = (GEN)bnf[8]; if (lg(x) < 7 || (lg(x[5]) == 1 && lg(nf[6]) > 2)) err(talker,"missing units in %s", f); return (GEN)x[5]; } void checkid(GEN x, long N) { if (typ(x)!=t_MAT) err(idealer2); if (lg(x) == 1 || lg(x[1]) != N+1) err(talker,"incorrect matrix for ideal"); } void checkbid(GEN bid) { if (typ(bid)!=t_VEC || lg(bid)!=6 || lg(bid[1])!=3) err(talker,"incorrect bigideal"); } void checkprimeid(GEN id) { if (typ(id) != t_VEC || lg(id) != 6) err(talker,"incorrect prime ideal"); } void checkprhall(GEN prhall) { if (typ(prhall) != t_VEC || lg(prhall) != 3 || typ(prhall[1]) != t_MAT) err(talker,"incorrect prhall format"); } void check_pol_int(GEN x) { long k = lg(x)-1; for ( ; k>1; k--) if (typ(x[k])!=t_INT) err(talker,"polynomial not in Z[X]"); } GEN get_primeid(GEN x) { if (typ(x) != t_VEC) return NULL; if (lg(x) == 3) x = (GEN)x[1]; if (lg(x) != 6 || typ(x[3]) != t_INT) return NULL; return x; } GEN get_bnf(GEN x, int *t) { switch(typ(x)) { case t_POL: *t = typ_POL; return NULL; case t_QUAD: *t = typ_Q ; return NULL; case t_VEC: switch(lg(x)) { case 3: if (typ(x[2]) != t_POLMOD) break; return get_bnf((GEN)x[1],t); case 6 : *t = typ_QUA; return NULL; case 10: *t = typ_NF; return NULL; case 11: *t = typ_BNF; return x; case 7 : *t = typ_BNR; x = (GEN)x[1]; if (typ(x)!=t_VEC || lg(x)!=11) break; return x; } case t_MAT: if (lg(x)==2) switch(lg(x[1])) { case 8: case 11: *t = typ_CLA; return NULL; } } *t = typ_NULL; return NULL; } GEN get_nf(GEN x, int *t) { switch(typ(x)) { case t_POL : *t = typ_POL; return NULL; case t_QUAD: *t = typ_Q ; return NULL; case t_VEC: switch(lg(x)) { case 3: if (typ(x[2]) != t_POLMOD) break; return get_nf((GEN)x[1],t); case 10: *t = typ_NF; return x; case 11: *t = typ_BNF; x = (GEN)x[7]; if (typ(x)!=t_VEC || lg(x)!=10) break; return x; case 7 : *t = typ_BNR; x = (GEN)x[1]; if (typ(x)!=t_VEC || lg(x)!=11) break; x = (GEN)x[7]; if (typ(x)!=t_VEC || lg(x)!=10) break; return x; case 14: case 20: *t = typ_ELL; return NULL; }break; case t_MAT: if (lg(x)==2) switch(lg(x[1])) { case 8: case 11: *t = typ_CLA; return NULL; } } *t = typ_NULL; return NULL; } /*************************************************************************/ /** **/ /** GALOIS GROUP **/ /** **/ /*************************************************************************/ /* exchange elements i and j in vector x */ static GEN transroot(GEN x, int i, int j) { long k; x = dummycopy(x); k=x[i]; x[i]=x[j]; x[j]=k; return x; } #define randshift (BITS_IN_RANDOM - 3) GEN tschirnhaus(GEN x) { long a, v = varn(x), av = avma; GEN u, p1 = cgetg(5,t_POL); if (typ(x)!=t_POL) err(notpoler,"tschirnhaus"); if (lgef(x) < 4) err(constpoler,"tschirnhaus"); if (v) { u=dummycopy(x); setvarn(u,0); x=u; } p1[1] = evalsigne(1)|evalvarn(0)|evallgef(5); do { a = mymyrand() >> randshift; if (a==0) a =1; p1[4]=lstoi(a); a = mymyrand() >> (randshift-1); if (a>=4) a-=8; p1[3]=lstoi(a); a = mymyrand() >> (randshift-1); if (a>=4) a-=8; p1[2]=lstoi(a); u = caract2(x,p1,v); a=avma; } while (lgef(srgcd(u,derivpol(u))) > 3); /* while u not separable */ if (DEBUGLEVEL>1) fprintferr("Tschirnhaus transform. New pol: %Z",u); avma=a; return gerepileupto(av,u); } #undef randshift int gpolcomp(GEN p1, GEN p2) { int s,j = lgef(p1)-2; if (lgef(p2)-2 != j) err(bugparier,"gpolcomp (different degrees)"); for (; j>=2; j--) { s = absi_cmp((GEN)p1[j], (GEN)p2[j]); if (s) return s; } return 0; } /* pol is assumed to be non-zero, primitive and integral */ static GEN primitive_pol_to_monic(GEN pol, GEN *ptlead) { long n = lgef(pol)-1; GEN p1,lead,res; if (gcmp1((GEN)pol[n])) { if (ptlead) *ptlead = NULL; return pol; } res = cgetg(n+1,t_POL); res[1]=pol[1]; lead = (GEN) pol[n]; p1 = gun; res[n] = un; n--; if (n>1) res[n] = pol[n]; for (n--; n>1; n--) { p1 = mulii(lead,p1); res[n] = lmulii(p1,(GEN)pol[n]); } if (ptlead) *ptlead = lead; return res; } /* compute x1*x2^2 + x2*x3^2 + x3*x4^2 + x4*x1^2 */ static GEN get_F4(GEN x) { GEN p1=gzero; long i; for (i=1; i<=4; i++) p1 = gadd(p1, gmul((GEN)x[i], gsqr((GEN)x[(i&3)+1]))); return p1; } GEN galoisbig(GEN x, long prec); GEN roots_to_pol(GEN a, long v); GEN galois(GEN x, long prec) { long av=avma,av1,i,j,k,n,f,l,l2,e,e1,pr,ind; GEN x1,p1,p2,p3,p4,p5,p6,w,y,z,ee; static int ind5[20]={2,5,3,4, 1,3,4,5, 1,5,2,4, 1,2,3,5, 1,4,2,3}; static int ind6[60]={3,5,4,6, 2,6,4,5, 2,3,5,6, 2,4,3,6, 2,5,3,4, 1,4,5,6, 1,5,3,6, 1,6,3,4, 1,3,4,5, 1,6,2,5, 1,2,4,6, 1,5,2,4, 1,3,2,6, 1,2,3,5, 1,4,2,3}; if (typ(x)!=t_POL) err(notpoler,"galois"); n=lgef(x)-3; if (n<=0) err(constpoler,"galois"); if (n>11) err(impl,"galois of degree higher than 11"); x = gdiv(x,content(x)); for (i=2; i<=n+2; i++) if (typ(x[i])!=t_INT) err(polrationer,"galois"); if (gisirreducible(x) != gun) err(impl,"galois of reducible polynomial"); if (n<4) { if (n<3) { avma=av; y=cgetg(4,t_VEC); y[1] = (n==1)? un: deux; y[2]=lnegi(gun); } else /* n=3 */ { f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC); if (f) { y[1]=lstoi(3); y[2]=un; } else { y[1]=lstoi(6); y[2]=lnegi(gun); } } y[3]=un; return y; } x1 = x = primitive_pol_to_monic(x,NULL); av1=avma; if (n>7) return galoisbig(x,prec); for(;;) { switch(n) { case 4: z = cgetg(7,t_VEC); for(;;) { p1=roots(x,prec); z[1] = (long)get_F4(p1); z[2] = (long)get_F4(transroot(p1,1,2)); z[3] = (long)get_F4(transroot(p1,1,3)); z[4] = (long)get_F4(transroot(p1,1,4)); z[5] = (long)get_F4(transroot(p1,2,3)); z[6] = (long)get_F4(transroot(p1,3,4)); p4 = roots_to_pol(z,0); p5=grndtoi(greal(p4),&e); e1=gexpo(gimag(p4)); if (e1>e) e=e1; if (e <= -10) break; prec = (prec<<1)-2; } p6 = modulargcd(p5, derivpol(p5)); if (typ(p6)==t_POL && lgef(p6)>3) goto tchi; p2 = (GEN)factor(p5)[1]; switch(lg(p2)-1) { case 1: f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC); y[3]=un; if (f) { y[2]=un; y[1]=lstoi(12); return y; } y[2]=lnegi(gun); y[1]=lstoi(24); return y; case 2: avma=av; y=cgetg(4,t_VEC); y[3]=un; y[2]=lnegi(gun); y[1]=lstoi(8); return y; case 3: avma=av; y=cgetg(4,t_VEC); y[1]=lstoi(4); y[3]=un; y[2] = (lgef(p2[1])==5)? un: lnegi(gun); return y; default: err(bugparier,"galois (bug1)"); } case 5: z = cgetg(7,t_VEC); ee = new_chunk(7); w = new_chunk(7); for(;;) { for(;;) { p1=roots(x,prec); for (l=1; l<=6; l++) { p2=(l==1)?p1: ((l<6)?transroot(p1,1,l): transroot(p1,2,5)); p3=gzero; for (k=0,i=1; i<=5; i++,k+=4) { p5 = gadd(gmul((GEN)p2[ind5[k]],(GEN)p2[ind5[k+1]]), gmul((GEN)p2[ind5[k+2]],(GEN)p2[ind5[k+3]])); p3 = gadd(p3, gmul(gsqr((GEN)p2[i]),p5)); } w[l]=lrndtoi(greal(p3),&e); e1 = gexpo(gimag(p3)); if (e1>e) e=e1; ee[l]=e; z[l] = (long)p3; } p4 = roots_to_pol(z,0); p5=grndtoi(greal(p4),&e); e1 = gexpo(gimag(p4)); if (e1>e) e=e1; if (e <= -10) break; prec = (prec<<1)-2; } p6 = modulargcd(p5,derivpol(p5)); if (typ(p6)==t_POL && lgef(p6)>3) goto tchi; p3=(GEN)factor(p5)[1]; f=carreparfait(discsr(x)); if (lg(p3)-1==1) { avma=av; y=cgetg(4,t_VEC); y[3]=un; if (f) { y[2]=un; y[1]=lstoi(60); return y; } else { y[2]=lneg(gun); y[1]=lstoi(120); return y; } } if (!f) { avma=av; y=cgetg(4,t_VEC); y[3]=un; y[2]=lneg(gun); y[1]=lstoi(20); return y; } pr = - (bit_accuracy(prec) >> 1); for (l=1; l<=6; l++) if (ee[l] <= pr && gcmp0(poleval(p5,(GEN)w[l]))) break; if (l>6) err(bugparier,"galois (bug4)"); p2=(l==6)? transroot(p1,2,5):transroot(p1,1,l); p3=gzero; for (i=1; i<=5; i++) { j=(i%5)+1; p3=gadd(p3,gmul(gmul((GEN)p2[i],(GEN)p2[j]), gsub((GEN)p2[j],(GEN)p2[i]))); } p5=gsqr(p3); p4=grndtoi(greal(p5),&e); e1 = gexpo(gimag(p5)); if (e1>e) e=e1; if (e <= -10) { if (gcmp0(p4)) goto tchi; f=carreparfait(p4); avma=av; y=cgetg(4,t_VEC); y[3]=y[2]=un; y[1]=lstoi(f?5:10); return y; } prec=(prec<<1)-2; } case 6: z = cgetg(7, t_VEC); for(;;) { for(;;) { p1=roots(x,prec); for (l=1; l<=6; l++) { p2=(l==1)?p1:transroot(p1,1,l); p3=gzero; k=0; for (i=1; i<=5; i++) for (j=i+1; j<=6; j++) { p5=gadd(gmul((GEN)p2[ind6[k]],(GEN)p2[ind6[k+1]]), gmul((GEN)p2[ind6[k+2]],(GEN)p2[ind6[k+3]])); p3=gadd(p3,gmul(gsqr(gmul((GEN)p2[i],(GEN)p2[j])),p5)); k+=4; } z[l] = (long)p3; } p4=roots_to_pol(z,0); p5=grndtoi(greal(p4),&e); e1 = gexpo(gimag(p4)); if (e1>e) e=e1; if (e <= -10) break; prec=(prec<<1)-2; } p6 = modulargcd(p5,derivpol(p5)); if (typ(p6)==t_POL && lgef(p6)>3) goto tchi; p2=(GEN)factor(p5)[1]; switch(lg(p2)-1) { case 1: z = cgetg(11,t_VEC); ind=0; p3=gadd(gmul(gmul((GEN)p1[1],(GEN)p1[2]),(GEN)p1[3]), gmul(gmul((GEN)p1[4],(GEN)p1[5]),(GEN)p1[6])); z[++ind] = (long)p3; for (i=1; i<=3; i++) for (j=4; j<=6; j++) { p2=transroot(p1,i,j); p3=gadd(gmul(gmul((GEN)p2[1],(GEN)p2[2]),(GEN)p2[3]), gmul(gmul((GEN)p2[4],(GEN)p2[5]),(GEN)p2[6])); z[++ind] = (long)p3; } p4 = roots_to_pol(z,0); p5=grndtoi(greal(p4),&e); e1 = gexpo(gimag(p4)); if (e1>e) e=e1; if (e <= -10) { p6 = modulargcd(p5,derivpol(p5)); if (typ(p6)==t_POL && lgef(p6)>3) goto tchi; p2=(GEN)factor(p5)[1]; f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC); y[3]=un; if (lg(p2)-1==1) { if (f) { y[2]=un; y[1]=lstoi(360); } else { y[2]=lnegi(gun); y[1]=lstoi(720); } } else { if (f) { y[2]=un; y[1]=lstoi(36); } else { y[2]=lnegi(gun); y[1]=lstoi(72); } } return y; } prec=(prec<<1)-2; break; case 2: l2=lgef(p2[1])-3; if (l2>3) l2=6-l2; switch(l2) { case 1: f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC); y[3]=un; if (f) { y[2]=un; y[1]=lstoi(60); } else { y[2]=lneg(gun); y[1]=lstoi(120); } return y; case 2: f=carreparfait(discsr(x)); if (f) { avma=av; y=cgetg(4,t_VEC); y[3]=y[2]=un; y[1]=lstoi(24); } else { p3=(lgef(p2[1])==5) ? (GEN)p2[2]:(GEN)p2[1]; f=carreparfait(discsr(p3)); avma=av; y=cgetg(4,t_VEC); y[2]=lneg(gun); if (f) { y[1]=lstoi(24); y[3]=deux; } else { y[1]=lstoi(48); y[3]=un; } } return y; case 3: f=carreparfait(discsr((GEN)p2[1])) || carreparfait(discsr((GEN)p2[2])); avma=av; y=cgetg(4,t_VEC); y[3]=un; y[2]=lneg(gun); y[1]=lstoi(f? 18: 36); return y; } case 3: for (l2=1; l2<=3; l2++) if (lgef(p2[l2])>=6) p3=(GEN)p2[l2]; if (lgef(p3)==6) { f=carreparfait(discsr(p3)); avma=av; y=cgetg(4,t_VEC); y[2]=lneg(gun); y[1]=lstoi(f? 6: 12); } else { f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC); if (f) { y[2]=un; y[1]=lstoi(12); } else { y[2]=lneg(gun); y[1]=lstoi(24); } } y[3]=un; return y; case 4: avma=av; y=cgetg(4,t_VEC); y[1]=lstoi(6); y[2]=lneg(gun); y[3]=deux; return y; default: err(bugparier,"galois (bug3)"); } } case 7: z = cgetg(36,t_VEC); for(;;) { ind = 0; p1=roots(x,prec); p4=gun; for (i=1; i<=5; i++) for (j=i+1; j<=6; j++) { p6 = gadd((GEN)p1[i],(GEN)p1[j]); for (k=j+1; k<=7; k++) z[++ind] = (long) gadd(p6,(GEN)p1[k]); } p4 = roots_to_pol(z,0); p5 = grndtoi(greal(p4),&e); e1 = gexpo(gimag(p4)); if (e1>e) e=e1; if (e <= -10) break; prec = (prec<<1)-2; } p6 = modulargcd(p5,derivpol(p5)); if (typ(p6)==t_POL && lgef(p6)>3) goto tchi; p2=(GEN)factor(p5)[1]; switch(lg(p2)-1) { case 1: f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC); y[3]=un; if (f) { y[2]=un; y[1]=lstoi(2520); } else { y[2]=lneg(gun); y[1]=lstoi(5040); } return y; case 2: f=lgef(p2[1])-3; avma=av; y=cgetg(4,t_VEC); y[3]=un; if (f==7 || f==28) { y[2]=un; y[1]=lstoi(168); } else { y[2]=lneg(gun); y[1]=lstoi(42); } return y; case 3: avma=av; y=cgetg(4,t_VEC); y[3]=y[2]=un; y[1]=lstoi(21); return y; case 4: avma=av; y=cgetg(4,t_VEC); y[3]=un; y[2]=lneg(gun); y[1]=lstoi(14); return y; case 5: avma=av; y=cgetg(4,t_VEC); y[3]=y[2]=un; y[1]=lstoi(7); return y; default: err(talker,"galois (bug2)"); } } tchi: avma=av1; x=tschirnhaus(x1); } } GEN galoisapply(GEN nf, GEN aut, GEN x) { long av=avma,tetpil,lx,j,N; GEN p,p1,y,pol; nf=checknf(nf); pol=(GEN)nf[1]; if (typ(aut)==t_POL) aut = gmodulcp(aut,pol); else { if (typ(aut)!=t_POLMOD || !gegal((GEN)aut[1],pol)) err(talker,"incorrect galois automorphism in galoisapply"); } switch(typ(x)) { case t_INT: case t_INTMOD: case t_FRAC: case t_FRACN: case t_PADIC: avma=av; return gcopy(x); case t_POLMOD: x = (GEN) x[2]; /* fall through */ case t_POL: p1 = gsubst(x,varn(pol),aut); if (typ(p1)!=t_POLMOD || !gegal((GEN)p1[1],pol)) p1 = gmodulcp(p1,pol); return gerepileupto(av,p1); case t_VEC: if (lg(x)==3) { y=cgetg(3,t_VEC); y[1]=(long)galoisapply(nf,aut,(GEN)x[1]); y[2]=lcopy((GEN)x[2]); return gerepileupto(av, y); } if (lg(x)!=6) err(typeer,"galoisapply"); y=cgetg(6,t_VEC); y[1]=x[1]; y[3]=x[3]; y[4]=x[4]; p = (GEN)x[1]; p1=centermod(galoisapply(nf,aut,(GEN)x[2]), p); if (is_pm1(x[3])) if (ggval(subres(gmul((GEN)nf[7],p1),pol), p) > itos((GEN)x[4])) p1[1] = (signe(p1[1]) > 0)? lsub((GEN)p1[1], p) : ladd((GEN)p1[1], p); y[2]=(long)p1; y[5]=(long)centermod(galoisapply(nf,aut,(GEN)x[5]), p); tetpil=avma; return gerepile(av,tetpil,gcopy(y)); case t_COL: N=lgef(pol)-3; if (lg(x)!=N+1) err(typeer,"galoisapply"); p1=galoisapply(nf,aut,gmul((GEN)nf[7],x)); tetpil=avma; return gerepile(av,tetpil,algtobasis(nf,p1)); case t_MAT: lx=lg(x); if (lx==1) return cgetg(1,t_MAT); N=lgef(pol)-3; if (lg(x[1])!=N+1) err(typeer,"galoisapply"); p1=cgetg(lx,t_MAT); for (j=1; j1; i--) p1 = gadd(p1, gmul((GEN)x[i],(GEN)sym[i])); } return p1; } /* Seek a new, simpler, polynomial pol defining the same number field as * x (assumed to be monic at this point). * *ptx receives pol * *ptdx receives disc(pol) * *ptrev expresses the new root in terms of the old one. * base updated in place. * prec = 0 <==> field is totally real */ static void nfinit_reduce(long flag, GEN *px, GEN *pdx, GEN *prev, GEN *pbase, long prec) { GEN chbas,a,phimax,dxn,s,sn,p1,p2,p3,polmax,rev,polr; GEN x = *px, dx = *pdx, base = *pbase; long i,j,nmax,numb,flc,v=varn(x), n=lg(base)-1; if (n == 1) { *px = gsub(polx[v],gun); *pdx = gun; *prev = polymodrecip(gmodulcp(gun, x)); return; } polr = prec? roots(x, prec): NULL; if (polr) for (s=gzero,i=1; i<=n; i++) s = gadd(s,gnorm((GEN)polr[i])); else s = subii(sqri((GEN)x[n+1]), shifti((GEN)x[n],1)); chbas = LLL_nfbasis(&x,polr,base,prec); if (DEBUGLEVEL) msgtimer("LLL basis"); phimax=polx[v]; polmax=dummycopy(x); nmax=(flag & nf_PARTIAL)?min(n,3):n; for (numb=0,i=2; i<=nmax || (!numb && i<=n); i++) { /* cf pols_for_polred */ if (DEBUGLEVEL>2) { fprintferr("i = %ld\n",i); flusherr(); } p1 = a = gmul(base,(GEN)chbas[i]); p3=content(p1); if (gcmp1(p3)) p3 = NULL; else p1 = gdiv(p1,p3); p1 = caract2(x,p1,v); if (p3) for (p2=gun, j=lgef(p1)-2; j>=2; j--) { p2 = gmul(p2,p3); p1[j] = lmul((GEN)p1[j], p2); } p2 = modulargcd(derivpol(p1),p1); if (lgef(p2) > 3) continue; if (DEBUGLEVEL>3) outerr(p1); dxn=discsr(p1); flc=absi_cmp(dxn,dx); numb++; if (flc>0) continue; if (polr) for (sn=gzero,j=1; j<=n; j++) sn = gadd(sn,gnorm(poleval(a,(GEN)polr[j]))); else sn = subii(sqri((GEN)p1[n+1]), shifti((GEN)p1[n],1)); if (flc>=0) { flc=gcmp(sn,s); if (flc>0 || (!flc && gpolcomp(p1,polmax) >= 0)) continue; } dx=dxn; s=sn; polmax=p1; phimax=a; } if (!numb) { if (gisirreducible(x)!=gun) err(redpoler,"nfinit_reduce"); err(talker,"you have found a counter-example to a conjecture, " "please send us\nthe polynomial as soon as possible"); } if (phimax == polx[v]) /* no improvement */ rev = gmodulcp(phimax,x); else { if (canon_pol(polmax) < 0) phimax = gneg_i(phimax); if (DEBUGLEVEL>1) fprintferr("polmax = %Z\n",polmax); p2 = gmodulcp(phimax,x); rev = polymodrecip(p2); a = base; base = cgetg(n+1,t_VEC); p1 = (GEN)rev[2]; for (i=1; i<=n; i++) base[i] = (long)eleval(polmax, (GEN)a[i], p1); p1 = vecpol_to_mat(base,n); p2=denom(p1); p1=gmul(p2,p1); p1 = gdiv(hnfmod(p1,detint(p1)), p2); base = mat_to_vecpol(p1,v); } *px=polmax; *pdx=dx; *prev=rev; *pbase = base; } /* pol belonging to Z[x], return a monic polynomial generating the same field * as pol (x-> ax+b)) set lead = NULL if pol was monic (after dividing * by the content), and to to leading coeff otherwise. * No garbage collecting done. */ GEN pol_to_monic(GEN pol, GEN *lead) { long n = lgef(pol)-1; GEN p1; if (n==1 || gcmp1((GEN)pol[n])) { *lead = NULL; return pol; } p1=content(pol); if (!gcmp1(p1)) pol = gdiv(pol,p1); return primitive_pol_to_monic(pol,lead); } GEN make_TI(GEN nf, GEN TI, GEN con) { GEN z, p1 = hnfmod(TI,detint(TI)), d = dethnf(p1); long n = lg(TI)-1; d = mulii(d, gpowgs(con, n)); p1 = ideal_two_elt(nf, p1); p1 = gmul(p1,con); z = cgetg(4,t_VEC); z[1]=p1[1]; z[2]=p1[2]; z[3]=(long)d; return z; } /* basis = integer basis. roo = real part of the roots */ GEN make_M(long n,long ru,GEN basis,GEN roo) { GEN p1,res = cgetg(n+1,t_MAT); long i,j; for (j=1; j<=n; j++) { p1=cgetg(ru+1,t_COL); res[j]=(long)p1; for (i=1; i<=ru; i++) p1[i]=(long)poleval((GEN)basis[j],(GEN)roo[i]); } if (DEBUGLEVEL>4) msgtimer("matrix M"); return res; } GEN make_MC(long n,long r1,long ru,GEN M) { GEN p1,p2,res=cgetg(ru+1,t_MAT); long i,j,av,tetpil; for (j=1; j<=ru; j++) { p1=cgetg(n+1,t_COL); res[j]=(long)p1; for (i=1; i<=n; i++) { av=avma; p2=gconj(gcoeff(M,j,i)); tetpil=avma; p1[i] = (j<=r1)? (long)p2: lpile(av,tetpil,gmul2n(p2,1)); } } if (DEBUGLEVEL>4) msgtimer("matrix MC"); return res; } GEN get_roots(GEN x,long r1,long ru,long prec) { GEN roo = (typ(x)==t_VEC)? dummycopy(x): roots(x,prec); long i; for (i=1; i<=r1; i++) roo[i]=lreal((GEN)roo[i]); for ( ; i<=ru; i++) roo[i]=roo[(i<<1)-r1]; roo[0]=evaltyp(t_VEC)|evallg(ru+1); return roo; } GEN get_mul_table(GEN x,GEN bas,GEN *ptT) { long i,j,k, n = lgef(x)-3; GEN T,sym,mul=cgetg(n*n+1,t_MAT); for (j=1; j<=n*n; j++) mul[j]=lgetg(n+1,t_COL); if (ptT) { sym = polsym(x,n-1); T=cgetg(n+1,t_MAT); *ptT = T; for (j=1; j<=n; j++) T[j]=lgetg(n+1,t_COL); } for (i=1; i<=n; i++) for (j=i; j<=n; j++) { GEN t = gres(gmul((GEN)bas[j],(GEN)bas[i]), x); GEN a = (GEN)mul[j+(i-1)*n]; GEN b = (GEN)mul[i+(j-1)*n]; long l = lgef(t)-1; for (k=1; k=3 && typ(x[1])==t_POL) { /* polynomial + integer basis */ bas=(GEN)x[2]; x=(GEN)x[1]; n=lgef(x)-3; if (gisirreducible(x) == gzero) err(redpoler,"nfinit"); dx=discsr(x); if (typ(bas) == t_MAT) { mat = bas; bas = mat_to_vecpol(mat,varn(x)); } else mat = vecpol_to_mat(bas,n); dK = gmul(dx, gsqr(det2(mat))); r1 = sturm(x); } else { nf=checknf(x); bas=(GEN)nf[7]; x=(GEN)nf[1]; n=lgef(x)-3; dK=(GEN)nf[3]; dx=mulii(dK, sqri((GEN)nf[4])); r1 = itos(gmael(nf,2,1)); } bas[1]=lpolun[varn(x)]; /* it may be gun => SEGV later */ if (flag & nf_DIFFERENT) fa = factor(absi(dK)); } r2=(n-r1)>>1; ru=r1+r2; PRECREG = prec + (expi(dK)>>(TWOPOTBITS_IN_LONG+1)) + (long)((sqrt((double)n)+3) / sizeof(long) * 4); if (flag & nf_REDUCE) { nfinit_reduce(flag, &x, &dx, &rev, &bas, r1==n? 0: prec); if (DEBUGLEVEL) msgtimer("polred"); } if (!carrecomplet(divii(dx,dK),&index)) err(bugparier,"nfinit (incorrect discriminant)"); if (!(flag & nf_SMALL)) { mul = get_mul_table(x,bas, &T); if (DEBUGLEVEL) msgtimer("mult. table"); p1=vecpol_to_mat(bas,n); } ro=get_roots(x,r1,ru,PRECREG); if (DEBUGLEVEL) msgtimer("roots"); if (flag & nf_ORIG) { if (!(flag & nf_REDUCE)) err(talker,"bad flag in initalgall0"); res = cgetg(3,t_VEC); } nf=cgetg(10,t_VEC); nf[1]=lcopy(x); nf[2]=lgetg(3,t_VEC); mael(nf,2,1)=lstoi(r1); mael(nf,2,2)=lstoi(r2); nf[3]=lcopy(dK); nf[4]=lcopy(index); mat = cgetg(8,t_VEC); nf[5]=(long)mat; nf[6]=lcopy(ro); nf[7]=lcopy(bas); if (flag & nf_SMALL) nf[8]=nf[9]=zero; else { nf[8]=linvmat(p1); nf[9]=lmul((GEN)nf[8],mul); } M = make_M(n,ru,bas,ro); MC = make_MC(n,r1,ru,M); mat[1]=(long)M; mat[5]=zero; /* dummy for the different */ mat[3]=(long)mulmat_real(MC,M); if (flag & nf_SMALL) mat[2]=mat[4]=mat[6]=mat[7]=zero; else { long av2, av3; GEN a2; mat[2]=(long)MC; mat[4]=lcopy(T); av2=avma; p1=ginv(T); av3=avma; mat[6] = lpile(av2,av3, gmul(p1,dK)); av2=avma; p1=content((GEN)mat[6]); a2=gdiv((GEN)mat[6],p1); a2 = make_TI(nf,a2,p1); av3=avma; /* Ideal basis for discriminant * (inverse of different) */ mat[7] = lpile(av2,av3,gcopy(a2)); } if (DEBUGLEVEL>=2) msgtimer("matrices"); if (flag & nf_DIFFERENT) { mat[5]=(long)differente(nf,fa); if (DEBUGLEVEL) msgtimer("different"); } if (!(flag & nf_ORIG)) res = nf; else { res[1]=(long)nf; res[2]=lead? ldiv(rev,lead): lcopy(rev); } return gerepileupto(av,res); } GEN initalgred(GEN x, long prec) { return initalgall0(x,nf_REDUCE|nf_DIFFERENT,prec); } GEN initalgred2(GEN x, long prec) { return initalgall0(x,nf_REDUCE|nf_DIFFERENT|nf_ORIG,prec); } GEN nfinit0(GEN x, long flag,long prec) { switch(flag) { case 0: return initalgall0(x,nf_DIFFERENT,prec); case 1: return initalgall0(x,nf_REGULAR,prec); case 2: return initalgall0(x,nf_REDUCE|nf_DIFFERENT,prec); case 3: return initalgall0(x,nf_REDUCE|nf_ORIG|nf_DIFFERENT,prec); case 4: return initalgall0(x,nf_REDUCE|nf_PARTIAL|nf_DIFFERENT,prec); case 5: return initalgall0(x,nf_REDUCE|nf_ORIG|nf_PARTIAL|nf_DIFFERENT,prec); case 6: return initalgall0(x,nf_SMALL,prec); default: err(flagerr,"nfinit"); } return NULL; /* not reached */ } GEN initalg(GEN x, long prec) { return initalgall0(x,nf_DIFFERENT,prec); } GEN nfnewprec(GEN nf, long prec) { long av=avma,i,r1,r2,ru,n,nf_small,tetpil; GEN y,pol,ro,bas,MC,mat,M; if (typ(nf) != t_VEC) err(talker,"incorrect nf in nfnewprec"); if (lg(nf) == 11) return bnfnewprec(nf,prec); if (prec <= 0) { ro = (GEN)nf[6]; prec = (typ(ro)==t_VEC)?precision((GEN)ro[1]): DEFAULTPREC; return (GEN)prec; } y=cgetg(10,t_VEC); for (i=1; i<=4; i++) y[i]=nf[i]; for (i=6; i<=9; i++) y[i]=nf[i]; nf_small = gcmp0((GEN)nf[8]); pol=(GEN)nf[1]; n=degree(pol); r1=itos(gmael(nf,2,1)); r2=itos(gmael(nf,2,2)); ru=r1+r2; mat=cgetg(8,t_VEC); y[5]=(long)mat; bas=(GEN)nf[7]; ro=get_roots(pol,r1,ru,prec); M = make_M(n,ru,bas,ro); MC = make_MC(n,r1,ru,M); if (nf_small) mat[2]=mat[4]=mat[5]=mat[6]=mat[7]=zero; else { GEN matrices=(GEN)nf[5]; y[6]=(long)ro; mat[2]=(long)MC; for (i=4; i<=7; i++) mat[i]=matrices[i]; } mat[1]=(long)M; mat[3]=lreal(gmul(MC,M)); tetpil=avma; return gerepile(av,tetpil,gcopy(y)); } static long nf_pm1(GEN y) { long i,l; if (!is_pm1(y[1])) return 0; l = lg(y); for (i=2; i 0) /* y = 1 */ { if (p!=2 || !gcmp1(gcoeff(fa,i,2))) return NULL; x = gneg_i(x); } } return x; } GEN rootsof1(GEN nf) { long av,tetpil,N,k,i,ws,prec; GEN algun,p1,y,R1,d,list,w; y=cgetg(3,t_VEC); av=avma; nf=checknf(nf); R1=gmael(nf,2,1); algun=gmael(nf,8,1); if (signe(R1)) { y[1]=deux; y[2]=lneg(algun); return y; } N=lgef(nf[1])-3; prec=gprecision((GEN)nf[6]); #ifdef LONG_IS_32BIT if (prec < 10) prec = 10; #else if (prec < 6) prec = 6; #endif for (i=1; ; i++) { p1 = fincke_pohst(gmael(nf,5,3),stoi(N),stoi(1000),1,prec,NULL); if (p1) break; if (i == MAXITERPOL) err(accurer,"rootsof1"); prec=(prec<<1)-2; if (DEBUGLEVEL) err(warnprec,"rootsof1",prec); nf=nfnewprec(nf,prec); } if (itos(ground((GEN)p1[2])) != N) err(bugparier,"rootsof1 (bug1)"); w=(GEN)p1[1]; ws = itos(w); if (ws == 2) { y[1]=deux; avma=av; y[2]=lneg(algun); return y; } d = decomp(w); list = (GEN)p1[3]; k = lg(list); for (i=1; i6) fprintferr(" %ld",court[2]); } if (DEBUGLEVEL>6) { fprintferr("\n"); flusherr(); } free(c2); return c; } GEN dirzetak(GEN nf, GEN b) { GEN z,c; long i; if (typ(b)!=t_INT) err(talker,"not an integer type in dirzetak"); if (signe(b)<=0) return cgetg(1,t_VEC); nf = checknf(nf); if (is_bigint(b)) err(talker,"too many terms in dirzetak"); c = dirzetak0(nf,itos(b)); i = lg(c); z=cgetg(i,t_VEC); for (i-- ; i; i--) z[i]=lstoi(c[i]); free(c); return z; } GEN initzeta(GEN pol, long prec) { GEN nfz,nf,alpha,beta,mu,gr1,gr2,gru,p1,p2,cst,A0,c0,c1,c2,eps,coef; GEN limx,bnf,resi,zet,C,coeflog,racpi,aij,tabj,colzero, *tabcstn, *tabcstni; GEN c_even,ck_even,c_odd,ck_odd,serie_even,serie_odd,serie_exp,Pi; long N0,imin,imax,r1,r2,ru,R,N,i,j,k,n, av,av2,tetpil; long court[] = {evaltyp(t_INT)|m_evallg(3), evalsigne(1)|evallgefint(3),0}; stackzone *zone, *zone0, *zone1; /*************** Calcul du residu et des constantes ***************/ eps=gmul2n(gun,-bit_accuracy(prec)-6); p1=dbltor(0.5); nfz=cgetg(10,t_VEC); bnf=buchinit(pol,p1,p1,prec+1); prec=(prec<<1)-1; Pi = mppi(prec); racpi=gsqrt(Pi,prec); /* Nb de classes et regulateur */ nf=(GEN)bnf[7]; N=lgef(nf[1])-3; gr1=gmael(nf,2,1); gr2=gmael(nf,2,2); r1=itos(gr1); r2=itos(gr2); ru=r1+r2; R=ru+2; av=avma; p1=(GEN)bnf[8]; p2 = gmul(gmul2n(gmael(p1,1,1),r1), (GEN)p1[2]); tetpil = avma; resi=gerepile(av,tetpil,gdiv(p2, gmael(p1,4,1))); /* Calcul de N0 */ cst = cgetr(prec); av = avma; mu = gadd(gmul2n(gr1,-1),gr2); alpha = gmul2n(stoi(ru+1),-1); beta = gpui(gdeux,gmul2n(gr1,-1),DEFAULTPREC); A0 = gmul2n(gpowgs(mu,R),r1); A0 = gmul(A0,gpowgs(gmul2n(Pi,1),1-ru)); A0 = gsqrt(A0,DEFAULTPREC); c1 = gmul(mu,gpui(beta,ginv(mu),DEFAULTPREC)); c0 = gdiv(gmul(A0,gpowgs(gmul2n(Pi,1),ru-1)),mu); c0 = gmul(c0,gpui(c1,gneg_i(alpha),DEFAULTPREC)); c2 = gdiv(alpha,mu); p1 = glog(gdiv(c0,eps),DEFAULTPREC); limx = gdiv(gsub(glog(p1,DEFAULTPREC),glog(c1,DEFAULTPREC)), gadd(c2,gdiv(p1,mu))); limx = gmul(gpui(gdiv(c1,p1),mu,DEFAULTPREC), gadd(gun,gmul(alpha,limx))); p1 = gsqrt(absi((GEN)nf[3]),prec); p2 = gmul2n(gpowgs(racpi,N),r2); gaffect(gdiv(p1,p2), cst); av = avma; p1 = gfloor(gdiv(cst,limx)); N0 = p1[2]; if (is_bigint(p1) || N0 > 10000000) err(talker,"discriminant too large for initzeta, sorry"); if (DEBUGLEVEL>=2) { fprintferr("\ninitzeta:\nN0 = %ld\n",N0); flusherr(); timer2(); } /* Calcul de imax */ imin=1; imax=1400; p1 = gmul(gpowgs(gmul2n(racpi,1),r2),gpowgs(stoi(5),r1)); p1 = gdiv(p1,gmul(gmul(gsqrt(limx,DEFAULTPREC),gmul2n(eps,4)), gpowgs(racpi,3))); while (imax-imin >= 4) { long itest = (imax+imin)>>1; p2 = gmul(gpowgs(mpfactr(itest,DEFAULTPREC),r2),gpowgs(limx,itest)); p2 = gmul(p2,gpowgs(mpfactr(itest/2,DEFAULTPREC),r1)); if (gcmp(p2,p1) >= 0) imax=itest; else imin=itest; } imax -= (imax & 1); avma = av; if (DEBUGLEVEL>=2) { fprintferr("imax = %ld\n",imax); flusherr(); } /* Tableau des i/cst (i=1 a N0) */ i = prec*N0; zone = switch_stack(NULL,i + 2*(N0+1) + 6*prec); zone1 = switch_stack(NULL,2*i); zone0 = switch_stack(NULL,2*i); switch_stack(zone,1); tabcstn = (GEN*) cgetg(N0+1,t_VEC); tabcstni = (GEN*) cgetg(N0+1,t_VEC); p1 = ginv(cst); for (i=1; i<=N0; i++) { tabcstni[i] = gun; tabcstn[i] = mulsr(i,p1); } switch_stack(zone,0); /********** Calcul des coefficients a(i,j) independants de s **********/ zet=cgetg(R,t_VEC); zet[1] = lmpeuler(prec); for (i=2; i=2) msgtimer("a(i,j)"); p1=cgetg(5,t_VEC); p1[1]=lstoi(r1); p1[2]=lstoi(r2); p1[3]=lstoi(imax); p1[4]=(long)bnf; nfz[1]=(long)p1; nfz[2]=(long)resi; nfz[5]=(long)cst; nfz[6]=llog(cst,prec); nfz[7]=(long)aij; /************* Calcul du nombre d'ideaux de norme donnee *************/ coef = dirzetak0(nf,N0); tabj = cgetg(N0+1,t_MAT); if (DEBUGLEVEL>=2) msgtimer("coef"); colzero=cgetg(ru+2,t_COL); for (j=1; j<=ru+1; j++) colzero[j]=zero; for (i=1; i<=N0; i++) if (coef[i]) { GEN t = cgetg(ru+2,t_COL); p1 = glog((GEN)tabcstn[i],prec); setsigne(p1, -signe(p1)); t[1] = lstoi(coef[i]); t[2] = lmul((GEN)t[1],p1); for (j=2; j<=ru; j++) { long av2 = avma; p2 = gmul((GEN)t[j],p1); t[j+1] = (long)gerepileuptoleaf(av2, divrs(p2,j)); } /* tabj[n,j]=coef(n)*ln(c/n)^(j-1)/(j-1)! */ tabj[i] = (long)t; } else tabj[i]=(long)colzero; if (DEBUGLEVEL>=2) msgtimer("a(n)"); coeflog=cgetg(N0+1,t_VEC); coeflog[1]=zero; for (i=2; i<=N0; i++) if (coef[i]) { court[2]=i; p1=glog(court,prec); setsigne(p1,-1); coeflog[i]=(long)p1; } else coeflog[i] = zero; if (DEBUGLEVEL>=2) msgtimer("log(n)"); nfz[3]=(long)tabj; p1 = cgetg(N0+1,t_VECSMALL); for (i=1; i<=N0; i++) p1[i] = coef[i]; nfz[8]=(long)p1; nfz[9]=(long)coeflog; /******************** Calcul des coefficients Cik ********************/ C = cgetg(ru+1,t_MAT); for (k=1; k<=ru; k++) C[k] = lgetg(imax+1,t_COL); av2 = avma; for (i=1; i<=imax; i++) { stackzone *z; for (k=1; k<=ru; k++) { p1 = NULL; for (n=1; n<=N0; n++) if (coef[n]) for (j=1; j<=ru-k+1; j++) { p2 = gmul(tabcstni[n], gmul(gmael(aij,i,j+k), gmael(tabj,n,j))); p1 = p1? gadd(p1,p2): p2; } coeff(C,i,k) = p1? (long)gerepileupto(av2,p1): zero; av2 = avma; } /* use a parallel stack */ z = i&1? zone1: zone0; switch_stack(z, 1); for (n=1; n<=N0; n++) if (coef[n]) tabcstni[n] = mpmul(tabcstni[n],tabcstn[n]); /* come back */ switch_stack(z, 0); } nfz[4] = (long) C; if (DEBUGLEVEL>=2) msgtimer("Cik"); gunclone(aij); free((void*)zone); free((void*)zone1); free((void*)zone0); free((void*)coef); return nfz; } GEN gzetakall(GEN nfz, GEN s, long flag, long prec2) { GEN resi,C,cst,cstlog,coeflog,cs,coef; GEN lambd,gammas,gammaunmoins,gammas2,gammaunmoins2,var1,var2; GEN p1,unmoins,gexpro,gar,val,valm,valk,valkm; long ts = typ(s), r1,r2,ru,imax,i,j,k,N0,sl,prec,bigprec, av = avma; if (typ(nfz)!=t_VEC || lg(nfz)!=10 || typ(nfz[1]) != t_VEC) err(talker,"not a zeta number field in zetakall"); if (! is_intreal_t(ts) && ts != t_COMPLEX && ! is_frac_t(ts)) err(typeer,"gzetakall"); resi=(GEN)nfz[2]; C=(GEN)nfz[4]; cst=(GEN)nfz[5]; cstlog=(GEN)nfz[6]; coef=(GEN)nfz[8]; coeflog=(GEN)nfz[9]; r1 =itos(gmael(nfz,1,1)); r2 =itos(gmael(nfz,1,2)); imax=itos(gmael(nfz,1,3)); N0=lg(coef)-1; ru=r1+r2; /* from initzeta. Certainly excessive, at least if LONG_IS_64BIT */ bigprec = min(precision(cst), (prec2<<1) - 1); prec = prec2+1; if (ts==t_COMPLEX && gcmp0(gimag(s))) { s=greal(s); ts = typ(s); } if (ts==t_REAL && !signe(gfrac(s))) { s=mptrunc(s); ts = t_INT; } if (ts==t_INT) { sl=itos(s); if (sl==1) err(talker,"s = 1 is a pole (gzetakall)"); if (sl==0) { if (flag) err(talker,"s = 0 is a pole (gzetakall)"); if (ru == 1) { if (r1) return gneg(ghalf); return gneg(resi); } return gzero; } if (sl<0 && (r2 || !odd(sl))) { if (!flag) return gzero; s = subsi(1,s); sl = 1-sl; } unmoins=subsi(1,s); lambd = gdiv(resi, mulis(s,sl-1)); gammas2=ggamma(gmul2n(s,-1),prec); gar=gpowgs(gammas2,r1); cs=gexp(gmul(cstlog,s),prec); val=s; valm=unmoins; if (sl<0) /* r2 = 0 && odd(sl) */ { gammaunmoins2=ggamma(gmul2n(unmoins,-1),prec); var1=var2=gun; for (i=2; i<=N0; i++) if (coef[i]) { gexpro=gexp(gmul((GEN)coeflog[i],s),bigprec); var1 = gadd(var1,gmulsg(coef[i],gexpro)); var2 = gadd(var2,gdivsg(coef[i],gmulsg(i,gexpro))); } lambd=gadd(lambd,gmul(gmul(var1,cs),gar)); lambd=gadd(lambd,gmul(gmul(var2,gdiv(cst,cs)), gpowgs(gammaunmoins2,r1))); for (i=1; i<=imax; i+=2) { valk = val; valkm = valm; for (k=1; k<=ru; k++) { p1 = gcoeff(C,i,k); lambd = gsub(lambd,gdiv(p1,valk )); valk = mulii(val,valk); lambd = gsub(lambd,gdiv(p1,valkm)); valkm = mulii(valm,valkm); } val = addis(val, 2); valm = addis(valm,2); } } else { GEN tabj=(GEN)nfz[3], aij=(GEN)nfz[7]; gar = gmul(gar,gpowgs(ggamma(s,prec),r2)); var1=var2=gzero; for (i=1; i<=N0; i++) if (coef[i]) { gexpro=gexp(gmul((GEN)coeflog[i],s),bigprec); var1 = gadd(var1,gmulsg(coef[i],gexpro)); if (sl <= imax) { p1=gzero; for (j=1; j<=ru+1; j++) p1 = gadd(p1, gmul(gmael(aij,sl,j), gmael(tabj,i,j))); var2=gadd(var2,gdiv(p1,gmulsg(i,gexpro))); } } lambd=gadd(lambd,gmul(gmul(var1,cs),gar)); lambd=gadd(lambd,gmul(var2,gdiv(cst,cs))); for (i=1; i<=imax; i++) { valk = val; valkm = valm; if (i == sl) for (k=1; k<=ru; k++) { p1 = gcoeff(C,i,k); lambd = gsub(lambd,gdiv(p1,valk)); valk = mulii(val,valk); } else for (k=1; k<=ru; k++) { p1 = gcoeff(C,i,k); lambd = gsub(lambd,gdiv(p1,valk )); valk = mulii(val,valk); lambd = gsub(lambd,gdiv(p1,valkm)); valkm = mulii(valm,valkm); } val = addis(val,1); valm = addis(valm,1); } } } else { GEN Pi = mppi(prec); if (is_frac_t(ts)) s = gmul(s, realun(bigprec)); else s = gprec_w(s, bigprec); unmoins = gsub(gun,s); lambd = gdiv(resi,gmul(s,gsub(s,gun))); gammas = ggamma(s,prec); gammas2= ggamma(gmul2n(s,-1),prec); gar = gmul(gpowgs(gammas,r2),gpowgs(gammas2,r1)); cs = gexp(gmul(cstlog,s),prec); var1 = gmul(Pi,s); gammaunmoins = gdiv(Pi,gmul(gsin(var1,prec),gammas)); gammaunmoins2= gdiv(gmul(gmul(gsqrt(Pi,prec),gpui(gdeux,gsub(s,gun),prec)), gammas2), gmul(gcos(gmul2n(var1,-1),prec),gammas)); var1 = var2 = gun; for (i=2; i<=N0; i++) if (coef[i]) { gexpro = gexp(gmul((GEN)coeflog[i],s),bigprec); var1 = gadd(var1,gmulsg(coef[i], gexpro)); var2 = gadd(var2,gdivsg(coef[i], gmulsg(i,gexpro))); } lambd = gadd(lambd,gmul(gmul(var1,cs),gar)); lambd = gadd(lambd,gmul(gmul(gmul(var2,gdiv(cst,cs)), gpowgs(gammaunmoins,r2)), gpowgs(gammaunmoins2,r1))); val = s; valm = unmoins; for (i=1; i<=imax; i++) { valk = val; valkm = valm; for (k=1; k<=ru; k++) { p1 = gcoeff(C,i,k); lambd = gsub(lambd,gdiv(p1,valk )); valk = gmul(val, valk); lambd = gsub(lambd,gdiv(p1,valkm)); valkm = gmul(valm,valkm); } if (r2) { val = gadd(val, gun); valm = gadd(valm,gun); } else { val = gadd(val, gdeux); valm = gadd(valm,gdeux); i++; } } } if (!flag) lambd = gdiv(lambd,gmul(gar,cs)); /* zetak */ return gerepileupto(av, gprec_w(lambd, prec2)); } GEN gzetak(GEN nfz, GEN s, long prec) { return gzetakall(nfz,s,0,prec); } GEN glambdak(GEN nfz, GEN s, long prec) { return gzetakall(nfz,s,1,prec); }