Annotation of OpenXM_contrib/pari-2.2/src/basemath/trans1.c, Revision 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>