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