[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.2

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

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