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

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

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

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