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

Annotation of OpenXM_contrib/pari/src/basemath/trans2.c, Revision 1.1

1.1     ! maekawa     1: /********************************************************************/
        !             2: /**                                                                **/
        !             3: /**                   TRANSCENDENTAL FONCTIONS                     **/
        !             4: /**                          (part 2)                              **/
        !             5: /**                                                                **/
        !             6: /********************************************************************/
        !             7: /* $Id: trans2.c,v 1.2 1999/09/23 17:50:57 karim Exp $ */
        !             8: #include "pari.h"
        !             9:
        !            10: GEN mpsin(GEN x);
        !            11: static GEN mpach(GEN x);
        !            12:
        !            13: /********************************************************************/
        !            14: /**                                                                **/
        !            15: /**                       FONCTION ARCTG                           **/
        !            16: /**                                                                **/
        !            17: /********************************************************************/
        !            18:
        !            19: static GEN
        !            20: mpatan(GEN x)
        !            21: {
        !            22:   long l,l1,l2,n,m,u,i,av0,av,lp,e,sx,s;
        !            23:   double alpha,beta,gama=1.0,delta,fi;
        !            24:   GEN y,p1,p2,p3,p4,p5,unr;
        !            25:
        !            26:   sx=signe(x);
        !            27:   if (!sx)
        !            28:   {
        !            29:     y=cgetr(3); y[1]=x[1]; y[2]=0; return y;
        !            30:   }
        !            31:   l = lp = lg(x);
        !            32:   if (sx<0) setsigne(x,1);
        !            33:   u = cmprs(x,1);
        !            34:   if (!u)
        !            35:   {
        !            36:     y=mppi(l+1); setexpo(y,-1);
        !            37:     if (sx<0)
        !            38:     {
        !            39:       setsigne(x,-1);
        !            40:       setsigne(y,-1);
        !            41:     }
        !            42:     return y;
        !            43:   }
        !            44:
        !            45:   e = expo(x);
        !            46:   if (e>0) lp += (e>>TWOPOTBITS_IN_LONG);
        !            47:
        !            48:   y=cgetr(lp); av0=avma;
        !            49:   p1=cgetr(l+1); affrr(x,p1); setsigne(x,sx);
        !            50:   if (u==1) divsrz(1,p1,p1);
        !            51:   e = expo(p1);
        !            52:   if (e<-100)
        !            53:     alpha = log(PI)-e*LOG2;
        !            54:   else
        !            55:   {
        !            56:     alpha = rtodbl(p1);
        !            57:     alpha = log(PI/atan(alpha));
        !            58:   }
        !            59:   beta = (bit_accuracy(l)>>1) * LOG2;
        !            60:   delta=LOG2+beta-alpha/2;
        !            61:   if (delta<=0) { n=1; m=0; }
        !            62:   else
        !            63:   {
        !            64:     fi=alpha-2*LOG2;
        !            65:     if (delta>=gama*fi*fi/LOG2)
        !            66:     {
        !            67:       n=(long)(1+sqrt(gama*delta/LOG2));
        !            68:       m=(long)(1+sqrt(delta/(gama*LOG2))-fi/LOG2);
        !            69:     }
        !            70:     else
        !            71:     {
        !            72:       n=(long)(1+beta/fi); m=0;
        !            73:     }
        !            74:   }
        !            75:   l2=l+1+(m>>TWOPOTBITS_IN_LONG);
        !            76:   p2=cgetr(l2); p3=cgetr(l2);
        !            77:   affrr(p1,p2); av=avma;
        !            78:   for (i=1; i<=m; i++)
        !            79:   {
        !            80:     p5 = mulrr(p2,p2); setlg(p5,l2);
        !            81:     p5 = addsr(1,p5); setlg(p5,l2);
        !            82:     p5 = mpsqrt(p5);
        !            83:     p5 = addsr(1,p5); setlg(p5,l2);
        !            84:     divrrz(p2,p5,p2); avma=av;
        !            85:   }
        !            86:   mulrrz(p2,p2,p3); l1=4;
        !            87:   unr=realun(l2); setlg(unr,4);
        !            88:   p4=cgetr(l2); setlg(p4,4);
        !            89:   divrsz(unr,2*n+1,p4);
        !            90:
        !            91:   s=0; e=expo(p3); av=avma;
        !            92:   for (i=n; i>=1; i--)
        !            93:   {
        !            94:     setlg(p3,l1); p5 = mulrr(p4,p3);
        !            95:     s -= e; l1 += (s>>TWOPOTBITS_IN_LONG);
        !            96:     if (l1>l2) l1=l2;
        !            97:     s %= BITS_IN_LONG;
        !            98:     setlg(unr,l1); p5 = subrr(divrs(unr,2*i-1), p5);
        !            99:     setlg(p4,l1); affrr(p5,p4); avma=av;
        !           100:   }
        !           101:   setlg(p4,l2); p4 = mulrr(p2,p4);
        !           102:   setexpo(p4, expo(p4)+m);
        !           103:   if (u==1)
        !           104:   {
        !           105:     p5 = mppi(lp+1); setexpo(p5,0);
        !           106:     p4 = subrr(p5,p4);
        !           107:   }
        !           108:   if (sx == -1) setsigne(p4,-signe(p4));
        !           109:   affrr(p4,y); avma=av0; return y;
        !           110: }
        !           111:
        !           112: GEN
        !           113: gatan(GEN x, long prec)
        !           114: {
        !           115:   long av,tetpil;
        !           116:   GEN y,p1;
        !           117:
        !           118:   switch(typ(x))
        !           119:   {
        !           120:     case t_REAL:
        !           121:       return mpatan(x);
        !           122:
        !           123:     case t_COMPLEX:
        !           124:       av=avma; p1=cgetg(3,t_COMPLEX);
        !           125:       p1[1]=lneg((GEN)x[2]);
        !           126:       p1[2]=x[1]; tetpil=avma;
        !           127:       y=gerepile(av,tetpil,gath(p1,prec));
        !           128:       p1=(GEN)y[1]; y[1]=y[2]; y[2]=(long)p1;
        !           129:       setsigne(p1,-signe(p1)); return y;
        !           130:
        !           131:     case t_SER:
        !           132:       av=avma; if (valp(x)<0) err(negexper,"gatan");
        !           133:       p1=gdiv(derivser(x), gaddsg(1,gsqr(x)));
        !           134:       y=integ(p1,varn(x)); if (valp(x)) return gerepileupto(av,y);
        !           135:
        !           136:       p1=gatan((GEN)x[2],prec); tetpil=avma;
        !           137:       return gerepile(av,tetpil,gadd(p1,y));
        !           138:
        !           139:     case t_INTMOD: case t_PADIC:
        !           140:       err(typeer,"gatan");
        !           141:   }
        !           142:   return transc(gatan,x,prec);
        !           143: }
        !           144:
        !           145: void
        !           146: gatanz(GEN x, GEN y)
        !           147: {
        !           148:   long av=avma,prec = precision(y);
        !           149:
        !           150:   if (!prec) err(infprecer,"gatanz");
        !           151:   gaffect(gatan(x,prec),y); avma=av;
        !           152: }
        !           153:
        !           154: /********************************************************************/
        !           155: /**                                                                **/
        !           156: /**                      FONCTION ARCSINUS                         **/
        !           157: /**                                                                **/
        !           158: /********************************************************************/
        !           159:
        !           160: /* x is non zero |x| <= 1 */
        !           161: static GEN
        !           162: mpasin(GEN x)
        !           163: {
        !           164:   long l,u,v,av;
        !           165:   GEN y,p1;
        !           166:
        !           167:   u=cmprs(x,1); v=cmpsr(-1,x);
        !           168:   if (!u || !v)
        !           169:   {
        !           170:     y=mppi(lg(x)); setexpo(y,0);
        !           171:     if (signe(x)<0) setsigne(y,-1);
        !           172:     return y;
        !           173:   }
        !           174:   l = lg(x); y=cgetr(l); av=avma;
        !           175:
        !           176:   p1 = cgetr(l+1); mulrrz(x,x,p1);
        !           177:   subsrz(1,p1,p1);
        !           178:   divrrz(x,mpsqrt(p1),p1);
        !           179:   affrr(mpatan(p1),y); if (signe(x)<0) setsigne(y,-1);
        !           180:   avma=av; return y;
        !           181: }
        !           182:
        !           183: GEN
        !           184: gasin(GEN x, long prec)
        !           185: {
        !           186:   long av,tetpil,l,sx;
        !           187:   GEN y,p1;
        !           188:
        !           189:   switch(typ(x))
        !           190:   {
        !           191:     case t_REAL: sx=signe(x);
        !           192:       if (!sx) { y=cgetr(3); y[1]=x[1]; y[2]=0; return y; }
        !           193:       if (sx<0) setsigne(x,1);
        !           194:       if (cmpsr(1,x)>=0) { setsigne(x,sx); return mpasin(x); }
        !           195:
        !           196:       y=cgetg(3,t_COMPLEX);
        !           197:       y[1]=lmppi(lg(x)); setexpo(y[1],0);
        !           198:       y[2]=lmpach(x);
        !           199:       if (sx<0)
        !           200:       {
        !           201:         setsigne(y[1],-signe(y[1]));
        !           202:         setsigne(y[2],-signe(y[2]));
        !           203:         setsigne(x,sx);
        !           204:       }
        !           205:       return y;
        !           206:
        !           207:     case t_COMPLEX:
        !           208:       av=avma; p1=cgetg(3,t_COMPLEX);
        !           209:       p1[1]=lneg((GEN)x[2]);
        !           210:       p1[2]=x[1]; tetpil=avma;
        !           211:       y=gerepile(av,tetpil,gash(p1,prec));
        !           212:       l=y[1]; y[1]=y[2];
        !           213:       y[2]=l; gnegz((GEN)l,(GEN)l);
        !           214:       return y;
        !           215:
        !           216:     case t_SER:
        !           217:       if (gcmp0(x)) return gcopy(x);
        !           218:
        !           219:       av=avma; if (valp(x)<0) err(negexper,"gasin");
        !           220:       p1=gdiv(derivser(x), gsqrt(gsubsg(1,gsqr(x)),prec));
        !           221:       y=integ(p1,varn(x)); if (valp(x)) return gerepileupto(av,y);
        !           222:
        !           223:       p1=gasin((GEN)x[2],prec); tetpil=avma;
        !           224:       return gerepile(av,tetpil,gadd(p1,y));
        !           225:
        !           226:     case t_INTMOD: case t_PADIC:
        !           227:       err(typeer,"gasin");
        !           228:   }
        !           229:   return transc(gasin,x,prec);
        !           230: }
        !           231:
        !           232: void
        !           233: gasinz(GEN x, GEN y)
        !           234: {
        !           235:   long av=avma, prec = precision(y);
        !           236:
        !           237:   if (!prec) err(infprecer,"gasinz");
        !           238:   gaffect(gasin(x,prec),y); avma=av;
        !           239: }
        !           240:
        !           241: /********************************************************************/
        !           242: /**                                                                **/
        !           243: /**                      FONCTION ARCCOSINUS                       **/
        !           244: /**                                                                **/
        !           245: /********************************************************************/
        !           246:
        !           247: /* |x|<=1 */
        !           248: static GEN
        !           249: mpacos(GEN x)
        !           250: {
        !           251:   long l,u,v,sx,av;
        !           252:   GEN y,p1,p2;
        !           253:
        !           254:   u=cmprs(x,1); v=cmpsr(-1,x); sx = signe(x);
        !           255:   if (!sx)
        !           256:   {
        !           257:     l=expo(x)>>TWOPOTBITS_IN_LONG; if (l>=0) l = -1;
        !           258:     y=mppi(2-l); setexpo(y,0); return y;
        !           259:   }
        !           260:   l=lg(x);
        !           261:   if (!u)
        !           262:   {
        !           263:     y = cgetr(3);
        !           264:     y[1] = evalexpo(-(bit_accuracy(l)>>1));
        !           265:     y[2] = 0; return y;
        !           266:   }
        !           267:   if (!v) return mppi(l);
        !           268:   y=cgetr(l); av=avma;
        !           269:
        !           270:   p1=cgetr(l+1);
        !           271:   if (expo(x)<0)
        !           272:   {
        !           273:     mulrrz(x,x,p1);
        !           274:     subsrz(1,p1,p1);
        !           275:     p1 = mpsqrt(p1); divrrz(x,p1,p1);
        !           276:     p1 = mpatan(p1);
        !           277:     p2 = mppi(l); setexpo(p2,0);
        !           278:     p1 = subrr(p2,p1);
        !           279:   }
        !           280:   else
        !           281:   {
        !           282:     p2=cgetr(l+1);
        !           283:     if (sx>0) addsrz(1,x,p1); else subsrz(1,x,p1);
        !           284:     subsrz(2,p1,p2);
        !           285:     mulrrz(p1,p2,p1);
        !           286:     p1 = mpsqrt(p1); divrrz(p1,x,p1);
        !           287:     p1 = mpatan(p1);
        !           288:     if (sx<0) { setlg(p1,l); p1 = addrr(mppi(l),p1); }
        !           289:   }
        !           290:   affrr(p1,y); avma=av; return y;
        !           291: }
        !           292:
        !           293: GEN
        !           294: gacos(GEN x, long prec)
        !           295: {
        !           296:   long av,tetpil,l,sx;
        !           297:   GEN y,p1;
        !           298:
        !           299:   switch(typ(x))
        !           300:   {
        !           301:     case t_REAL: sx=signe(x);
        !           302:       if (sx<0) setsigne(x,1);
        !           303:       if (cmprs(x,1)<=0) { setsigne(x,sx); return mpacos(x); }
        !           304:
        !           305:       y=cgetg(3,t_COMPLEX); y[2]=lmpach(x);
        !           306:       if (sx<0) y[1]=lmppi(lg(x));
        !           307:       else
        !           308:       {
        !           309:        y[1]=zero; setsigne(y[2],-signe(y[2]));
        !           310:       }
        !           311:       setsigne(x,sx); return y;
        !           312:
        !           313:     case t_COMPLEX:
        !           314:       y=gach(x,prec);
        !           315:       l=y[1]; y[1]=y[2]; y[2]=l;
        !           316:       setsigne(y[2],-signe(y[2])); return y;
        !           317:
        !           318:     case t_SER: av=avma;
        !           319:       if (valp(x)<0) err(negexper,"gacos");
        !           320:       p1=integ(gdiv(derivser(x), gsqrt(gsubsg(1,gsqr(x)),prec)),varn(x));
        !           321:       if (gcmp1((GEN)x[2]) && !valp(x))
        !           322:       {
        !           323:        tetpil=avma; return gerepile(av,tetpil,gneg(p1));
        !           324:       }
        !           325:       if (valp(x)) { y=mppi(prec); setexpo(y,0); }
        !           326:       else y=gacos((GEN)x[2],prec);
        !           327:       tetpil=avma; return gerepile(av,tetpil,gsub(y,p1));
        !           328:
        !           329:     case t_INTMOD: case t_PADIC:
        !           330:       err(typeer,"gacos");
        !           331:   }
        !           332:   return transc(gacos,x,prec);
        !           333: }
        !           334:
        !           335: void
        !           336: gacosz(GEN x, GEN y)
        !           337: {
        !           338:   long av=avma, prec = precision(y);
        !           339:
        !           340:   if (!prec) err(infprecer,"gacosz");
        !           341:   gaffect(gacos(x,prec),y); avma=av;
        !           342: }
        !           343:
        !           344: /********************************************************************/
        !           345: /**                                                                **/
        !           346: /**                      FONCTION ARGUMENT                         **/
        !           347: /**                                                                **/
        !           348: /********************************************************************/
        !           349:
        !           350: /* we know that x and y are not both 0 */
        !           351: static GEN
        !           352: mparg(GEN x, GEN y)
        !           353: {
        !           354:   long prec,sx,sy;
        !           355:   GEN theta,pitemp;
        !           356:
        !           357:   sx=signe(x); sy=signe(y);
        !           358:   if (!sy)
        !           359:   {
        !           360:     if (sx>0)
        !           361:     {
        !           362:       theta=cgetr(3); theta[1]=y[1]-expo(x);
        !           363:       theta[2]=0; return theta;
        !           364:     }
        !           365:     return mppi(lg(x));
        !           366:   }
        !           367:   prec = lg(y); if (prec<lg(x)) prec = lg(x);
        !           368:   if (!sx)
        !           369:   {
        !           370:     theta=mppi(prec); setexpo(theta,0);
        !           371:     if (sy<0) setsigne(theta,-1);
        !           372:     return theta;
        !           373:   }
        !           374:
        !           375:   if (expo(x)-expo(y) > -2)
        !           376:   {
        !           377:     theta = mpatan(divrr(y,x));
        !           378:     if (sx>0) return theta;
        !           379:     pitemp=mppi(prec);
        !           380:     if (sy>0) return addrr(pitemp,theta);
        !           381:     return subrr(theta,pitemp);
        !           382:   }
        !           383:   theta = mpatan(divrr(x,y));
        !           384:   pitemp=mppi(prec); setexpo(pitemp,0);
        !           385:   if (sy>0) return subrr(pitemp,theta);
        !           386:
        !           387:   theta = addrr(pitemp,theta);
        !           388:   setsigne(theta,-signe(theta)); return theta;
        !           389: }
        !           390:
        !           391: static GEN
        !           392: rfix(GEN x,long prec)
        !           393: {
        !           394:   GEN p1;
        !           395:   switch(typ(x))
        !           396:   {
        !           397:     case t_INT: case t_FRAC: case t_FRACN:
        !           398:       p1=cgetr(prec); gaffect(x,p1); return p1;
        !           399:   }
        !           400:   return x;
        !           401: }
        !           402:
        !           403: static GEN
        !           404: sarg(GEN x, GEN y, long prec)
        !           405: {
        !           406:   long av=avma;
        !           407:   x = rfix(x,prec); y = rfix(y,prec);
        !           408:   return gerepileupto(av,mparg(x,y));
        !           409: }
        !           410:
        !           411: GEN
        !           412: garg(GEN x, long prec)
        !           413: {
        !           414:   GEN p1;
        !           415:   long av,tx=typ(x),tetpil;
        !           416:
        !           417:   if (gcmp0(x)) err(talker,"zero argument in garg");
        !           418:   switch(tx)
        !           419:   {
        !           420:     case t_REAL:
        !           421:       prec=lg(x); /* fall through */
        !           422:     case t_INT: case t_FRAC: case t_FRACN:
        !           423:       return (gsigne(x)>0)? realzero(prec): mppi(prec);
        !           424:
        !           425:     case t_QUAD:
        !           426:       av=avma; gaffsg(1,p1=cgetr(prec)); p1=gmul(p1,x);
        !           427:       tetpil=avma; return gerepile(av,tetpil,garg(p1,prec));
        !           428:
        !           429:     case t_COMPLEX:
        !           430:       return sarg((GEN)x[1],(GEN)x[2],prec);
        !           431:
        !           432:     case t_VEC: case t_COL: case t_MAT:
        !           433:       return transc(garg,x,prec);
        !           434:   }
        !           435:   err(typeer,"garg");
        !           436:   return NULL; /* not reached */
        !           437: }
        !           438:
        !           439: /********************************************************************/
        !           440: /**                                                                **/
        !           441: /**                 FONCTION COSINUS HYPERBOLIQUE                  **/
        !           442: /**                                                                **/
        !           443: /********************************************************************/
        !           444:
        !           445: static GEN
        !           446: mpch(GEN x)
        !           447: {
        !           448:   long l,av;
        !           449:   GEN y,p1;
        !           450:
        !           451:   if (gcmp0(x)) return gaddsg(1,x);
        !           452:
        !           453:   l=lg(x); y=cgetr(l); av=avma;
        !           454:   p1=mpexp(x); p1 = addrr(p1, divsr(1,p1));
        !           455:   setexpo(p1, expo(p1)-1);
        !           456:   affrr(p1,y); avma=av; return y;
        !           457: }
        !           458:
        !           459: GEN
        !           460: gch(GEN x, long prec)
        !           461: {
        !           462:   long av,tetpil;
        !           463:   GEN p1;
        !           464:
        !           465:   switch(typ(x))
        !           466:   {
        !           467:     case t_REAL:
        !           468:       return mpch(x);
        !           469:
        !           470:     case t_COMPLEX:
        !           471:       av=avma; p1=gexp(x,prec);
        !           472:       p1=gadd(p1,ginv(p1)); tetpil=avma;
        !           473:       return gerepile(av,tetpil,gmul2n(p1,-1));
        !           474:
        !           475:     case t_SER:
        !           476:       av=avma; p1=gexp(x,prec); p1=gadd(p1,gdivsg(1,p1));
        !           477:       tetpil=avma; return gerepile(av,tetpil,gmul2n(p1,-1));
        !           478:
        !           479:     case t_INTMOD: case t_PADIC:
        !           480:       err(typeer,"gch");
        !           481:   }
        !           482:   return transc(gch,x,prec);
        !           483: }
        !           484:
        !           485: void
        !           486: gchz(GEN x, GEN y)
        !           487: {
        !           488:   long av=avma,prec = precision(y);
        !           489:
        !           490:   if (!prec) err(infprecer,"gchz");
        !           491:   gaffect(gch(x,prec),y); avma=av;
        !           492: }
        !           493:
        !           494: /********************************************************************/
        !           495: /**                                                                **/
        !           496: /**                 FONCTION SINUS HYPERBOLIQUE                    **/
        !           497: /**                                                                **/
        !           498: /********************************************************************/
        !           499:
        !           500: static GEN
        !           501: mpsh(GEN x)
        !           502: {
        !           503:   long l,av;
        !           504:   GEN y,p1;
        !           505:
        !           506:   if (!signe(x))
        !           507:   {
        !           508:     y=cgetr(3); y[1]=x[1]; y[2]=0; return y;
        !           509:   }
        !           510:   l=lg(x); y=cgetr(l); av=avma;
        !           511:   p1=mpexp(x); p1 = addrr(p1, divsr(-1,p1));
        !           512:   setexpo(p1, expo(p1)-1);
        !           513:   affrr(p1,y); avma=av; return y;
        !           514: }
        !           515:
        !           516: GEN
        !           517: gsh(GEN x, long prec)
        !           518: {
        !           519:   long av,tetpil;
        !           520:   GEN p1;
        !           521:
        !           522:   switch(typ(x))
        !           523:   {
        !           524:     case t_REAL:
        !           525:       return mpsh(x);
        !           526:
        !           527:     case t_COMPLEX:
        !           528:       av=avma; p1=gexp(x,prec);
        !           529:       p1=gsub(p1,ginv(p1)); tetpil=avma;
        !           530:       return gerepile(av,tetpil,gmul2n(p1,-1));
        !           531:
        !           532:     case t_SER:
        !           533:       if (gcmp0(x)) return gcopy(x);
        !           534:
        !           535:       av=avma; p1=gexp(x,prec); p1=gsub(p1,gdivsg(1,p1));
        !           536:       tetpil=avma; return gerepile(av,tetpil,gmul2n(p1,-1));
        !           537:
        !           538:     case t_INTMOD: case t_PADIC:
        !           539:       err(typeer,"gsh");
        !           540:   }
        !           541:   return transc(gsh,x,prec);
        !           542: }
        !           543:
        !           544: void
        !           545: gshz(GEN x, GEN y)
        !           546: {
        !           547:   long av=avma, prec = precision(y);
        !           548:
        !           549:   if (!prec) err(infprecer,"gshz");
        !           550:   gaffect(gsh(x,prec),y); avma=av;
        !           551: }
        !           552:
        !           553: /********************************************************************/
        !           554: /**                                                                **/
        !           555: /**                 FONCTION TANGENTE HYPERBOLIQUE                 **/
        !           556: /**                                                                **/
        !           557: /********************************************************************/
        !           558:
        !           559: static GEN
        !           560: mpth(GEN x)
        !           561: {
        !           562:   long l,av;
        !           563:   GEN y,p1,p2;
        !           564:
        !           565:   if (!signe(x))
        !           566:   {
        !           567:     y=cgetr(3); y[1]=x[1]; y[2]=0;
        !           568:     return y;
        !           569:   }
        !           570:   l=lg(x); y=cgetr(l); av=avma;
        !           571:
        !           572:   p1=cgetr(l+1); affrr(x,p1);
        !           573:   setexpo(p1,expo(p1)+1);
        !           574:   p1 = mpexp1(p1);
        !           575:   p2 = addsr(2,p1); setlg(p2,l+1);
        !           576:   p1 = divrr(p1,p2);
        !           577:   affrr(p1,y); avma=av; return y;
        !           578: }
        !           579:
        !           580: GEN
        !           581: gth(GEN x, long prec)
        !           582: {
        !           583:   long av,tetpil;
        !           584:   GEN p1,p2,p3;
        !           585:
        !           586:   switch(typ(x))
        !           587:   {
        !           588:     case t_REAL:
        !           589:       return mpth(x);
        !           590:
        !           591:     case t_COMPLEX:
        !           592:       av=avma; p1=gexp(gmul2n(x,1),prec);
        !           593:       p1=gdivsg(-2,gaddgs(p1,1)); tetpil=avma;
        !           594:       return gerepile(av,tetpil,gaddsg(1,p1));
        !           595:
        !           596:     case t_SER:
        !           597:       if (gcmp0(x)) return gcopy(x);
        !           598:
        !           599:       av=avma; p1=gexp(gmul2n(x ,1),prec);
        !           600:       p2=gsubgs(p1,1); p3=gaddgs(p1,1);
        !           601:       tetpil=avma; return gerepile(av,tetpil,gdiv(p2,p3));
        !           602:
        !           603:     case t_INTMOD: case t_PADIC:
        !           604:       err(typeer,"gth");
        !           605:   }
        !           606:   return transc(gth,x,prec);
        !           607: }
        !           608:
        !           609: void
        !           610: gthz(GEN x, GEN y)
        !           611: {
        !           612:   long av=avma, prec = precision(y);
        !           613:
        !           614:   if (!prec) err(infprecer,"gthz");
        !           615:   gaffect(gth(x,prec),y); avma=av;
        !           616: }
        !           617:
        !           618: /********************************************************************/
        !           619: /**                                                                **/
        !           620: /**             FONCTION ARGUMENT SINUS HYPERBOLIQUE               **/
        !           621: /**                                                                **/
        !           622: /********************************************************************/
        !           623:
        !           624: /* x is non-zero */
        !           625: static GEN
        !           626: mpash(GEN x)
        !           627: {
        !           628:   long s=signe(x),av;
        !           629:   GEN y,p1;
        !           630:
        !           631:   y=cgetr(lg(x)); av=avma;
        !           632:   p1 = (s<0)? negr(x): x;
        !           633:   p1 = addrr(p1,mpsqrt(addsr(1,mulrr(p1,p1))));
        !           634:   p1 = mplog(p1); if (s<0) setsigne(p1,-signe(p1));
        !           635:   affrr(p1,y); avma=av; return y;
        !           636: }
        !           637:
        !           638: GEN
        !           639: gash(GEN x, long prec)
        !           640: {
        !           641:   long av,tetpil,sx,sy,sz;
        !           642:   GEN y,p1;
        !           643:
        !           644:   if (gcmp0(x)) return gcopy(x);
        !           645:   switch(typ(x))
        !           646:   {
        !           647:     case t_REAL:
        !           648:       return mpash(x);
        !           649:
        !           650:     case t_COMPLEX:
        !           651:       av=avma; p1=gaddsg(1,gsqr(x));
        !           652:       p1=gadd(x,gsqrt(p1,prec));
        !           653:       tetpil=avma; y=glog(p1,prec);
        !           654:       sz=gsigne((GEN)y[1]);
        !           655:       sx=gsigne((GEN)p1[1]);
        !           656:       sy=gsigne((GEN)p1[2]);
        !           657:       if (sx>0 || (!sx && sy*sz<=0)) return gerepile(av,tetpil,y);
        !           658:
        !           659:       y=gneg_i(y); p1=cgetg(3,t_COMPLEX); p1[1]=zero;
        !           660:       p1[2]=lmppi(prec); if (sy<0) setsigne(p1[2],-1);
        !           661:       tetpil=avma;
        !           662:       return gerepile(av,tetpil,gadd(y,p1));
        !           663:
        !           664:     case t_SER:
        !           665:       if (gcmp0(x)) return gcopy(x);
        !           666:       if (valp(x)<0) err(negexper,"gash");
        !           667:
        !           668:       av=avma; p1=gdiv(derivser(x),gsqrt(gaddsg(1,gsqr(x)),0));
        !           669:       y = integ(p1,varn(x)); if (valp(x)) return gerepileupto(av,y);
        !           670:       p1=gash((GEN)x[2],prec);
        !           671:       tetpil=avma; return gerepile(av,tetpil,gadd(p1,y));
        !           672:
        !           673:     case t_INTMOD: case t_PADIC:
        !           674:       err(typeer,"gash");
        !           675:   }
        !           676:   return transc(gash,x,prec);
        !           677: }
        !           678:
        !           679: void
        !           680: gashz(GEN x, GEN y)
        !           681: {
        !           682:   long av=avma, prec = precision(y);
        !           683:
        !           684:   if (!prec) err(infprecer,"gashz");
        !           685:   gaffect(gash(x,prec),y); avma=av;
        !           686: }
        !           687:
        !           688: /********************************************************************/
        !           689: /**                                                                **/
        !           690: /**            FONCTION ARGUMENT COSINUS HYPERBOLIQUE              **/
        !           691: /**                                                                **/
        !           692: /********************************************************************/
        !           693:
        !           694: static GEN
        !           695: mpach(GEN x)
        !           696: {
        !           697:   long l,av;
        !           698:   GEN y,p1;
        !           699:
        !           700:   l=lg(x); y=cgetr(l); av=avma;
        !           701:
        !           702:   p1=cgetr(l+1); affrr(x,p1);
        !           703:   p1 = mulrr(p1,p1);
        !           704:   subrsz(p1,1,p1);
        !           705:   p1 = mpsqrt(p1);
        !           706:   p1 = mplog(addrr(x,p1));
        !           707:   affrr(p1,y); avma=av; return y;
        !           708: }
        !           709:
        !           710: GEN
        !           711: gach(GEN x, long prec)
        !           712: {
        !           713:   long av,tetpil;
        !           714:   GEN y,p1;
        !           715:
        !           716:   switch(typ(x))
        !           717:   {
        !           718:     case t_REAL:
        !           719:       if (gcmpgs(x,1)>=0) return mpach(x);
        !           720:
        !           721:       y=cgetg(3,t_COMPLEX);
        !           722:       if (gcmpgs(x,-1)>=0)
        !           723:       {
        !           724:        y[2]=lmpacos(x); y[1]=zero;
        !           725:        return y;
        !           726:       }
        !           727:       av=avma; p1=mpach(gneg_i(x)); tetpil=avma;
        !           728:       y[1]=lpile(av,tetpil,gneg(p1));
        !           729:       y[2]=lmppi(lg(x));
        !           730:       return y;
        !           731:
        !           732:     case t_COMPLEX:
        !           733:       av=avma; p1=gaddsg(-1,gsqr(x));
        !           734:       p1=gadd(x,gsqrt(p1,prec)); tetpil=avma;
        !           735:       y=glog(p1,prec);
        !           736:       if (signe(y[2])<0) { tetpil=avma; y=gneg(y); }
        !           737:       return gerepile(av,tetpil,y);
        !           738:
        !           739:     case t_SER:
        !           740:       av=avma; if (valp(x)<0) err(negexper,"gach");
        !           741:       p1=gdiv(derivser(x),gsqrt(gsubgs(gsqr(x),1),prec));
        !           742:       y=integ(p1,varn(x));
        !           743:       if (!valp(x) && gcmp1((GEN)x[2])) return gerepileupto(av,y);
        !           744:       if (valp(x))
        !           745:       {
        !           746:        p1=cgetg(3,t_COMPLEX); p1[1]=zero; p1[2]=lmppi(prec);
        !           747:        setexpo(p1[2],0);
        !           748:       }
        !           749:       else p1=gach((GEN)x[2],prec);
        !           750:       tetpil=avma; return gerepile(av,tetpil,gadd(p1,y));
        !           751:
        !           752:     case t_INTMOD: case t_PADIC:
        !           753:       err(typeer,"gach");
        !           754:   }
        !           755:   return transc(gach,x,prec);
        !           756: }
        !           757:
        !           758: void
        !           759: gachz(GEN x, GEN y)
        !           760: {
        !           761:   long av=avma,prec = precision(y);
        !           762:
        !           763:   if (!prec) err(infprecer,"gachz");
        !           764:   gaffect(gach(x,prec),y); avma=av;
        !           765: }
        !           766:
        !           767: /********************************************************************/
        !           768: /**                                                                **/
        !           769: /**           FONCTION ARGUMENT TANGENTE HYPERBOLIQUE              **/
        !           770: /**                                                                **/
        !           771: /********************************************************************/
        !           772:
        !           773: static GEN
        !           774: mpath(GEN x)
        !           775: {
        !           776:   long av;
        !           777:   GEN y,p1;
        !           778:
        !           779:   if (!signe(x))
        !           780:   {
        !           781:     y=cgetr(3); y[1]=x[1]; y[2]=0;
        !           782:     return y;
        !           783:   }
        !           784:   y=cgetr(lg(x)); av=avma;
        !           785:   p1 = addrs(divsr(2,subsr(1,x)),-1);
        !           786:   affrr(mplog(p1), y); avma=av;
        !           787:   setexpo(y,expo(y)-1); return y;
        !           788: }
        !           789:
        !           790: GEN
        !           791: gath(GEN x, long prec)
        !           792: {
        !           793:   long av,tetpil;
        !           794:   GEN y,p1;
        !           795:
        !           796:   switch(typ(x))
        !           797:   {
        !           798:     case t_REAL:
        !           799:       if (expo(x)<0) return mpath(x);
        !           800:
        !           801:       av=avma; p1=addrs(divsr(2,addsr(-1,x)),1);
        !           802:       tetpil=avma; y=cgetg(3,t_COMPLEX);
        !           803:       p1=mplog(p1); setexpo(p1,expo(p1)-1);
        !           804:       y[1]=(long)p1;
        !           805:       y[2]=lmppi(lg(x)); setexpo(y[2],0);
        !           806:       return gerepile(av,tetpil,y);
        !           807:
        !           808:     case t_COMPLEX:
        !           809:       av=avma;
        !           810:       p1=gaddgs(gdivsg(2,gsubsg(1,x)),-1);
        !           811:       p1=glog(p1,prec); tetpil=avma;
        !           812:       return gerepile(av,tetpil,gmul2n(p1,-1));
        !           813:
        !           814:     case t_SER:
        !           815:       av=avma; if (valp(x)<0) err(negexper,"gath");
        !           816:       p1=gdiv(derivser(x), gsubsg(1,gsqr(x)));
        !           817:       y = integ(p1,varn(x)); if (valp(x)) return gerepileupto(av,y);
        !           818:       p1=gath((GEN)x[2],prec); tetpil=avma;
        !           819:       return gerepile(av,tetpil,gadd(p1,y));
        !           820:
        !           821:     case t_INTMOD: case t_PADIC:
        !           822:       err(typeer,"gath");
        !           823:   }
        !           824:   return transc(gath,x,prec);
        !           825: }
        !           826:
        !           827: void
        !           828: gathz(GEN x, GEN y)
        !           829: {
        !           830:   long av=avma, prec = precision(y);
        !           831:
        !           832:   if (!prec) err(infprecer,"gathz");
        !           833:   gaffect(gath(x,prec),y); avma=av;
        !           834: }
        !           835:
        !           836: /********************************************************************/
        !           837: /**                                                                **/
        !           838: /**             FONCTION TABLEAU DES NOMBRES DE BERNOULLI          **/
        !           839: /**                                                                **/
        !           840: /********************************************************************/
        !           841:
        !           842: /* pour calculer B_0,B_2,...,B_2*nb */
        !           843: void
        !           844: mpbern(long nb, long prec)
        !           845: {
        !           846:   long n,m,i,j,d,d1,d2,l,av,av2,code0;
        !           847:   GEN p1,p2;
        !           848:
        !           849:   if (nb<0) nb=0;
        !           850:   if (bernzone)
        !           851:   {
        !           852:     if (bernzone[1]>=nb && bernzone[2]>=prec) return;
        !           853:     gunclone(bernzone);
        !           854:   }
        !           855:   d = 3 + prec*(nb+1); bernzone=newbloc(d);
        !           856:   bernzone[0]=evallg(d);
        !           857:   bernzone[1]=nb;
        !           858:   bernzone[2]=prec;
        !           859:   av=avma; l = prec+1; p1=realun(l);
        !           860:
        !           861:   code0 = evaltyp(t_REAL) | evallg(prec);
        !           862:   *(bern(0)) = code0; affsr(1,bern(0));
        !           863:   p2 = p1; av2=avma;
        !           864:   for (i=1; i<=nb; i++)
        !           865:   {
        !           866:     if (i>1)
        !           867:     {
        !           868:       n=8; m=5; d = d1 = i-1; d2 = 2*i-3;
        !           869:       for (j=d; j>0; j--)
        !           870:       {
        !           871:         p2 = bern(j);
        !           872:         if (j<d) p2 = addrr(p2,p1);
        !           873:         else
        !           874:         {
        !           875:           affrr(p2,p1); p2=p1;
        !           876:         }
        !           877:         p2 = mulsr(n*m,p2); setlg(p2,l);
        !           878:         p2 = divrs(p2, d1*d2); affrr(p2,p1);
        !           879:         n+=4; m+=2; d1--; d2-=2;
        !           880:       }
        !           881:       p2 = addsr(1,p1); setlg(p2,l);
        !           882:     }
        !           883:     p2 = divrs(p2,2*i+1); p2 = subsr(1,p2);
        !           884:     setexpo(p2, expo(p2) - 2*i);
        !           885:     *(bern(i)) = code0; affrr(p2,bern(i)); avma=av2;
        !           886:   }
        !           887:   avma=av;
        !           888: }
        !           889:
        !           890: GEN
        !           891: bernreal(long n, long prec)
        !           892: {
        !           893:   GEN B;
        !           894:
        !           895:   if (n==1) { B=cgetr(prec); affsr(-1,B); setexpo(B,-1); return B; }
        !           896:   if (n<0 || n&1) return gzero;
        !           897:   n >>= 1; mpbern(n+1,prec); B=cgetr(prec);
        !           898:   affrr(bern(n),B); return B;
        !           899: }
        !           900:
        !           901: /* k > 0 */
        !           902: static GEN
        !           903: bernfracspec(long k)
        !           904: {
        !           905:   long n,av,lim, K = k+1;
        !           906:   GEN s,c,N,h;
        !           907:
        !           908:   c = N = stoi(K); s = gun; h = gzero;
        !           909:   av = avma; lim = stack_lim(av,2);
        !           910:   for (n=2; ; n++)
        !           911:   {
        !           912:     c = gdivgs(gmulgs(c,n-k-2),n);
        !           913:     h = gadd(h, gdivgs(gmul(c,s), n));
        !           914:     if (n==K) return gerepileupto(av,h);
        !           915:     N[2] = n; s = addii(s, gpuigs(N,k));
        !           916:     if (low_stack(lim, stack_lim(av,2)))
        !           917:     {
        !           918:       GEN *gptr[3]; gptr[0]=&c; gptr[1]=&h; gptr[2]=&s;
        !           919:       if (DEBUGMEM>1) err(warnmem,"bernfrac");
        !           920:       gerepilemany(av,gptr,3);
        !           921:     }
        !           922:   }
        !           923: }
        !           924:
        !           925: GEN
        !           926: bernfrac(long k)
        !           927: {
        !           928:   if (!k) return gun;
        !           929:   if (k==1) return gneg(ghalf);
        !           930:   if (k<0 || k&1) return gzero;
        !           931:   return bernfracspec(k);
        !           932: }
        !           933:
        !           934: static GEN
        !           935: bernvec2(long k)
        !           936: {
        !           937:   GEN B = cgetg(k+2,t_VEC);
        !           938:   ulong i;
        !           939:
        !           940:   for (i=1; i<=k; i++)
        !           941:     B[i+1]=(long)bernfracspec(i<<1);
        !           942:   B[1]=un; return B;
        !           943: }
        !           944:
        !           945: /* mpbern as exact fractions */
        !           946: GEN
        !           947: bernvec(long nb)
        !           948: {
        !           949:   long n,m,i,j,d1,d2,av,tetpil;
        !           950:   GEN  p1,y;
        !           951:
        !           952:   if (nb < 300) return bernvec2(nb);
        !           953:
        !           954:   y=cgetg(nb+2,t_VEC); y[1]=un;
        !           955:   for (i=1; i<=nb; i++)
        !           956:   {
        !           957:     av=avma; p1=gzero;
        !           958:     n=8; m=5; d1=i-1; d2=2*i-3;
        !           959:     for (j=d1; j>0; j--)
        !           960:     {
        !           961:       p1 = gmulsg(n*m, gadd(p1,(GEN)y[j+1]));
        !           962:       p1 = gdivgs(p1, d1*d2);
        !           963:       n+=4; m+=2; d1--; d2-=2;
        !           964:     }
        !           965:     p1 = gsubsg(1,gdivgs(gaddsg(1,p1),2*i+1));
        !           966:     tetpil=avma; p1 = gmul2n(p1,-2*i);
        !           967:     y[i+1] = lpile(av,tetpil,p1);
        !           968:   }
        !           969:   return y;
        !           970: }
        !           971:
        !           972: /********************************************************************/
        !           973: /**                                                                **/
        !           974: /**                      FONCTION GAMMA                            **/
        !           975: /**                                                                **/
        !           976: /********************************************************************/
        !           977:
        !           978: static GEN
        !           979: mpgamma(GEN x)
        !           980: {
        !           981:   GEN y,p1,p2,p3,p4,p5,p6,p7,p71,pitemp;
        !           982:   long l,l1,l2,u,i,k,e,s,sx,n,p,av,av1;
        !           983:   double alpha,beta,dk;
        !           984:
        !           985:   sx=signe(x); if (!sx) err(gamer2);
        !           986:   l=lg(x); y=cgetr(l); av=avma;
        !           987:
        !           988:   l2=l+1; p1=cgetr(l2);
        !           989:   u = (expo(x)<-1 || sx<0);
        !           990:   if (!u) p2 = x;
        !           991:   else
        !           992:   {
        !           993:     p2=gfrac(x); if (gcmp0(p2)) err(gamer2);
        !           994:     p2 = subsr(1,x);
        !           995:   }
        !           996:   affrr(p2,p1);
        !           997:   alpha=rtodbl(p1); beta=((bit_accuracy(l)>>1)*LOG2/PI) - alpha;
        !           998:   if (beta>=0) n=(long)(1 + pariK2*beta); else n=0;
        !           999:   if (n)
        !          1000:   {
        !          1001:     p = (long)(1 + PI*(alpha+n));
        !          1002:     l2 += n>>TWOPOTBITS_IN_LONG;
        !          1003:     p2 = cgetr(l2); addsrz(n,p1,p2);
        !          1004:   }
        !          1005:   else
        !          1006:   {
        !          1007:     dk = pariK4*alpha/(l-2); beta = log(dk)/LOG2;
        !          1008:     if (beta>1.) beta += log(beta)/LOG2;
        !          1009:     p = (long)((bit_accuracy(l)>>1)/beta + 1);
        !          1010:     p2 = p1;
        !          1011:   }
        !          1012:   mpbern(p,l2); p3=mplog(p2);
        !          1013:
        !          1014:   p4=realun(l2); setexpo(p4,-1);
        !          1015:   p6 = subrr(p2,p4); p6 = mulrr(p6,p3);
        !          1016:   p6 = subrr(p6,p2);
        !          1017:   pitemp = mppi(l2); setexpo(pitemp,2);
        !          1018:   p7 = mplog(pitemp); setexpo(pitemp,1);
        !          1019:   setexpo(p7,-1); addrrz(p6,p7,p4);
        !          1020:
        !          1021:   affrr(ginv(gsqr(p2)), p3); e=expo(p3);
        !          1022:
        !          1023:   p5=cgetr(l2); setlg(p5,4);
        !          1024:   p71=cgetr(l2); p7 = bern(p);
        !          1025:   if (bernzone[2]>4) { setlg(p71,4); affrr(p7,p71); p7=p71; }
        !          1026:   p7 = divrs(p7, 2*p*(2*p-1)); affrr(p7,p5);
        !          1027:
        !          1028:   s=0; l1=4; av1=avma;
        !          1029:   for (k=p-1; k>0; k--)
        !          1030:   {
        !          1031:     setlg(p3,l1); p6 = mulrr(p3,p5); p7 = bern(k);
        !          1032:     if (bernzone[2]>l1) { setlg(p71,l1); affrr(p7,p71); p7=p71; }
        !          1033:     p7 = divrs(p7, (2*k)*(2*k-1));
        !          1034:     s -= e; l1 += (s>>TWOPOTBITS_IN_LONG); if (l1>l2) l1=l2;
        !          1035:     s &= (BITS_IN_LONG-1); p7 = addrr(p7,p6);
        !          1036:     setlg(p5,l1); affrr(p7,p5); avma=av1;
        !          1037:   }
        !          1038:   setlg(p5,l2); p6 = divrr(p5,p2);
        !          1039:   p4 = addrr(p4,p6); setlg(p4,l2); p4 = mpexp(p4);
        !          1040:   for (i=1; i<=n; i++)
        !          1041:   {
        !          1042:     addsrz(-1,p2,p2); p4 = divrr(p4,p2);
        !          1043:   }
        !          1044:   if (u)
        !          1045:   {
        !          1046:     setlg(pitemp,l+1); p1 = mulrr(pitemp,x);
        !          1047:     p4 = mulrr(mpsin(p1), p4); p4 = divrr(pitemp,p4);
        !          1048:   }
        !          1049:   affrr(p4,y); avma=av; return y;
        !          1050: }
        !          1051:
        !          1052: static GEN
        !          1053: cxgamma(GEN x, long prec)
        !          1054: {
        !          1055:   GEN y,p1,p2,p3,p4,p5,p6,p7,p71,pitemp;
        !          1056:   long l,l1,l2,u,i,k,e,s,n,p,av,av1;
        !          1057:   double alpha,beta,dk;
        !          1058:
        !          1059:   l = precision(x); if (!l) l = prec;
        !          1060:   l2 = l+1; y=cgetg(3,t_COMPLEX);
        !          1061:   y[1]=lgetr(l); y[2]=lgetr(l); av=avma;
        !          1062:
        !          1063:   p1=cgetg(3,t_COMPLEX); p1[1]=lgetr(l2); p1[2]=lgetr(l2);
        !          1064:   u = (typ(x[1])!=t_REAL && gsigne((GEN)x[1])<=0)? 1: (gexpo((GEN)x[1]) < -1);
        !          1065:   p2 = u? gsub(gun,x): x;
        !          1066:   gaffect(p2,p1);
        !          1067:
        !          1068:   alpha=rtodbl(gabs(p1,DEFAULTPREC));
        !          1069:   beta = (bit_accuracy(l)>>1) * LOG2 / PI - alpha;
        !          1070:   if (beta>=0) n=(long)(1 + pariK2*beta); else n=0;
        !          1071:   if (n)
        !          1072:   {
        !          1073:     p = (long)(1+PI*(alpha+n));
        !          1074:     l2 += n>>TWOPOTBITS_IN_LONG;
        !          1075:     p2=cgetg(3,t_COMPLEX); p2[1]=lgetr(l2); p2[2]=lgetr(l2);
        !          1076:     addsrz(n,(GEN)p1[1],(GEN)p2[1]);
        !          1077:     affrr((GEN)p1[2],(GEN)p2[2]);
        !          1078:   }
        !          1079:   else
        !          1080:   {
        !          1081:     dk = pariK4*alpha/(l-2); beta = log(dk)/LOG2;
        !          1082:     if (beta>1.) beta += log(beta)/LOG2;
        !          1083:     p = (long)((bit_accuracy(l)>>1)/beta + 1);
        !          1084:     p2 = p1;
        !          1085:   }
        !          1086:   mpbern(p,l2); p3 = glog(p2,l2);
        !          1087:
        !          1088:   p4=cgetg(3,t_COMPLEX);
        !          1089:   p4[1] = (long)realun(l2); setexpo(p4[1],-1);
        !          1090:   p4[2] = (long)rcopy((GEN)p2[2]);
        !          1091:   subrrz((GEN)p2[1],(GEN)p4[1],(GEN)p4[1]);
        !          1092:   gmulz(p4,p3,p4); gsubz(p4,p2,p4);
        !          1093:
        !          1094:   pitemp = mppi(l2); setexpo(pitemp,2);
        !          1095:   p7 = mplog(pitemp); setexpo(pitemp,1);
        !          1096:   setexpo(p7,-1); addrrz((GEN)p4[1],p7, (GEN)p4[1]);
        !          1097:
        !          1098:   gaffect(ginv(gsqr(p2)), p3); e=gexpo(p3);
        !          1099:
        !          1100:   p5=cgetg(3,t_COMPLEX);
        !          1101:   p5[1]=lgetr(l2); setlg(p5[1],4);
        !          1102:   p5[2]=lgetr(l2); setlg(p5[2],4);
        !          1103:   p71=cgetr(l2); p7 = bern(p);
        !          1104:   if (bernzone[2]>4) { setlg(p71,4); affrr(p7,p71); p7=p71; }
        !          1105:   p7 = divrs(p7, 2*p*(2*p-1)); gaffect(p7,p5);
        !          1106:
        !          1107:   s=0; l1=4; av1=avma;
        !          1108:   for (k=p-1; k>0; k--)
        !          1109:   {
        !          1110:     setlg(p3[1],l1); setlg(p3[2],l1);
        !          1111:     p6 = gmul(p3,p5); p7 = bern(k);
        !          1112:     if (bernzone[2]>l1) { setlg(p71,l1); affrr(p7,p71); p7=p71; }
        !          1113:     p7 = divrs(p7, (2*k)*(2*k-1));
        !          1114:     s -= e; l1 += (s>>TWOPOTBITS_IN_LONG); if (l1>l2) l1=l2;
        !          1115:     s &= (BITS_IN_LONG-1); p7 = addrr(p7, (GEN)p6[1]);
        !          1116:     setlg(p5[1],l1); affrr(p7, (GEN)p5[1]); p7 = (GEN)p6[2];
        !          1117:     setlg(p5[2],l1); affrr(p7, (GEN)p5[2]); avma=av1;
        !          1118:   }
        !          1119:   setlg(p5[1],l2); setlg(p5[2],l2);
        !          1120:   p6 = gdiv(p5,p2); setlg(p6[1],l2); setlg(p6[2],l2);
        !          1121:   p4 = gadd(p4,p6); setlg(p4[1],l2); setlg(p4[2],l2);
        !          1122:   p4 = gexp(p4,l2);
        !          1123:   for (i=1; i<=n; i++)
        !          1124:   {
        !          1125:     addsrz(-1,(GEN)p2[1],(GEN)p2[1]); p4 = gdiv(p4,p2);
        !          1126:   }
        !          1127:   if (u)
        !          1128:   {
        !          1129:     setlg(pitemp,l+1); p1 = gmul(pitemp,x);
        !          1130:     p4 = gmul(gsin(p1,l+1), p4); p4 = gdiv(pitemp,p4);
        !          1131:   }
        !          1132:   gaffect(p4,y); avma=av; return y;
        !          1133: }
        !          1134:
        !          1135: GEN
        !          1136: ggamma(GEN x, long prec)
        !          1137: {
        !          1138:   switch(typ(x))
        !          1139:   {
        !          1140:     case t_INT:
        !          1141:       if (signe(x)<=0) err(gamer2);
        !          1142:       return transc(ggamma,x,prec);
        !          1143:
        !          1144:     case t_REAL:
        !          1145:       return mpgamma(x);
        !          1146:
        !          1147:     case t_COMPLEX:
        !          1148:       return gcmp0((GEN)x[2])? ggamma((GEN)x[1],prec): cxgamma(x,prec);
        !          1149:
        !          1150:     case t_SER:
        !          1151:       return gexp(glngamma(x,prec),prec);
        !          1152:
        !          1153:     case t_PADIC:
        !          1154:       err(impl,"p-adic gamma function");
        !          1155:     case t_INTMOD:
        !          1156:       err(typeer,"ggamma");
        !          1157:   }
        !          1158:   return transc(ggamma,x,prec);
        !          1159: }
        !          1160:
        !          1161: void
        !          1162: ggammaz(GEN x, GEN y)
        !          1163: {
        !          1164:   long av=avma, prec = precision(y);
        !          1165:
        !          1166:   if (!prec) err(infprecer,"ggammaz");
        !          1167:   gaffect(ggamma(x,prec),y); avma=av;
        !          1168: }
        !          1169:
        !          1170: static GEN
        !          1171: mplngamma(GEN x)
        !          1172: {
        !          1173:   GEN y,p1,p2,p3,p4,p5,p6,p7,p71,pitemp;
        !          1174:   long l,l1,l2,u,i,k,e,f,s,sx,n,p,av,av1;
        !          1175:   double alpha,beta,dk;
        !          1176:
        !          1177:   sx=signe(x); if (!sx) err(talker,"zero argument in mplngamma");
        !          1178:   cgetg(3, t_COMPLEX); l=lg(x); y=cgetr(l); av=avma;
        !          1179:
        !          1180:   l2=l+1; p1=cgetr(l2);
        !          1181:   u = (expo(x)<-1 || sx<0);
        !          1182:   if (!u) p2 = x;
        !          1183:   else
        !          1184:   {
        !          1185:     p2=gfrac(x); if (gcmp0(p2)) err(gamer2);
        !          1186:     p2 = subsr(1,x);
        !          1187:   }
        !          1188:   affrr(p2,p1);
        !          1189:   if (expo(p1)>1000)
        !          1190:   {
        !          1191:     n=0; beta = log(pariK4/(l-2))/LOG2+expo(p1);
        !          1192:     beta += log(beta)/LOG2;
        !          1193:     p = (long)((bit_accuracy(l)>>1)/beta + 1);
        !          1194:     p2 = p1;
        !          1195:   }
        !          1196:   else
        !          1197:   {
        !          1198:     alpha=rtodbl(p1); beta = ((bit_accuracy(l)>>1) * LOG2 / PI) - alpha;
        !          1199:     if (beta>=0) n=(long)(1 + pariK2*beta); else n=0;
        !          1200:     if (n)
        !          1201:     {
        !          1202:       p=(long)(1+PI*(alpha+n));
        !          1203:       l2 += n>>TWOPOTBITS_IN_LONG;
        !          1204:       p2 = cgetr(l2); addsrz(n,p1,p2);
        !          1205:     }
        !          1206:     else
        !          1207:     {
        !          1208:       dk = pariK4*alpha/(l-2); beta = log(dk)/LOG2;
        !          1209:       if (beta>1.) beta += (log(beta)/LOG2);
        !          1210:       p = (long)((bit_accuracy(l)>>1)/beta + 1);
        !          1211:       p2 = p1;
        !          1212:     }
        !          1213:   }
        !          1214:   mpbern(p,l2); p3=mplog(p2);
        !          1215:
        !          1216:   p4=realun(l2); setexpo(p4,-1);
        !          1217:   p6 = subrr(p2,p4); p6 = mulrr(p6,p3);
        !          1218:   p6 = subrr(p6,p2);
        !          1219:   pitemp = mppi(l2); setexpo(pitemp,2);
        !          1220:   p7 = mplog(pitemp); setexpo(pitemp,1);
        !          1221:   setexpo(p7,-1); addrrz(p6,p7,p4);
        !          1222:
        !          1223:   affrr(ginv(gsqr(p2)), p3); e=expo(p3);
        !          1224:
        !          1225:   p5=cgetr(l2); setlg(p5,4);
        !          1226:   p71=cgetr(l2); p7 = bern(p);
        !          1227:   if (bernzone[2]>4) { setlg(p71,4); affrr(p7,p71); p7=p71; }
        !          1228:   p7 = divrs(p7, 2*p*(2*p-1)); affrr(p7,p5);
        !          1229:
        !          1230:   s=0; l1=4; av1=avma;
        !          1231:   for (k=p-1; k>0; k--)
        !          1232:   {
        !          1233:     setlg(p3,l1); p6 = mulrr(p3,p5); p7 = bern(k);
        !          1234:     if (bernzone[2]>l1) { setlg(p71,l1); affrr(p7,p71); p7=p71; }
        !          1235:     p7 = divrs(p7, (2*k)*(2*k-1));
        !          1236:     s -= e; l1 += (s>>TWOPOTBITS_IN_LONG); if (l1>l2) l1=l2;
        !          1237:     s &= (BITS_IN_LONG-1); p7 = addrr(p7,p6);
        !          1238:     setlg(p5,l1); affrr(p7,p5); avma=av1;
        !          1239:   }
        !          1240:   setlg(p5,l2); p6 = divrr(p5,p2);
        !          1241:   p4 = addrr(p4,p6); setlg(p4,l2);
        !          1242:   if (n)
        !          1243:   {
        !          1244:     for (i=1; i<=n; i++)
        !          1245:     {
        !          1246:       addsrz(-1,p2,p2); p7 = (i==1)? rcopy(p2): mulrr(p7,p2);
        !          1247:     }
        !          1248:     f=signe(p7); if (f<0) setsigne(p7,1);
        !          1249:     subrrz(p4,mplog(p7),p4);
        !          1250:   }
        !          1251:   else f=1;
        !          1252:   if (u)
        !          1253:   {
        !          1254:     setlg(pitemp,l+1); p1 = mulrr(pitemp,x);
        !          1255:     p1 = divrr(pitemp,mpsin(p1));
        !          1256:     if (signe(p1) < 0) { setsigne(p1,1); f = -f; }
        !          1257:     p4 = subrr(mplog(p1),p4);
        !          1258:   }
        !          1259:   if (f<0) /* t_COMPLEX result */
        !          1260:   {
        !          1261:     p2 = y - 3;
        !          1262:     p2[1] = (long)y; affrr(p4,y); avma = av;
        !          1263:     p2[2] = (long)mppi(l); return p2;
        !          1264:   }
        !          1265:   /* t_REAL result */
        !          1266:   y[3] = y[0]; y += 3;
        !          1267:   affrr(p4,y); avma = (long)y; return y;
        !          1268: }
        !          1269:
        !          1270: static GEN
        !          1271: cxlngamma(GEN x, long prec)
        !          1272: {
        !          1273:   GEN y,p1,p2,p3,p4,p5,p6,p7,p71,pitemp;
        !          1274:   long l,l1,l2,u,i,k,e,s,n,p,av,av1;
        !          1275:   double alpha,beta,dk;
        !          1276:
        !          1277:   l = precision(x); if (!l) l = prec;
        !          1278:   l2 = l+1; y=cgetg(3,t_COMPLEX);
        !          1279:   y[1]=lgetr(l); y[2]=lgetr(l); av=avma;
        !          1280:
        !          1281:   p1=cgetg(3,t_COMPLEX); p1[1]=lgetr(l2); p1[2]=lgetr(l2);
        !          1282:   u = (typ(x[1])!=t_REAL && gsigne((GEN)x[1])<=0)? 1: (gexpo((GEN)x[1]) < -1);
        !          1283:   if (u && (gcmp0((GEN)x[2]) || gexpo((GEN)x[2])>16)) u = 0;
        !          1284:   p2 = u? gsub(gun,x): x;
        !          1285:   gaffect(p2,p1);
        !          1286:
        !          1287:   p2=gabs(p1,DEFAULTPREC);
        !          1288:   if (expo(p2)>1000)
        !          1289:   {
        !          1290:     n=0; beta = log(pariK4/(l-2)) / LOG2 + expo(p1);
        !          1291:     beta += log(beta)/LOG2;
        !          1292:     p = (long)((bit_accuracy(l)>>1)/beta + 1);
        !          1293:     p2 = p1;
        !          1294:   }
        !          1295:   else
        !          1296:   {
        !          1297:     alpha=rtodbl(p2); beta = ((bit_accuracy(l)>>1) * LOG2 / PI) - alpha;
        !          1298:     if (beta>=0) n=(long)(1+pariK2*beta); else n=0;
        !          1299:     if (n)
        !          1300:     {
        !          1301:       p = (long)(1+PI*(alpha+n));
        !          1302:       l2 += n>>TWOPOTBITS_IN_LONG;
        !          1303:       p2=cgetg(3,t_COMPLEX); p2[1]=lgetr(l2); p2[2]=lgetr(l2);
        !          1304:       addsrz(n,(GEN)p1[1],(GEN)p2[1]);
        !          1305:       affrr((GEN)p1[2],(GEN)p2[2]);
        !          1306:     }
        !          1307:     else
        !          1308:     {
        !          1309:       dk = pariK4*alpha/(l-2); beta = log(dk)/LOG2;
        !          1310:       if (beta>1.) beta += log(beta)/LOG2;
        !          1311:       p = (long)((bit_accuracy(l)>>1)/beta + 1);
        !          1312:       p2 = p1;
        !          1313:     }
        !          1314:   }
        !          1315:   mpbern(p,l2); p3 = glog(p2,l2);
        !          1316:
        !          1317:   p4=cgetg(3,t_COMPLEX);
        !          1318:   p4[1] = (long)realun(l2); setexpo(p4[1],-1);
        !          1319:   subrrz((GEN)p2[1],(GEN)p4[1],(GEN)p4[1]);
        !          1320:   p4[2] = (long)rcopy((GEN)p2[2]);
        !          1321:   gmulz(p4,p3,p4); gsubz(p4,p2,p4);
        !          1322:
        !          1323:   pitemp = mppi(l2); setexpo(pitemp,2);
        !          1324:   p7 = mplog(pitemp); setexpo(pitemp,1);
        !          1325:   setexpo(p7,-1); addrrz((GEN)p4[1],p7, (GEN)p4[1]);
        !          1326:
        !          1327:   gaffect(ginv(gsqr(p2)),p3); e=gexpo(p3);
        !          1328:
        !          1329:   p5=cgetg(3,t_COMPLEX);
        !          1330:   p5[1]=lgetr(l2); setlg(p5[1],4);
        !          1331:   p5[2]=lgetr(l2); setlg(p5[2],4);
        !          1332:   p71=cgetr(l2); p7 = bern(p);
        !          1333:   if (bernzone[2]>4) { setlg(p71,4); affrr(p7,p71); p7=p71; }
        !          1334:   p7 = divrs(p7, 2*p*(2*p-1)); gaffect(p7,p5);
        !          1335:
        !          1336:   s=0; l1=4; av1=avma;
        !          1337:   for (k=p-1; k>0; k--)
        !          1338:   {
        !          1339:     setlg(p3[1],l1); setlg(p3[2],l1);
        !          1340:     p6 = gmul(p3,p5); p7 = bern(k);
        !          1341:     if (bernzone[2]>l1) { setlg(p71,l1); affrr(p7,p71); p7=p71; }
        !          1342:     p7 = divrs(p7, (2*k)*(2*k-1));
        !          1343:     s -= e; l1 += (s>>TWOPOTBITS_IN_LONG); if (l1>l2) l1=l2;
        !          1344:     s &= (BITS_IN_LONG-1); p7 = addrr(p7, (GEN)p6[1]);
        !          1345:     setlg(p5[1],l1); affrr(p7, (GEN)p5[1]); p7 = (GEN)p6[2];
        !          1346:     setlg(p5[2],l1); affrr(p7, (GEN)p5[2]); avma=av1;
        !          1347:   }
        !          1348:   setlg(p5[1],l2); setlg(p5[2],l2);
        !          1349:   p6 = gdiv(p5,p2); setlg(p6[1],l2); setlg(p6[2],l2);
        !          1350:   p4 = gadd(p4,p6); setlg(p4[1],l2); setlg(p4[2],l2);
        !          1351:
        !          1352:   if (n)
        !          1353:   {
        !          1354:     p7 = cgetg(3,t_COMPLEX); p7[2] = p2[2];
        !          1355:     for (i=1; i<=n; i++)
        !          1356:     {
        !          1357:       addsrz(-1,(GEN)p2[1], (GEN)p2[1]);
        !          1358:       if (i==1) p7[1] = lrcopy((GEN)p2[1]); else p7 = gmul(p7,p2);
        !          1359:     }
        !          1360:     gsubz(p4,glog(p7,l+1), p4);
        !          1361:   }
        !          1362:   if (u)
        !          1363:   {
        !          1364:     setlg(pitemp,l+1); p1 = gmul(pitemp,x);
        !          1365:     p1 = gdiv(pitemp,gsin(p1,l+1));
        !          1366:     p4 = gsub(glog(p1,l+1),p4);
        !          1367:   }
        !          1368:   affrr((GEN)p4[1], (GEN)y[1]); setlg(p4[2],l+1);
        !          1369:
        !          1370:   p1 = subrr(pitemp, (GEN)p4[2]); setexpo(pitemp,2);
        !          1371:   p1 = gfloor(divrr(p1,pitemp));
        !          1372:   p1 = addrr(mulir(p1,pitemp), (GEN)p4[2]);
        !          1373:   affrr(p1, (GEN)y[2]); avma=av; return y;
        !          1374: }
        !          1375:
        !          1376: GEN
        !          1377: glngamma(GEN x, long prec)
        !          1378: {
        !          1379:   long i,av,tetpil,n;
        !          1380:   GEN y,p1;
        !          1381:
        !          1382:   switch(typ(x))
        !          1383:   {
        !          1384:     case t_INT:
        !          1385:       if (signe(x)<=0) err(gamer2);
        !          1386:       return transc(glngamma,x,prec);
        !          1387:
        !          1388:     case t_REAL:
        !          1389:       return mplngamma(x);
        !          1390:
        !          1391:     case t_COMPLEX:
        !          1392:       return gcmp0((GEN)x[2])? glngamma((GEN)x[1],prec): cxlngamma(x,prec);
        !          1393:
        !          1394:     case t_SER:
        !          1395:       av=avma; if (valp(x)) err(negexper,"glngamma");
        !          1396:       if (!gcmp1((GEN)x[2])) err(impl,"lngamma around a!=1");
        !          1397:       p1=gsubsg(1,x); n=(lg(x)-3)/valp(p1);
        !          1398:       y=ggrando(polx[varn(x)],lg(x)-2);
        !          1399:       for (i=n; i>=2; i--)
        !          1400:        y = gmul(p1,gadd(gdivgs(gzeta(stoi(i),prec),i),y));
        !          1401:       y = gadd(mpeuler(prec),y); tetpil=avma;
        !          1402:       return gerepile(av,tetpil,gmul(p1,y));
        !          1403:
        !          1404:     case t_PADIC:
        !          1405:       err(impl,"p-adic lngamma function");
        !          1406:     case t_INTMOD:
        !          1407:       err(typeer,"glngamma");
        !          1408:   }
        !          1409:   return transc(glngamma,x,prec);
        !          1410: }
        !          1411:
        !          1412: void
        !          1413: glngammaz(GEN x, GEN y)
        !          1414: {
        !          1415:   long av=avma, prec = precision(y);
        !          1416:
        !          1417:   if (!prec) err(infprecer,"glngammaz");
        !          1418:   gaffect(glngamma(x,prec),y); avma=av;
        !          1419: }
        !          1420:
        !          1421: /********************************************************************/
        !          1422: /**                                                                **/
        !          1423: /**             FONCTION GAMMA DES DEMI-ENTIERS                    **/
        !          1424: /**                                                                **/
        !          1425: /********************************************************************/
        !          1426:
        !          1427: static GEN
        !          1428: mpgamd(long x, long prec)
        !          1429: {
        !          1430:   long i,j,a,l,av;
        !          1431:   GEN y,p1,p2;
        !          1432:
        !          1433:   a = labs(x);
        !          1434:   l = prec+1+(a>>TWOPOTBITS_IN_LONG);
        !          1435:   if (l > LGBITS>>1) err(talker,"argument too large in ggamd");
        !          1436:   y=cgetr(prec); av=avma;
        !          1437:
        !          1438:   p1 = mpsqrt(mppi(l));
        !          1439:   j = 1; p2 = realun(l);
        !          1440:   for (i=1; i<a; i++)
        !          1441:   {
        !          1442:     j += 2;
        !          1443:     p2 = mulsr(j,p2); setlg(p2,l);
        !          1444:   }
        !          1445:   if (x>=0) p1 = mulrr(p1,p2);
        !          1446:   else
        !          1447:   {
        !          1448:     p1 = divrr(p1,p2); if (a&1) setsigne(p1,-1);
        !          1449:   }
        !          1450:   setexpo(p1, expo(p1)-x);
        !          1451:   affrr(p1,y); avma=av; return y;
        !          1452: }
        !          1453:
        !          1454: void
        !          1455: mpgamdz(long s, GEN y)
        !          1456: {
        !          1457:   long av=avma;
        !          1458:
        !          1459:   affrr(mpgamd(s,lg(y)),y); avma=av;
        !          1460: }
        !          1461:
        !          1462: GEN
        !          1463: ggamd(GEN x, long prec)
        !          1464: {
        !          1465:   long av,tetpil;
        !          1466:
        !          1467:   switch(typ(x))
        !          1468:   {
        !          1469:     case t_INT:
        !          1470:       return mpgamd(itos(x),prec);
        !          1471:
        !          1472:     case t_REAL: case t_FRAC: case t_FRACN: case t_COMPLEX: case t_QUAD:
        !          1473:       av=avma; x = gadd(x,ghalf); tetpil=avma;
        !          1474:       return gerepile(av,tetpil,ggamma(x,prec));
        !          1475:
        !          1476:     case t_INTMOD: case t_PADIC:
        !          1477:       err(typeer,"ggamd");
        !          1478:     case t_SER:
        !          1479:       err(impl,"gamd of a power series");
        !          1480:   }
        !          1481:   return transc(ggamd,x,prec);
        !          1482: }
        !          1483:
        !          1484: void
        !          1485: ggamdz(GEN x, GEN y)
        !          1486: {
        !          1487:   long av=avma, prec = precision(y);
        !          1488:
        !          1489:   if (!prec) err(infprecer,"ggamdz");
        !          1490:   gaffect(ggamd(x,prec),y); avma=av;
        !          1491: }
        !          1492:
        !          1493: /********************************************************************/
        !          1494: /**                                                                **/
        !          1495: /**                      FONCTION PSI                              **/
        !          1496: /**                                                                **/
        !          1497: /********************************************************************/
        !          1498:
        !          1499: #if 1
        !          1500: static GEN
        !          1501: mppsi(GEN z)  /* version p=2 */
        !          1502: {
        !          1503:   long l,n,k,x,xx,av,av1,tetpil;
        !          1504:   GEN zk,u,v,a,b;
        !          1505:
        !          1506:   av=avma; l=lg(z);
        !          1507:   x=(long)(1 + (bit_accuracy(l)>>1)*LOG2 + 1.58*rtodbl(absr(z)));
        !          1508:   if (expo(z)>=15 || x>46340) err(impl,"psi(x) for x>=29000");
        !          1509:   xx=x*x; n=(long)(1+3.591*x);
        !          1510:   affsr(x,a=cgetr(l));
        !          1511:   a = mplog(a);
        !          1512:   gaffect(a,u=cgetr(l));
        !          1513:   gaffsg(1,b=cgetr(l));
        !          1514:   gaffsg(1,v=cgetr(l)); av1=avma;
        !          1515:   for (k=1; k<=n; k++)
        !          1516:   {
        !          1517:     zk = (k>1)? addsr(k-1,z): z;
        !          1518:     divrrz(mulsr(xx,b),gsqr(zk),b);
        !          1519:     divrrz(subrr(divrr(mulsr(xx,a),zk),b),zk,a);
        !          1520:     addrrz(u,a,u); addrrz(v,b,v); avma=av1;
        !          1521:   }
        !          1522:   tetpil=avma; return gerepile(av,tetpil,divrr(u,v));
        !          1523: }
        !          1524: #else
        !          1525: static GEN /* by Manfred Radimersky */
        !          1526: mppsi(GEN z)
        !          1527: {
        !          1528:   long head, tail;
        !          1529:   long len, num, k;
        !          1530:   GEN a, b, f, s, x;
        !          1531:
        !          1532:   head = avma;
        !          1533:   len = lg(z);
        !          1534:   num = bit_accuracy(len);
        !          1535:
        !          1536:   if(signe(z) < 0) {
        !          1537:     x = subsr(1, z);
        !          1538:     s = mppsi(x);
        !          1539:     f = mulrr(mppi(len), z);
        !          1540:     mpsincos(f, &a, &b);
        !          1541:     f = divrr(b, a);
        !          1542:     a = mulrr(mppi(len), f);
        !          1543:     tail = avma;
        !          1544:     gerepile(head, tail, subrr(s, a));
        !          1545:   }
        !          1546:
        !          1547:   a = cgetr(len);
        !          1548:   affsr(0, a);
        !          1549:   x = cgetr(len);
        !          1550:   affrr(z, x);
        !          1551:   tail = avma;
        !          1552:   while(cmprs(x, num >> 2) < 0) {
        !          1553:     gaddz(a, divsr(1, x), a);
        !          1554:     gaddgsz(x, 1, x);
        !          1555:     avma = tail;
        !          1556:   }
        !          1557:
        !          1558:   s = mplog(x);
        !          1559:   gsubz(s, a, s);
        !          1560:   b = gmul2n(x, 1);
        !          1561:   gsubz(s, divsr(1, b), s);
        !          1562:
        !          1563:   mpbern(num, len);
        !          1564:
        !          1565:   affsr(-1, a);
        !          1566:   gdivgsz(a, 2, a);
        !          1567:   f = mulrr(x, x);
        !          1568:   f = divsr(1, f);
        !          1569:   k = 1;
        !          1570:   do {
        !          1571:     gmulz(a, f, a);
        !          1572:     gdivgsz(a, k, b);
        !          1573:     gmulz(b, bern(k), b);
        !          1574:     gaddz(s, b, s);
        !          1575:     k++;
        !          1576:   } while(expo(s) - expo(b) < num);
        !          1577:
        !          1578:   tail = avma;
        !          1579:   return gerepile(head, tail, gcopy(s));
        !          1580: }
        !          1581: #endif
        !          1582:
        !          1583: #if 1
        !          1584: static GEN
        !          1585: cxpsi(GEN z, long prec) /* version p=2 */
        !          1586: {
        !          1587:   long l,n,k,x,xx,av,av1,tetpil;
        !          1588:   GEN zk,u,v,a,b,p1;
        !          1589:
        !          1590:   l = precision(z); if (!l) l = prec; av=avma;
        !          1591:   x=(long)(1 + (bit_accuracy(l)>>1)*LOG2 + 1.58*rtodbl(gabs(z,DEFAULTPREC)));
        !          1592:   xx=x*x; n=(long)(1+3.591*x);
        !          1593:   a=cgetg(3,t_COMPLEX); a[1]=lgetr(l); a[2]=lgetr(l); gaffsg(x,a);
        !          1594:   b=cgetg(3,t_COMPLEX); b[1]=lgetr(l); b[2]=lgetr(l); gaffsg(1,b);
        !          1595:   u=cgetg(3,t_COMPLEX); u[1]=lgetr(l); u[2]=lgetr(l);
        !          1596:   v=cgetg(3,t_COMPLEX); v[1]=lgetr(l); v[2]=lgetr(l); gaffsg(1,v);
        !          1597:   p1=glog(a,l); gaffect(p1,a); gaffect(p1,u); av1=avma;
        !          1598:   for (k=1; k<=n; k++)
        !          1599:   {
        !          1600:     zk=(k>1) ? gaddsg(k-1,z) : z;
        !          1601:     gdivz(gmulsg(xx,b),gsqr(zk),b);
        !          1602:     gdivz(gsub(gdiv(gmulsg(xx,a),zk),b),zk,a);
        !          1603:     gaddz(u,a,u); gaddz(v,b,v); avma=av1;
        !          1604:   }
        !          1605:   tetpil=avma; return gerepile(av,tetpil,gdiv(u,v));
        !          1606: }
        !          1607: #else
        !          1608: GEN
        !          1609: cxpsi(GEN z, long prec) /* by Manfred Radimersky */
        !          1610: {
        !          1611:   long head, tail;
        !          1612:   long bord, nubi, k;
        !          1613:   GEN a, b, f, s, w, wn;
        !          1614:
        !          1615:   head = avma;
        !          1616:   nubi = bit_accuracy(prec);
        !          1617:   bord = (nubi * nubi) >> 4;
        !          1618:
        !          1619:   if(signe((GEN) z[1]) < 0) {
        !          1620:     w = gsubsg(1, z);
        !          1621:     s = cxpsi(w, prec);
        !          1622:     f = gmul(mppi(prec), z);
        !          1623:     gsincos(f, &a, &b, prec);
        !          1624:     f = gdiv(b, a);
        !          1625:     a = gmul(mppi(prec), f);
        !          1626:     tail = avma;
        !          1627:     gerepile(head, tail, gsub(s, a));
        !          1628:   }
        !          1629:
        !          1630:   a = cgetg(3, t_COMPLEX);
        !          1631:   a[1] = (long) cgetr(prec);
        !          1632:   a[2] = (long) cgetr(prec);
        !          1633:   gaffsg(0, a);
        !          1634:   w = cgetg(3, t_COMPLEX);
        !          1635:   w[1] = (long) cgetr(prec);
        !          1636:   w[2] = (long) cgetr(prec);
        !          1637:   gaffect(z, w);
        !          1638:   wn = gnorm(w);
        !          1639:   tail = avma;
        !          1640:   while(cmprs(wn, bord) < 0) {
        !          1641:     gaddz(a, gdivsg(1, w), a);
        !          1642:     gaddgsz((GEN) w[1], 1, (GEN) w[1]);
        !          1643:     gaffect(gnorm(w), wn);
        !          1644:     avma = tail;
        !          1645:   }
        !          1646:
        !          1647:   s = glog(w, prec);
        !          1648:   gsubz(s, a, s);
        !          1649:   b = gmul2n(w, 1);
        !          1650:   gsubz(s, gdivsg(1, b), s);
        !          1651:
        !          1652:   mpbern(nubi, prec);
        !          1653:
        !          1654:   gaffsg(-1, a);
        !          1655:   gdivgsz(a, 2, a);
        !          1656:   f = gmul(w, w);
        !          1657:   f = gdivsg(1, f);
        !          1658:   k = 1;
        !          1659:   tail = avma;
        !          1660:   do {
        !          1661:     gmulz(a, f, a);
        !          1662:     gdivgsz(a, k, b);
        !          1663:     gmulz(b, bern(k), b);
        !          1664:     gaddz(s, b, s);
        !          1665:     bord = expo(gnorm(s)) - expo(gnorm(b));
        !          1666:     k++;
        !          1667:     avma = tail;
        !          1668:   } while(bord < nubi << 1);
        !          1669:
        !          1670:   tail = avma;
        !          1671:   return gerepile(head, tail, gcopy(s));
        !          1672: }
        !          1673: #endif
        !          1674:
        !          1675: GEN
        !          1676: gpsi(GEN x, long prec)
        !          1677: {
        !          1678:   switch(typ(x))
        !          1679:   {
        !          1680:     case t_REAL:
        !          1681:       return mppsi(x);
        !          1682:
        !          1683:     case t_COMPLEX:
        !          1684:       return cxpsi(x,prec);
        !          1685:
        !          1686:     case t_INTMOD: case t_PADIC:
        !          1687:       err(typeer,"gpsi");
        !          1688:     case t_SER:
        !          1689:       err(impl,"psi of power series");
        !          1690:   }
        !          1691:   return transc(gpsi,x,prec);
        !          1692: }
        !          1693:
        !          1694: void
        !          1695: gpsiz(GEN x, GEN y)
        !          1696: {
        !          1697:   long av=avma, prec = precision(y);
        !          1698:
        !          1699:   if (!prec) err(infprecer,"gpsiz");
        !          1700:   gaffect(gpsi(x,prec),y); avma=av;
        !          1701: }

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