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

Annotation of OpenXM_contrib/pari-2.2/src/basemath/trans1.c, Revision 1.1.1.1

1.1       noro        1: /* $Id: trans1.c,v 1.35 2001/10/01 12:11:32 karim Exp $
                      2:
                      3: Copyright (C) 2000  The PARI group.
                      4:
                      5: This file is part of the PARI/GP package.
                      6:
                      7: PARI/GP is free software; you can redistribute it and/or modify it under the
                      8: terms of the GNU General Public License as published by the Free Software
                      9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
                     10: ANY WARRANTY WHATSOEVER.
                     11:
                     12: Check the License for details. You should have received a copy of it, along
                     13: with the package; see the file 'COPYING'. If not, write to the Free Software
                     14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
                     15:
                     16: /********************************************************************/
                     17: /**                                                                **/
                     18: /**                   TRANSCENDENTAL FONCTIONS                     **/
                     19: /**                                                                **/
                     20: /********************************************************************/
                     21: #include "pari.h"
                     22:
                     23: #ifdef LONG_IS_64BIT
                     24: # define C31 (9223372036854775808.0) /* VERYBIGINT * 1.0 */
                     25: # define SQRTVERYBIGINT 3037000500   /* ceil(sqrt(VERYBIGINT)) */
                     26: # define CBRTVERYBIGINT 2097152      /* ceil(cbrt(VERYBIGINT)) */
                     27: #else
                     28: # define C31 (2147483648.0)
                     29: # define SQRTVERYBIGINT 46341
                     30: # define CBRTVERYBIGINT  1291
                     31: #endif
                     32:
                     33:
                     34: /********************************************************************/
                     35: /**                                                                **/
                     36: /**                        FONCTION PI                             **/
                     37: /**                                                                **/
                     38: /********************************************************************/
                     39:
                     40: void
                     41: constpi(long prec)
                     42: {
                     43:   GEN p1,p2,p3,tmppi;
                     44:   long l,n,n1,av1,av2;
                     45:   double alpha;
                     46:
                     47: #define k1  545140134
                     48: #define k2  13591409
                     49: #define k3  640320
                     50: #define alpha2 (1.4722004/(BYTES_IN_LONG/4))  /* 3*log(k3/12)/(32*log(2)) */
                     51:
                     52:   if (gpi && lg(gpi) >= prec) return;
                     53:
                     54:   av1 = avma; tmppi = newbloc(prec);
                     55:   *tmppi = evaltyp(t_REAL) | evallg(prec);
                     56:
                     57:   prec++;
                     58:
                     59:   n=(long)(1+(prec-2)/alpha2);
                     60:   n1=6*n-1; p1=cgetr(prec);
                     61:   p2=addsi(k2,mulss(n,k1));
                     62:   affir(p2,p1);
                     63:
                     64:   /* initialisation longueur mantisse */
                     65:   if (prec>=4) l=4; else l=prec;
                     66:   setlg(p1,l); alpha=l;
                     67:
                     68:   av2 = avma;
                     69:   while (n)
                     70:   {
                     71:     if (n < CBRTVERYBIGINT)
                     72:       p3 = divrs(mulsr(n1-4,mulsr(n1*(n1-2),p1)),n*n*n);
                     73:     else
                     74:     {
                     75:       if (n1 < SQRTVERYBIGINT)
                     76:        p3 = divrs(divrs(mulsr(n1-4,mulsr(n1*(n1-2),p1)),n*n),n);
                     77:       else
                     78:        p3 = divrs(divrs(divrs(mulsr(n1-4,mulsr(n1,mulsr(n1-2,p1))),n),n),n);
                     79:     }
                     80:     p3 = divrs(divrs(p3,100100025), 327843840);
                     81:     subisz(p2,k1,p2); subirz(p2,p3,p1);
                     82:     alpha += alpha2; l = (long)(1+alpha); /* nouvelle longueur mantisse */
                     83:     if (l>prec) l=prec;
                     84:     setlg(p1,l); avma = av2;
                     85:     n--; n1-=6;
                     86:   }
                     87:   p1 = divsr(53360,p1);
                     88:   mulrrz(p1,gsqrt(stoi(k3),prec), tmppi);
                     89:   gunclone(gpi); avma = av1;  gpi = tmppi;
                     90: }
                     91:
                     92: GEN
                     93: mppi(long prec)
                     94: {
                     95:   GEN x = cgetr(prec);
                     96:   constpi(prec); affrr(gpi,x); return x;
                     97: }
                     98:
                     99: /********************************************************************/
                    100: /**                                                                **/
                    101: /**                      FONCTION EULER                            **/
                    102: /**                                                                **/
                    103: /********************************************************************/
                    104:
                    105: void
                    106: consteuler(long prec)
                    107: {
                    108:   GEN u,v,a,b,tmpeuler;
                    109:   long l,n,k,x,av1,av2;
                    110:
                    111:   if (geuler && lg(geuler) >= prec) return;
                    112:
                    113:   av1 = avma; tmpeuler = newbloc(prec);
                    114:   *tmpeuler = evaltyp(t_REAL) | evallg(prec);
                    115:
                    116:   prec++;
                    117:
                    118:   l = prec+1; x = (long) (1 + (bit_accuracy(l) >> 2) * LOG2);
                    119:   a=cgetr(l); affsr(x,a); u=mplog(a); setsigne(u,-1); affrr(u,a);
                    120:   b=realun(l);
                    121:   v=realun(l);
                    122:   n=(long)(1+3.591*x); /* z=3.591: z*[ ln(z)-1 ]=1 */
                    123:   av2 = avma;
                    124:   if (x < SQRTVERYBIGINT)
                    125:   {
                    126:     long xx = x*x;
                    127:     for (k=1; k<=n; k++)
                    128:     {
                    129:       divrsz(mulsr(xx,b),k*k, b);
                    130:       divrsz(addrr(divrs(mulsr(xx,a),k),b),k, a);
                    131:       addrrz(u,a,u); addrrz(v,b,v); avma = av2;
                    132:     }
                    133:   }
                    134:   else
                    135:   {
                    136:     GEN xx = mulss(x,x);
                    137:     for (k=1; k<=n; k++)
                    138:     {
                    139:       divrsz(mulir(xx,b),k*k, b);
                    140:       divrsz(addrr(divrs(mulir(xx,a),k),b),k, a);
                    141:       addrrz(u,a,u); addrrz(v,b,v); avma = av2;
                    142:     }
                    143:   }
                    144:   divrrz(u,v,tmpeuler);
                    145:   gunclone(geuler); avma = av1; geuler = tmpeuler;
                    146: }
                    147:
                    148: GEN
                    149: mpeuler(long prec)
                    150: {
                    151:   GEN x = cgetr(prec);
                    152:   consteuler(prec); affrr(geuler,x); return x;
                    153: }
                    154:
                    155: /********************************************************************/
                    156: /**                                                                **/
                    157: /**       CONVERSION DE TYPES POUR FONCTIONS TRANSCENDANTES        **/
                    158: /**                                                                **/
                    159: /********************************************************************/
                    160:
                    161: GEN
                    162: transc(GEN (*f)(GEN,long), GEN x, long prec)
                    163: {
                    164:   GEN p1,p2,y;
                    165:   long lx,i,av,tetpil;
                    166:
                    167:   av=avma;
                    168:   switch(typ(x))
                    169:   {
                    170:     case t_INT: case t_FRAC: case t_FRACN:
                    171:       p1=cgetr(prec); gaffect(x,p1); tetpil=avma;
                    172:       return gerepile(av,tetpil,f(p1,prec));
                    173:
                    174:     case t_COMPLEX: case t_QUAD:
                    175:       av=avma; p1=gmul(x,realun(prec)); tetpil=avma;
                    176:       return gerepile(av,tetpil,f(p1,prec));
                    177:
                    178:     case t_POL: case t_RFRAC: case t_RFRACN:
                    179:       p1=tayl(x,gvar(x),precdl); tetpil=avma;
                    180:       return gerepile(av,tetpil,f(p1,prec));
                    181:
                    182:     case t_VEC: case t_COL: case t_MAT:
                    183:       lx=lg(x); y=cgetg(lx,typ(x));
                    184:       for (i=1; i<lx; i++)
                    185:        y[i] = (long) f((GEN)x[i],prec);
                    186:       return y;
                    187:
                    188:     case t_POLMOD:
                    189:       av=avma; p1=roots((GEN)x[1],prec); lx=lg(p1); p2=cgetg(lx,t_COL);
                    190:       for (i=1; i<lx; i++) p2[i]=lpoleval((GEN)x[2],(GEN)p1[i]);
                    191:       tetpil=avma; y=cgetg(lx,t_COL);
                    192:       for (i=1; i<lx; i++)
                    193:         y[i] = (long)f((GEN)p2[i],prec);
                    194:       return gerepile(av,tetpil,y);
                    195:
                    196:   default:
                    197:     err(typeer,"a transcendental function");
                    198:   }
                    199:   return f(x,prec);
                    200: }
                    201:
                    202: /*******************************************************************/
                    203: /*                                                                 */
                    204: /*                            POWERING                             */
                    205: /*                                                                 */
                    206: /*******************************************************************/
                    207: extern GEN real_unit_form(GEN x);
                    208: extern GEN imag_unit_form(GEN x);
                    209:
                    210: static GEN
                    211: puiss0(GEN x)
                    212: {
                    213:   long lx,i;
                    214:   GEN y;
                    215:
                    216:   switch(typ(x))
                    217:   {
                    218:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN: case t_PADIC:
                    219:       return gun;
                    220:
                    221:     case t_INTMOD:
                    222:       y=cgetg(3,t_INTMOD); copyifstack(x[1],y[1]); y[2]=un; break;
                    223:
                    224:     case t_COMPLEX:
                    225:       y=cgetg(3,t_COMPLEX); y[1]=un; y[2]=zero; break;
                    226:
                    227:     case t_QUAD:
                    228:       y=cgetg(4,t_QUAD); copyifstack(x[1],y[1]);
                    229:       y[2]=un; y[3]=zero; break;
                    230:
                    231:     case t_POLMOD:
                    232:       y=cgetg(3,t_POLMOD); copyifstack(x[1],y[1]);
                    233:       y[2]=lpolun[varn(x[1])]; break;
                    234:
                    235:     case t_POL: case t_SER: case t_RFRAC: case t_RFRACN:
                    236:       return polun[gvar(x)];
                    237:
                    238:     case t_MAT:
                    239:       lx=lg(x); if (lx==1) return cgetg(1,t_MAT);
                    240:       if (lx != (lg(x[1]))) err(mattype1,"gpowgs");
                    241:       y = idmat(lx-1);
                    242:       for (i=1; i<lx; i++) coeff(y,i,i) = lpuigs(gcoeff(x,i,i),0);
                    243:       break;
                    244:     case t_QFR: return real_unit_form(x);
                    245:     case t_QFI: return imag_unit_form(x);
                    246:     case t_VECSMALL:
                    247:       lx = lg(x);
                    248:       y = cgetg(lx, t_VECSMALL);
                    249:       for (i=1; i<lx; i++) y[i] = i;
                    250:       return y;
                    251:     default: err(typeer,"gpowgs");
                    252:       return NULL; /* not reached */
                    253:   }
                    254:   return y;
                    255: }
                    256:
                    257: /* INTEGER POWERING (a^|n| for integer a and integer |n| > 1)
                    258:  *
                    259:  * Nonpositive powers and exponent one should be handled by gpow() and
                    260:  * gpowgs() in trans1.c, which at the time of this writing is the only place
                    261:  * where the following is [slated to be] used.
                    262:  *
                    263:  * Use left shift binary algorithm (RS is wasteful: multiplies big numbers,
                    264:  * with LS one of them is the base, hence small). If result is nonzero, its
                    265:  * sign is set to s (= +-1) regardless of what it would have been. This makes
                    266:  * life easier for gpow()/gpowgs(), which otherwise might do a
                    267:  * setsigne(gun,-1)... -- GN1998May04
                    268:  */
                    269: static GEN
                    270: puissii(GEN a, GEN n, long s)
                    271: {
                    272:   long av,*p,m,k,i,lim;
                    273:   GEN y;
                    274:
                    275:   if (!signe(a)) return gzero; /* a==0 */
                    276:   if (lgefint(a)==3)
                    277:   { /* easy if |a| < 3 */
                    278:     if (a[2] == 1) return (s>0)? gun: negi(gun);
                    279:     if (a[2] == 2) { a = shifti(gun, labs(itos(n))); setsigne(a,s); return a; }
                    280:   }
                    281:   if (lgefint(n)==3)
                    282:   { /* or if |n| < 3 */
                    283:     if (n[2] == 1) { a = icopy(a); setsigne(a,s); return a; }
                    284:     if (n[2] == 2) return sqri(a);
                    285:   }
                    286:   /* be paranoid about memory consumption */
                    287:   av=avma; lim=stack_lim(av,1);
                    288:   y = a; p = n+2; m = *p;
                    289:   /* normalize, i.e set highest bit to 1 (we know m != 0) */
                    290:   k = 1+bfffo(m); m<<=k; k = BITS_IN_LONG-k;
                    291:   /* first bit is now implicit */
                    292:   for (i=lgefint(n)-2;;)
                    293:   {
                    294:     for (; k; m<<=1,k--)
                    295:     {
                    296:       y = sqri(y);
                    297:       if (m < 0) y = mulii(y,a); /* first bit is set: multiply by base */
                    298:       if (low_stack(lim, stack_lim(av,1)))
                    299:       {
                    300:         if (DEBUGMEM>1) err(warnmem,"puissii");
                    301:         y = gerepileuptoint(av,y);
                    302:       }
                    303:     }
                    304:     if (--i == 0) break;
                    305:     m = *++p; k = BITS_IN_LONG;
                    306:   }
                    307:   setsigne(y,s); return gerepileuptoint(av,y);
                    308: }
                    309:
                    310: /* return a^n as a t_REAL of precision prec. Adapted from puissii().
                    311:  * Assume a > 0, n > 0 */
                    312: GEN
                    313: rpowsi(ulong a, GEN n, long prec)
                    314: {
                    315:   long av,*p,m,k,i,lim;
                    316:   GEN y, unr = realun(prec);
                    317:   GEN (*sq)(GEN);
                    318:   GEN (*mulsg)(long,GEN);
                    319:
                    320:   if (a == 1) return unr;
                    321:   if (a == 2) { setexpo(unr, itos(n)); return unr; }
                    322:   if (is_pm1(n)) { affsr(a, unr); return unr; }
                    323:   /* be paranoid about memory consumption */
                    324:   av=avma; lim=stack_lim(av,1);
                    325:   y = stoi(a); p = n+2; m = *p;
                    326:   /* normalize, i.e set highest bit to 1 (we know m != 0) */
                    327:   k = 1+bfffo(m); m<<=k; k = BITS_IN_LONG-k;
                    328:   /* first bit is now implicit */
                    329:   sq = &sqri; mulsg = &mulsi;
                    330:   for (i=lgefint(n)-2;;)
                    331:   {
                    332:     for (; k; m<<=1,k--)
                    333:     {
                    334:       y = sq(y);
                    335:       if (m < 0) y = mulsg(a,y);
                    336:       if (lgefint(y) >= prec && typ(y) == t_INT) /* switch to t_REAL */
                    337:       {
                    338:         sq = &gsqr; mulsg = &mulsr;
                    339:         affir(y, unr); y = unr;
                    340:       }
                    341:
                    342:       if (low_stack(lim, stack_lim(av,1)))
                    343:       {
                    344:         if (DEBUGMEM>1) err(warnmem,"rpuisssi");
                    345:         y = gerepileuptoleaf(av,y);
                    346:       }
                    347:     }
                    348:     if (--i == 0) break;
                    349:     m = *++p, k = BITS_IN_LONG;
                    350:   }
                    351:   if (typ(y) == t_INT) { affir(y, unr); y = unr ; }
                    352:   return gerepileuptoleaf(av,y);
                    353: }
                    354:
                    355: GEN
                    356: gpowgs(GEN x, long n)
                    357: {
                    358:   long lim,av,m,tx;
                    359:   static long gn[3] = {evaltyp(t_INT)|m_evallg(3), 0, 0};
                    360:   GEN y;
                    361:
                    362:   if (n == 0) return puiss0(x);
                    363:   if (n == 1) return gcopy(x);
                    364:   if (n ==-1) return ginv(x);
                    365:   if (n>0) { gn[1] = evalsigne( 1) | evallgefint(3); gn[2]= n; }
                    366:   else     { gn[1] = evalsigne(-1) | evallgefint(3); gn[2]=-n; }
                    367:  /* If gpowgs were only ever called from gpow, the switch wouldn't be needed.
                    368:   * In fact, under current word and bit field sizes, an integer power with
                    369:   * multiword exponent will always overflow.  But it seems easier to call
                    370:   * puissii|powmodulo() with a mock-up GEN as 2nd argument than to write
                    371:   * separate versions for a long exponent.  Note that n = HIGHBIT is an
                    372:   * invalid argument. --GN
                    373:   */
                    374:   switch((tx=typ(x)))
                    375:   {
                    376:     case t_INT:
                    377:     {
                    378:       long sx=signe(x), sr = (sx<0 && (n&1))? -1: 1;
                    379:       if (n>0) return puissii(x,(GEN)gn,sr);
                    380:       if (!sx) err(talker, "division by zero in gpowgs");
                    381:       if (is_pm1(x)) return (sr < 0)? icopy(x): gun;
                    382:       /* n<0, |x|>1 */
                    383:       y=cgetg(3,t_FRAC); setsigne(gn,1);
                    384:       y[1]=(sr>0)? un: lnegi(gun);
                    385:       y[2]=(long)puissii(x,(GEN)gn,1); /* force denominator > 0 */
                    386:       return y;
                    387:     }
                    388:     case t_INTMOD:
                    389:       y=cgetg(3,tx); copyifstack(x[1],y[1]);
                    390:       y[2]=(long)powmodulo((GEN)(x[2]),(GEN)gn,(GEN)(x[1]));
                    391:       return y;
                    392:     case t_FRAC: case t_FRACN:
                    393:     {
                    394:       GEN a = (GEN)x[1], b = (GEN)x[2];
                    395:       long sr = (n&1 && (signe(a)!=signe(b))) ? -1 : 1;
                    396:       if (n > 0) { if (!signe(a)) return gzero; }
                    397:       else
                    398:       { /* n < 0 */
                    399:         if (!signe(a)) err(talker, "division by zero fraction in gpowgs");
                    400:         /* +-1/x[2] inverts to an integer */
                    401:         if (is_pm1(a)) return puissii(b,(GEN)gn,sr);
                    402:         y = b; b = a; a = y;
                    403:       }
                    404:       /* HACK: puissii disregards the sign of gn */
                    405:       y = cgetg(3,tx);
                    406:       y[1] = (long)puissii(a,(GEN)gn,sr);
                    407:       y[2] = (long)puissii(b,(GEN)gn,1);
                    408:       return y;
                    409:     }
                    410:     case t_PADIC: case t_POL: case t_POLMOD:
                    411:       return powgi(x,gn);
                    412:     case t_RFRAC: case t_RFRACN:
                    413:     {
                    414:       av=avma; y=cgetg(3,tx); m = labs(n);
                    415:       y[1]=lpuigs((GEN)x[1],m);
                    416:       y[2]=lpuigs((GEN)x[2],m);
                    417:       if (n<0) y=ginv(y);      /* let ginv worry about normalizations */
                    418:       return gerepileupto(av,y);
                    419:     }
                    420:     default:
                    421:       m = labs(n);
                    422:       av=avma; y=NULL; lim=stack_lim(av,1);
                    423:       for (; m>1; m>>=1)
                    424:       {
                    425:         if (m&1) y = y? gmul(y,x): x;
                    426:         x=gsqr(x);
                    427:         if (low_stack(lim, stack_lim(av,1)))
                    428:         {
                    429:           GEN *gptr[2]; gptr[0]=&x; gptr[1]=&y;
                    430:           if(DEBUGMEM>1) err(warnmem,"[3]: gpowgs");
                    431:           gerepilemany(av,gptr,y? 2: 1);
                    432:         }
                    433:       }
                    434:       y = y? gmul(y,x): x;
                    435:       if (n<=0) y=ginv(y);
                    436:       return gerepileupto(av,y);
                    437:   }
                    438: }
                    439:
                    440: GEN
                    441: pow_monome(GEN x, GEN nn)
                    442: {
                    443:   long n,m,i,j,dd,tetpil, av = avma;
                    444:   GEN p1,y;
                    445:   if (is_bigint(nn)) err(talker,"power overflow in pow_monome");
                    446:   n = itos(nn); m = labs(n);
                    447:   j=lgef(x); dd=(j-3)*m+3;
                    448:   p1=cgetg(dd,t_POL); m = labs(n);
                    449:   p1[1] = evalsigne(1) | evallgef(dd) | evalvarn(varn(x));
                    450:   for (i=2; i<dd-1; i++) p1[i]=zero;
                    451:   p1[i]=lpuigs((GEN)x[j-1],m);
                    452:   if (n>0) return p1;
                    453:
                    454:   tetpil=avma; y=cgetg(3,t_RFRAC);
                    455:   y[1]=(long)denom((GEN)p1[i]);
                    456:   y[2]=lmul(p1,(GEN)y[1]); return gerepile(av,tetpil,y);
                    457: }
                    458:
                    459: extern GEN powrealform(GEN x, GEN n);
                    460:
                    461: /* n is assumed to be an integer */
                    462: GEN
                    463: powgi(GEN x, GEN n)
                    464: {
                    465:   long i,j,m,tx, sn=signe(n);
                    466:   ulong lim,av;
                    467:   GEN y, p1;
                    468:
                    469:   if (typ(n) != t_INT) err(talker,"not an integral exponent in powgi");
                    470:   if (!sn) return puiss0(x);
                    471:
                    472:   switch(tx=typ(x))
                    473:   {/* catch some types here, instead of trying gpowgs() first, because of
                    474:     * the simpler call interface to puissii() and powmodulo() -- even though
                    475:     * for integer/rational bases other than 0,+-1 and non-wordsized
                    476:     * exponents the result will be certain to overflow. --GN
                    477:     */
                    478:     case t_INT:
                    479:     {
                    480:       long sx=signe(x), sr = (sx<0 && mod2(n))? -1: 1;
                    481:       if (sn>0) return puissii(x,n,sr);
                    482:       if (!sx) err(talker, "division by zero in powgi");
                    483:       if (is_pm1(x)) return (sr < 0)? icopy(x): gun;
                    484:       /* n<0, |x|>1 */
                    485:       y=cgetg(3,t_FRAC); setsigne(n,1); /* temporarily replace n by abs(n) */
                    486:       y[1]=(sr>0)? un: lnegi(gun);
                    487:       y[2]=(long)puissii(x,n,1);
                    488:       setsigne(n,-1); return y;
                    489:     }
                    490:     case t_INTMOD:
                    491:       y=cgetg(3,tx); copyifstack(x[1],y[1]);
                    492:       y[2]=(long)powmodulo((GEN)x[2],n,(GEN)x[1]);
                    493:       return y;
                    494:     case t_FRAC: case t_FRACN:
                    495:     {
                    496:       GEN a = (GEN)x[1], b = (GEN)x[2];
                    497:       long sr = (mod2(n) && (signe(a)!=signe(b))) ? -1 : 1;
                    498:       if (sn > 0) { if (!signe(a)) return gzero; }
                    499:       else
                    500:       { /* n < 0 */
                    501:         if (!signe(a)) err(talker, "division by zero fraction in powgi");
                    502:         /* +-1/b inverts to an integer */
                    503:         if (is_pm1(a)) return puissii(b,n,sr);
                    504:         y = b; b = a; a = y;
                    505:       }
                    506:       /* HACK: puissii disregards the sign of n */
                    507:       y = cgetg(3,tx);
                    508:       y[1] = (long)puissii(a,n,sr);
                    509:       y[2] = (long)puissii(b,n,1);
                    510:       return y;
                    511:     }
                    512:     case t_PADIC:
                    513:     {
                    514:       GEN p, pe;
                    515:       if (!signe(x[4]))
                    516:       {
                    517:         if (sn < 0) err(talker, "division by 0 p-adic in powgi");
                    518:         y=gcopy(x); setvalp(y, itos(n)*valp(x)); return y;
                    519:       }
                    520:       y = cgetg(5,t_PADIC);
                    521:       p = (GEN)x[2];
                    522:       pe= (GEN)x[3]; i = ggval(n, p);
                    523:       if (i == 0) pe = icopy(pe);
                    524:       else
                    525:       {
                    526:         pe = mulii(pe, gpowgs(p,i));
                    527:         pe = gerepileuptoint((long)y, pe);
                    528:       }
                    529:       y[1] = evalprecp(precp(x)+i) | evalvalp(itos(n) * valp(x));
                    530:       icopyifstack(p, y[2]);
                    531:       y[3] = (long)pe;
                    532:       y[4] = (long)powmodulo((GEN)x[4], n, pe);
                    533:       return y;
                    534:     }
                    535:     case t_QFR:
                    536:       if (signe(x[4])) return powrealform(x,n);
                    537:     case t_POL:
                    538:       if (ismonome(x)) return pow_monome(x,n);
                    539:     default:
                    540:       av=avma; lim=stack_lim(av,1);
                    541:       p1 = n+2; m = *p1;
                    542:       y=x; j=1+bfffo(m); m<<=j; j = BITS_IN_LONG-j;
                    543:       for (i=lgefint(n)-2;;)
                    544:       {
                    545:         for (; j; m<<=1,j--)
                    546:         {
                    547:           y=gsqr(y);
                    548:           if (low_stack(lim, stack_lim(av,1)))
                    549:           {
                    550:             if(DEBUGMEM>1) err(warnmem,"[1]: powgi");
                    551:             y = gerepileupto(av, y);
                    552:           }
                    553:           if (m<0) y=gmul(y,x);
                    554:           if (low_stack(lim, stack_lim(av,1)))
                    555:           {
                    556:             if(DEBUGMEM>1) err(warnmem,"[2]: powgi");
                    557:             y = gerepileupto(av, y);
                    558:           }
                    559:         }
                    560:         if (--i == 0) break;
                    561:         m = *++p1, j = BITS_IN_LONG;
                    562:       }
                    563:       if (sn < 0) y = ginv(y);
                    564:       return av==avma? gcopy(y): gerepileupto(av,y);
                    565:   }
                    566: }
                    567:
                    568: /* we suppose n != 0, and valp(x) = 0 */
                    569: static GEN
                    570: ser_pui(GEN x, GEN n, long prec)
                    571: {
                    572:   long av,tetpil,lx,i,j;
                    573:   GEN p1,p2,y,alp;
                    574:
                    575:   if (gvar9(n) > varn(x))
                    576:   {
                    577:     GEN lead = (GEN)x[2];
                    578:     if (gcmp1(lead))
                    579:     {
                    580:       av=avma; alp = gclone(gadd(n,gun)); avma=av;
                    581:       y=cgetg(lx=lg(x),t_SER);
                    582:       y[1] = evalsigne(1) | evalvalp(0) | evalvarn(varn(x));
                    583:       y[2] = un;
                    584:       for (i=3; i<lx; i++)
                    585:       {
                    586:        av=avma; p1=gzero;
                    587:        for (j=1; j<i-1; j++)
                    588:        {
                    589:          p2 = gsubgs(gmulgs(alp,j),i-2);
                    590:          p1 = gadd(p1,gmul(gmul(p2,(GEN)x[j+2]),(GEN)y[i-j]));
                    591:        }
                    592:        tetpil=avma; y[i]=lpile(av,tetpil,gdivgs(p1,i-2));
                    593:       }
                    594:       gunclone(alp); return y;
                    595:     }
                    596:     av=avma; p1=gdiv(x,lead); p1[2] = un; /* in case it's inexact */
                    597:     p1=gpow(p1,n,prec); p2=gpow(lead,n,prec);
                    598:     tetpil=avma; return gerepile(av,tetpil,gmul(p1,p2));
                    599:   }
                    600:   av=avma; y=gmul(n,glog(x,prec)); tetpil=avma;
                    601:   return gerepile(av,tetpil,gexp(y,prec));
                    602: }
                    603:
                    604: GEN
                    605: gpow(GEN x, GEN n, long prec)
                    606: {
                    607:   long av,tetpil,i,lx,tx;
                    608:   GEN y;
                    609:
                    610:   if (typ(n)==t_INT) return powgi(x,n);
                    611:   tx = typ(x);
                    612:   if (is_matvec_t(tx))
                    613:   {
                    614:     lx=lg(x); y=cgetg(lx,tx);
                    615:     for (i=1; i<lx; i++) y[i]=lpui((GEN)x[i],n,prec);
                    616:     return y;
                    617:   }
                    618:   if (tx==t_SER)
                    619:   {
                    620:     if (valp(x))
                    621:       err(talker,"not an integer exponent for non invertible series in gpow");
                    622:     if (lg(x) == 2) return gcopy(x); /* O(1) */
                    623:     return ser_pui(x,n,prec);
                    624:   }
                    625:   av=avma;
                    626:   if (gcmp0(x))
                    627:   {
                    628:     long tn = typ(n);
                    629:     if (!is_scalar_t(tn) || tn == t_PADIC || tn == t_INTMOD)
                    630:       err(talker,"zero to a forbidden power in gpow");
                    631:     n = greal(n);
                    632:     if (gsigne(n) <= 0)
                    633:       err(talker,"zero to a non positive exponent in gpow");
                    634:     if (!precision(x)) return gcopy(x);
                    635:
                    636:     x = ground(gmulsg(gexpo(x),n));
                    637:     if (is_bigint(x) || (ulong)x[2] >= (ulong)HIGHEXPOBIT)
                    638:       err(talker,"underflow or overflow in gpow");
                    639:     avma = av; y = cgetr(3);
                    640:     y[1] = evalexpo(itos(x));
                    641:     y[2] = 0; return y;
                    642:   }
                    643:   if (tx==t_INTMOD && typ(n)==t_FRAC)
                    644:   {
                    645:     GEN p1;
                    646:     if (!isprime((GEN)x[1])) err(talker,"modulus must be prime in gpow");
                    647:     y=cgetg(3,tx); copyifstack(x[1],y[1]);
                    648:     av=avma;
                    649:     p1=mpsqrtnmod((GEN)x[2],(GEN)n[2],(GEN)x[1],NULL);
                    650:     if(!p1) err(talker,"n-root does not exists in gpow");
                    651:     p1=powmodulo(p1,(GEN)n[1],(GEN)x[1]);
                    652:     y[2]=lpileupto(av,p1);
                    653:     return y;
                    654:   }
                    655:   i = (long) precision(n); if (i) prec=i;
                    656:   y=gmul(n,glog(x,prec)); tetpil=avma;
                    657:   return gerepile(av,tetpil,gexp(y,prec));
                    658: }
                    659:
                    660: /********************************************************************/
                    661: /**                                                                **/
                    662: /**                        RACINE CARREE                           **/
                    663: /**                                                                **/
                    664: /********************************************************************/
                    665:
                    666: GEN
                    667: mpsqrt(GEN x)
                    668: {
                    669:   long l,l0,l1,l2,s,eps,n,i,ex,av;
                    670:   double beta;
                    671:   GEN y,p1,p2,p3;
                    672:
                    673:   if (typ(x)!=t_REAL) err(typeer,"mpsqrt");
                    674:   s=signe(x); if (s<0) err(talker,"negative argument in mpsqrt");
                    675:   if (!s)
                    676:   {
                    677:     y = cgetr(3);
                    678:     y[1] = evalexpo(expo(x)>>1);
                    679:     y[2] = 0; return y;
                    680:   }
                    681:   l=lg(x); y=cgetr(l); av=avma;
                    682:
                    683:   p1=cgetr(l+1); affrr(x,p1);
                    684:   ex=expo(x); eps = ex & 1; ex >>= 1;
                    685:   setexpo(p1,eps); setlg(p1,3);
                    686:
                    687:   n=(long)(2+log((double) (l-2))/LOG2);
                    688:   p2=cgetr(l+1); p2[1]=evalexpo(0) | evalsigne(1);
                    689:   beta=sqrt((eps+1) * (2 + p1[2]/C31));
                    690:   p2[2]=(long)((beta-2)*C31);
                    691:   if (!p2[2]) { p2[2]=HIGHBIT; setexpo(p2,1); }
                    692:   for (i=3; i<=l; i++) p2[i]=0;
                    693:   setlg(p2,3);
                    694:
                    695:   p3=cgetr(l+1); l-=2; l1=1; l2=3;
                    696:   for (i=1; i<=n; i++)
                    697:   {
                    698:     l0 = l1<<1;
                    699:     if (l0<=l)
                    700:       { l2 += l1; l1=l0; }
                    701:     else
                    702:       { l2 += l+1-l1; l1=l+1; }
                    703:     setlg(p3,l1+2); setlg(p1,l1+2); setlg(p2,l2);
                    704:     divrrz(p1,p2,p3); addrrz(p2,p3,p2); setexpo(p2,expo(p2)-1);
                    705:   }
                    706:   affrr(p2,y); setexpo(y,expo(y)+ex);
                    707:   avma=av; return y;
                    708: }
                    709:
                    710: static GEN
                    711: padic_sqrt(GEN x)
                    712: {
                    713:   long av = avma, av2,lim,e,r,lpp,lp,pp;
                    714:   GEN y;
                    715:
                    716:   e=valp(x); y=cgetg(5,t_PADIC); copyifstack(x[2],y[2]);
                    717:   if (gcmp0(x))
                    718:   {
                    719:     y[4] = zero; e = (e+1)>>1;
                    720:     y[3] = un;
                    721:     y[1] = evalvalp(e) | evalprecp(precp(x));
                    722:     return y;
                    723:   }
                    724:   if (e & 1) err(sqrter6);
                    725:   e>>=1; setvalp(y,e); y[3] = y[2];
                    726:   pp = precp(x);
                    727:   if (egalii(gdeux, (GEN)x[2]))
                    728:   {
                    729:     lp=3; y[4] = un; r = mod8((GEN)x[4]);
                    730:     if ((r!=1 && pp>=2) && (r!=5 || pp!=2)) err(sqrter5);
                    731:     if (pp <= lp) { setprecp(y,1); return y; }
                    732:
                    733:     x = dummycopy(x); setvalp(x,0); setvalp(y,0);
                    734:     av2=avma; lim = stack_lim(av2,2);
                    735:     y[3] = lstoi(8);
                    736:     for(;;)
                    737:     {
                    738:       lpp=lp; lp=(lp<<1)-1;
                    739:       if (lp < pp) y[3] = lshifti((GEN)y[3], lpp-1);
                    740:       else
                    741:         { lp=pp; y[3] = x[3]; }
                    742:       setprecp(y,lp); y = gdiv(gadd(y, gdiv(x,y)), gdeux);
                    743:       if (lp < pp) lp--;
                    744:       if (cmpii((GEN)y[4], (GEN)y[3]) >= 0)
                    745:         y[4] = lsubii((GEN)y[4], (GEN)y[3]);
                    746:
                    747:       if (pp <= lp) break;
                    748:       if (low_stack(lim,stack_lim(av2,2)))
                    749:       {
                    750:         if (DEBUGMEM > 1) err(warnmem,"padic_sqrt");
                    751:         y = gerepileupto(av2,y);
                    752:       }
                    753:     }
                    754:     y = gcopy(y);
                    755:   }
                    756:   else /* p != 2 */
                    757:   {
                    758:     lp=1; y[4] = (long)mpsqrtmod((GEN)x[4],(GEN)x[2]);
                    759:     if (!y[4]) err(sqrter5);
                    760:     if (pp <= lp) { setprecp(y,1); return y; }
                    761:
                    762:     x = dummycopy(x); setvalp(x,0); setvalp(y,0);
                    763:     av2=avma; lim = stack_lim(av2,2);
                    764:     for(;;)
                    765:     {
                    766:       lp<<=1;
                    767:       if (lp < pp) y[3] = lsqri((GEN)y[3]);
                    768:       else
                    769:         { lp=pp; y[3] = x[3]; }
                    770:       setprecp(y,lp); y = gdiv(gadd(y, gdiv(x,y)), gdeux);
                    771:
                    772:       if (pp <= lp) break;
                    773:       if (low_stack(lim,stack_lim(av2,2)))
                    774:       {
                    775:         if (DEBUGMEM > 1) err(warnmem,"padic_sqrt");
                    776:         y = gerepileupto(av2,y);
                    777:       }
                    778:     }
                    779:   }
                    780:   setvalp(y,e); return gerepileupto(av,y);
                    781: }
                    782:
                    783: GEN
                    784: gsqrt(GEN x, long prec)
                    785: {
                    786:   long av,tetpil,e;
                    787:   GEN y,p1,p2;
                    788:
                    789:   switch(typ(x))
                    790:   {
                    791:     case t_REAL:
                    792:       if (signe(x)>=0) return mpsqrt(x);
                    793:       y=cgetg(3,t_COMPLEX); y[1]=zero;
                    794:       setsigne(x,1); y[2]=lmpsqrt(x); setsigne(x,-1);
                    795:       return y;
                    796:
                    797:     case t_INTMOD:
                    798:       y=cgetg(3,t_INTMOD); copyifstack(x[1],y[1]);
                    799:       p1 = mpsqrtmod((GEN)x[2],(GEN)y[1]);
                    800:       if (!p1) err(sqrter5);
                    801:       y[2] = (long)p1; return y;
                    802:
                    803:     case t_COMPLEX:
                    804:       y=cgetg(3,t_COMPLEX); av=avma;
                    805:       if (gcmp0((GEN)x[2]))
                    806:       {
                    807:        long tx=typ(x[1]);
                    808:
                    809:        if ((is_intreal_t(tx) || is_frac_t(tx)) && gsigne((GEN)x[1]) < 0)
                    810:        {
                    811:          y[1]=zero; p1=gneg_i((GEN)x[1]); tetpil=avma;
                    812:          y[2]=lpile(av,tetpil,gsqrt(p1,prec));
                    813:          return y;
                    814:        }
                    815:        y[1]=lsqrt((GEN)x[1],prec);
                    816:        y[2]=zero; return y;
                    817:       }
                    818:
                    819:       p1 = gsqr((GEN)x[1]);
                    820:       p2 = gsqr((GEN)x[2]);
                    821:       p1 = gsqrt(gadd(p1,p2),prec);
                    822:       if (gcmp0(p1))
                    823:       {
                    824:        y[1]=lsqrt(p1,prec);
                    825:        y[2]=lcopy((GEN)y[1]);
                    826:        return y;
                    827:       }
                    828:
                    829:       if (gsigne((GEN)x[1]) < 0)
                    830:       {
                    831:        p1 = gmul2n(gsub(p1,(GEN)x[1]), -1);
                    832:        y[2] = lsqrt(p1,prec);
                    833:         y[1] = ldiv((GEN)x[2],gmul2n((GEN)y[2],1));
                    834:        tetpil=avma;
                    835:         y = (gsigne((GEN)x[2]) > 0)? gcopy(y): gneg(y);
                    836:        return gerepile(av,tetpil,y);
                    837:       }
                    838:
                    839:       p1 = gmul2n(gadd(p1,(GEN)x[1]), -1); tetpil=avma;
                    840:       y[1] = lpile(av,tetpil,gsqrt(p1,prec));
                    841:       av=avma; p1=gmul2n((GEN)y[1],1); tetpil=avma;
                    842:       y[2] = lpile(av,tetpil,gdiv((GEN)x[2],p1));
                    843:       return y;
                    844:
                    845:     case t_PADIC:
                    846:       return padic_sqrt(x);
                    847:
                    848:     case t_SER:
                    849:       e=valp(x);
                    850:       if (gcmp0(x)) return zeroser(varn(x), (e+1)>>1);
                    851:       if (e & 1) err(sqrter6);
                    852:       av = avma;
                    853:       /* trick: ser_pui assumes valp(x) = 0 */
                    854:       y = ser_pui(x,ghalf,prec);
                    855:       if (typ(y) == t_SER) /* generic case */
                    856:         y[1] = evalsigne(1) | evalvalp(e>>1) | evalvarn(varn(x));
                    857:       else /* e.g coeffs are POLMODs */
                    858:         y = gerepileupto(av, gmul(y, gpowgs(polx[varn(x)], e>>1)));
                    859:       return y;
                    860:   }
                    861:   return transc(gsqrt,x,prec);
                    862: }
                    863:
                    864: void
                    865: gsqrtz(GEN x, GEN y)
                    866: {
                    867:   long av=avma, prec = precision(y);
                    868:
                    869:   if (!prec) err(infprecer,"gsqrtz");
                    870:   gaffect(gsqrt(x,prec),y); avma=av;
                    871: }
                    872: /********************************************************************/
                    873: /**                                                                **/
                    874: /**                    FONCTION RACINE N-IEME                      **/
                    875: /**                                                                **/
                    876: /********************************************************************/
                    877: GEN
                    878: rootsof1complex(GEN n, long prec)
                    879: {
                    880:   ulong ltop=avma;
                    881:   GEN z,a;
                    882:   if (is_pm1(n)) return realun(prec);
                    883:   if (lgefint(n)==3 && n[2]==2)
                    884:   {
                    885:     a=realun(prec);
                    886:     setsigne(a,-1);
                    887:     return a;
                    888:   }
                    889:   a=mppi(prec); setexpo(a,2); /* a=2*pi */
                    890:   a=divri(a,n);
                    891:   z = cgetg(3,t_COMPLEX);
                    892:   gsincos(a,(GEN*)(z+2),(GEN*)(z+1),prec);
                    893:   return gerepileupto(ltop,z);
                    894: }
                    895: /*Only the O() of y is used*/
                    896: GEN
                    897: rootsof1padic(GEN n, GEN y)
                    898: {
                    899:   ulong ltop=avma;
                    900:   GEN z,r;
                    901:   (void)mpsqrtnmod(gun,n,(GEN)y[2],&z);
                    902:   if (z==gzero){avma=ltop;return gzero;}/*should not happen*/
                    903:   r=cgetg(5,t_PADIC);
                    904:   r[1]=y[1];setvalp(r,0);/*rootsofunity are unramified*/
                    905:   r[2]=licopy((GEN)y[2]);
                    906:   r[3]=licopy((GEN)y[3]);
                    907:   r[4]=(long)padicsqrtnlift(gun,n,z,(GEN)y[2],precp(y));
                    908:   return gerepileupto(ltop,r);
                    909: }
                    910: static GEN paexp(GEN x);
                    911: /*compute the p^e th root of x p-adic*/
                    912: GEN padic_sqrtn_ram(GEN x, long e)
                    913: {
                    914:   ulong ltop=avma;
                    915:   GEN n,a;
                    916:   GEN p=(GEN)x[2];
                    917:   long v=0;
                    918:   n=gpowgs((GEN) x[2],e);
                    919:   if (valp(x))
                    920:   {
                    921:     GEN p1,z;
                    922:     p1=dvmdsi(valp(x),n,&z);
                    923:     if (signe(z))
                    924:       err(talker,"n-root does not exists in gsqrtn");
                    925:     v=itos(p1);
                    926:     x=gcopy(x);setvalp(x,0);
                    927:   }
                    928:   /*If p=2 -1 is an root of unity in U1,we need an extra check*/
                    929:   if (lgefint(p)==3 && p[2]==2 && mod8((GEN)x[4])!=signe((GEN)x[4]))
                    930:     err(talker,"n-root does not exists in gsqrtn");
                    931:   /*Other "n-root does not exists in gsqrtn" are caught by paexp...*/
                    932:   a=paexp(gdiv(palog(x),n));
                    933:   /*Here n=p^e and a^n=z*x where z is a root of unity. note that
                    934:       z^p=z, so z^n=z. and if b=a/z then b^n=x. We say b=x/(a^(n-1))*/
                    935:   a=gdiv(x,powgi(a,addis(n,-1)));
                    936:   if (v)  {  a=gcopy(a);setvalp(a,v);  }
                    937:   a=gerepileupto(ltop,a);
                    938:   return a;
                    939: }
                    940: /*compute the nth root of x p-adic p prime with n*/
                    941: GEN padic_sqrtn_unram(GEN x, GEN n, GEN *zetan)
                    942: {
                    943:   ulong ltop=avma,tetpil;
                    944:   GEN a,r;
                    945:   GEN p=(GEN)x[2];
                    946:   long v=0;
                    947:   /*check valuation*/
                    948:   if (valp(x))
                    949:   {
                    950:     GEN p1,z;
                    951:     p1=dvmdsi(valp(x),n,&z);
                    952:     if (signe(z))
                    953:       err(talker,"n-root does not exists in gsqrtn");
                    954:     v=itos(p1);
                    955:   }
                    956:   a=mpsqrtnmod((GEN)x[4],n,p,zetan);
                    957:   if (!a)
                    958:     err(talker,"n-root does not exists in gsqrtn");
                    959:   tetpil=avma;
                    960:   r=cgetg(5,t_PADIC);
                    961:   r[1]=x[1];setvalp(r,v);
                    962:   r[2]=licopy(p);
                    963:   r[3]=licopy((GEN)x[3]);
                    964:   r[4]=(long)padicsqrtnlift((GEN)x[4],n,a,p,precp(x));
                    965:   if (zetan)
                    966:   {
                    967:     GEN z,*gptr[2];
                    968:     z=cgetg(5,t_PADIC);
                    969:     z[1]=x[1];setvalp(z,0);
                    970:     z[2]=licopy(p);
                    971:     z[3]=licopy((GEN)x[3]);
                    972:     z[4]=(long)padicsqrtnlift(gun,n,*zetan,p,precp(x));
                    973:     gptr[0]=&r;gptr[1]=&z;
                    974:     gerepilemanysp(ltop,tetpil,gptr,2);
                    975:     *zetan=z;
                    976:     return r;
                    977:   }
                    978:   else
                    979:     return gerepile(ltop,tetpil,r);
                    980: }
                    981: GEN padic_sqrtn(GEN x, GEN n, GEN *zetan)
                    982: {
                    983:   ulong ltop=avma,tetpil;
                    984:   GEN p=(GEN)x[2];
                    985:   GEN q;
                    986:   long e;
                    987:   GEN *gptr[2];
                    988:   if (gcmp0(x))
                    989:   {
                    990:     GEN y;
                    991:     long m = itos(n);
                    992:     e=valp(x); y=cgetg(5,t_PADIC); copyifstack(x[2],y[2]);
                    993:     y[4] = zero; e = (e+m-1)/m;
                    994:     y[3] = un;
                    995:     y[1] = evalvalp(e) | evalprecp(precp(x));
                    996:     return y;
                    997:   }
                    998:   /*First treat the ramified part using logarithms*/
                    999:   e=pvaluation(n,p,&q);
                   1000:   tetpil=avma;
                   1001:   if (e)
                   1002:   {
                   1003:     x=padic_sqrtn_ram(x,e);
                   1004:   }
                   1005:   /*finished ?*/
                   1006:   if (is_pm1(q))
                   1007:   {
                   1008:     if (signe(q)<0)
                   1009:     {
                   1010:       tetpil=avma;
                   1011:       x=ginv(x);
                   1012:     }
                   1013:     if (zetan && e && lgefint(p)==3 && p[2]==2)/*-1 in Q_2*/
                   1014:     {
                   1015:       *zetan=negi(gun);
                   1016:       gptr[0]=&x;gptr[1]=zetan;
                   1017:       gerepilemanysp(ltop,tetpil,gptr,2);
                   1018:       return x;
                   1019:     }
                   1020:     if (zetan) *zetan=gun;
                   1021:     return gerepile(ltop,tetpil,x);
                   1022:   }
                   1023:   /*Now we use hensel lift for unramified case. 4x faster.*/
                   1024:   tetpil=avma;
                   1025:   x=padic_sqrtn_unram(x,q,zetan);
                   1026:   if (zetan)
                   1027:   {
                   1028:     if (e && lgefint(p)==3 && p[2]==2)/*-1 in Q_2*/
                   1029:     {
                   1030:       tetpil=avma;
                   1031:       x=gcopy(x);
                   1032:       *zetan=gneg(*zetan);
                   1033:     }
                   1034:     gptr[0]=&x;gptr[1]=zetan;
                   1035:     gerepilemanysp(ltop,tetpil,gptr,2);
                   1036:     return x;
                   1037:   }
                   1038:   return gerepile(ltop,tetpil,x);
                   1039: }
                   1040:
                   1041: GEN
                   1042: gsqrtn(GEN x, GEN n, GEN *zetan, long prec)
                   1043: {
                   1044:   long av,tetpil,i,lx,tx;
                   1045:   long e,m;
                   1046:   GEN y,z;
                   1047:   if (zetan) *zetan=gzero;
                   1048:   if (typ(n)!=t_INT) err(talker,"second arg must be integer in gsqrtn");
                   1049:   if (!signe(n)) err(talker,"1/0 exponent in gsqrtn");
                   1050:   if (is_pm1(n))
                   1051:   {
                   1052:     if (zetan) *zetan=gun;
                   1053:     if (signe(n)>0)
                   1054:       return gcopy(x);
                   1055:     return ginv(x);
                   1056:   }
                   1057:   tx = typ(x);
                   1058:   if (is_matvec_t(tx))
                   1059:   {
                   1060:     lx=lg(x); y=cgetg(lx,tx);
                   1061:     for (i=1; i<lx; i++) y[i]=(long)gsqrtn((GEN)x[i],n,NULL,prec);
                   1062:     return y;
                   1063:   }
                   1064:   switch(tx)
                   1065:   {
                   1066:   case t_POL: case t_RFRAC: case t_RFRACN:
                   1067:     av = avma;
                   1068:     y=tayl(x,gvar(x),precdl); tetpil=avma;
                   1069:     return gerepile(av,tetpil,gsqrtn(y,n,zetan,prec));
                   1070:   case t_SER:
                   1071:     e=valp(x);m=itos(n);
                   1072:     if (gcmp0(x)) return zeroser(varn(x), (e+m-1)/m);
                   1073:     if (e % m) err(talker,"incorrect valuation in gsqrt");
                   1074:     av = avma;
                   1075:     /* trick: ser_pui assumes valp(x) = 0 */
                   1076:     y = ser_pui(x,ginv(n),prec);
                   1077:     if (typ(y) == t_SER) /* generic case */
                   1078:       y[1] = evalsigne(1) | evalvalp(e/m) | evalvarn(varn(x));
                   1079:     else /* e.g coeffs are POLMODs */
                   1080:       y = gerepileupto(av, gmul(y, gpowgs(polx[varn(x)], e/m)));
                   1081:     return y;
                   1082:   case t_INTMOD:
                   1083:     z=gzero;
                   1084:     /*This is not great, but else it will generate too much trouble*/
                   1085:     if (!isprime((GEN)x[1])) err(talker,"modulus must be prime in gsqrtn");
                   1086:     if (zetan)
                   1087:     {
                   1088:       z=cgetg(3,tx); copyifstack(x[1],z[1]);
                   1089:       z[2]=lgetg(lgefint(z[1]),t_INT);
                   1090:     }
                   1091:     y=cgetg(3,tx); copyifstack(x[1],y[1]);
                   1092:     y[2]=(long)mpsqrtnmod((GEN)x[2],n,(GEN)x[1],zetan);
                   1093:     if (zetan)
                   1094:     {
                   1095:       cgiv(*zetan);/*Ole!*/
                   1096:       affii(*zetan,(GEN)z[2]);
                   1097:       *zetan=z;
                   1098:     }
                   1099:     if(!y[2]) err(talker,"n-root does not exists in gsqrtn");
                   1100:     return y;
                   1101:
                   1102:   case t_PADIC:
                   1103:     return padic_sqrtn(x,n,zetan);
                   1104:   case t_INT: case t_FRAC: case t_FRACN: case t_REAL: case t_COMPLEX:
                   1105:     i = (long) precision(n); if (i) prec=i;
                   1106:     if (tx==t_INT && is_pm1(x) && signe(x)>0)
                   1107:       y=gun;    /*speed-up since there is no way to call rootsof1complex
                   1108:                directly from gp*/
                   1109:     else
                   1110:     {
                   1111:       av=avma;
                   1112:       y=gmul(ginv(n),glog(x,prec)); tetpil=avma;
                   1113:       y=gerepile(av,tetpil,gexp(y,prec));
                   1114:     }
                   1115:     if (zetan)
                   1116:       *zetan=rootsof1complex(n,prec);
                   1117:     return y;
                   1118:   default:
                   1119:     err(typeer,"gsqrtn");
                   1120:   }
                   1121:   return NULL;/*keep GCC happy*/
                   1122: }
                   1123:
                   1124: /********************************************************************/
                   1125: /**                                                                **/
                   1126: /**                    FONCTION EXPONENTIELLE-1                    **/
                   1127: /**                                                                **/
                   1128: /********************************************************************/
                   1129: #ifdef LONG_IS_64BIT
                   1130: #  define EXMAX 46
                   1131: #else
                   1132: #  define EXMAX 22
                   1133: #endif
                   1134:
                   1135: GEN
                   1136: mpexp1(GEN x)
                   1137: {
                   1138:   long l,l1,l2,i,n,m,ex,s,av,av2, sx = signe(x);
                   1139:   double a,b,alpha,beta, gama = 2.0 /* optimized for SUN3 */;
                   1140:                                     /* KB: 3.0 is better for UltraSparc */
                   1141:   GEN y,p1,p2,p3,p4,unr;
                   1142:
                   1143:   if (typ(x)!=t_REAL) err(typeer,"mpexp1");
                   1144:   if (!sx)
                   1145:   {
                   1146:     y=cgetr(3); y[1]=x[1]; y[2]=0; return y;
                   1147:   }
                   1148:   l=lg(x); y=cgetr(l); av=avma; /* room for result */
                   1149:
                   1150:   l2 = l+1; ex = expo(x);
                   1151:   if (ex > EXMAX) err(talker,"exponent too large in exp");
                   1152:   alpha = -1-log(2+x[2]/C31)-ex*LOG2;
                   1153:   beta = 5 + bit_accuracy(l)*LOG2;
                   1154:   a = sqrt(beta/(gama*LOG2));
                   1155:   b = (alpha + 0.5*log(beta*gama/LOG2))/LOG2;
                   1156:   if (a>=b)
                   1157:   {
                   1158:     n=(long)(1+sqrt(beta*gama/LOG2));
                   1159:     m=(long)(1+a-b);
                   1160:     l2 += m>>TWOPOTBITS_IN_LONG;
                   1161:   }
                   1162:   else
                   1163:   {
                   1164:     n=(long)(1+beta/alpha);
                   1165:     m=0;
                   1166:   }
                   1167:   unr=realun(l2);
                   1168:   p2=rcopy(unr); setlg(p2,4);
                   1169:   p4=cgetr(l2); affrr(x,p4); setsigne(p4,1);
                   1170:   if (m) setexpo(p4,ex-m);
                   1171:
                   1172:   s=0; l1=4; av2 = avma;
                   1173:   for (i=n; i>=2; i--)
                   1174:   {
                   1175:     setlg(p4,l1); p3 = divrs(p4,i);
                   1176:     s -= expo(p3); p1 = mulrr(p3,p2); setlg(p1,l1);
                   1177:     l1 += s>>TWOPOTBITS_IN_LONG; if (l1>l2) l1=l2;
                   1178:     s %= BITS_IN_LONG;
                   1179:     setlg(unr,l1); p1 = addrr(unr,p1);
                   1180:     setlg(p2,l1); affrr(p1,p2); avma = av2;
                   1181:   }
                   1182:   setlg(p2,l2); setlg(p4,l2); p2 = mulrr(p4,p2);
                   1183:
                   1184:   for (i=1; i<=m; i++)
                   1185:   {
                   1186:     setlg(p2,l2);
                   1187:     p2 = mulrr(addsr(2,p2),p2);
                   1188:   }
                   1189:   if (sx == -1)
                   1190:   {
                   1191:     setlg(unr,l2); p2 = addrr(unr,p2);
                   1192:     setlg(p2,l2); p2 = ginv(p2);
                   1193:     p2 = subrr(p2,unr);
                   1194:   }
                   1195:   affrr(p2,y); avma = av; return y;
                   1196: }
                   1197: #undef EXMAX
                   1198:
                   1199: /********************************************************************/
                   1200: /**                                                                **/
                   1201: /**                   FONCTION EXPONENTIELLE                       **/
                   1202: /**                                                                **/
                   1203: /********************************************************************/
                   1204:
                   1205: GEN
                   1206: mpexp(GEN x)
                   1207: {
                   1208:   long av, sx = signe(x);
                   1209:   GEN y;
                   1210:
                   1211:   if (!sx) return addsr(1,x);
                   1212:   if (sx<0) setsigne(x,1);
                   1213:   av = avma; y = addsr(1, mpexp1(x));
                   1214:   if (sx<0) { y = divsr(1,y); setsigne(x,-1); }
                   1215:   return gerepileupto(av,y);
                   1216: }
                   1217:
                   1218: static GEN
                   1219: paexp(GEN x)
                   1220: {
                   1221:   long k,av, e = valp(x), pp = precp(x), n = e + pp;
                   1222:   GEN y,r,p1;
                   1223:
                   1224:   if (gcmp0(x)) return gaddgs(x,1);
                   1225:   if (e<=0 || (!cmpis((GEN)x[2],2) && e==1))
                   1226:     err(talker,"p-adic argument out of range in gexp");
                   1227:   av = avma;
                   1228:   if (egalii(gdeux,(GEN)x[2]))
                   1229:   {
                   1230:     n--; e--; k = n/e;
                   1231:     if (n%e==0) k--;
                   1232:   }
                   1233:   else
                   1234:   {
                   1235:     p1 = subis((GEN)x[2], 1);
                   1236:     k = itos(dvmdii(subis(mulis(p1,n), 1), subis(mulis(p1,e), 1), &r));
                   1237:     if (!signe(r)) k--;
                   1238:   }
                   1239:   for (y=gun; k; k--) y = gaddsg(1, gdivgs(gmul(y,x), k));
                   1240:   return gerepileupto(av, y);
                   1241: }
                   1242:
                   1243: GEN
                   1244: gexp(GEN x, long prec)
                   1245: {
                   1246:   long av,tetpil,ex;
                   1247:   GEN r,y,p1,p2;
                   1248:
                   1249:   switch(typ(x))
                   1250:   {
                   1251:     case t_REAL:
                   1252:       return mpexp(x);
                   1253:
                   1254:     case t_COMPLEX:
                   1255:       y=cgetg(3,t_COMPLEX); av=avma;
                   1256:       r=gexp((GEN)x[1],prec);
                   1257:       gsincos((GEN)x[2],&p2,&p1,prec);
                   1258:       tetpil=avma;
                   1259:       y[1]=lmul(r,p1); y[2]=lmul(r,p2);
                   1260:       gerepilemanyvec(av,tetpil,y+1,2);
                   1261:       return y;
                   1262:
                   1263:     case t_PADIC:
                   1264:       return paexp(x);
                   1265:
                   1266:     case t_SER:
                   1267:       if (gcmp0(x)) return gaddsg(1,x);
                   1268:
                   1269:       ex=valp(x); if (ex<0) err(negexper,"gexp");
                   1270:       if (ex)
                   1271:       {
                   1272:        long i,j,ly=lg(x)+ex;
                   1273:
                   1274:        y=cgetg(ly,t_SER);
                   1275:        y[1] = evalsigne(1) | evalvalp(0) | evalvarn(varn(x));
                   1276:         y[2] = un;
                   1277:        for (i=3; i<ex+2; i++) y[i]=zero;
                   1278:        for (   ; i<ly; i++)
                   1279:        {
                   1280:          av=avma; p1=gzero;
                   1281:          for (j=ex; j<i-1; j++)
                   1282:            p1=gadd(p1,gmulgs(gmul((GEN)x[j-ex+2],(GEN)y[i-j]),j));
                   1283:          tetpil=avma; y[i]=lpile(av,tetpil,gdivgs(p1,i-2));
                   1284:        }
                   1285:        return y;
                   1286:       }
                   1287:       av=avma; p1=gcopy(x); p1[2]=zero;
                   1288:       p2=gexp(normalize(p1),prec);
                   1289:       p1=gexp((GEN)x[2],prec); tetpil=avma;
                   1290:       return gerepile(av,tetpil,gmul(p1,p2));
                   1291:
                   1292:     case t_INTMOD:
                   1293:       err(typeer,"gexp");
                   1294:   }
                   1295:   return transc(gexp,x,prec);
                   1296: }
                   1297:
                   1298: void
                   1299: gexpz(GEN x, GEN y)
                   1300: {
                   1301:   long av=avma, prec = precision(y);
                   1302:
                   1303:   if (!prec) err(infprecer,"gexpz");
                   1304:   gaffect(gexp(x,prec),y); avma=av;
                   1305: }
                   1306:
                   1307: /********************************************************************/
                   1308: /**                                                                **/
                   1309: /**                      FONCTION LOGARITHME                       **/
                   1310: /**                                                                **/
                   1311: /********************************************************************/
                   1312:
                   1313: GEN
                   1314: mplog(GEN x)
                   1315: {
                   1316:   long l,l1,l2,m,m1,n,i,ex,s,sgn,ltop,av;
                   1317:   double alpha,beta,a,b;
                   1318:   GEN y,p1,p2,p3,p4,p5,unr;
                   1319:
                   1320:   if (typ(x)!=t_REAL) err(typeer,"mplog");
                   1321:   if (signe(x)<=0) err(talker,"non positive argument in mplog");
                   1322:   l=lg(x); sgn = cmpsr(1,x); if (!sgn) return realzero(l);
                   1323:   y=cgetr(l); ltop=avma;
                   1324:
                   1325:   l2 = l+1; p2=p1=cgetr(l2); affrr(x,p1);
                   1326:   av=avma;
                   1327:   if (sgn > 0) p2 = divsr(1,p1); /* x<1 changer x en 1/x */
                   1328:   for (m1=1; expo(p2)>0; m1++) p2 = mpsqrt(p2);
                   1329:   if (m1 > 1 || sgn > 0) { affrr(p2,p1); avma=av; }
                   1330:
                   1331:   alpha = 1+p1[2]/C31; if (!alpha) alpha = 0.00000001;
                   1332:   l -= 2; alpha = -log(alpha);
                   1333:   beta = (BITS_IN_LONG/2)*l*LOG2;
                   1334:   a = alpha/LOG2;
                   1335:   b = sqrt((BITS_IN_LONG/2)*l/3.0);
                   1336:   if (a<=b)
                   1337:   {
                   1338:     n=(long)(1+sqrt((BITS_IN_LONG/2)*3.0*l));
                   1339:     m=(long)(1+b-a);
                   1340:     l2 += m>>TWOPOTBITS_IN_LONG;
                   1341:     p4=cgetr(l2); affrr(p1,p4);
                   1342:     p1 = p4; av=avma;
                   1343:     for (i=1; i<=m; i++)  p1 = mpsqrt(p1);
                   1344:     affrr(p1,p4); avma=av;
                   1345:   }
                   1346:   else
                   1347:   {
                   1348:     n=(long)(1+beta/alpha);
                   1349:     m=0; p4 = p1;
                   1350:   }
                   1351:   unr=realun(l2);
                   1352:   p2=cgetr(l2); p3=cgetr(l2); av=avma;
                   1353:
                   1354:   /* affrr needed here instead of setlg since prec may DECREASE */
                   1355:   p1 = cgetr(l2); affrr(subrr(p4,unr), p1);
                   1356:
                   1357:   p5 = addrr(p4,unr); setlg(p5,l2);
                   1358:   affrr(divrr(p1,p5), p2);
                   1359:   affrr(mulrr(p2,p2), p3);
                   1360:   affrr(divrs(unr,2*n+1), p4); setlg(p4,4); avma=av;
                   1361:
                   1362:   s=0; ex=expo(p3); l1 = 4;
                   1363:   for (i=n; i>=1; i--)
                   1364:   {
                   1365:     setlg(p3,l1); p5 = mulrr(p4,p3);
                   1366:     setlg(unr,l1); p1 = divrs(unr,2*i-1);
                   1367:     s -= ex;
                   1368:     l1 += s>>TWOPOTBITS_IN_LONG; if (l1>l2) l1=l2;
                   1369:     s %= BITS_IN_LONG;
                   1370:     setlg(p1,l1); setlg(p4,l1); setlg(p5,l1);
                   1371:     p1 = addrr(p1,p5); affrr(p1,p4); avma=av;
                   1372:   }
                   1373:   setlg(p4,l2); affrr(mulrr(p2,p4), y);
                   1374:   setexpo(y, expo(y)+m+m1);
                   1375:   if (sgn > 0) setsigne(y, -1);
                   1376:   avma=ltop; return y;
                   1377: }
                   1378:
                   1379: GEN
                   1380: teich(GEN x)
                   1381: {
                   1382:   GEN aux,y,z,p1;
                   1383:   long av,n,k;
                   1384:
                   1385:   if (typ(x)!=t_PADIC) err(talker,"not a p-adic argument in teichmuller");
                   1386:   if (!signe(x[4])) return gcopy(x);
                   1387:   y=cgetp(x); z=(GEN)x[4];
                   1388:   if (!cmpis((GEN)x[2],2))
                   1389:   {
                   1390:     n = mod4(z);
                   1391:     if (n & 2)
                   1392:       addsiz(-1,(GEN)x[3],(GEN)y[4]);
                   1393:     else
                   1394:       affsi(1,(GEN)y[4]);
                   1395:     return y;
                   1396:   }
                   1397:   av = avma; p1 = addsi(-1,(GEN)x[2]);
                   1398:   aux = divii(addsi(-1,(GEN)x[3]),p1); n = precp(x);
                   1399:   for (k=1; k<n; k<<=1)
                   1400:     z=modii(mulii(z,addsi(1,mulii(aux,addsi(-1,powmodulo(z,p1,(GEN)x[3]))))),
                   1401:             (GEN)x[3]);
                   1402:   affii(z,(GEN)y[4]); avma=av; return y;
                   1403: }
                   1404:
                   1405: static GEN
                   1406: palogaux(GEN x)
                   1407: {
                   1408:   long av1=avma,tetpil,k,e,pp;
                   1409:   GEN y,s,y2;
                   1410:
                   1411:   if (egalii(gun,(GEN)x[4]))
                   1412:   {
                   1413:     y=gaddgs(x,-1);
                   1414:     if (egalii(gdeux,(GEN)x[2]))
                   1415:     {
                   1416:       setvalp(y,valp(y)-1);
                   1417:       if (!gcmp1((GEN)y[3])) y[3]=lshifti((GEN)y[3],-1);
                   1418:     }
                   1419:     return gerepilecopy(av1,y);
                   1420:   }
                   1421:   y=gdiv(gaddgs(x,-1),gaddgs(x,1)); e=valp(y); pp=e+precp(y);
                   1422:   if (egalii(gdeux,(GEN)x[2])) pp--;
                   1423:   else
                   1424:   {
                   1425:     long av=avma;
                   1426:     GEN p1;
                   1427:
                   1428:     for (p1=stoi(e); cmpsi(pp,p1)>0; pp++)
                   1429:       p1 = mulii(p1,(GEN)x[2]);
                   1430:     avma=av; pp-=2;
                   1431:   }
                   1432:   k=pp/e; if (!odd(k)) k--;
                   1433:   y2=gsqr(y); s=gdivgs(gun,k);
                   1434:   while (k>=3)
                   1435:   {
                   1436:     k-=2; s=gadd(gmul(y2,s),gdivgs(gun,k));
                   1437:   }
                   1438:   tetpil=avma; return gerepile(av1,tetpil,gmul(s,y));
                   1439: }
                   1440:
                   1441: GEN
                   1442: palog(GEN x)
                   1443: {
                   1444:   long av=avma,tetpil;
                   1445:   GEN p1,y;
                   1446:
                   1447:   if (!signe(x[4])) err(talker,"zero argument in palog");
                   1448:   if (cmpis((GEN)x[2],2))
                   1449:   {
                   1450:     y=cgetp(x); p1=gsubgs((GEN)x[2],1);
                   1451:     affii(powmodulo((GEN)x[4],p1,(GEN)x[3]),(GEN)y[4]);
                   1452:     y=gmulgs(palogaux(y),2); tetpil=avma;
                   1453:     return gerepile(av,tetpil,gdiv(y,p1));
                   1454:   }
                   1455:   y=gsqr(x); setvalp(y,0); tetpil=avma;
                   1456:   return gerepile(av,tetpil,palogaux(y));
                   1457: }
                   1458:
                   1459: GEN
                   1460: log0(GEN x, long flag,long prec)
                   1461: {
                   1462:   switch(flag)
                   1463:   {
                   1464:     case 0: return glog(x,prec);
                   1465:     case 1: return glogagm(x,prec);
                   1466:     default: err(flagerr,"log");
                   1467:   }
                   1468:   return NULL; /* not reached */
                   1469: }
                   1470:
                   1471: GEN
                   1472: glog(GEN x, long prec)
                   1473: {
                   1474:   long av,tetpil;
                   1475:   GEN y,p1,p2;
                   1476:
                   1477:   switch(typ(x))
                   1478:   {
                   1479:     case t_REAL:
                   1480:       if (signe(x)>=0) return mplog(x);
                   1481:       y=cgetg(3,t_COMPLEX); y[2]=lmppi(lg(x));
                   1482:       setsigne(x,1); y[1]=lmplog(x);
                   1483:       setsigne(x,-1); return y;
                   1484:
                   1485:     case t_COMPLEX:
                   1486:       y=cgetg(3,t_COMPLEX); y[2]=larg(x,prec);
                   1487:       av=avma; p1=glog(gnorm(x),prec); tetpil=avma;
                   1488:       y[1]=lpile(av,tetpil,gmul2n(p1,-1));
                   1489:       return y;
                   1490:
                   1491:     case t_PADIC:
                   1492:       return palog(x);
                   1493:
                   1494:     case t_SER:
                   1495:       av=avma; if (valp(x)) err(negexper,"glog");
                   1496:       p1=gdiv(derivser(x),x);
                   1497:       tetpil=avma; p1=integ(p1,varn(x));
                   1498:       if (gcmp1((GEN)x[2])) return gerepile(av,tetpil,p1);
                   1499:
                   1500:       p2=glog((GEN)x[2],prec); tetpil=avma;
                   1501:       return gerepile(av,tetpil,gadd(p1,p2));
                   1502:
                   1503:     case t_INTMOD:
                   1504:       err(typeer,"glog");
                   1505:   }
                   1506:   return transc(glog,x,prec);
                   1507: }
                   1508:
                   1509: void
                   1510: glogz(GEN x, GEN y)
                   1511: {
                   1512:   long av=avma, prec = precision(y);
                   1513:
                   1514:   if (!prec) err(infprecer,"glogz");
                   1515:   gaffect(glog(x,prec),y); avma=av;
                   1516: }
                   1517:
                   1518: /********************************************************************/
                   1519: /**                                                                **/
                   1520: /**                      FONCTION SINCOS-1                         **/
                   1521: /**                                                                **/
                   1522: /********************************************************************/
                   1523:
                   1524: static GEN
                   1525: mpsc1(GEN x, long *ptmod8)
                   1526: {
                   1527:   const long mmax = 23169;
                   1528:  /* on a 64-bit machine with true 128 bit/64 bit division, one could
                   1529:   * take mmax=1518500248; on the alpha it does not seem worthwhile
                   1530:   */
                   1531:   long l,l0,l1,l2,l4,ee,i,n,m,s,t,av;
                   1532:   double alpha,beta,a,b,c,d;
                   1533:   GEN y,p1,p2,p3,p4,pitemp;
                   1534:
                   1535:   if (typ(x)!=t_REAL) err(typeer,"mpsc1");
                   1536:   if (!signe(x))
                   1537:   {
                   1538:     y=cgetr(3);
                   1539:     y[1] = evalexpo((expo(x)<<1) - 1);
                   1540:     y[2] = 0; *ptmod8=0; return y;
                   1541:   }
                   1542:   l=lg(x); y=cgetr(l); av=avma;
                   1543:
                   1544:   l++; pitemp = mppi(l+1); setexpo(pitemp,-1);
                   1545:   p1 = addrr(x,pitemp); setexpo(pitemp,0);
                   1546:   if (expo(p1) >= bit_accuracy(min(l,lg(p1))) + 3)
                   1547:     err(precer,"mpsc1");
                   1548:   p3 = divrr(p1,pitemp); p2 = mpent(p3);
                   1549:   if (signe(p2)) x = subrr(x, mulir(p2,pitemp));
                   1550:   p1 = cgetr(l+1); affrr(x, p1);
                   1551:
                   1552:   *ptmod8 = (signe(p1) < 0)? 4: 0;
                   1553:   if (signe(p2))
                   1554:   {
                   1555:     long mod4 = mod4(p2);
                   1556:     if (signe(p2) < 0 && mod4) mod4 = 4-mod4;
                   1557:     *ptmod8 += mod4;
                   1558:   }
                   1559:   if (gcmp0(p1)) alpha=1000000.0;
                   1560:   else
                   1561:   {
                   1562:     m=expo(p1); alpha=(m<-1022)? -1-m*LOG2: -1-log(fabs(rtodbl(p1)));
                   1563:   }
                   1564:   beta = 5 + bit_accuracy(l)*LOG2;
                   1565:   a=0.5/LOG2; b=0.5*a;
                   1566:   c = a+sqrt((beta+b)/LOG2);
                   1567:   d = ((beta/c)-alpha-log(c))/LOG2;
                   1568:   if (d>=0)
                   1569:   {
                   1570:     m=(long)(1+d);
                   1571:     n=(long)((1+c)/2.0);
                   1572:     setexpo(p1,expo(p1)-m);
                   1573:   }
                   1574:   else { m=0; n=(long)((1+beta/alpha)/2.0); }
                   1575:   l2=l+1+(m>>TWOPOTBITS_IN_LONG);
                   1576:   p2=realun(l2); setlg(p2,4);
                   1577:   p4=cgetr(l2); av = avma;
                   1578:   affrr(gsqr(p1),p4); setlg(p4,4);
                   1579:
                   1580:   if (n>mmax)
                   1581:     p3 = divrs(divrs(p4,2*n+2),2*n+1);
                   1582:   else
                   1583:     p3 = divrs(p4, (2*n+2)*(2*n+1));
                   1584:   ee = -expo(p3); s=0;
                   1585:   l4 = l1 = 3 + (ee>>TWOPOTBITS_IN_LONG);
                   1586:   if (l4<=l2) { setlg(p2,l4); setlg(p4,l4); }
                   1587:   for (i=n; i>mmax; i--)
                   1588:   {
                   1589:     p3 = divrs(divrs(p4,2*i),2*i-1); s -= expo(p3);
                   1590:     t=s&(BITS_IN_LONG-1); l0=(s>>TWOPOTBITS_IN_LONG);
                   1591:     if (t) l0++;
                   1592:     l1 += l0; if (l1>l2) { l0 += l2-l1; l1=l2; }
                   1593:     l4 += l0;
                   1594:     p3 = mulrr(p3,p2);
                   1595:     if (l4<=l2) { setlg(p2,l4); setlg(p4,l4); }
                   1596:     subsrz(1,p3,p2); avma=av;
                   1597:   }
                   1598:   for (  ; i>=2; i--)
                   1599:   {
                   1600:     p3 = divrs(p4, 2*i*(2*i-1)); s -= expo(p3);
                   1601:     t=s&(BITS_IN_LONG-1); l0=(s>>TWOPOTBITS_IN_LONG);
                   1602:     if (t) l0++;
                   1603:     l1 += l0; if (l1>l2) { l0 += l2-l1; l1=l2; }
                   1604:     l4 += l0;
                   1605:     p3 = mulrr(p3,p2);
                   1606:     if (l4<=l2) { setlg(p2,l4); setlg(p4,l4); }
                   1607:     subsrz(1,p3,p2); avma=av;
                   1608:   }
                   1609:   if (l4<=l2) { setlg(p2,l4); setlg(p4,l4); }
                   1610:   setexpo(p4,expo(p4)-1); setsigne(p4, -signe(p4));
                   1611:   p2 = mulrr(p4,p2);
                   1612:   for (i=1; i<=m; i++)
                   1613:   {
                   1614:     p2 = mulrr(p2,addsr(2,p2)); setexpo(p2,expo(p2)+1);
                   1615:   }
                   1616:   affrr(p2,y); avma=av; return y;
                   1617: }
                   1618:
                   1619: /********************************************************************/
                   1620: /**                                                                **/
                   1621: /**                      FONCTION sqrt(-x*(x+2))                   **/
                   1622: /**                                                                **/
                   1623: /********************************************************************/
                   1624:
                   1625: static GEN
                   1626: mpaut(GEN x)
                   1627: {
                   1628:   long av = avma;
                   1629:   GEN p1 = mulrr(x,addsr(2,x));
                   1630:   setsigne(p1,-signe(p1));
                   1631:   return gerepileuptoleaf(av, mpsqrt(p1));
                   1632: }
                   1633:
                   1634: /********************************************************************/
                   1635: /**                                                                **/
                   1636: /**                       FONCTION COSINUS                         **/
                   1637: /**                                                                **/
                   1638: /********************************************************************/
                   1639:
                   1640: static GEN
                   1641: mpcos(GEN x)
                   1642: {
                   1643:   long mod8,av,tetpil;
                   1644:   GEN y,p1;
                   1645:
                   1646:   if (typ(x)!=t_REAL) err(typeer,"mpcos");
                   1647:   if (!signe(x)) return addsr(1,x);
                   1648:
                   1649:   av=avma; p1=mpsc1(x,&mod8); tetpil=avma;
                   1650:   switch(mod8)
                   1651:   {
                   1652:     case 0: case 4:
                   1653:       y=addsr(1,p1); break;
                   1654:     case 1: case 7:
                   1655:       y=mpaut(p1); setsigne(y,-signe(y)); break;
                   1656:     case 2: case 6:
                   1657:       y=subsr(-1,p1); break;
                   1658:     default: /* case 3: case 5: */
                   1659:       y=mpaut(p1); break;
                   1660:   }
                   1661:   return gerepile(av,tetpil,y);
                   1662: }
                   1663:
                   1664: GEN
                   1665: gcos(GEN x, long prec)
                   1666: {
                   1667:   long av,tetpil;
                   1668:   GEN r,u,v,y,p1,p2;
                   1669:
                   1670:   switch(typ(x))
                   1671:   {
                   1672:     case t_REAL:
                   1673:       return mpcos(x);
                   1674:
                   1675:     case t_COMPLEX:
                   1676:       y=cgetg(3,t_COMPLEX); av=avma;
                   1677:       r=gexp((GEN)x[2],prec); p1=ginv(r);
                   1678:       p2=gmul2n(gadd(p1,r),-1);
                   1679:       p1=gsub(p2,r);
                   1680:       gsincos((GEN)x[1],&u,&v,prec);
                   1681:       tetpil=avma;
                   1682:       y[1]=lmul(p2,v); y[2]=lmul(p1,u);
                   1683:       gerepilemanyvec(av,tetpil,y+1,2);
                   1684:       return y;
                   1685:
                   1686:     case t_SER:
                   1687:       if (gcmp0(x)) return gaddsg(1,x);
                   1688:       if (valp(x)<0) err(negexper,"gcos");
                   1689:
                   1690:       av=avma; gsincos(x,&u,&v,prec);
                   1691:       return gerepilecopy(av,v);
                   1692:
                   1693:     case t_INTMOD: case t_PADIC:
                   1694:       err(typeer,"gcos");
                   1695:   }
                   1696:   return transc(gcos,x,prec);
                   1697: }
                   1698:
                   1699: void
                   1700: gcosz(GEN x, GEN y)
                   1701: {
                   1702:   long av = avma, prec = precision(y);
                   1703:
                   1704:   if (!prec) err(infprecer,"gcosz");
                   1705:   gaffect(gcos(x,prec),y); avma=av;
                   1706: }
                   1707:
                   1708: /********************************************************************/
                   1709: /**                                                                **/
                   1710: /**                       FONCTION SINUS                           **/
                   1711: /**                                                                **/
                   1712: /********************************************************************/
                   1713:
                   1714: GEN
                   1715: mpsin(GEN x)
                   1716: {
                   1717:   long mod8,av,tetpil;
                   1718:   GEN y,p1;
                   1719:
                   1720:   if (typ(x)!=t_REAL) err(typeer,"mpsin");
                   1721:   if (!signe(x))
                   1722:   {
                   1723:     y=cgetr(3); y[1]=x[1]; y[2]=0;
                   1724:     return y;
                   1725:   }
                   1726:
                   1727:   av=avma; p1=mpsc1(x,&mod8); tetpil=avma;
                   1728:   switch(mod8)
                   1729:   {
                   1730:     case 0: case 6:
                   1731:       y=mpaut(p1); break;
                   1732:     case 1: case 5:
                   1733:       y=addsr(1,p1); break;
                   1734:     case 2: case 4:
                   1735:       y=mpaut(p1); setsigne(y,-signe(y)); break;
                   1736:     default: /* case 3: case 7: */
                   1737:       y=subsr(-1,p1); break;
                   1738:   }
                   1739:   return gerepile(av,tetpil,y);
                   1740: }
                   1741:
                   1742: GEN
                   1743: gsin(GEN x, long prec)
                   1744: {
                   1745:   long av,tetpil;
                   1746:   GEN r,u,v,y,p1,p2;
                   1747:
                   1748:   switch(typ(x))
                   1749:   {
                   1750:     case t_REAL:
                   1751:       return mpsin(x);
                   1752:
                   1753:     case t_COMPLEX:
                   1754:       y=cgetg(3,t_COMPLEX); av=avma;
                   1755:       r=gexp((GEN)x[2],prec); p1=ginv(r);
                   1756:       p2=gmul2n(gadd(p1,r),-1);
                   1757:       p1=gsub(p2,p1);
                   1758:       gsincos((GEN)x[1],&u,&v,prec);
                   1759:       tetpil=avma;
                   1760:       y[1]=lmul(p2,u); y[2]=lmul(p1,v);
                   1761:       gerepilemanyvec(av,tetpil,y+1,2);
                   1762:       return y;
                   1763:
                   1764:     case t_SER:
                   1765:       if (gcmp0(x)) return gcopy(x);
                   1766:       if (valp(x)<0) err(negexper,"gsin");
                   1767:
                   1768:       av=avma; gsincos(x,&u,&v,prec);
                   1769:       return gerepilecopy(av,u);
                   1770:
                   1771:     case t_INTMOD: case t_PADIC:
                   1772:       err(typeer,"gsin");
                   1773:   }
                   1774:   return transc(gsin,x,prec);
                   1775: }
                   1776:
                   1777: void
                   1778: gsinz(GEN x, GEN y)
                   1779: {
                   1780:   long av=avma, prec = precision(y);
                   1781:
                   1782:   if (!prec) err(infprecer,"gsinz");
                   1783:   gaffect(gsin(x,prec),y); avma=av;
                   1784: }
                   1785:
                   1786: /********************************************************************/
                   1787: /**                                                                **/
                   1788: /**                    PROCEDURE SINUS,COSINUS                     **/
                   1789: /**                                                                **/
                   1790: /********************************************************************/
                   1791:
                   1792: void
                   1793: mpsincos(GEN x, GEN *s, GEN *c)
                   1794: {
                   1795:   long av,tetpil,mod8;
                   1796:   GEN p1, *gptr[2];
                   1797:
                   1798:   if (typ(x)!=t_REAL) err(typeer,"mpsincos");
                   1799:   if (!signe(x))
                   1800:   {
                   1801:     p1=cgetr(3); *s=p1; p1[1]=x[1];
                   1802:     p1[2]=0; *c=addsr(1,x); return;
                   1803:   }
                   1804:
                   1805:   av=avma; p1=mpsc1(x,&mod8); tetpil=avma;
                   1806:   switch(mod8)
                   1807:   {
                   1808:     case 0: *c=addsr( 1,p1); *s=mpaut(p1); break;
                   1809:     case 1: *s=addsr( 1,p1); *c=mpaut(p1); setsigne(*c,-signe(*c)); break;
                   1810:     case 2: *c=subsr(-1,p1); *s=mpaut(p1); setsigne(*s,-signe(*s)); break;
                   1811:     case 3: *s=subsr(-1,p1); *c=mpaut(p1); break;
                   1812:     case 4: *c=addsr( 1,p1); *s=mpaut(p1); setsigne(*s,-signe(*s)); break;
                   1813:     case 5: *s=addsr( 1,p1); *c=mpaut(p1); break;
                   1814:     case 6: *c=subsr(-1,p1); *s=mpaut(p1); break;
                   1815:     case 7: *s=subsr(-1,p1); *c=mpaut(p1); setsigne(*c,-signe(*c)); break;
                   1816:   }
                   1817:   gptr[0]=s; gptr[1]=c;
                   1818:   gerepilemanysp(av,tetpil,gptr,2);
                   1819: }
                   1820:
                   1821: void
                   1822: gsincos(GEN x, GEN *s, GEN *c, long prec)
                   1823: {
                   1824:   long av,tetpil,ii,i,j,ex,ex2,lx,ly;
                   1825:   GEN r,u,v,u1,v1,p1,p2,p3,p4,ps,pc;
                   1826:   GEN *gptr[4];
                   1827:
                   1828:   switch(typ(x))
                   1829:   {
                   1830:     case t_INT: case t_FRAC: case t_FRACN:
                   1831:       av=avma; p1=cgetr(prec); gaffect(x,p1); tetpil=avma;
                   1832:       mpsincos(p1,s,c); gptr[0]=s; gptr[1]=c;
                   1833:       gerepilemanysp(av,tetpil,gptr,2);
                   1834:       return;
                   1835:
                   1836:     case t_REAL:
                   1837:       mpsincos(x,s,c); return;
                   1838:
                   1839:     case t_COMPLEX:
                   1840:       ps=cgetg(3,t_COMPLEX); pc=cgetg(3,t_COMPLEX);
                   1841:       *s=ps; *c=pc; av=avma;
                   1842:       r=gexp((GEN)x[2],prec); p1=ginv(r);
                   1843:       v1=gmul2n(gadd(p1,r),-1);
                   1844:       u1=gsub(v1,p1); r=gsub(v1,r);/*u1=I*sin(I*Im(x));v1=cos(I*Im(x));r=-u1*/
                   1845:       gsincos((GEN)x[1],&u,&v,prec);
                   1846:       tetpil=avma;
                   1847:       p1=gmul(v1,u); p2=gmul(u1,v);
                   1848:       p3=gmul(v1,v); p4=gmul(r,u);
                   1849:       gptr[0]=&p1; gptr[1]=&p2; gptr[2]=&p3; gptr[3]=&p4;
                   1850:       gerepilemanysp(av,tetpil,gptr,4);
                   1851:       ps[1]=(long)p1; ps[2]=(long)p2; pc[1]=(long)p3; pc[2]=(long)p4;
                   1852:       return;
                   1853:
                   1854:     case t_SER:
                   1855:       if (gcmp0(x)) { *c=gaddsg(1,x); *s=gcopy(x); return; }
                   1856:
                   1857:       ex=valp(x); lx=lg(x); ex2=2*ex+2;
                   1858:       if (ex < 0) err(talker,"non zero exponent in gsincos");
                   1859:       if (ex2 > lx)
                   1860:       {
                   1861:         *s=gcopy(x); av=avma; p1=gdivgs(gsqr(x),2);
                   1862:         tetpil=avma; *c=gerepile(av,tetpil,gsubsg(1,p1));
                   1863:        return;
                   1864:       }
                   1865:       if (!ex)
                   1866:       {
                   1867:         av=avma; p1=gcopy(x); p1[2]=zero;
                   1868:         gsincos(normalize(p1),&u,&v,prec);
                   1869:         gsincos((GEN)x[2],&u1,&v1,prec);
                   1870:         p1=gmul(v1,v); p2=gmul(u1,u); p3=gmul(v1,u);
                   1871:         p4=gmul(u1,v); tetpil=avma;
                   1872:         *c=gsub(p1,p2); *s=gadd(p3,p4);
                   1873:        gptr[0]=s; gptr[1]=c;
                   1874:        gerepilemanysp(av,tetpil,gptr,2);
                   1875:        return;
                   1876:       }
                   1877:
                   1878:       ly=lx+2*ex;
                   1879:       pc=cgetg(ly,t_SER); *c=pc;
                   1880:       ps=cgetg(lx,t_SER); *s=ps;
                   1881:       pc[1] = evalsigne(1) | evalvalp(0) | evalvarn(varn(x));
                   1882:       pc[2]=un; ps[1]=x[1];
                   1883:       for (i=2; i<ex+2; i++) ps[i]=lcopy((GEN)x[i]);
                   1884:       for (i=3; i<ex2; i++) pc[i]=zero;
                   1885:       for (i=ex2; i<ly; i++)
                   1886:       {
                   1887:        ii=i-ex; av=avma; p1=gzero;
                   1888:        for (j=ex; j<ii-1; j++)
                   1889:          p1=gadd(p1,gmulgs(gmul((GEN)x[j-ex+2],(GEN)ps[ii-j]),j));
                   1890:        tetpil=avma;
                   1891:        pc[i]=lpile(av,tetpil,gdivgs(p1,2-i));
                   1892:        if (ii<lx)
                   1893:        {
                   1894:          av=avma; p1=gzero;
                   1895:          for (j=ex; j<=i-ex2; j++)
                   1896:            p1=gadd(p1,gmulgs(gmul((GEN)x[j-ex+2],(GEN)pc[i-j]),j));
                   1897:          p1=gdivgs(p1,i-2); tetpil=avma;
                   1898:          ps[i-ex]=lpile(av,tetpil,gadd(p1,(GEN)x[i-ex]));
                   1899:        }
                   1900:       }
                   1901:       return;
                   1902:     /* transc doesn't work for this prototype */
                   1903:     case t_QUAD:
                   1904:       av = avma; p1=gmul(x,realun(prec)); tetpil = avma;
                   1905:       gsincos(p1,s,c,prec);
                   1906:       gptr[0]=s; gptr[1]=c;
                   1907:       gerepilemanysp(av,tetpil,gptr,2);
                   1908:       return;
                   1909:
                   1910:     case t_POL: case t_RFRAC: case t_RFRACN:
                   1911:       av = avma; p1=tayl(x,gvar(x),precdl); tetpil=avma;
                   1912:       gsincos(p1,s,c,prec);
                   1913:       gptr[0]=s; gptr[1]=c;
                   1914:       gerepilemanysp(av,tetpil,gptr,2);
                   1915:       return;
                   1916:   }
                   1917:   err(typeer,"gsincos");
                   1918: }
                   1919:
                   1920: /********************************************************************/
                   1921: /**                                                                **/
                   1922: /**                FONCTIONS TANGENTE ET COTANGENTE                **/
                   1923: /**                                                                **/
                   1924: /********************************************************************/
                   1925:
                   1926: static GEN
                   1927: mptan(GEN x)
                   1928: {
                   1929:   long av=avma,tetpil;
                   1930:   GEN s,c;
                   1931:
                   1932:   mpsincos(x,&s,&c); tetpil=avma;
                   1933:   return gerepile(av,tetpil,divrr(s,c));
                   1934: }
                   1935:
                   1936: GEN
                   1937: gtan(GEN x, long prec)
                   1938: {
                   1939:   long av,tetpil;
                   1940:   GEN s,c;
                   1941:
                   1942:   switch(typ(x))
                   1943:   {
                   1944:     case t_REAL:
                   1945:       return mptan(x);
                   1946:
                   1947:     case t_SER:
                   1948:       if (gcmp0(x)) return gcopy(x);
                   1949:       if (valp(x)<0) err(negexper,"gtan"); /* fall through */
                   1950:     case t_COMPLEX:
                   1951:       av=avma; gsincos(x,&s,&c,prec); tetpil=avma;
                   1952:       return gerepile(av,tetpil,gdiv(s,c));
                   1953:
                   1954:     case t_INTMOD: case t_PADIC:
                   1955:       err(typeer,"gtan");
                   1956:   }
                   1957:   return transc(gtan,x,prec);
                   1958: }
                   1959:
                   1960: void
                   1961: gtanz(GEN x, GEN y)
                   1962: {
                   1963:   long av=avma, prec = precision(y);
                   1964:
                   1965:   if (!prec) err(infprecer,"gtanz");
                   1966:   gaffect(gtan(x,prec),y); avma=av;
                   1967: }
                   1968:
                   1969: static GEN
                   1970: mpcotan(GEN x)
                   1971: {
                   1972:   long av=avma,tetpil;
                   1973:   GEN s,c;
                   1974:
                   1975:   mpsincos(x,&s,&c); tetpil=avma;
                   1976:   return gerepile(av,tetpil,divrr(c,s));
                   1977: }
                   1978:
                   1979: GEN
                   1980: gcotan(GEN x, long prec)
                   1981: {
                   1982:   long av,tetpil;
                   1983:   GEN s,c;
                   1984:
                   1985:   switch(typ(x))
                   1986:   {
                   1987:     case t_REAL:
                   1988:       return mpcotan(x);
                   1989:
                   1990:     case t_SER:
                   1991:       if (gcmp0(x)) err(diver9);
                   1992:       if (valp(x)<0) err(negexper,"gcotan"); /* fall through */
                   1993:     case t_COMPLEX:
                   1994:       av=avma; gsincos(x,&s,&c,prec); tetpil=avma;
                   1995:       return gerepile(av,tetpil,gdiv(c,s));
                   1996:
                   1997:     case t_INTMOD: case t_PADIC:
                   1998:       err(typeer,"gcotan");
                   1999:   }
                   2000:   return transc(gcotan,x,prec);
                   2001: }
                   2002:
                   2003: void
                   2004: gcotanz(GEN x, GEN y)
                   2005: {
                   2006:   long av=avma, prec = precision(y);
                   2007:
                   2008:   if (!prec) err(infprecer,"gcotanz");
                   2009:   gaffect(gcotan(x,prec),y); avma=av;
                   2010: }

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