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