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