[BACK]Return to trans3.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari-2.2 / src / basemath

Annotation of OpenXM_contrib/pari-2.2/src/basemath/trans3.c, Revision 1.2

1.2     ! noro        1: /* $Id: trans3.c,v 1.49 2002/07/15 13:30:01 karim Exp $
1.1       noro        2:
                      3: Copyright (C) 2000  The PARI group.
                      4:
                      5: This file is part of the PARI/GP package.
                      6:
                      7: PARI/GP is free software; you can redistribute it and/or modify it under the
                      8: terms of the GNU General Public License as published by the Free Software
                      9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
                     10: ANY WARRANTY WHATSOEVER.
                     11:
                     12: Check the License for details. You should have received a copy of it, along
                     13: with the package; see the file 'COPYING'. If not, write to the Free Software
                     14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
                     15:
                     16: /********************************************************************/
                     17: /**                                                                **/
                     18: /**                   TRANSCENDENTAL FONCTIONS                     **/
                     19: /**                          (part 3)                              **/
                     20: /**                                                                **/
                     21: /********************************************************************/
                     22: #include "pari.h"
1.2     ! noro       23: extern GEN rpowsi(ulong a, GEN n, long prec);
        !            24: extern GEN divrs2_safe(GEN x, long i);
        !            25: extern void dcxlog(double s, double t, double *a, double *b);
        !            26: extern double dnorm(double s, double t);
        !            27: extern GEN trans_fix_arg(long *prec, GEN *s0, GEN *sig, gpmem_t *av, GEN *res);
1.1       noro       28:
                     29: GEN
                     30: cgetc(long l)
                     31: {
                     32:   GEN u = cgetg(3,t_COMPLEX); u[1]=lgetr(l); u[2]=lgetr(l);
                     33:   return u;
                     34: }
                     35:
                     36: static GEN
                     37: fix(GEN x, long l)
                     38: {
                     39:   GEN y;
                     40:   if (typ(x) == t_REAL) return x;
                     41:   y = cgetr(l); gaffect(x, y); return y;
                     42: }
                     43:
1.2     ! noro       44: long
        !            45: lgcx(GEN z)
        !            46: {
        !            47:   long tz = typ(z);
        !            48:
        !            49:   switch(tz)
        !            50:   {
        !            51:     case t_INT: case t_FRAC: case t_RFRAC: case t_QUAD: return BIGINT;
        !            52:     case t_REAL: return lg(z);
        !            53:     case t_COMPLEX: return min(lgcx((GEN)z[1]),lgcx((GEN)z[2]));
        !            54:     default: err(typeer,"lgcx");
        !            55:   }
        !            56:   return 0;
        !            57: }
        !            58:
        !            59: GEN
        !            60: setlgcx(GEN z, long l)
        !            61: {
        !            62:   long tz = typ(z);
        !            63:   GEN p1;
        !            64:
        !            65:   switch(tz)
        !            66:   {
        !            67:     case t_INT: case t_FRAC: case t_RFRAC: case t_QUAD: return z;
        !            68:     case t_REAL: p1 = cgetr(l); affrr(z,p1); return p1;
        !            69:     case t_COMPLEX: p1 = cgetc(l); gaffect(z,p1); return p1;
        !            70:     default: err(typeer,"setlgcx");  return gzero; /* not reached */
        !            71:   }
        !            72: }
        !            73:
        !            74: /* force z to be of type real/complex */
        !            75:
        !            76: GEN
        !            77: setlgcx2(GEN z, long l)
        !            78: {
        !            79:   long tz = typ(z);
        !            80:   GEN p1;
        !            81:
        !            82:   switch(tz)
        !            83:   {
        !            84:     case t_INT: case t_FRAC: case t_RFRAC: case t_QUAD: case t_REAL:
        !            85:       p1 = cgetr(l); gaffect(z,p1); return p1;
        !            86:     case t_COMPLEX: p1 = cgetc(l); gaffect(z,p1); return p1;
        !            87:     default: err(typeer,"setlgcx"); return gzero; /* not reached */
        !            88:   }
        !            89: }
        !            90:
        !            91: /* a exporter ou ca existe deja ? */
        !            92:
        !            93: long
        !            94: isint(GEN n, long *ptk)
        !            95: {
        !            96:   long tn=typ(n);
        !            97:   GEN p1,p2;
        !            98:
        !            99:   switch(tn)
        !           100:   {
        !           101:     case t_INT:
        !           102:       *ptk = itos(n); return 1;
        !           103:     case t_REAL:
        !           104:       p1 = gfloor(n);
        !           105:       if (gcmp(p1,n)==0) {*ptk = itos(p1); return 1;}
        !           106:       else return 0;
        !           107:     case t_FRAC: case t_FRACN:
        !           108:       p1 = dvmdii((GEN)n[1],(GEN)n[2],&p2);
        !           109:       if (!signe(p2)) {*ptk = itos(p1); return 1;}
        !           110:       else return 0;
        !           111:     case t_COMPLEX:
        !           112:       if (gcmp0((GEN)n[2])) return isint((GEN)n[1],ptk);
        !           113:       else return 0;
        !           114:     case t_QUAD:
        !           115:       if (gcmp0((GEN)n[3])) return isint((GEN)n[2],ptk);
        !           116:       else return 0;
        !           117:     default: err(typeer,"isint"); return 0; /* not reached */
        !           118:   }
        !           119: }
        !           120:
        !           121: double
        !           122: norml1(GEN n, long prec)
        !           123: {
        !           124:   long tn=typ(n);
        !           125:   gpmem_t av;
        !           126:   double res;
        !           127:
        !           128:   switch(tn)
        !           129:   {
        !           130:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
        !           131:       return gtodouble(gabs(n,prec));
        !           132:     case t_COMPLEX:
        !           133:       return norml1((GEN)n[1],prec)+norml1((GEN)n[2],prec);
        !           134:     case t_QUAD:
        !           135:       av = avma; res = norml1(gmul(n,realun(prec)),prec); avma = av;
        !           136:       return res;
        !           137:     default: err(typeer,"norml1"); return 0.; /* not reached */
        !           138:   }
        !           139: }
        !           140:
1.1       noro      141: /***********************************************************************/
                    142: /**                                                                   **/
1.2     ! noro      143: /**                       BESSEL FUNCTIONS                            **/
1.1       noro      144: /**                                                                   **/
                    145: /***********************************************************************/
                    146:
1.2     ! noro      147: /* computes sum_{k=0}^m n!*((-1)^flag*z^2/4)^k/(k!*(k+n)!) */
        !           148:
        !           149: static GEN
        !           150: _jbessel(GEN n, GEN z, long flag, long m)
        !           151: {
        !           152:   long k, limit;
        !           153:   gpmem_t av;
        !           154:   GEN p1,s;
        !           155:
        !           156:   p1 = gmul2n(gsqr(z),-2); if (flag & 1) p1 = gneg(p1);
        !           157:   if (typ(z) == t_SER)
        !           158:   {
        !           159:     long v = valp(z);
        !           160:     k = lg(p1)-2 - v;
        !           161:     if (v < 0) err(negexper,"jbessel");
        !           162:     if (k <= 0) return gadd(gun, zeroser(varn(z), 2*v));
        !           163:     p1 = gprec(p1, k);
        !           164:   }
        !           165:   s = gun;
        !           166:   av = avma; limit = stack_lim(av,1);
        !           167:   for (k=m; k>=1; k--)
        !           168:   {
        !           169:     s = gadd(gun,gdiv(gdivgs(gmul(p1,s),k),gaddsg(k,n)));
        !           170:     if (low_stack(limit,stack_lim(av,1)))
        !           171:     {
        !           172:       if (DEBUGMEM>1) err(warnmem,"jbessel");
        !           173:       s = gerepilecopy(av, s);
        !           174:     }
        !           175:   }
        !           176:   return s;
        !           177: }
        !           178:
        !           179: static GEN
        !           180: jbesselintern(GEN n, GEN z, long flag, long prec)
        !           181: {
        !           182:   long tz=typ(z), i, lz, lim, k=-1, ki, precnew;
        !           183:   gpmem_t av=avma, tetpil;
        !           184:   double B,N,L,x;
        !           185:   GEN p1,p2,y,znew,nnew;
        !           186:
        !           187:   switch(tz)
        !           188:   {
        !           189:     case t_REAL: case t_COMPLEX:
        !           190:       i = precision(z); if (i) prec = i;
        !           191:       if (isint(setlgcx2(n,prec),&ki))
        !           192:       {
        !           193:        k = labs(ki);
        !           194:        p2 = gdiv(gpowgs(gmul2n(z,-1),k),mpfact(k));
        !           195:        if ((flag&1) && (ki<0) && (k&1)) p2 = gneg(p2);
        !           196:       }
        !           197:       else p2 = gdiv(gpow(gmul2n(z,-1),n,prec),ggamma(gaddgs(n,1),prec));
        !           198:       if (gcmp0(z)) return gerepilecopy(av, p2);
        !           199:       else
        !           200:       {
        !           201:        x = gtodouble(gabs(z,prec));
        !           202:        L = x*1.3591409;
        !           203:        B = bit_accuracy(prec)*LOG2/(2*L);
        !           204:        N = 1 + B;
        !           205: /* 3 Newton iterations are enough except in pathological cases */
        !           206:        N = (N + B)/(log(N)+1); N = (N + B)/(log(N)+1); N = (N + B)/(log(N)+1);
        !           207:        lim = max((long)(L*N),2);
        !           208:        precnew  = prec;
        !           209:        if (x >= 1.0) precnew += 1 + (long)(x/(LOG2*BITS_IN_LONG));
        !           210:        znew = setlgcx(z,precnew);
        !           211:        if (k >= 0) p1 = setlgcx(_jbessel(stoi(k),znew,flag,lim),prec);
        !           212:        else
        !           213:        {
        !           214:          i = precision(n);
        !           215:          nnew = (i && (i < precnew)) ? setlgcx(n,precnew) : n;
        !           216:          p1 = setlgcx(_jbessel(nnew,znew,flag,lim),prec);
        !           217:        }
        !           218:        tetpil = avma; return gerepile(av,tetpil,gmul(p2,p1));
        !           219:       }
        !           220:
        !           221:     case t_SER:
        !           222:       if (isint(setlgcx2(n,prec),&ki))
        !           223:       {
        !           224:        k = labs(ki);
        !           225:        p1 = _jbessel(stoi(k),z,flag,lg(z)-2);
        !           226:       }
        !           227:       else p1 = _jbessel(n,z,flag,lg(z)-2);
        !           228:       return gerepilecopy(av,p1);
        !           229:
        !           230:     case t_VEC: case t_COL: case t_MAT:
        !           231:       lz=lg(z); y=cgetg(lz,typ(z));
        !           232:       for (i=1; i<lz; i++)
        !           233:        y[i]=(long)jbesselintern(n,(GEN)z[i],flag,prec);
        !           234:       return y;
        !           235:
        !           236:     case t_INT: case t_FRAC: case t_FRACN:
        !           237:       av=avma; p1=cgetr(prec); gaffect(z,p1); tetpil=avma;
        !           238:       return gerepile(av,tetpil,jbesselintern(n,p1,flag,prec));
        !           239:
        !           240:     case t_QUAD:
        !           241:       av=avma; p1=gmul(z,realun(prec)); tetpil=avma;
        !           242:       return gerepile(av,tetpil,jbesselintern(n,p1,flag,prec));
        !           243:
        !           244:     case t_POL: case t_RFRAC: case t_RFRACN:
        !           245:       av=avma; p1=tayl(z,gvar(z),precdl); tetpil=avma;
        !           246:       return gerepile(av,tetpil,jbesselintern(n,p1,flag,prec));
        !           247:
        !           248:     case t_POLMOD:
        !           249:       av=avma; p1=roots((GEN)z[1],prec); lz=lg(p1); p2=cgetg(lz,t_COL);
        !           250:       for (i=1; i<lz; i++) p2[i]=lpoleval((GEN)z[2],(GEN)p1[i]);
        !           251:       tetpil=avma; y=cgetg(lz,t_COL);
        !           252:       for (i=1; i<lz; i++) y[i]=(long)jbesselintern(n,(GEN)p2[i],flag,prec);
        !           253:       return gerepile(av,tetpil,y);
        !           254:
        !           255:     case t_PADIC:
        !           256:       err(impl,"p-adic jbessel function");
        !           257:   }
        !           258:   err(typeer,"jbessel");
        !           259:   return NULL; /* not reached */
        !           260: }
        !           261:
        !           262: GEN
        !           263: jbessel(GEN n, GEN z, long prec)
        !           264: {
        !           265:   return jbesselintern(n,z,1,prec);
        !           266: }
        !           267:
        !           268: GEN
        !           269: ibessel(GEN n, GEN z, long prec)
        !           270: {
        !           271:   return jbesselintern(n,z,0,prec);
        !           272: }
        !           273:
        !           274: GEN
        !           275: _jbesselh(long k, GEN z, long prec)
        !           276: {
        !           277:   GEN zinv,s,c,p0,p1,p2;
        !           278:   long i;
        !           279:
        !           280:   zinv=ginv(z);
        !           281:   gsincos(z,&s,&c,prec);
        !           282:   p1=gmul(zinv,s);
        !           283:   if (k)
        !           284:   {
        !           285:     p0=p1; p1=gmul(zinv,gsub(p0,c));
        !           286:     for (i=2; i<=k; i++)
        !           287:     {
        !           288:       p2=gsub(gmul(gmulsg(2*i-1,zinv),p1),p0);
        !           289:       p0=p1; p1=p2;
        !           290:     }
        !           291:   }
        !           292:   return p1;
        !           293: }
        !           294:
1.1       noro      295: GEN
1.2     ! noro      296: jbesselh(GEN n, GEN z, long prec)
1.1       noro      297: {
1.2     ! noro      298:   long gz, k, l, linit, i, lz, tz=typ(z);
        !           299:   gpmem_t av, tetpil;
        !           300:   GEN y,p1,p2;
        !           301:
        !           302:   if (typ(n)!=t_INT) err(talker,"not an integer index in jbesselh");
        !           303:   k = itos(n);
        !           304:   if (k < 0)
        !           305:   {
        !           306:     av = avma; n = gadd(ghalf,n); tetpil = avma;
        !           307:     return gerepile(av,tetpil,jbessel(n,z,prec));
        !           308:   }
        !           309:
        !           310:   switch(tz)
1.1       noro      311:   {
1.2     ! noro      312:     case t_REAL: case t_COMPLEX:
        !           313:       av = avma;
        !           314:       if (gcmp0(z))
        !           315:       {
        !           316:        p1 = gmul(gsqrt(gdiv(z,mppi(prec)),prec),gpowgs(z,k));
        !           317:        p1 = gdiv(gmul(mpfact(k),p1),mpfact(2*k+1));
        !           318:        tetpil = avma; return gerepile(av,tetpil,gmul2n(p1,2*k));
        !           319:       }
        !           320:       gz = gexpo(z);
        !           321:       linit = lgcx(z); if (linit==BIGINT) linit = prec;
        !           322:       if (gz>=0) l = linit;
        !           323:       else l = lgcx(z) - 1 + ((-2*k*gz)>>TWOPOTBITS_IN_LONG);
        !           324:       if (l>prec) prec = l;
        !           325:       prec += (-gz)>>TWOPOTBITS_IN_LONG;
        !           326:       z = setlgcx(z,prec);
        !           327:       p1 = _jbesselh(k,z,prec);
        !           328:       p1 = gmul(gsqrt(gdiv(gmul2n(z,1),mppi(prec)),prec),p1);
        !           329:       tetpil = avma; return gerepile(av,tetpil,setlgcx(p1,linit));
        !           330:
        !           331:     case t_SER:
        !           332:       if (gcmp0(z)) return gpowgs(z,k);
        !           333:       av = avma;
        !           334:       if (valp(z) < 0) err(negexper,"jbesselh");
        !           335:       z = gprec(z, lg(z)-2 + (2*k+1)*valp(z));
        !           336:       p1 = gdiv(_jbesselh(k,z,prec),gpowgs(z,k));
        !           337:       for (i=1; i<=k; i++) p1 = gmulgs(p1,2*i+1);
        !           338:       return gerepilecopy(av,p1);
        !           339:
        !           340:     case t_VEC: case t_COL: case t_MAT:
        !           341:       lz=lg(z); y=cgetg(lz,typ(z));
        !           342:       for (i=1; i<lz; i++) y[i]=(long)jbesselh(n,(GEN)z[i],prec);
        !           343:       return y;
        !           344:
        !           345:     case t_INT: case t_FRAC: case t_FRACN:
        !           346:       av=avma; p1=cgetr(prec); gaffect(z,p1); tetpil=avma;
        !           347:       return gerepile(av,tetpil,jbesselh(n,p1,prec));
        !           348:
        !           349:     case t_QUAD:
        !           350:       av=avma; p1=gmul(z,realun(prec)); tetpil=avma;
        !           351:       return gerepile(av,tetpil,jbesselh(n,p1,prec));
        !           352:
        !           353:     case t_POL: case t_RFRAC: case t_RFRACN:
        !           354:       av=avma; p1=tayl(z,gvar(z),precdl); tetpil=avma;
        !           355:       return gerepile(av,tetpil,jbesselh(n,p1,prec));
        !           356:
        !           357:     case t_POLMOD:
        !           358:       av=avma; p1=roots((GEN)z[1],prec); lz=lg(p1); p2=cgetg(lz,t_COL);
        !           359:       for (i=1; i<lz; i++) p2[i]=lpoleval((GEN)z[2],(GEN)p1[i]);
        !           360:       tetpil=avma; y=cgetg(lz,t_COL);
        !           361:       for (i=1; i<lz; i++) y[i]=(long)jbesselh(n,(GEN)p2[i],prec);
        !           362:       return gerepile(av,tetpil,y);
        !           363:
        !           364:     case t_PADIC:
        !           365:       err(impl,"p-adic jbesselh function");
1.1       noro      366:   }
1.2     ! noro      367:   err(typeer,"jbesselh");
1.1       noro      368:   return NULL; /* not reached */
                    369: }
                    370:
                    371: GEN
                    372: kbessel(GEN nu, GEN gx, long prec)
                    373: {
1.2     ! noro      374:   GEN x,y,yfin,p1,p2,zf,zz,s,t,q,r,u,v,e,f,c,d,ak,pitemp,nu2,w;
        !           375:   long l, lnew, lbin, k, k2, l1, n2, n, ex, rab=0;
        !           376:   gpmem_t av, av1;
1.1       noro      377:
                    378:   if (typ(nu)==t_COMPLEX) return kbessel2(nu,gx,prec);
                    379:   l = (typ(gx)==t_REAL)? lg(gx): prec;
1.2     ! noro      380:   ex = gexpo(gx);
        !           381:   if (ex < 0)
        !           382:   {
        !           383:     rab = 1 + ((-ex)>>TWOPOTBITS_IN_LONG);
        !           384:     lnew = l + rab; prec += rab;
        !           385:   }
        !           386:   else lnew = l;
        !           387:   yfin=cgetr(l); l1=lnew+1;
        !           388:   av=avma; x = fix(gx, lnew); y=cgetr(lnew);
1.1       noro      389:   u=cgetr(l1); v=cgetr(l1); c=cgetr(l1); d=cgetr(l1);
                    390:   e=cgetr(l1); f=cgetr(l1);
                    391:   nu2=gmulgs(gsqr(nu),-4);
                    392:   n = (long) (bit_accuracy(l)*LOG2 + PI*sqrt(gtodouble(gnorm(nu)))) / 2;
                    393:   n2=(n<<1); pitemp=mppi(l1);
                    394:   /* this 10 should really be a 5, but then kbessel(15.99) enters oo loop */
                    395:   lbin = 10 - bit_accuracy(l); av1=avma;
                    396:   if (gcmpgs(x,n)<0)
                    397:   {
                    398:     zf=gsqrt(gdivgs(pitemp,n2),prec);
                    399:     zz=cgetr(l1); gaffect(ginv(stoi(n2<<2)), zz);
                    400:     s=gun; t=gzero;
                    401:     for (k=n2,k2=2*n2-1; k > 0; k--,k2-=2)
                    402:     {
                    403:       if (k2 & ~(MAXHALFULONG>>1))
                    404:         p1 = gadd(mulss(k2,k2),nu2);
                    405:       else
                    406:         p1 = gaddsg(k2*k2,nu2);
                    407:       ak=gdivgs(gmul(p1,zz),-k);
                    408:       s=gadd(gun,gmul(ak,s));
                    409:       t=gaddsg(k2,gmul(ak,t));
                    410:     }
                    411:     gmulz(s,zf,u); t=gmul2n(t,-1);
                    412:     gdivgsz(gadd(gmul(t,zf),gmul(u,nu)),-n2,v); avma=av1;
1.2     ! noro      413:     q = stor(n2, l1);
1.1       noro      414:     r=gmul2n(x,1); av1=avma;
                    415:     for(;;)
                    416:     {
                    417:       p1=divsr(5,q); if (expo(p1) >= -1) p1=ghalf;
                    418:       p2=subsr(1,divrr(r,q));
                    419:       if (gcmp(p1,p2)>0) p1=p2;
                    420:       gnegz(p1,c); gaffsg(1,d); affrr(u,e); affrr(v,f);
                    421:       for (k=1; ; k++)
                    422:       {
                    423:        w=gadd(gmul(gsubsg(k,ghalf),u), gmul(subrs(q,k),v));
                    424:        w=gadd(w, gmul(nu,gsub(u,gmul2n(v,1))));
                    425:        gdivgsz(gmul(q,v),k,u);
                    426:        gdivgsz(w,k,v);
                    427:        gmulz(d,c,d);
                    428:        gaddz(e,gmul(d,u),e); p1=gmul(d,v);
                    429:        gaddz(f,p1,f);
                    430:        if (gexpo(p1)-gexpo(f) <= lbin) break;
                    431:        avma=av1;
                    432:       }
                    433:       p1=u; u=e; e=p1;
                    434:       p1=v; v=f; f=p1;
                    435:       gmulz(q,gaddsg(1,c),q);
                    436:       if (expo(subrr(q,r)) <= lbin) break;
                    437:     }
                    438:     gmulz(u,gpui(gdivgs(x,n),nu,prec),y);
                    439:   }
                    440:   else
                    441:   {
                    442:     p2=gmul2n(x,1);
                    443:     zf=gsqrt(gdiv(pitemp,p2),prec);
                    444:     zz=ginv(gmul2n(p2,2)); s=gun;
                    445:     for (k=n2,k2=2*n2-1; k > 0; k--,k2-=2)
                    446:     {
                    447:       if (k2 & ~(MAXHALFULONG>>1))
                    448:         p1=gadd(mulss(k2,k2),nu2);
                    449:       else
                    450:         p1=gaddsg(k2*k2,nu2);
                    451:       ak=gdivgs(gmul(p1,zz),k);
                    452:       s=gsub(gun,gmul(ak,s));
                    453:     }
                    454:     gmulz(s,zf,y);
                    455:   }
1.2     ! noro      456:   gdivz(y,mpexp(x),yfin);
        !           457:   avma=av; return yfin;
        !           458: }
        !           459:
        !           460: /* computes sum_{k=0}^m ((-1)^flag*z^2/4)^k/(k!*(k+n)!)*(H(k)+H(k+n))
        !           461:  +sum_{k=0}^{n-1}((-1)^(flag+1)*z^2/4)^(k-n)*(n-k-1)!/k!. Ici n
        !           462:  doit etre un long. Attention, contrairement a _jbessel, pas de n! devant.
        !           463:  Quand flag > 1, calculer exactement les H(k) et factorielles */
        !           464:
        !           465: static GEN
        !           466: _kbessel(long n, GEN z, long flag, long m, long prec)
        !           467: {
        !           468:   long k, limit;
        !           469:   gpmem_t av;
        !           470:   GEN p1,p2,p3,s,*tabh;
        !           471:
        !           472:   p1 = gmul2n(gsqr(z),-2); if (flag & 1) p1 = gneg(p1);
        !           473:   if (typ(z) == t_SER)
        !           474:   {
        !           475:     long v = valp(z);
        !           476:     k = lg(p1)-2 - v;
        !           477:     if (v < 0) err(negexper,"kbessel");
        !           478:     if (k <= 0) return gadd(gun, zeroser(varn(z), 2*v));
        !           479:     p1 = gprec(p1, k);
        !           480:   }
        !           481:   tabh = (GEN*)cgetg(m+n+2,t_VEC); tabh[1] = gzero;
        !           482:   if (flag <= 1)
        !           483:   {
        !           484:     s = realun(prec); tabh[2] = s;
        !           485:     for (k=2; k<=m+n; k++)
        !           486:     {
        !           487:       s = divrs(addsr(1,mulsr(k,s)),k); tabh[k+1] = s;
        !           488:     }
        !           489:   }
        !           490:   else
        !           491:   {
        !           492:     s = gun; tabh[2] = s;
        !           493:     for (k=2; k<=m+n; k++)
        !           494:     {
        !           495:       s = gdivgs(gaddsg(1,gmulsg(k,s)),k); tabh[k+1] = s;
        !           496:     }
        !           497:   }
        !           498:   s = gadd(tabh[m+1],tabh[m+n+1]);
        !           499:   av = avma; limit = stack_lim(av,1);
        !           500:   for (k=m; k>=1; k--)
        !           501:   {
        !           502:     s = gadd(gadd(tabh[k],tabh[k+n]),gdiv(gmul(p1,s),mulss(k,k+n)));
        !           503:     if (low_stack(limit,stack_lim(av,1)))
        !           504:     {
        !           505:       if (DEBUGMEM>1) err(warnmem,"kbessel");
        !           506:       s = gerepilecopy(av, s);
        !           507:     }
        !           508:   }
        !           509:   p3 = (flag <= 1) ? mpfactr(n,prec) : mpfact(n);
        !           510:   s = gdiv(s,p3);
        !           511:   if (n)
        !           512:   {
        !           513:     p1 = gneg(ginv(p1));
        !           514:     p2 = gmulsg(n,gdiv(p1,p3));
        !           515:     for (k=n-1; k>=0; k--)
        !           516:     {
        !           517:       s = gadd(s,p2);
        !           518:       p2 = gmul(p2,gmul(mulss(k,n-k),p1));
        !           519:     }
        !           520:   }
        !           521:   return s;
        !           522: }
        !           523:
        !           524: static GEN
        !           525: kbesselintern(GEN n, GEN z, long flag, long prec)
        !           526: {
        !           527:   long tz=typ(z), i, k, ki, lz, lim, precnew, fl, fl2, ex;
        !           528:   gpmem_t av=avma, tetpil;
        !           529:   double B,N,L,x,rab;
        !           530:   GEN p1,p2,y,p3,znew,nnew,pplus,pmoins,s,c;
        !           531:
        !           532:   fl = (flag & 1) == 0;
        !           533:   switch(tz)
        !           534:   {
        !           535:     case t_REAL: case t_COMPLEX:
        !           536:       if (gcmp0(z)) err(talker,"zero argument in a k/n bessel function");
        !           537:       i = precision(z); if (i) prec = i;
        !           538:       x = gtodouble(gabs(z,prec));
        !           539: /* Experimentally optimal on a PIII 500 Mhz. Your optimum may vary. */
        !           540:       if ((x > (8*(prec-2)+norml1(n,prec)-3)) && !flag) return kbessel(n,z,prec);
        !           541:       precnew  = prec;
        !           542:       if (x >= 1.0)
        !           543:       {
        !           544:        rab = x/(LOG2*BITS_IN_LONG); if (fl) rab *= 2;
        !           545:        precnew += 1 + (long)rab;
        !           546:       }
        !           547:       znew = setlgcx(z,precnew);
        !           548:       if (isint(setlgcx2(n,precnew),&ki))
        !           549:       {
        !           550:        k = labs(ki);
        !           551:        L = x*1.3591409;
        !           552:        B = (bit_accuracy(prec)*LOG2)/(2*L);
        !           553:        if (fl) B += 0.367879;
        !           554:        N = 1 + B;
        !           555: /* 3 Newton iterations are enough except in pathological cases */
        !           556:        N = (N + B)/(log(N)+1); N = (N + B)/(log(N)+1); N = (N + B)/(log(N)+1);
        !           557:        lim = max((long)(L*N),2);
        !           558:        p1 = _kbessel(k,znew,flag,lim,precnew);
        !           559:        p1 = gmul(gpowgs(gmul2n(znew,-1),k),p1);
        !           560:        p2 = gadd(mpeuler(precnew),glog(gmul2n(znew,-1),precnew));
        !           561:        p3 = jbesselintern(stoi(k),znew,flag,precnew);
        !           562:        p2 = gsub(gmul2n(p1,-1),gmul(p2,p3));
        !           563:        p2 = setlgcx(p2,prec);
        !           564:        if (fl == 0) {p1 = mppi(prec); p2 = gmul2n(gdiv(p2,p1),1);}
        !           565:        fl = (fl && (k&1)) || (!fl && (ki>=0 || (k&1)==0));
        !           566:        tetpil = avma; return gerepile(av,tetpil,fl ? gneg(p2) : gcopy(p2));
        !           567:       }
        !           568:       else
        !           569:       {
        !           570:        i = precision(n);
        !           571:        nnew = (i && (i < precnew)) ? setlgcx(n,precnew) : n;
        !           572:        p2 = mppi(precnew); gsincos(gmul(nnew,p2),&s,&c,precnew);
        !           573:        ex = gexpo(s);
        !           574:         if (ex < 0)
        !           575:         {
        !           576:           rab = (-ex)/(LOG2*BITS_IN_LONG); if (fl) rab *= 2;
        !           577:           precnew += 1 + (long)rab;
        !           578:         }
        !           579:        nnew = (i && (i < precnew)) ? setlgcx(n,precnew) : n;
        !           580:        znew = setlgcx(znew,precnew);
        !           581:        p2 = mppi(precnew); gsincos(gmul(nnew,p2),&s,&c,precnew);
        !           582:        pplus = jbesselintern(nnew,znew,flag,precnew);
        !           583:        pmoins = jbesselintern(gneg(nnew),znew,flag,precnew);
        !           584:        if (fl) p1 = gmul(gsub(pmoins,pplus),gdiv(p2,gmul2n(s,1)));
        !           585:        else p1 = gdiv(gsub(gmul(c,pplus),pmoins),s);
        !           586:        tetpil = avma; return gerepile(av,tetpil,setlgcx(p1,prec));
        !           587:       }
        !           588:
        !           589:     case t_SER:
        !           590:       if (isint(setlgcx2(n,prec),&ki))
        !           591:       {
        !           592:        k = labs(ki);
        !           593:        p1 = _kbessel(k,z,flag+2,lg(z)-2,prec);
        !           594:        return gerepilecopy(av,p1);
        !           595:       }
        !           596:       else
        !           597:       {
        !           598:        fl2 = isint(setlgcx2(gmul2n(n,1),prec),&ki);
        !           599:        if (!fl2)
        !           600:          err(talker,"cannot give a power series result in k/n bessel function");
        !           601:        else
        !           602:        {
        !           603:          k = labs(ki); n = gmul2n(stoi(k),-1);
        !           604:          fl2 = (k&3)==1;
        !           605:          pmoins = jbesselintern(gneg(n),z,flag,prec);
        !           606:          if (fl)
        !           607:          {
        !           608:            pplus = jbesselintern(n,z,flag,prec);
        !           609:            p2 = gpowgs(z,-k); if (fl2 == 0) p2 = gneg(p2);
        !           610:            p3 = gmul2n(divii(mpfact(k + 1),mpfact((k + 1) >> 1)),-(k + 1));
        !           611:            p3 = gdivgs(gmul2n(gsqr(p3),1),k);
        !           612:            p2 = gmul(p2,p3);
        !           613:            p1 = gsub(pplus,gmul(p2,pmoins));
        !           614:          }
        !           615:          else p1 = pmoins;
        !           616:          tetpil = avma;
        !           617:          return gerepile(av,tetpil,fl2 ? gneg(p1) : gcopy(p1));
        !           618:        }
        !           619:       }
        !           620:
        !           621:     case t_VEC: case t_COL: case t_MAT:
        !           622:       lz=lg(z); y=cgetg(lz,typ(z));
        !           623:       for (i=1; i<lz; i++)
        !           624:        y[i]=(long)kbesselintern(n,(GEN)z[i],flag,prec);
        !           625:       return y;
        !           626:
        !           627:     case t_INT: case t_FRAC: case t_FRACN:
        !           628:       av=avma; p1=cgetr(prec); gaffect(z,p1); tetpil=avma;
        !           629:       return gerepile(av,tetpil,kbesselintern(n,p1,flag,prec));
        !           630:
        !           631:     case t_QUAD:
        !           632:       av=avma; p1=gmul(z,realun(prec)); tetpil=avma;
        !           633:       return gerepile(av,tetpil,kbesselintern(n,p1,flag,prec));
        !           634:
        !           635:     case t_POL: case t_RFRAC: case t_RFRACN:
        !           636:       av=avma; p1=tayl(z,gvar(z),precdl); tetpil=avma;
        !           637:       return gerepile(av,tetpil,kbesselintern(n,p1,flag,prec));
        !           638:
        !           639:     case t_POLMOD:
        !           640:       av=avma; p1=roots((GEN)z[1],prec); lz=lg(p1); p2=cgetg(lz,t_COL);
        !           641:       for (i=1; i<lz; i++) p2[i]=lpoleval((GEN)z[2],(GEN)p1[i]);
        !           642:       tetpil=avma; y=cgetg(lz,t_COL);
        !           643:       for (i=1; i<lz; i++) y[i]=(long)kbesselintern(n,(GEN)p2[i],flag,prec);
        !           644:       return gerepile(av,tetpil,y);
        !           645:
        !           646:     case t_PADIC:
        !           647:       err(impl,"p-adic kbessel function");
        !           648:   }
        !           649:   err(typeer,"kbessel");
        !           650:   return NULL; /* not reached */
        !           651: }
        !           652:
        !           653: GEN
        !           654: kbesselnew(GEN n, GEN z, long prec)
        !           655: {
        !           656:   return kbesselintern(n,z,0,prec);
        !           657: }
        !           658:
        !           659: GEN
        !           660: kbesselnewalways(GEN n, GEN z, long prec)
        !           661: {
        !           662:   return kbesselintern(n,z,2,prec);
        !           663: }
        !           664:
        !           665: GEN
        !           666: nbessel(GEN n, GEN z, long prec)
        !           667: {
        !           668:   return kbesselintern(n,z,1,prec);
        !           669: }
        !           670:
        !           671: GEN
        !           672: hbessel1(GEN n, GEN z, long prec)
        !           673: {
        !           674:   gpmem_t av=avma, tetpil;
        !           675:   GEN p1,p2;
        !           676:
        !           677:   p1 = jbessel(n,z,prec); p2 = gmul(gi,nbessel(n,z,prec));
        !           678:   tetpil = avma; return gerepile(av,tetpil,gadd(p1,p2));
        !           679: }
        !           680:
        !           681: GEN
        !           682: hbessel2(GEN n, GEN z, long prec)
        !           683: {
        !           684:   gpmem_t av=avma, tetpil;
        !           685:   GEN p1,p2;
        !           686:
        !           687:   p1 = jbessel(n,z,prec); p2 = gmul(gi,nbessel(n,z,prec));
        !           688:   tetpil = avma; return gerepile(av,tetpil,gsub(p1,p2));
        !           689: }
        !           690:
        !           691: GEN kbessel2(GEN nu, GEN x, long prec);
        !           692:
        !           693: GEN
        !           694: kbessel0(GEN nu, GEN gx, long flag, long prec)
        !           695: {
        !           696:   switch(flag)
        !           697:   {
        !           698:     case 0: return kbesselnew(nu,gx,prec);
        !           699:     case 1: return kbessel(nu,gx,prec);
        !           700:     case 2: return kbessel2(nu,gx,prec);
        !           701:     case 3: return kbesselnewalways(nu,gx,prec);
        !           702:     default: err(flagerr,"besselk");
        !           703:   }
        !           704:   return NULL; /* not reached */
1.1       noro      705: }
                    706:
                    707: /***********************************************************************/
                    708: /*                                                                    **/
                    709: /**                    FONCTION U(a,b,z) GENERALE                     **/
                    710: /**                         ET CAS PARTICULIERS                       **/
                    711: /**                                                                   **/
                    712: /***********************************************************************/
                    713: /* Assume gx > 0 and a,b complex */
                    714: /* This might one day be extended to handle complex gx */
                    715: /* see Temme, N. M. "The numerical computation of the confluent        */
                    716: /* hypergeometric function U(a,b,z)" in Numer. Math. 41 (1983),        */
                    717: /* no. 1, 63--82.                                                      */
                    718: GEN
                    719: hyperu(GEN a, GEN b, GEN gx, long prec)
                    720: {
                    721:   GEN x,y,p1,p2,p3,zf,zz,s,t,q,r,u,v,e,f,c,d,w,a1,gn;
1.2     ! noro      722:   long l, lbin, k, l1, n, ex;
        !           723:   gpmem_t av, av1, av2;
1.1       noro      724:
                    725:   if(gsigne(gx) <= 0) err(talker,"hyperu's third argument must be positive");
                    726:   ex = (iscomplex(a) || iscomplex(b));
                    727:
                    728:   l = (typ(gx)==t_REAL)? lg(gx): prec;
                    729:   if (ex) y=cgetc(l); else y=cgetr(l);
                    730:   l1=l+1; av=avma; x = fix(gx, l);
                    731:   a1=gaddsg(1,gsub(a,b));
                    732:   if (ex)
                    733:   {
                    734:     u=cgetc(l1); v=cgetc(l1); c=cgetc(l1);
                    735:     d=cgetc(l1); e=cgetc(l1); f=cgetc(l1);
                    736:   }
                    737:   else
                    738:   {
                    739:     u=cgetr(l1); v=cgetr(l1); c=cgetr(l1);
                    740:     d=cgetr(l1); e=cgetr(l1); f=cgetr(l1);
                    741:   }
                    742:   n=(long)(bit_accuracy(l)*LOG2 + PI*sqrt(gtodouble(gabs(gmul(a,a1),l1))));
                    743:   lbin = 10-bit_accuracy(l); av1=avma;
                    744:   if (gcmpgs(x,n)<0)
                    745:   {
                    746:     gn=stoi(n); zf=gpui(gn,gneg_i(a),l1);
                    747:     zz=gdivsg(-1,gn); s=gun; t=gzero;
                    748:     for (k=n-1; k>=0; k--)
                    749:     {
                    750:       p1=gdivgs(gmul(gmul(gaddgs(a,k),gaddgs(a1,k)),zz),k+1);
                    751:       s=gaddsg(1,gmul(p1,s));
                    752:       t=gadd(gaddsg(k,a),gmul(p1,t));
                    753:     }
                    754:     gmulz(s,zf,u); t=gmul(t,zz); gmulz(t,zf,v); avma=av1;
1.2     ! noro      755:     q = stor(n, l1); r=x; av1=avma;
1.1       noro      756:     do
                    757:     {
                    758:       p1=divsr(5,q); if (expo(p1)>= -1) p1=ghalf;
                    759:       p2=subsr(1,divrr(r,q)); if (gcmp(p1,p2)>0) p1=p2;
                    760:       gnegz(p1,c); avma=av1;
                    761:       k=0; gaffsg(1,d);
                    762:       gaffect(u,e); gaffect(v,f);
                    763:       p3=gsub(q,b); av2=avma;
                    764:       for(;;)
                    765:       {
                    766:        w=gadd(gmul(gaddsg(k,a),u),gmul(gaddsg(-k,p3),v));
                    767:        k++; gdivgsz(gmul(q,v),k,u);
                    768:        gdivgsz(w,k,v);
                    769:        gmulz(d,c,d);
                    770:        gaddz(e,gmul(d,u),e); p1=gmul(d,v);
                    771:        gaddz(f,p1,f);
                    772:        if (gexpo(p1)-gexpo(f) <= lbin) break;
                    773:        avma=av2;
                    774:       }
                    775:       p1=u; u=e; e=p1;
                    776:       p1=v; v=f; f=p1;
                    777:       gmulz(q,gadd(gun,c),q);
                    778:       p1=subrr(q,r); ex=expo(p1); avma=av1;
                    779:     }
                    780:     while (ex>lbin);
                    781:   }
                    782:   else
                    783:   {
                    784:     zf=gpui(x,gneg_i(a),l1);
                    785:     zz=gdivsg(-1,x); s=gun;
                    786:     for (k=n-1; k>=0; k--)
                    787:     {
                    788:       p1=gdivgs(gmul(gmul(gaddgs(a,k),gaddgs(a1,k)),zz),k+1);
                    789:       s=gadd(gun,gmul(p1,s));
                    790:     }
                    791:     u = gmul(s,zf);
                    792:   }
                    793:   gaffect(u,y); avma=av; return y;
                    794: }
                    795:
                    796: GEN
                    797: kbessel2(GEN nu, GEN x, long prec)
                    798: {
1.2     ! noro      799:   gpmem_t av = avma, tetpil;
1.1       noro      800:   GEN p1,p2,x2,a,pitemp;
                    801:
                    802:   if (typ(x)==t_REAL) prec = lg(x);
                    803:   x2=gshift(x,1); pitemp=mppi(prec);
                    804:   if (gcmp0(gimag(nu))) a=cgetr(prec); else a=cgetc(prec);
                    805:   gaddz(gun,gshift(nu,1),a);
                    806:   p1=hyperu(gshift(a,-1),a,x2,prec);
                    807:   p1=gmul(gmul(p1,gpui(x2,nu,prec)),mpsqrt(pitemp));
                    808:   p2=gexp(x,prec); tetpil=avma;
                    809:   return gerepile(av,tetpil,gdiv(p1,p2));
                    810: }
                    811:
                    812: GEN
                    813: incgam(GEN s, GEN x, long prec)
                    814: {
                    815:   GEN p1,z = cgetr(prec);
1.2     ! noro      816:   gpmem_t av = avma;
1.1       noro      817:
                    818:   if (gcmp0(x)) return ggamma(s,prec);
                    819:   if (typ(x)!=t_REAL) { gaffect(x,z); x=z; }
                    820:   if (gcmp(subrs(x,1),s) > 0 || gsigne(greal(s)) <= 0)
                    821:     p1 = incgam2(s,x,prec);
                    822:   else
                    823:     p1 = gsub(ggamma(s,prec), incgam3(s,x,prec));
                    824:   affrr(p1,z); avma = av; return z;
                    825: }
                    826:
                    827: /* = incgam2(0, x, prec). typ(x) = t_REAL. Optimized for eint1 */
                    828: static GEN
                    829: incgam2_0(GEN x)
                    830: {
                    831:   long l,n,i;
                    832:   GEN p1;
                    833:   double m,mx;
                    834:
                    835:   l = lg(x); mx = rtodbl(x);
                    836:   m = (bit_accuracy(l)*LOG2 + mx)/4; n=(long)(1+m*m/mx);
                    837:   p1 = divsr(-n, addsr(n<<1,x));
                    838:   for (i=n-1; i >= 1; i--)
                    839:     p1 = divsr(-i, addrr(addsr(i<<1,x), mulsr(i,p1)));
                    840:   return mulrr(divrr(mpexp(negr(x)), x), addrr(realun(l),p1));
                    841: }
                    842:
                    843: GEN
                    844: incgam1(GEN a, GEN x, long prec)
                    845: {
                    846:   GEN p2,p3,y, z = cgetr(prec);
1.2     ! noro      847:   long l, n, i;
        !           848:   gpmem_t av=avma, av1;
1.1       noro      849:   double m,mx;
                    850:
                    851:   if (typ(x) != t_REAL) { gaffect(x,z); x=z; }
                    852:   l=lg(x); mx=rtodbl(x);
                    853:   m=(long) bit_accuracy(l)*LOG2; n=(long)(m/(log(m)-(1+log(mx))));
                    854:   p2 = cgetr(l); affrr(addir(gun,gsub(x,a)), p2);
                    855:   p3 = subrs(p2, n+1); av1 = avma;
                    856:   for (i=n; i>=1; i--)
                    857:   {
                    858:     affrr(addrr(subrs(p2,i), divrr(mulsr(i,x),p3)), p3);
                    859:     avma = av1;
                    860:   }
                    861:   y = mulrr(mpexp(negr(x)),gpui(x,a,prec));
                    862:   affrr(divrr(y,p3), z);
                    863:   avma = av; return z;
                    864: }
                    865:
                    866: /* assume x != 0 */
                    867: GEN
                    868: incgam2(GEN a, GEN x, long prec)
                    869: {
                    870:   GEN b,p1,p2,p3,y, z = cgetr(prec);
1.2     ! noro      871:   long l, n, i;
        !           872:   gpmem_t av = avma, av1;
1.1       noro      873:   double m,mx;
                    874:
                    875:   if (typ(x) != t_REAL) { gaffect(x,z); x=z; }
                    876:   if (gcmp0(a)) { affrr(incgam2_0(x), z); avma = av; return z; }
                    877:   l=lg(x); mx=rtodbl(x);
                    878:   m = (bit_accuracy(l)*LOG2 + mx)/4; n=(long)(1+m*m/mx);
                    879:   i = typ(a);
                    880:   if (i == t_REAL) b = addsr(-1,a);
                    881:   else
                    882:   { /* keep b integral : final powering more efficient */
                    883:     gaffect(a,p1=cgetr(prec));
                    884:     b = (i == t_INT)? addsi(-1,a): addsr(-1,p1);
                    885:     a = p1;
                    886:   }
                    887:   p2 = cgetr(l); gaffect(subrr(x,a),p2);
                    888:   p3 = divrr(addsr(-n,a), addrs(p2,n<<1));
                    889:   av1 = avma;
                    890:   for (i=n-1; i>=1; i--)
                    891:   {
                    892:     affrr(divrr(addsr(-i,a), addrr(addrs(p2,i<<1),mulsr(i,p3))), p3);
                    893:     avma = av1;
                    894:   }
                    895:   y = gmul(mpexp(negr(x)), gpui(x,b,prec));
                    896:   affrr(mulrr(y, addsr(1,p3)), z);
                    897:   avma = av; return z;
                    898: }
                    899:
                    900: GEN
                    901: incgam3(GEN s, GEN x, long prec)
                    902: {
                    903:   GEN b,p1,p2,p3,y, z = cgetr(prec);
1.2     ! noro      904:   long l, n, i;
        !           905:   gpmem_t av = avma, av1;
1.1       noro      906:
                    907:   if (typ(x) != t_REAL) { gaffect(x,z); x=z; }
                    908:   l=lg(x); n = -bit_accuracy(l)-1;
                    909:   p3 = realun(l);
                    910:   p2 = rcopy(p3);
                    911:   i = typ(s);
                    912:   if (i == t_REAL) b = s;
                    913:   else
                    914:   {
                    915:     gaffect(s,p1=cgetr(prec));
                    916:     b = (i == t_INT)? s: p1;
                    917:     s = p1;
                    918:   }
                    919:   if (signe(s) <= 0)
                    920:   {
                    921:     p1 = gcvtoi(s, &i);
                    922:     if (i < 5 - bit_accuracy(prec))
                    923:       err(talker,"negative argument too close to an integer in incgamc");
                    924:   }
                    925:   av1 = avma;
                    926:   for (i=1; expo(p2) >= n; i++)
                    927:   {
                    928:     affrr(divrr(mulrr(x,p2), addsr(i,s)), p2);
                    929:     affrr(addrr(p2,p3), p3); avma = av1;
                    930:   }
                    931:   y = gdiv(mulrr(mpexp(negr(x)), gpui(x,b,prec)), s);
                    932:   affrr(mulrr(y,p3), z);
                    933:   avma = av; return z;
                    934: }
                    935:
                    936: /* Assumes that g=gamma(a,prec). Unchecked */
                    937: GEN
                    938: incgam4(GEN a, GEN x, GEN g, long prec)
                    939: {
                    940:   GEN p1, z = cgetr(prec);
1.2     ! noro      941:   gpmem_t av = avma;
1.1       noro      942:
                    943:   if (typ(x) != t_REAL) { gaffect(x,z); x=z; }
                    944:   if (gcmp(subrs(x,1),a) > 0 || gsigne(greal(a)) <= 0)
                    945:     p1 = incgam2(a,x,prec);
                    946:   else
                    947:     p1 = gsub(g, incgam3(a,x,prec));
                    948:   affrr(p1, z);
                    949:   avma = av; return z;
                    950: }
                    951:
                    952: GEN
                    953: incgam0(GEN a, GEN x, GEN z,long prec)
                    954: {
                    955:   return z? incgam4(a,x,z,prec): incgam(a,x,prec);
                    956: }
                    957:
                    958: GEN
                    959: eint1(GEN x, long prec)
                    960: {
1.2     ! noro      961:   long l, n, i;
        !           962:   gpmem_t av = avma, tetpil;
1.1       noro      963:   GEN p1,p2,p3,p4,run,y;
                    964:
                    965:   if (typ(x) != t_REAL) { gaffect(x,p1=cgetr(prec)); x = p1;}
                    966:   if (signe(x) >= 0)
                    967:   {
                    968:     if (expo(x) >= 4)
                    969:       return gerepileupto(av, incgam2_0(x));
                    970:
                    971:     l = lg(x);
                    972:     n = -bit_accuracy(l)-1;
                    973:
                    974:     run = realun(l);
                    975:     p4 = p3 = p2 = p1 = run;
                    976:     for (i=2; expo(p2)>=n; i++)
                    977:     {
                    978:       p1 = addrr(p1,divrs(run,i)); /* p1 = sum_{i=1} 1/i */
                    979:       p4 = divrs(mulrr(x,p4),i);   /* p4 = sum_{i=1} x^(i-1)/i */
                    980:       p2 = mulrr(p4,p1);
                    981:       p3 = addrr(p2,p3);
                    982:     }
                    983:     p3 = mulrr(x,mulrr(mpexp(negr(x)),p3));
                    984:     p1 = addrr(mplog(x), mpeuler(l));
                    985:     return gerepileupto(av, subrr(p3,p1));
                    986:   }
                    987:   else
                    988:   { /* written by Manfred Radimersky */
                    989:     l  = lg(x);
                    990:     n  = bit_accuracy(l);
                    991:     /* IS: line split to avoid a Workshop cc-5.0 bug (Sun BugID #4254959) */
                    992:     n  = 3 * n / 4;
                    993:     y  = negr(x);
                    994:     if(gcmpgs(y, n) < 0) {
                    995:       p1 = p2 = p3 = y;
                    996:       p4 = gzero;
                    997:       i  = 2;
                    998:       while(gcmp(p3, p4)) {
                    999:         p4 = p3;
                   1000:         p1 = gmul(p1, gdivgs(y, i));
                   1001:         p2 = gdivgs(p1, i);
                   1002:         p3 = gadd(p3, p2);
                   1003:         i++;
                   1004:       }
                   1005:       p1 = gadd(mplog(y), mpeuler(l));
                   1006:       y  = gadd(p3, p1);
                   1007:     } else {
                   1008:       p1 = gdivsg(1, y);
                   1009:       p2 = realun(l);
                   1010:       p3 = p2;
                   1011:       p4 = gzero;
                   1012:       i  = 1;
                   1013:       while(gcmp(p3, p4)) {
                   1014:         p4 = p3;
                   1015:         p2 = gmulgs(p2, i);
                   1016:         p2 = gmul(p2, p1);
                   1017:         p3 = gadd(p3, p2);
                   1018:         i++;
                   1019:       }
                   1020:       p1 = gdiv(mpexp(y), y);
                   1021:       y  = gmul(p3, p1);
                   1022:     }
                   1023:     tetpil = avma;
                   1024:     y  = gerepile(av, tetpil, negr(y));
                   1025:   }
                   1026:   return y;
                   1027: }
                   1028:
                   1029: GEN
                   1030: veceint1(GEN C, GEN nmax, long prec)
                   1031: {
1.2     ! noro     1032:   long k, n, nstop, i, cd, nmin, G, a, chkpoint;
        !          1033:   gpmem_t av, av1;
1.1       noro     1034:   GEN y,e1,e2,F0,F,M2,f,den,minvn,mcn,p1,vdiff,ap,unr,zeror,deninit;
                   1035:
                   1036:   if (!nmax) return eint1(C,prec);
                   1037:
                   1038:   if (signe(nmax)<=0) return cgetg(1,t_VEC);
                   1039:   if (DEBUGLEVEL>1) fprintferr("Entering veceint1:\n");
                   1040:   if (typ(C) != t_REAL || lg(C) > prec)
                   1041:     { y = cgetr(prec); gaffect(C,y); C = y; }
                   1042:   if (signe(C) <= 0) err(talker,"negative or zero constant in veceint1");
                   1043:
                   1044:   G = -bit_accuracy(prec);
                   1045:   n=itos(nmax); y=cgetg(n+1,t_VEC);
                   1046:   for(i=1; i<=n; i++) y[i]=lgetr(prec);
                   1047:   av=avma;
                   1048:
                   1049:   nstop = itos(gceil(divsr(4,C)));
                   1050:   if (nstop<1) nstop=1;
                   1051:   if (nstop>n) nstop=n;
                   1052:   nmin=n-10; if (nmin<nstop) nmin=nstop;
                   1053:   if(DEBUGLEVEL>1) fprintferr("nstop = %ld\n",nstop);
                   1054:
                   1055:   e1=mpexp(negr(mulsr(n,C)));
                   1056:   e2=mpexp(mulsr(10,C));
                   1057:   unr = realun(prec);
                   1058:   zeror=realzero(prec); deninit=negr(unr);
                   1059:   f=cgetg(3,t_COL); M2=cgetg(3,t_VEC); av1=avma;
                   1060:
                   1061:   F0=(GEN)y[n]; chkpoint = n;
                   1062:   affrr(eint1(mulsr(n,C),prec), F0);
                   1063:   do
                   1064:   {
                   1065:     if (DEBUGLEVEL>1 && n < chkpoint)
                   1066:       { fprintferr("%ld ",n) ; chkpoint -= (itos(nmax) / 20); }
                   1067:     minvn=divrs(unr,-n); mcn=mulrr(C,minvn);
                   1068:     M2[1] = (long)zeror; M2[2] = lsubrr(minvn,C);
                   1069:     f[1]=(long)zeror; f[2]=ldivrs(e1,-n);
                   1070:     affrr(mulrr(e1,e2), e1);
                   1071:     vdiff=cgetg(2,t_VEC); vdiff[1]=f[2];
                   1072:     for (cd=a=1,n--; n>=nmin; n--,a++)
                   1073:     {
                   1074:       F = F0;
                   1075:       ap = stoi(a); den = deninit;
                   1076:       for (k=1;;)
                   1077:       {
                   1078:        if (k>cd)
                   1079:         {
                   1080:           cd++; p1 = (GEN)f[2];
                   1081:           f[2] = lmul(M2,f);
                   1082:           f[1] = (long)p1;
                   1083:           M2[1] = laddrr((GEN)M2[1],mcn);
                   1084:           M2[2] = laddrr((GEN)M2[2],minvn);
                   1085:           vdiff = concatsp(vdiff,(GEN)f[2]);
                   1086:         }
                   1087:        p1 = mulrr(mulri(den,ap),(GEN)vdiff[k]);
                   1088:         if (expo(p1) < G) { affrr(F,(GEN)y[n]); break; }
                   1089:        F = addrr(F,p1); ap = mulis(ap,a);
                   1090:        k++; den = divrs(den,-k);
                   1091:       }
                   1092:     }
                   1093:     avma=av1; n++; F0=(GEN)y[n]; nmin -= 10;
                   1094:     if (nmin < nstop) nmin=nstop;
                   1095:   }
                   1096:   while(n>nstop);
                   1097:   for(i=1; i<=nstop; i++)
                   1098:     affrr(eint1(mulsr(i,C),prec), (GEN)y[i]);
                   1099:   if (DEBUGLEVEL>1) fprintferr("\n");
                   1100:   avma=av; return y;
                   1101: }
                   1102:
                   1103: GEN
                   1104: gerfc(GEN x, long prec)
                   1105: {
1.2     ! noro     1106:   gpmem_t av=avma;
1.1       noro     1107:   GEN p1,p2;
                   1108:
                   1109:   if (typ(x)!=t_REAL) { p1=cgetr(prec); gaffect(x,p1); x=p1; }
                   1110:   av = avma; p1 = incgam(ghalf,gsqr(x),prec);
                   1111:   p2 = mpsqrt(mppi(lg(x)));
                   1112:   p1 = divrr(p1,p2);
                   1113:   if (signe(x) < 0) p1 = subsr(2,p1);
                   1114:   return gerepileupto(av,p1);
                   1115: }
                   1116:
                   1117: /***********************************************************************/
                   1118: /**                                                                  **/
                   1119: /**                    FONCTION ZETA DE RIEMANN                      **/
                   1120: /**                                                                  **/
                   1121: /***********************************************************************/
                   1122:
                   1123: #if 0
                   1124: static GEN
                   1125: czeta(GEN s, long prec)
                   1126: {
1.2     ! noro     1127:   long n, p, n1, flag1, flag2, i, i2;
        !          1128:   gpmem_t av;
1.1       noro     1129:   double st,sp,sn,ssig,ns,alpha,beta,maxbeta,xinf;
                   1130:   GEN y,z,res,sig,ms,p1,p2,p3,p31,pitemp;
                   1131:
                   1132:   i=precision(s); if (i) prec = i;
                   1133:   if (typ(s)==t_COMPLEX)
                   1134:   {
                   1135:     res = cgetc(prec); av=avma;
                   1136:     p1 = cgetc(prec+1);
                   1137:     gaffect(s,p1); s=p1; sig=(GEN)s[1];
                   1138:   }
                   1139:   else
                   1140:   {
                   1141:     res = cgetr(prec); av=avma;
                   1142:     p1 = cgetr(prec+1); affrr(s,p1); sig = s = p1;
                   1143:   }
                   1144:
                   1145:   if (signe(sig)>0 && expo(sig)>-2) flag1 = 0;
                   1146:   else
                   1147:   {
                   1148:     if (gcmp0(gimag(s)) && gcmp0(gfrac(gmul2n(sig,-1))))
                   1149:     {
                   1150:       if (gcmp0(sig)) gaffect(gneg_i(ghalf),res); else gaffsg(0,res);
                   1151:       avma=av; return res;
                   1152:     }
                   1153:     flag1 = 1; s = gsub(gun,s); sig = greal(s);
                   1154:   }
                   1155:   ssig=rtodbl(sig); st=fabs(rtodbl(gimag(s))); maxbeta = pow(3.0,-2.5);
                   1156:   if (st)
                   1157:   {
                   1158:     ns = ssig*ssig + st*st;
                   1159:     alpha=pariC2*(prec-2)-0.39-0.5*(ssig-1.0)*log(ns)-log(ssig)+ssig*2*pariC1;
                   1160:     beta=(alpha+ssig)/st-atan(ssig/st);
                   1161:     if (beta<=0)
                   1162:     {
                   1163:       if (ssig>=1.0)
                   1164:       {
                   1165:        p=0; sn=sqrt(ns);
                   1166:        n=(long)(ceil(exp(pariC2*(prec-2)/ssig)*pow(sn/(2*ssig),1.0/ssig)));
                   1167:       }
                   1168:       else
                   1169:       {
                   1170:        p=1; sn=ssig+1; n=(long)ceil(sqrt(sn*sn+st*st)/(2*PI));
                   1171:       }
                   1172:     }
                   1173:     else
                   1174:     {
                   1175:       if (beta<maxbeta) xinf=beta+pow(3*beta,1.0/3.0);
                   1176:       else
                   1177:       {
                   1178:        double eps=0.0087, x00 = beta+PI/2.0, y00,x11;
                   1179:         for(;;)
                   1180:        {
                   1181:          y00=x00*x00; x11=(beta+atan(x00))*(1+y00)/y00-1/x00;
                   1182:          if (x00-x11 < eps) break;
                   1183:          x00 = x11;
                   1184:        }
                   1185:        xinf=x11;
                   1186:       }
                   1187:       sp=1.0-ssig+st*xinf;
                   1188:       if (sp>0)
                   1189:       {
                   1190:        p=(long)ceil(sp/2.0); sn=ssig+2*p-1;
                   1191:        n=(long)ceil(sqrt(sn*sn+st*st)/(2*PI));
                   1192:       }
                   1193:       else
                   1194:       {
                   1195:        p=0; sn=sqrt(ns);
                   1196:        n=(long)ceil(exp(pariC2*(prec-2)/ssig)*pow(sn/(2*ssig),1.0/ssig));
                   1197:       }
                   1198:     }
                   1199:   }
                   1200:   else
                   1201:   {
                   1202:     beta=pariC2*(prec-2)+0.61+ssig*2*pariC1-ssig*log(ssig);
                   1203:     if (beta>0)
                   1204:     {
                   1205:       p=(long)ceil(beta/2.0); sn=ssig+2*p-1;
                   1206:       n=(long)ceil(sqrt(sn*sn+st*st)/(2*PI));
                   1207:     }
                   1208:     else
                   1209:     {
                   1210:       p=0; sn=sqrt(ssig*ssig+st*st);
                   1211:       n=(long)ceil(exp(pariC2*(prec-2)/ssig)*pow(sn/(2*ssig),1.0/ssig));
                   1212:     }
                   1213:   }
                   1214:   if (n < 46340) n1=n*n; else n1=0;
                   1215:   y=gun; ms=gneg_i(s); p1=cgetr(prec+1); p2=gun;
                   1216:   for (i=2; i<=n; i++)
                   1217:   {
                   1218:     affsr(i,p1); p2 = gexp(gmul(ms,mplog(p1)), prec+1);
                   1219:     y = gadd(y,p2);
                   1220:   }
                   1221:   flag2 = (2*p < 46340);
                   1222:   mpbern(p,prec+1); p31=cgetr(prec+1); z=gzero;
                   1223:   for (i=p; i>=1; i--)
                   1224:   {
                   1225:     i2=i<<1;
                   1226:     p1=gmul(gaddsg(i2-1,s),gaddsg(i2,s));
                   1227:     p1=flag2? gdivgs(p1,i2*(i2+1)): gdivgs(gdivgs(p1,i2),i2+1);
                   1228:     p1=n1? gdivgs(p1,n1): gdivgs(gdivgs(p1,n),n);
                   1229:     p3 = bern(i);
                   1230:     if (bernzone[2]>prec+1) { affrr(p3,p31); p3=p31; }
                   1231:     z=gadd(divrs(p3,i),gmul(p1,z));
                   1232:   }
                   1233:   p1=gsub(gdivsg(n,gsubgs(s,1)),ghalf);
                   1234:   z=gmul(gadd(p1,gmul(s,gdivgs(z,n<<1))),p2);
                   1235:   y = gadd(y,z);
                   1236:   if (flag1)
                   1237:   {
                   1238:     pitemp=mppi(prec+1); setexpo(pitemp,2);
                   1239:     y=gmul(gmul(y,ggamma(s,prec+1)),gpui(pitemp,ms,prec+1));
                   1240:     setexpo(pitemp,0);
                   1241:     y=gmul2n(gmul(y,gcos(gmul(pitemp,s),prec+1)),1);
                   1242:   }
                   1243:   gaffect(y,res); avma = av; return res;
                   1244: }
                   1245:
                   1246: /* y = binomial(n,k-2). Return binomial(n,k) */
                   1247: static GEN
                   1248: next_bin(GEN y, long n, long k)
                   1249: {
                   1250:   y = divrs(mulrs(y, n-k+2), k-1);
                   1251:   return divrs(mulrs(y, n-k+1), k);
                   1252: }
                   1253:
                   1254: static GEN
                   1255: izeta(long k, long prec)
                   1256: {
1.2     ! noro     1257:   long kk, n, li;
        !          1258:   gpmem_t av=avma, av2, limit;
1.1       noro     1259:   GEN y,p1,pi2,qn,z,q,binom;
                   1260:
                   1261:   /* treat trivial cases */
                   1262:   if (!k) return gneg(ghalf);
                   1263:   if (k < 0)
                   1264:   {
                   1265:     if ((k&1) == 0) return gzero;
                   1266:     y = bernreal(1-k,prec);
                   1267:     return gerepileuptoleaf(av, divrs(y,k-1));
                   1268:   }
                   1269:   if (k > bit_accuracy(prec)+1) return realun(prec);
1.2     ! noro     1270:   pi2 = Pi2n(1, prec);
1.1       noro     1271:   if ((k&1) == 0)
                   1272:   {
                   1273:     p1 = mulrr(gpuigs(pi2,k),absr(bernreal(k,prec)));
                   1274:     y = divrr(p1, mpfactr(k,prec)); setexpo(y,expo(y)-1);
                   1275:     return gerepileuptoleaf(av, y);
                   1276:   }
                   1277:   /* k > 1 odd */
                   1278:   binom = realun(prec+1);
                   1279:   q = mpexp(pi2); kk = k+1; /* >= 4 */
                   1280:   li = -(1+bit_accuracy(prec));
                   1281:   y = NULL; /* gcc -Wall */
                   1282:   if ((k&3)==3)
                   1283:   {
                   1284:     for (n=0; n <= kk>>1; n+=2)
                   1285:     {
                   1286:       p1 = mulrr(bernreal(kk-n,prec),bernreal(n,prec));
                   1287:       if (n) { binom = next_bin(binom,kk,n); setlg(binom,prec+1); }
                   1288:       p1 = mulrr(binom,p1);
                   1289:       if (n == kk>>1) setexpo(p1, expo(p1)-1);
                   1290:       if ((n>>1)&1) setsigne(p1,-signe(p1));
                   1291:       y = n? addrr(y,p1): p1;
                   1292:     }
                   1293:     y = mulrr(divrr(gpuigs(pi2,k),mpfactr(kk,prec)),y);
                   1294:
                   1295:     av2 = avma; limit = stack_lim(av2,1);
1.2     ! noro     1296:     qn = gsqr(q); z = ginv( addrs(q,-1) );
1.1       noro     1297:     for (n=2; ; n++)
                   1298:     {
1.2     ! noro     1299:       p1 = ginv( mulir(gpuigs(stoi(n),k),addrs(qn,-1)) );
1.1       noro     1300:
                   1301:       z = addrr(z,p1); if (expo(p1)< li) break;
                   1302:       qn = mulrr(qn,q);
                   1303:       if (low_stack(limit,stack_lim(av2,1)))
                   1304:       {
                   1305:         if (DEBUGMEM>1) err(warnmem,"izeta");
1.2     ! noro     1306:         gerepileall(av2,2, &z, &qn);
1.1       noro     1307:       }
                   1308:     }
                   1309:     setexpo(z,expo(z)+1);
                   1310:     y = addrr(y,z); setsigne(y,-signe(y));
                   1311:   }
                   1312:   else
                   1313:   {
                   1314:     GEN p2 = divrs(pi2, k-1);
                   1315:     for (n=0; n <= k>>1; n+=2)
                   1316:     {
                   1317:       p1 = mulrr(bernreal(kk-n,prec),bernreal(n,prec));
                   1318:       if (n) binom = next_bin(binom,kk,n);
                   1319:       p1 = mulrr(binom,p1);
                   1320:       p1 = mulsr(kk-(n<<1),p1);
                   1321:       if ((n>>1)&1) setsigne(p1,-signe(p1));
                   1322:       y = n? addrr(y,p1): p1;
                   1323:     }
                   1324:     y = mulrr(divrr(gpuigs(pi2,k),mpfactr(kk,prec)),y);
                   1325:     y = divrs(y,k-1);
                   1326:     av2 = avma; limit = stack_lim(av2,1);
                   1327:     qn = q; z=gzero;
                   1328:     for (n=1; ; n++)
                   1329:     {
                   1330:       p1=mulir(gpuigs(stoi(n),k),gsqr(addrs(qn,-1)));
                   1331:       p1=divrr(addrs(mulrr(qn,addsr(1,mulsr(n<<1,p2))),-1),p1);
                   1332:
                   1333:       z=addrr(z,p1); if (expo(p1) < li) break;
                   1334:       qn=mulrr(qn,q);
                   1335:       if (low_stack(limit,stack_lim(av2,1)))
                   1336:       {
                   1337:         if (DEBUGMEM>1) err(warnmem,"izeta");
1.2     ! noro     1338:         gerepileall(av2,2, &z, &qn);
1.1       noro     1339:       }
                   1340:     }
                   1341:     setexpo(z,expo(z)+1);
                   1342:     y = subrr(y,z);
                   1343:   }
                   1344:   return gerepileuptoleaf(av, y);
                   1345: }
                   1346: #else
                   1347:
                   1348: /* return x^n, assume n > 0 */
                   1349: static long
                   1350: pows(long x, long n)
                   1351: {
                   1352:   long i, y = x;
                   1353:   for (i=1; i<n; i++) y *= x;
                   1354:   return y;
                   1355: }
                   1356:
                   1357: /* return n^-s, n > 1 odd. tab[q] := q^-s, q prime power */
                   1358: static GEN
1.2     ! noro     1359: n_s(ulong n, GEN *tab)
1.1       noro     1360: {
                   1361:   byteptr d =  diffptr + 2;
                   1362:   GEN x = NULL;
                   1363:   long p, e;
                   1364:
1.2     ! noro     1365:   for (p = 3; n > 1; )
1.1       noro     1366:   {
                   1367:     e = svaluation(n, p, &n);
                   1368:     if (e)
                   1369:     {
                   1370:       GEN y = tab[pows(p,e)];
                   1371:       if (!x) x = y; else x = gmul(x,y);
                   1372:     }
1.2     ! noro     1373:     NEXT_PRIME_VIADIFF_CHECK(p,d);
1.1       noro     1374:   }
                   1375:   return x;
                   1376: }
                   1377:
                   1378: GEN czeta(GEN s0, long prec);
                   1379:
                   1380: /* assume k != 1 */
                   1381: static GEN
                   1382: izeta(long k, long prec)
                   1383: {
1.2     ! noro     1384:   gpmem_t av = avma;
1.1       noro     1385:   GEN y,p1,pi2;
                   1386:
                   1387:   /* treat trivial cases */
                   1388:   if (!k) { y = realun(prec); setexpo(y,-1); setsigne(y,-1); return y; }
                   1389:   if (k < 0)
                   1390:   {
                   1391:     if ((k&1) == 0) return gzero;
                   1392:     y = bernreal(1-k,prec);
                   1393:     return gerepileuptoleaf(av, divrs(y,k-1));
                   1394:   }
                   1395:   if (k > bit_accuracy(prec)+1) return realun(prec);
                   1396:   if ((k&1) == 0)
                   1397:   {
                   1398:     pi2 = mppi(prec); setexpo(pi2,2); /* 2Pi */
                   1399:     p1 = mulrr(gpuigs(pi2,k),absr(bernreal(k,prec)));
                   1400:     y = divrr(p1, mpfactr(k,prec)); setexpo(y,expo(y)-1);
                   1401:     return gerepileuptoleaf(av, y);
                   1402:   }
                   1403:   /* k > 1 odd */
                   1404:   return czeta(stoi(k), prec);
                   1405: }
                   1406:
                   1407: /* s0 a t_INT, t_REAL or t_COMPLEX.
                   1408:  * If a t_INT, assume it's not a trivial case (i.e we have s0 > 1, odd)
                   1409:  * */
                   1410: GEN
                   1411: czeta(GEN s0, long prec)
                   1412: {
                   1413:   GEN s, u, a, y, res, tes, sig, invn2, p1, unr;
                   1414:   GEN sim, ms, s1, s2, s3, s4, s5, *tab, tabn;
1.2     ! noro     1415:   long p, i, sqn, nn, lim, lim2, ct;
        !          1416:   gpmem_t av, av2 = avma, avlim;
1.1       noro     1417:   int funeq = 0;
                   1418:   byteptr d;
                   1419:
1.2     ! noro     1420:   if (DEBUGLEVEL>2) (void)timer2();
1.1       noro     1421:   s = trans_fix_arg(&prec,&s0,&sig,&av,&res);
                   1422:   if (gcmp0(s)) { y = gneg(ghalf); goto END; }
                   1423:   if (signe(sig) <= 0 || expo(sig) < -1)
                   1424:   { /* s <--> 1-s */
                   1425:     if (typ(s0) == t_INT)
                   1426:     {
                   1427:       p = itos(s0); avma = av2;
                   1428:       return izeta(p,prec);
                   1429:     }
                   1430:     funeq = 1; s = gsub(gun, s); sig = greal(s);
                   1431:   }
                   1432:   if (gcmp(sig, stoi(bit_accuracy(prec) + 1)) > 0) { y = gun; goto END; }
                   1433:
                   1434:   { /* find "optimal" parameters [lim, nn] */
                   1435:     double ssig = rtodbl(sig);
                   1436:     double st = rtodbl(gimag(s));
                   1437:     double ns = dnorm(ssig,st), l,l2;
                   1438:     long la = 1;
                   1439:
                   1440:     if (typ(s0) == t_INT)
                   1441:     {
                   1442:       long ss = itos(s0);
                   1443:       switch(ss)
                   1444:       { /* should depend on prec ? */
                   1445:         case 3:  la = 6; break;
                   1446:         default: la = 3; break;
                   1447:       }
                   1448:     }
                   1449:     if (dnorm(ssig-1,st) < 0.1) /* |s - 1| < 0.1 */
                   1450:       l2 = -(ssig - 0.5);
                   1451:     else
                   1452:     { /* l2 = Re( (s - 1/2) log (s-1) ) */
                   1453:       double rlog, ilog; /* log(s-1) */
                   1454:       dcxlog(ssig-1,st, &rlog,&ilog);
                   1455:       l2 = (ssig - 0.5)*rlog - st*ilog;
                   1456:     }
                   1457:     l = (pariC2*(prec-2) - l2 + ssig*2*pariC1) / (2. * (1.+ log((double)la)));
                   1458:     l2 = sqrt(ns)/2;
                   1459:     if (l < l2) l = l2;
                   1460:     lim = (long) ceil(l); if (lim < 2) lim = 2;
                   1461:     l2 = (lim+ssig/2.-.25);
                   1462:     nn = 1 + (long)ceil( sqrt(l2*l2 + st*st/4) * la / PI );
1.2     ! noro     1463:     if (DEBUGLEVEL>2) fprintferr("lim, nn: [%ld, %ld]\n",lim,nn);
1.1       noro     1464:     if ((ulong)nn >= maxprime()) err(primer1);
                   1465:   }
                   1466:   prec++; unr = realun(prec); /* one extra word of precision */
                   1467:
                   1468:   tab = (GEN*)cgetg(nn, t_VEC); /* table of q^(-s), q = p^e */
                   1469:   d = diffptr + 1;
                   1470:   if (typ(s0) == t_INT)
                   1471:   { /* no explog for 1/p^s */
1.2     ! noro     1472:     for (p=2; p < nn;) {
1.1       noro     1473:       tab[p] = divrr(unr, rpowsi(p, s0, prec));
1.2     ! noro     1474:       NEXT_PRIME_VIADIFF_CHECK(p,d);
        !          1475:     }
1.1       noro     1476:     a = divrr(unr, rpowsi(nn, s0, prec));
                   1477:   }
                   1478:   else
                   1479:   { /* general case */
                   1480:     ms = gneg(s); p1 = cgetr(prec);
1.2     ! noro     1481:     for (p=2; p < nn;)
1.1       noro     1482:     {
                   1483:       affsr(p, p1);
                   1484:       tab[p] = gexp(gmul(ms, mplog(p1)), prec);
1.2     ! noro     1485:       NEXT_PRIME_VIADIFF_CHECK(p,d);
1.1       noro     1486:     }
                   1487:     affsr(nn,p1);
                   1488:     a = gexp(gmul(ms, mplog(p1)), prec);
                   1489:   }
                   1490:   sqn = (long)sqrt(nn-1.);
                   1491:   d = diffptr + 2; /* fill in odd prime powers */
1.2     ! noro     1492:   for (p=3; p <= sqn; )
1.1       noro     1493:   {
                   1494:     ulong oldq = p, q = p*p;
                   1495:     while (q<(ulong)nn) { tab[q] = gmul(tab[p], tab[oldq]); oldq = q; q *= p; }
1.2     ! noro     1496:     NEXT_PRIME_VIADIFF_CHECK(p,d);
1.1       noro     1497:   }
1.2     ! noro     1498:   if (DEBUGLEVEL>2) msgtimer("tab[q^-s] from 1 to N-1");
1.1       noro     1499:
                   1500:   tabn = cgetg(nn, t_VECSMALL); ct = 0;
                   1501:   for (i = nn-1; i; i>>=1) tabn[++ct] = (i-1)>>1;
                   1502:   sim = y = unr;
                   1503:   for (i=ct; i > 1; i--)
                   1504:   {
1.2     ! noro     1505:     long j;
        !          1506:     gpmem_t av2 = avma;
1.1       noro     1507:     for (j=tabn[i]+1; j<=tabn[i-1]; j++)
                   1508:       sim = gadd(sim, n_s(2*j+1, tab));
                   1509:     sim = gerepileupto(av2, sim);
                   1510:     y = gadd(sim, gmul(tab[2],y));
                   1511:   }
                   1512:   y = gadd(y, gmul2n(a,-1));
1.2     ! noro     1513:   if (DEBUGLEVEL>2) msgtimer("sum from 1 to N-1");
1.1       noro     1514:
                   1515:   invn2 = divrs(unr, nn*nn); lim2 = lim<<1;
                   1516:   tes = bernreal(lim2, prec);
                   1517:   if (typ(s0) == t_INT)
                   1518:   {
                   1519:     av2 = avma; avlim = stack_lim(av2,3);
                   1520:     for (i=lim2-2; i>=2; i-=2)
                   1521:     { /* using single prec (when (s0 + i) < 2^31) not faster (even at \p28) */
                   1522:       u = mulri(mulrr(tes,invn2), mulii(addsi(i,s0), addsi(i-1,s0)));
                   1523:       tes = addrr(bernreal(i,prec), divrs2_safe(u, i+1)); /* u / (i+1)(i+2) */
                   1524:       if (low_stack(avlim,stack_lim(av2,3)))
                   1525:       {
                   1526:         if(DEBUGMEM>1) err(warnmem,"czeta");
                   1527:         tes = gerepileuptoleaf(av2, tes);
                   1528:       }
                   1529:     }
                   1530:     u = gmul(gmul(tes,invn2), gmul2n(mulii(s0, addsi(-1,s0)), -1));
                   1531:     tes = gmulsg(nn, gaddsg(1, u));
                   1532:   }
                   1533:   else /* typ(s0) != t_INT */
                   1534:   {
                   1535:     s1 = gsub(gmul2n(s,1), unr);
                   1536:     s2 = gmul(s, gsub(s,unr));
                   1537:     s3 = gmul2n(invn2,3);
                   1538:     av2 = avma; avlim = stack_lim(av2,3);
                   1539:     s4 = gmul(invn2, gmul2n(gaddsg(4*lim-2,s1),1));
                   1540:     s5 = gmul(invn2, gadd(s2, gmulsg(lim2, gaddgs(s1, lim2))));
                   1541:     for (i = lim2-2; i>=2; i -= 2)
                   1542:     {
                   1543:       s5 = gsub(s5, s4);
                   1544:       s4 = gsub(s4, s3);
                   1545:       tes = gadd(bernreal(i,prec), gdivgs(gmul(s5,tes), (i+1)*(i+2)));
                   1546:       if (low_stack(avlim,stack_lim(av2,3)))
                   1547:       {
                   1548:         GEN *gptr[3]; gptr[0]=&tes; gptr[1]=&s5; gptr[2]=&s4;
                   1549:         if(DEBUGMEM>1) err(warnmem,"czeta");
                   1550:         gerepilemany(av2,gptr,3);
                   1551:       }
                   1552:     }
                   1553:     u = gmul(gmul(tes,invn2), gmul2n(s2, -1));
                   1554:     tes = gmulsg(nn, gaddsg(1, u));
                   1555:   }
1.2     ! noro     1556:   if (DEBUGLEVEL>2) msgtimer("Bernoulli sum");
1.1       noro     1557:   /* y += tes a / (s-1) */
                   1558:   y = gadd(y, gmul(tes, gdiv(a, gsub(s, unr))));
                   1559:
                   1560: END:
                   1561:   if (funeq)
                   1562:   {
                   1563:     GEN pitemp = mppi(prec); setexpo(pitemp,2); /* 2Pi */
1.2     ! noro     1564:     y = gmul(gmul(y, ggamma(gprec_w(s,prec-1),prec)),
        !          1565:              gpui(pitemp,gneg(s),prec));
1.1       noro     1566:     setexpo(pitemp,0); /* Pi/2 */
                   1567:     y = gmul2n(gmul(y, gcos(gmul(pitemp,s),prec)), 1);
                   1568:   }
                   1569:   gaffect(y,res); avma = av; return res;
                   1570: }
                   1571: #endif
                   1572:
                   1573: GEN
                   1574: gzeta(GEN x, long prec)
                   1575: {
                   1576:   if (gcmp1(x)) err(talker,"argument equal to one in zeta");
                   1577:   switch(typ(x))
                   1578:   {
                   1579:     case t_INT:
                   1580:       if (is_bigint(x))
                   1581:       {
                   1582:         if (signe(x) > 0) return realun(prec);
                   1583:         if (signe(x) < 0 && mod2(x) == 0) return realzero(prec);
                   1584:       }
                   1585:       return izeta(itos(x),prec);
                   1586:
                   1587:     case t_REAL: case t_COMPLEX:
                   1588:       return czeta(x,prec);
                   1589:
                   1590:     case t_INTMOD: case t_PADIC:
                   1591:       err(typeer,"gzeta");
                   1592:     case t_SER:
                   1593:       err(impl,"zeta of power series");
                   1594:   }
                   1595:   return transc(gzeta,x,prec);
                   1596: }
                   1597:
                   1598: void
                   1599: gzetaz(GEN x, GEN y)
                   1600: {
1.2     ! noro     1601:   long prec = precision(y);
        !          1602:   gpmem_t av=avma;
1.1       noro     1603:
                   1604:   if (!prec) err(infprecer,"gzetaz");
                   1605:   gaffect(gzeta(x,prec),y); avma=av;
                   1606: }
                   1607:
                   1608: /***********************************************************************/
                   1609: /**                                                                   **/
                   1610: /**                    FONCTIONS POLYLOGARITHME                       **/
                   1611: /**                                                                   **/
                   1612: /***********************************************************************/
                   1613:
                   1614: /* validity domain contains .005 < |x| < 230
                   1615:  * Li_m(x = e^z) = sum_n=0 zeta(m-n) z^n / n!
                   1616:  *    with zeta(1) := H_m - log(-z) */
                   1617: static GEN
                   1618: cxpolylog(long m, GEN x, long prec)
                   1619: {
1.2     ! noro     1620:   long li, i, n, bern_upto;
        !          1621:   gpmem_t av=avma;
1.1       noro     1622:   GEN p1,z,h,q,s;
                   1623:
                   1624:   if (gcmp1(x)) return izeta(m,prec);
                   1625:   z=glog(x,prec); h=gneg_i(glog(gneg_i(z),prec));
                   1626:   for (i=1; i<m; i++) h = gadd(h,ginv(stoi(i)));
                   1627:
                   1628:   bern_upto=m+50; mpbern(bern_upto,prec);
                   1629:   q=gun; s=izeta(m,prec);
                   1630:   for (n=1; n<=m+1; n++)
                   1631:   {
                   1632:     q=gdivgs(gmul(q,z),n);
                   1633:     s=gadd(s,gmul((n==(m-1))? h: izeta(m-n,prec),q));
                   1634:   }
                   1635:
                   1636:   n = m+3; z=gsqr(z); li = -(bit_accuracy(prec)+1);
                   1637:
                   1638:   for(;;)
                   1639:   {
                   1640:     q = gdivgs(gmul(q,z),(n-1)*n);
                   1641:     p1 = gmul(izeta(m-n,prec),q);
                   1642:     s = gadd(s,p1);
                   1643:     if (gexpo(p1) < li) break;
                   1644:     n+=2;
                   1645:     if (n>=bern_upto) { bern_upto += 50; mpbern(bern_upto,prec); }
                   1646:   }
                   1647:   return gerepileupto(av,s);
                   1648: }
                   1649:
                   1650: GEN
                   1651: polylog(long m, GEN x, long prec)
                   1652: {
1.2     ! noro     1653:   long l, e, i, G, sx;
        !          1654:   gpmem_t av, av1, limpile;
1.1       noro     1655:   GEN X,z,p1,p2,n,y,logx;
                   1656:
                   1657:   if (m<0) err(talker,"negative index in polylog");
                   1658:   if (!m) return gneg(ghalf);
                   1659:   if (gcmp0(x)) return gcopy(x);
                   1660:   av = avma;
                   1661:   if (m==1)
                   1662:     return gerepileupto(av, gneg(glog(gsub(gun,x), prec)));
                   1663:
                   1664:   l = precision(x);
                   1665:   if (!l) { l=prec; x=gmul(x, realun(l)); }
                   1666:   e = gexpo(gnorm(x)); if (!e || e== -1) return cxpolylog(m,x,prec);
                   1667:   X = (e > 0)? ginv(x): x;
                   1668:   G = -bit_accuracy(l);
                   1669:   n = icopy(gun);
                   1670:   av1=avma; limpile=stack_lim(av1,1);
                   1671:   y = p1 = X;
                   1672:   for (i=2; ; i++)
                   1673:   {
                   1674:     n[2] = i; p1 = gmul(X,p1); p2 = gdiv(p1,gpuigs(n,m));
                   1675:     y = gadd(y,p2);
                   1676:     if (gexpo(p2) <= G) break;
                   1677:
                   1678:     if (low_stack(limpile, stack_lim(av1,1)))
                   1679:     { GEN *gptr[2]; gptr[0]=&y; gptr[1]=&p1;
                   1680:       if(DEBUGMEM>1) err(warnmem,"polylog");
                   1681:       gerepilemany(av1,gptr,2);
                   1682:     }
                   1683:   }
                   1684:   if (e < 0) return gerepileupto(av, y);
                   1685:
                   1686:   sx = gsigne(gimag(x));
                   1687:   if (!sx)
                   1688:   {
                   1689:     if (m&1) sx = gsigne(gsub(gun,greal(x)));
                   1690:     else     sx = - gsigne(greal(x));
                   1691:   }
                   1692:   z = cgetg(3,t_COMPLEX);
                   1693:   z[1] = zero;
                   1694:   z[2] = ldivri(mppi(l), mpfact(m-1));
                   1695:   if (sx < 0) z[2] = lnegr((GEN)z[2]);
                   1696:   logx = glog(x,l);
                   1697:
                   1698:   if (m == 2)
                   1699:   { /* same formula as below, written more efficiently */
                   1700:     y = gneg_i(y);
                   1701:     p1 = gmul2n(gsqr(gsub(logx, z)), -1); /* = (log(-x))^2 / 2 */
                   1702:     p1 = gadd(divrs(gsqr(mppi(l)), 6), p1);
                   1703:     p1 = gneg_i(p1);
                   1704:   }
                   1705:   else
                   1706:   {
                   1707:     GEN logx2 = gsqr(logx); p1 = gneg_i(ghalf);
                   1708:     for (i=m-2; i>=0; i-=2)
                   1709:       p1 = gadd(izeta(m-i,l), gmul(p1,gdivgs(logx2,(i+1)*(i+2))));
                   1710:     if (m&1) p1 = gmul(logx,p1); else y = gneg_i(y);
                   1711:     p1 = gadd(gmul2n(p1,1), gmul(z,gpuigs(logx,m-1)));
                   1712:   }
                   1713:
                   1714:   return gerepileupto(av, gadd(y,p1));
                   1715: }
                   1716:
                   1717: GEN
                   1718: dilog(GEN x, long prec)
                   1719: {
                   1720:   return gpolylog(2, x, prec);
                   1721: }
                   1722:
                   1723: GEN
                   1724: polylogd0(long m, GEN x, long flag, long prec)
                   1725: {
1.2     ! noro     1726:   long k, l, fl, m2;
        !          1727:   gpmem_t av;
1.1       noro     1728:   GEN p1,p2,p3,y;
                   1729:
                   1730:   m2=m&1; av=avma;
                   1731:   if (gcmp0(x)) return gcopy(x);
                   1732:   if (gcmp1(x) && m>=2) return m2?izeta(m,prec):gzero;
                   1733:   l=precision(x);
                   1734:   if (!l) { l=prec; x=gmul(x,realun(l)); }
                   1735:   p1=gabs(x,prec); fl=0;
                   1736:   if (gcmpgs(p1,1)>0) { x=ginv(x); p1=gabs(x,prec); fl=!m2; }
                   1737:
                   1738:   p1=gneg_i(glog(p1,prec)); p2=gun;
                   1739:   y=polylog(m,x,prec); y=m2?greal(y):gimag(y);
                   1740:   for (k=1; k<m; k++)
                   1741:   {
                   1742:     p2=gdivgs(gmul(p2,p1),k);
                   1743:     p3=m2?greal(polylog(m-k,x,prec)):gimag(polylog(m-k,x,prec));
                   1744:     y=gadd(y,gmul(p2,p3));
                   1745:   }
                   1746:   if (m2)
                   1747:   {
                   1748:     if (flag)
                   1749:       p2 = gdivgs(gmul(p2,p1),-2*m);
                   1750:     else
                   1751:       p2 = gdivgs(gmul(glog(gnorm(gsub(gun,x)),prec),p2),2*m);
                   1752:     y=gadd(y,p2);
                   1753:   }
                   1754:   if (fl) y = gneg(y);
                   1755:   return gerepileupto(av, y);
                   1756: }
                   1757:
                   1758: GEN
                   1759: polylogd(long m, GEN x, long prec)
                   1760: {
                   1761:   return polylogd0(m,x,0,prec);
                   1762: }
                   1763:
                   1764: GEN
                   1765: polylogdold(long m, GEN x, long prec)
                   1766: {
                   1767:   return polylogd0(m,x,1,prec);
                   1768: }
                   1769:
                   1770: GEN
                   1771: polylogp(long m, GEN x, long prec)
                   1772: {
1.2     ! noro     1773:   long k, l, fl, m2;
        !          1774:   gpmem_t av;
1.1       noro     1775:   GEN p1,y;
                   1776:
                   1777:   m2=m&1; av=avma;
                   1778:   if (gcmp0(x)) return gcopy(x);
                   1779:   if (gcmp1(x) && m>=2) return m2?izeta(m,prec):gzero;
                   1780:   l=precision(x);
                   1781:   if (!l) { l=prec; x=gmul(x,realun(l)); }
                   1782:   p1=gabs(x,prec); fl=0;
                   1783:   if (gcmpgs(p1,1)>0) { x=ginv(x); p1=gabs(x,prec); fl=!m2; }
                   1784:
                   1785:   p1=gmul2n(glog(p1,prec),1); mpbern(m>>1,prec);
                   1786:   y=polylog(m,x,prec); y=m2?greal(y):gimag(y);
                   1787:
                   1788:   if (m==1)
                   1789:   {
                   1790:     p1=gmul2n(p1,-2); y=gadd(y,p1);
                   1791:   }
                   1792:   else
                   1793:   {
                   1794:     GEN p2=gun, p3, p4, p5, p51=cgetr(prec);
                   1795:
                   1796:     for (k=1; k<m; k++)
                   1797:     {
                   1798:       p2=gdivgs(gmul(p2,p1),k);
                   1799:       if (!(k&1) || k==1)
                   1800:       {
                   1801:        if (k!=1)
                   1802:        {
                   1803:          p5=(GEN)bern(k>>1);
                   1804:          if (bernzone[2]>prec) { affrr(p5,p51); p5=p51; }
                   1805:          p4=gmul(p2,p5);
                   1806:        }
                   1807:        else p4=gneg_i(gmul2n(p2,-1));
                   1808:        p3=polylog(m-k,x,prec); p3=m2?greal(p3):gimag(p3);
                   1809:        y=gadd(y,gmul(p4,p3));
                   1810:       }
                   1811:     }
                   1812:   }
                   1813:   if (fl) y = gneg(y);
                   1814:   return gerepileupto(av, y);
                   1815: }
                   1816:
                   1817: GEN
                   1818: gpolylog(long m, GEN x, long prec)
                   1819: {
1.2     ! noro     1820:   long i, lx, v, n;
        !          1821:   gpmem_t av=avma;
1.1       noro     1822:   GEN y,p1,p2;
                   1823:
                   1824:   if (m<=0)
                   1825:   {
                   1826:     p1=polx[0]; p2=gsub(gun,p1);
                   1827:     for (i=1; i<=(-m); i++)
                   1828:       p1=gmul(polx[0],gadd(gmul(p2,derivpol(p1)),gmulsg(i,p1)));
                   1829:     p1=gdiv(p1,gpuigs(p2,1-m));
                   1830:     return gerepileupto(av, poleval(p1,x));
                   1831:   }
                   1832:
                   1833:   switch(typ(x))
                   1834:   {
                   1835:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
                   1836:     case t_COMPLEX: case t_QUAD:
                   1837:       return polylog(m,x,prec);
                   1838:
                   1839:     case t_INTMOD: case t_PADIC:
                   1840:       err(impl, "padic polylogarithm");
                   1841:     case t_POLMOD:
                   1842:       p1=roots((GEN)x[1],prec); lx=lg(p1); p2=cgetg(lx,t_COL);
                   1843:       for (i=1; i<lx; i++) p2[i]=lpoleval((GEN)x[2],(GEN)p1[i]);
                   1844:       y=cgetg(lx,t_COL);
                   1845:       for (i=1; i<lx; i++) y[i]=(long)polylog(m,(GEN)p2[i],prec);
                   1846:       return gerepileupto(av, y);
                   1847:
                   1848:     case t_POL: case t_RFRAC: case t_RFRACN:
                   1849:       p1=tayl(x,gvar(x),precdl);
                   1850:       return gerepileupto(av, gpolylog(m,p1,prec));
                   1851:
                   1852:     case t_SER:
                   1853:       if (!m) return gneg(ghalf);
                   1854:       if (m==1)
                   1855:       {
                   1856:        p1=glog(gsub(gun,x),prec);
                   1857:        return gerepileupto(av, gneg(p1));
                   1858:       }
1.2     ! noro     1859:       if (gcmp0(x)) return gcopy(x);
1.1       noro     1860:       if (valp(x)<=0) err(impl,"polylog around a!=0");
                   1861:       v=varn(x); n=(lg(x)-2)/valp(x); y=ggrando(polx[v],lg(x)-2);
                   1862:       for (i=n; i>=1; i--)
                   1863:       {
                   1864:        p1=gadd(gpuigs(stoi(i),-m),y);
                   1865:        y=gmul(x,p1);
                   1866:       }
                   1867:       return gerepileupto(av, y);
                   1868:
                   1869:     case t_VEC: case t_COL: case t_MAT:
                   1870:       lx=lg(x); y=cgetg(lx,typ(x));
                   1871:       for (i=1; i<lx; i++)
                   1872:        y[i]=(long)gpolylog(m,(GEN)x[i],prec);
                   1873:       return y;
                   1874:   }
                   1875:   err(typeer,"gpolylog");
                   1876:   return NULL; /* not reached */
                   1877: }
                   1878:
                   1879: void
                   1880: gpolylogz(long m, GEN x, GEN y)
                   1881: {
1.2     ! noro     1882:   long prec = precision(y);
        !          1883:   gpmem_t av=avma;
1.1       noro     1884:
                   1885:   if (!prec) err(infprecer,"gpolylogz");
                   1886:   gaffect(gpolylog(m,x,prec),y); avma=av;
                   1887: }
                   1888:
                   1889: GEN
                   1890: polylog0(long m, GEN x, long flag, long prec)
                   1891: {
                   1892:   switch(flag)
                   1893:   {
                   1894:     case 0: return gpolylog(m,x,prec);
                   1895:     case 1: return polylogd(m,x,prec);
                   1896:     case 2: return polylogdold(m,x,prec);
                   1897:     case 3: return polylogp(m,x,prec);
                   1898:     default: err(flagerr,"polylog");
                   1899:   }
                   1900:   return NULL; /* not reached */
                   1901: }
                   1902:
                   1903: static GEN
                   1904: qq(GEN x, long prec)
                   1905: {
                   1906:   long tx=typ(x);
                   1907:
                   1908:   if (tx==t_PADIC) return x;
                   1909:   if (is_scalar_t(tx))
                   1910:   {
1.2     ! noro     1911:     long l = precision(x);
        !          1912:     if (!l) l = prec;
        !          1913:     if (tx != t_COMPLEX || gsigne((GEN)x[2]) <= 0)
1.1       noro     1914:       err(talker,"argument must belong to upper half-plane");
                   1915:
1.2     ! noro     1916:     return gexp(gmul(x, PiI2(l)), l); /* e(x) */
1.1       noro     1917:   }
1.2     ! noro     1918:   if (tx == t_SER) return x;
        !          1919:   if (tx != t_POL) err(talker,"bad argument for modular function");
1.1       noro     1920:
                   1921:   return tayl(x,gvar(x),precdl);
                   1922: }
                   1923:
                   1924: static GEN
                   1925: inteta(GEN q)
                   1926: {
                   1927:   long tx=typ(q);
                   1928:   GEN p1,ps,qn,y;
                   1929:
                   1930:   y=gun; qn=gun; ps=gun;
                   1931:   if (tx==t_PADIC)
                   1932:   {
1.2     ! noro     1933:     if (valp(q) <= 0) err(talker,"non-positive valuation in eta");
1.1       noro     1934:     for(;;)
                   1935:     {
                   1936:       p1=gneg_i(gmul(ps,gmul(q,gsqr(qn))));
                   1937:       y=gadd(y,p1); qn=gmul(qn,q); ps=gmul(p1,qn);
                   1938:       p1=y; y=gadd(y,ps); if (gegal(p1,y)) return y;
                   1939:     }
                   1940:   }
                   1941:   else
                   1942:   {
1.2     ! noro     1943:     long l, v = 0; /* gcc -Wall */
        !          1944:     gpmem_t av = avma, lim = stack_lim(av, 3);
1.1       noro     1945:
                   1946:     if (is_scalar_t(tx)) l = -bit_accuracy(precision(q));
                   1947:     else
                   1948:     {
1.2     ! noro     1949:       v = gvar(q); l = lg(q)-2; tx = 0;
        !          1950:       if (valp(q) <= 0) err(talker,"non-positive valuation in eta");
1.1       noro     1951:     }
                   1952:     for(;;)
                   1953:     {
1.2     ! noro     1954:       p1 = gneg_i(gmul(ps,gmul(q,gsqr(qn))));
        !          1955:       /* qn = q^n
        !          1956:        * ps = (-1)^n q^(n(3n+1)/2)
        !          1957:        * p1 = (-1)^(n+1) q^(n(3n+1)/2 + 2n+1) */
        !          1958:       y = gadd(y,p1); qn = gmul(qn,q); ps = gmul(p1,qn);
        !          1959:       y = gadd(y,ps);
1.1       noro     1960:       if (tx)
                   1961:         { if (gexpo(ps)-gexpo(y) < l) return y; }
                   1962:       else
1.2     ! noro     1963:         { if (gval(ps,v) >= l) return y; }
1.1       noro     1964:       if (low_stack(lim, stack_lim(av,3)))
                   1965:       {
1.2     ! noro     1966:         if(DEBUGMEM>1) err(warnmem,"eta");
        !          1967:         gerepileall(av, 3, &y, &qn, &ps);
1.1       noro     1968:       }
                   1969:     }
                   1970:   }
                   1971: }
                   1972:
                   1973: GEN
                   1974: eta(GEN x, long prec)
                   1975: {
1.2     ! noro     1976:   gpmem_t av = avma;
1.1       noro     1977:   GEN q = qq(x,prec);
                   1978:   return gerepileupto(av,inteta(q));
                   1979: }
                   1980:
                   1981: /* returns the true value of eta(x) for Im(x) > 0, using reduction */
                   1982: GEN
                   1983: trueeta(GEN x, long prec)
                   1984: {
1.2     ! noro     1985:   long tx=typ(x), l;
        !          1986:   gpmem_t av=avma, tetpil;
1.1       noro     1987:   GEN p1,p2,q,q24,n,z,m,unapprox;
                   1988:
                   1989:   if (!is_scalar_t(tx)) err(typeer,"trueeta");
                   1990:   if (tx != t_COMPLEX || gsigne((GEN)x[2])<=0)
                   1991:     err(talker,"argument must belong to upper half-plane");
                   1992:   l=precision(x); if (l) prec=l;
1.2     ! noro     1993:   p2 = PiI2(prec);
1.1       noro     1994:   z=gexp(gdivgs(p2,24),prec); /* exp(2*I*Pi/24) */
                   1995:   unapprox=gsub(gun,gpuigs(stoi(10),-8));
                   1996:   m=gun;
                   1997:   for(;;)
                   1998:   {
                   1999:     n=ground(greal(x));
                   2000:     if (signe(n)) {x=gsub(x,n); m=gmul(m,powgi(z,n));}
                   2001:     if (gcmp(gnorm(x), unapprox)>=0) break;
                   2002:     m=gmul(m,gsqrt(gdiv(gi,x),prec)); x=gdivsg(-1,x);
                   2003:   }
                   2004:   q=gmul(p2,x);
                   2005:   q24=gexp(gdivgs(q,24),prec); q=gpuigs(q24,24);
                   2006:   p1=gmul(m,q24); q = inteta(q); tetpil=avma;
                   2007:   return gerepile(av,tetpil,gmul(p1,q));
                   2008: }
                   2009:
                   2010: GEN
                   2011: eta0(GEN x, long flag,long prec)
                   2012: {
                   2013:   return flag? trueeta(x,prec): eta(x,prec);
                   2014: }
                   2015:
                   2016: GEN
                   2017: jell(GEN x, long prec)
                   2018: {
1.2     ! noro     2019:   long tx = typ(x);
        !          2020:   gpmem_t av=avma, tetpil;
1.1       noro     2021:   GEN p1;
                   2022:
                   2023:   if (!is_scalar_t(tx) || tx == t_PADIC)
                   2024:   {
                   2025:     GEN p2,q = qq(x,prec);
                   2026:     p1=gdiv(inteta(gsqr(q)), inteta(q));
                   2027:     p1=gmul2n(gsqr(p1),1);
                   2028:     p1=gmul(q,gpuigs(p1,12));
                   2029:     p2=gaddsg(768,gadd(gsqr(p1),gdivsg(4096,p1)));
                   2030:     p1=gmulsg(48,p1); tetpil=avma;
                   2031:     return gerepile(av,tetpil,gadd(p2,p1));
                   2032:   }
                   2033:   p1=gdiv(trueeta(gmul2n(x,1),prec),trueeta(x,prec));
                   2034:   p1=gsqr(gsqr(gsqr(p1)));
                   2035:   p1=gadd(gmul2n(gsqr(p1),8), ginv(p1)); tetpil=avma;
                   2036:   return gerepile(av,tetpil,gpuigs(p1,3));
                   2037: }
                   2038:
                   2039: GEN
                   2040: wf2(GEN x, long prec)
                   2041: {
1.2     ! noro     2042:   gpmem_t av=avma, tetpil;
1.1       noro     2043:   GEN p1,p2;
                   2044:
                   2045:   p1=gsqrt(gdeux,prec);
                   2046:   p2=gdiv(trueeta(gmul2n(x,1),prec),trueeta(x,prec));
                   2047:   tetpil=avma;
                   2048:   return gerepile(av,tetpil,gmul(p1,p2));
                   2049: }
                   2050:
                   2051: GEN
                   2052: wf1(GEN x, long prec)
                   2053: {
1.2     ! noro     2054:   gpmem_t av=avma, tetpil;
1.1       noro     2055:   GEN p1,p2;
                   2056:
                   2057:   p1=trueeta(gmul2n(x,-1),prec); p2=trueeta(x,prec);
                   2058:   tetpil=avma;
                   2059:   return gerepile(av,tetpil,gdiv(p1,p2));
                   2060: }
                   2061:
                   2062: GEN
                   2063: wf(GEN x, long prec)
                   2064: {
1.2     ! noro     2065:   gpmem_t av=avma, tetpil;
1.1       noro     2066:   GEN p1,p2;
                   2067:
                   2068:   p1=gdiv(trueeta(gmul2n(gaddgs(x,1),-1),prec),trueeta(x,prec));
                   2069:   p2=cgetg(3,t_COMPLEX); p2[1]=zero; p2[2]=ldivrs(mppi(prec),-24);
                   2070:   p2=gexp(p2,prec); tetpil=avma;
                   2071:   return gerepile(av,tetpil,gmul(p1,p2));
                   2072: }
                   2073:
                   2074: GEN
                   2075: weber0(GEN x, long flag,long prec)
                   2076: {
                   2077:   switch(flag)
                   2078:   {
                   2079:     case 0: return wf(x,prec);
                   2080:     case 1: return wf1(x,prec);
                   2081:     case 2: return wf2(x,prec);
                   2082:     default: err(flagerr,"weber");
                   2083:   }
                   2084:   return NULL; /* not reached */
                   2085: }
                   2086:
                   2087: static GEN
                   2088: sagm(GEN x, long prec)
                   2089: {
                   2090:   GEN p1,a,b,a1,b1,y;
                   2091:   long l,ep;
1.2     ! noro     2092:   gpmem_t av;
1.1       noro     2093:
                   2094:   if (gcmp0(x)) return gcopy(x);
                   2095:   switch(typ(x))
                   2096:   {
                   2097:     case t_REAL:
                   2098:       l = precision(x); y = cgetr(l); av=avma;
                   2099:       a1 = x; b1 = realun(l);
                   2100:       l = 5-bit_accuracy(prec);
                   2101:       do
                   2102:       {
                   2103:        a=a1; b=b1; a1 = addrr(a,b);
                   2104:         setexpo(a1,expo(a1)-1);
                   2105:        b1=mpsqrt(mulrr(a,b));
                   2106:       }
                   2107:       while (expo(subrr(b1,a1))-expo(b1) >= l);
                   2108:       affrr(a1,y); avma=av; return y;
                   2109:
                   2110:     case t_COMPLEX:
                   2111:       if (gcmp0((GEN)x[2]))
                   2112:         return transc(sagm,(GEN)x[1],prec);
                   2113:       av=avma; l=precision(x); if (l) prec=l;
                   2114:       a1=x; b1=gun; l = 5-bit_accuracy(prec);
                   2115:       do
                   2116:       {
                   2117:        a=a1; b=b1;
                   2118:        a1=gmul2n(gadd(a,b),-1);
                   2119:        b1=gsqrt(gmul(a,b),prec);
                   2120:       }
                   2121:       while (gexpo(gsub(b1,a1))-gexpo(b1) >= l);
                   2122:       return gerepilecopy(av,a1);
                   2123:
                   2124:     case t_PADIC:
                   2125:       av=avma; a1=x; b1=gun; l=precp(x);
                   2126:       do
                   2127:       {
                   2128:        a=a1; b=b1;
                   2129:        a1=gmul2n(gadd(a,b),-1); b1=gsqrt(gmul(a,b),0);
                   2130:        p1=gsub(b1,a1); ep=valp(p1)-valp(b1);
                   2131:        if (ep<=0) { b1=gneg_i(b1); p1=gsub(b1,a1); ep=valp(p1)-valp(b1); }
                   2132:       }
                   2133:       while (ep<l && !gcmp0(p1));
                   2134:       return gerepilecopy(av,a1);
                   2135:
                   2136:     case t_SER:
                   2137:       av=avma; a1=x; b1=gun; l=lg(x)-2;
                   2138:       do
                   2139:       {
                   2140:        a=a1; b=b1;
                   2141:        a1=gmul2n(gadd(a,b),-1); b1=gsqrt(gmul(a,b),prec);
                   2142:        p1=gsub(b1,a1); ep=valp(p1)-valp(b1);
                   2143:       }
                   2144:       while (ep<l && !gcmp0(p1));
                   2145:       return gerepilecopy(av,a1);
                   2146:
                   2147:     case t_INTMOD:
                   2148:       err(impl,"agm of mod");
                   2149:   }
                   2150:   return transc(sagm,x,prec);
                   2151: }
                   2152:
                   2153: GEN
                   2154: agm(GEN x, GEN y, long prec)
                   2155: {
1.2     ! noro     2156:   long ty=typ(y);
        !          2157:   gpmem_t av, tetpil;
1.1       noro     2158:   GEN z;
                   2159:
                   2160:   if (is_matvec_t(ty))
                   2161:   {
                   2162:     ty=typ(x);
                   2163:     if (is_matvec_t(ty)) err(talker,"agm of two vector/matrices");
                   2164:     z=x; x=y; y=z;
                   2165:   }
                   2166:   if (gcmp0(y)) return gcopy(y);
                   2167:   av=avma; z=sagm(gdiv(x,y),prec); tetpil=avma;
                   2168:   return gerepile(av,tetpil,gmul(y,z));
                   2169: }
                   2170:
                   2171: GEN
                   2172: logagm(GEN q)
                   2173: {
1.2     ! noro     2174:   long prec=lg(q), s, n, lim;
        !          2175:   gpmem_t av=avma, tetpil;
1.1       noro     2176:   GEN y,q4,q1;
                   2177:
                   2178:   if (typ(q)!=t_REAL) err(typeer,"logagm");
                   2179:   if (signe(q)<=0) err(talker,"non positive argument in logagm");
                   2180:   if (expo(q)<0) s=1; else { q=ginv(q); s=0; }
                   2181:   lim = - (bit_accuracy(prec) >> 1);
                   2182:   q1 = NULL; /* gcc -Wall */
                   2183:   for (n=0; expo(q)>=lim; n++) { q1=q; q=gsqr(q); }
                   2184:   q4=gmul2n(q,2);
                   2185:   if (!n) q1=gsqrt(q,prec);
                   2186:   y=divrr(mppi(prec), agm(addsr(1,q4),gmul2n(q1,2),prec));
                   2187:   tetpil=avma; y=gmul2n(y,-n); if (s) setsigne(y,-1);
                   2188:   return gerepile(av,tetpil,y);
                   2189: }
                   2190:
                   2191: GEN
                   2192: glogagm(GEN x, long prec)
                   2193: {
1.2     ! noro     2194:   gpmem_t av, tetpil;
1.1       noro     2195:   GEN y,p1,p2;
                   2196:
                   2197:   switch(typ(x))
                   2198:   {
                   2199:     case t_REAL:
                   2200:       if (signe(x)>=0) return logagm(x);
                   2201:
                   2202:       y=cgetg(3,t_COMPLEX); y[2]=lmppi(lg(x));
                   2203:       setsigne(x,1); y[1]=(long)logagm(x);
                   2204:       setsigne(x,-1); return y;
                   2205:
                   2206:     case t_COMPLEX:
                   2207:       y=cgetg(3,t_COMPLEX); y[2]=larg(x,prec);
                   2208:       av=avma; p1=glogagm(gnorm(x),prec); tetpil=avma;
                   2209:       y[1]=lpile(av,tetpil,gmul2n(p1,-1));
                   2210:       return y;
                   2211:
                   2212:     case t_PADIC:
                   2213:       return palog(x);
                   2214:
                   2215:     case t_SER:
                   2216:       av=avma; if (valp(x)) err(negexper,"glogagm");
                   2217:       p1=gdiv(derivser(x),x);
                   2218:       p1=integ(p1,varn(x));
                   2219:       if (gcmp1((GEN)x[2])) return gerepileupto(av,p1);
                   2220:       p2=glogagm((GEN)x[2],prec); tetpil=avma;
                   2221:       return gerepile(av,tetpil,gadd(p1,p2));
                   2222:
                   2223:     case t_INTMOD:
                   2224:       err(typeer,"glogagm");
                   2225:   }
                   2226:   return transc(glogagm,x,prec);
                   2227: }
                   2228:
                   2229: GEN
                   2230: theta(GEN q, GEN z, long prec)
                   2231: {
1.2     ! noro     2232:   long l, n;
        !          2233:   gpmem_t av=avma, tetpil;
1.1       noro     2234:   GEN ps,qn,qnold,y,zy,lq,ps2,p1,k,zold;
                   2235:
1.2     ! noro     2236:   if (!is_scalar_t(typ(q)) || !is_scalar_t(typ(z)))
        !          2237:     err(impl,"theta for non-scalar types");
        !          2238:
1.1       noro     2239:   l=precision(q); if (l) prec=l;
                   2240:   p1=realun(prec); z=gmul(p1,z);
                   2241:   if (!l) q=gmul(p1,q);
                   2242:   if (gexpo(q)>=0) err(thetaer1);
                   2243:   zy = gimag(z);
                   2244:   zold = NULL; /* gcc -Wall */
                   2245:   if (gcmp0(zy)) k=gzero;
                   2246:   else
                   2247:   {
                   2248:     lq=glog(q,prec); k=ground(gdiv(zy,greal(lq)));
                   2249:     if (!gcmp0(k)) { zold=z; z=gadd(z,gdiv(gmul(lq,k),gi)); }
                   2250:   }
                   2251:   y=gsin(z,prec); n=0; qn=gun;
                   2252:   ps2=gsqr(q); ps=gneg_i(ps2);
                   2253:   do
                   2254:   {
                   2255:     n++; p1=gsin(gmulsg(2*n+1,z),prec);
                   2256:     qnold=qn; qn=gmul(qn,ps);
                   2257:     ps=gmul(ps,ps2); p1=gmul(p1,qn); y=gadd(y,p1);
                   2258:   }
                   2259:   while (gexpo(qnold) >= -bit_accuracy(prec));
                   2260:   if (signe(k))
                   2261:   {
                   2262:     y=gmul(y,gmul(gpui(q,gsqr(k),prec),
                   2263:                   gexp(gmul2n(gmul(gmul(gi,zold),k),1),prec)));
                   2264:     if (mod2(k)) y=gneg_i(y);
                   2265:   }
                   2266:   p1=gmul2n(gsqrt(gsqrt(q,prec),prec),1); tetpil=avma;
                   2267:   return gerepile(av,tetpil,gmul(p1,y));
                   2268: }
                   2269:
                   2270: GEN
                   2271: thetanullk(GEN q, long k, long prec)
                   2272: {
1.2     ! noro     2273:   long l, n;
        !          2274:   gpmem_t av=avma, tetpil;
1.1       noro     2275:   GEN p1,ps,qn,y,ps2;
                   2276:
                   2277:   l=precision(q);
                   2278:   if (!l) { l=prec; q=gmul(q,realun(l)); }
                   2279:   if (gexpo(q)>=0) err(thetaer1);
                   2280:
                   2281:   if (!(k&1)) { avma = av; return gzero; }
                   2282:   ps2=gsqr(q); ps=gneg_i(ps2);
                   2283:   qn = gun; y = gun; n = 0;
                   2284:
                   2285:   do
                   2286:   {
                   2287:     n++; p1=gpuigs(stoi(n+n+1),k); qn=gmul(qn,ps);
                   2288:     ps=gmul(ps,ps2); p1=gmul(p1,qn); y=gadd(y,p1);
                   2289:   }
                   2290:   while (gexpo(p1) >= -bit_accuracy(l));
                   2291:   p1=gmul2n(gsqrt(gsqrt(q,prec),prec),1); tetpil=avma;
                   2292:   if (k&2) { p1=gneg_i(p1); tetpil=avma; }
                   2293:   return gerepile(av,tetpil,gmul(p1,y));
                   2294: }
                   2295:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>