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