Annotation of OpenXM_contrib/pari-2.2/src/language/sumiter.c, Revision 1.2
1.2 ! noro 1: /* $Id: sumiter.c,v 1.36 2002/07/15 13:30:01 karim Exp $
1.1 noro 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: /** SUMS, PRODUCTS, ITERATIONS **/
19: /** **/
20: /********************************************************************/
21: #include "pari.h"
22: #include "anal.h"
23: extern void changevalue_p(entree *ep, GEN x);
1.2 ! noro 24: extern GEN polint_i(GEN xa, GEN ya, GEN x, long n, GEN *ptdy);
1.1 noro 25:
26: /********************************************************************/
27: /** **/
28: /** ITERATIONS **/
29: /** **/
30: /********************************************************************/
31:
32: void
33: forpari(entree *ep, GEN a, GEN b, char *ch)
34: {
1.2 ! noro 35: gpmem_t av, av0 = avma, lim;
1.1 noro 36:
37: b = gcopy(b); av=avma; lim = stack_lim(av,1);
38: /* gcopy nedeed in case b gets overwritten in ch, as in
39: * b=10; for(a=1,b, print(a);b=1)
40: */
41: push_val(ep, a);
42: while (gcmp(a,b) <= 0)
43: {
1.2 ! noro 44: gpmem_t av1=avma; (void)lisseq(ch); avma=av1;
1.1 noro 45: if (loop_break()) break;
46: a = (GEN) ep->value; a = gadd(a,gun);
47: if (low_stack(lim, stack_lim(av,1)))
48: {
49: if (DEBUGMEM>1) err(warnmem,"forpari");
50: a = gerepileupto(av,a);
51: }
52: changevalue_p(ep,a);
53: }
54: pop_val(ep); avma = av0;
55: }
56:
57: static int negcmp(GEN x, GEN y) { return gcmp(y,x); }
58:
59: void
60: forstep(entree *ep, GEN a, GEN b, GEN s, char *ch)
61: {
1.2 ! noro 62: long ss, i;
! 63: gpmem_t av, av0 = avma, lim;
1.1 noro 64: GEN v = NULL;
65: int (*cmp)(GEN,GEN);
66:
67: b = gcopy(b); av=avma; lim = stack_lim(av,1);
68: push_val(ep, a);
69: if (is_vec_t(typ(s)))
70: {
71: v = s; s = gzero;
72: for (i=lg(v)-1; i; i--) s = gadd(s,(GEN)v[i]);
73: }
74: ss = gsigne(s);
75: if (!ss) err(talker, "step equal to zero in forstep");
76: cmp = (ss > 0)? gcmp: negcmp;
77: i = 0;
78: while (cmp(a,b) <= 0)
79: {
1.2 ! noro 80: gpmem_t av1=avma; (void)lisseq(ch); avma=av1;
1.1 noro 81: if (loop_break()) break;
82: if (v)
83: {
84: if (++i >= lg(v)) i = 1;
85: s = (GEN)v[i];
86: }
87: a = (GEN) ep->value; a = gadd(a,s);
88:
89: if (low_stack(lim, stack_lim(av,1)))
90: {
91: if (DEBUGMEM>1) err(warnmem,"forstep");
92: a = gerepileupto(av,a);
93: }
94: changevalue_p(ep,a);
95: }
96: pop_val(ep); avma = av0;
97: }
98:
99: /* assume ptr is the address of a diffptr containing the succesive
100: * differences between primes, and c = current prime (up to *p excluded)
101: * return smallest prime >= a, update ptr */
102: static long
103: sinitp(long a, long c, byteptr *ptr)
104: {
105: byteptr p = *ptr;
106: if (a <= 0) a = 2;
107: if (maxprime() < (ulong)a) err(primer1);
1.2 ! noro 108: while (a > c)
! 109: NEXT_PRIME_VIADIFF(c,p);
1.1 noro 110: *ptr = p; return c;
111: }
112:
113: /* value changed during the loop, replace by the first prime whose
114: value is strictly larger than new value */
115: static void
116: update_p(entree *ep, byteptr *ptr, long prime[])
117: {
118: GEN z = (GEN)ep->value;
119: long a, c;
120:
121: if (typ(z) == t_INT) a = 1; else { z = gceil(z); a = 0; }
122: if (is_bigint(z)) { prime[2] = -1; /* = infinity */ return; }
123: a += itos(z); c = prime[2];
124: if (c < a)
125: prime[2] = sinitp(a, c, ptr); /* increased */
126: else if (c > a)
127: { /* lowered, reset p */
128: *ptr = diffptr;
129: prime[2] = sinitp(a, 0, ptr);
130: }
1.2 ! noro 131: changevalue_p(ep, prime);
1.1 noro 132: }
133:
134: static byteptr
135: prime_loop_init(GEN ga, GEN gb, long *a, long *b, long prime[])
136: {
137: byteptr p = diffptr;
138: ulong P;
139:
140: ga = gceil(ga); gb = gfloor(gb);
141: if (typ(ga) != t_INT || typ(gb) != t_INT)
142: err(typeer,"prime_loop_init");
143: if (is_bigint(ga) || is_bigint(gb))
144: {
145: if (cmpii(ga, gb) > 0) return NULL;
146: err(primer1);
147: }
148: P = maxprime();
149: *a = itos(ga); if (*a <= 0) *a = 1;
150: *b = itos(gb); if (*a > *b) return NULL;
151: if ((ulong)*a <= P) prime[2] = sinitp(*a, 0, &p);
152: if ((ulong)*b > P) err(primer1);
153: return p;
154: }
155:
156: void
157: forprime(entree *ep, GEN ga, GEN gb, char *ch)
158: {
1.2 ! noro 159: long prime[] = {evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 0};
! 160: long a, b;
! 161: gpmem_t av = avma;
1.1 noro 162: byteptr p;
163:
164: p = prime_loop_init(ga,gb, &a,&b, prime);
165: if (!p) { avma = av; return; }
166:
167: avma = av; push_val(ep, prime);
168: while ((ulong)prime[2] < (ulong)b)
169: {
170: (void)lisseq(ch); if (loop_break()) break;
171: if (ep->value == prime)
172: prime[2] += *p++;
173: else
174: update_p(ep, &p, prime);
175: avma = av;
176: }
177: /* if b = P --> *p = 0 now and the loop wouldn't end if it read 'while
178: * (prime[2] <= b)' */
179: if (prime[2] == b) { (void)lisseq(ch); (void)loop_break(); avma = av; }
180: pop_val(ep);
181: }
182:
183: void
184: fordiv(GEN a, entree *ep, char *ch)
185: {
1.2 ! noro 186: long i, l;
! 187: gpmem_t av2, av = avma;
1.1 noro 188: GEN t = divisors(a);
189:
190: push_val(ep, NULL); l=lg(t); av2 = avma;
191: for (i=1; i<l; i++)
192: {
1.2 ! noro 193: ep->value = (void*) t[i];
1.1 noro 194: (void)lisseq(ch); if (loop_break()) break;
195: avma = av2;
196: }
197: pop_val(ep); avma=av;
198: }
199:
200: /* Embedded for loops:
201: * fl = 0: execute ch (a), where a = (ai) runs through all n-uplets in
202: * [m1,M1] x ... x [mn,Mn]
203: * fl = 1: impose a1 <= ... <= an
204: * fl = 2: a1 < ... < an
205: */
1.2 ! noro 206: typedef struct {
! 207: GEN *a, *m, *M;
! 208: long n,fl;
! 209: char *ch;
! 210: } fvdat;
1.1 noro 211:
212: /* general case */
213: static void
1.2 ! noro 214: fvloop(long i, fvdat *d)
1.1 noro 215: {
1.2 ! noro 216: d->a[i] = d->m[i];
! 217: if (d->fl && i > 1)
1.1 noro 218: {
1.2 ! noro 219: GEN p1 = gsub(d->a[i], d->a[i-1]);
1.1 noro 220: if (gsigne(p1) < 0)
1.2 ! noro 221: d->a[i] = gadd(d->a[i], gceil(gneg_i(p1)));
! 222: if (d->fl == 2 && gegal(d->a[i], d->a[i-1]))
! 223: d->a[i] = gadd(d->a[i], gun);
! 224: }
! 225: if (i+1 == d->n)
! 226: while (gcmp(d->a[i], d->M[i]) <= 0)
! 227: {
! 228: gpmem_t av = avma; (void)lisseq(d->ch); avma = av;
! 229: if (loop_break()) { d->n = 0; return; }
! 230: d->a[i] = gadd(d->a[i], gun);
1.1 noro 231: }
232: else
1.2 ! noro 233: while (gcmp(d->a[i], d->M[i]) <= 0)
1.1 noro 234: {
1.2 ! noro 235: gpmem_t av = avma; fvloop(i+1, d); avma = av;
! 236: if (!d->n) return;
! 237: d->a[i] = gadd(d->a[i], gun);
1.1 noro 238: }
239: }
240:
241: /* we run through integers */
242: static void
1.2 ! noro 243: fvloop_i(long i, fvdat *d)
1.1 noro 244: {
1.2 ! noro 245: d->a[i] = setloop(d->m[i]);
! 246: if (d->fl && i > 1)
1.1 noro 247: {
1.2 ! noro 248: int c = cmpii(d->a[i], d->a[i-1]);
1.1 noro 249: if (c < 0)
250: {
1.2 ! noro 251: d->a[i] = setloop(d->a[i-1]);
1.1 noro 252: c = 0;
253: }
1.2 ! noro 254: if (c == 0 && d->fl == 2)
! 255: d->a[i] = incloop(d->a[i]);
1.1 noro 256: }
1.2 ! noro 257: if (i+1 == d->n)
! 258: while (gcmp(d->a[i], d->M[i]) <= 0)
1.1 noro 259: {
1.2 ! noro 260: gpmem_t av = avma; (void)lisseq(d->ch); avma = av;
! 261: if (loop_break()) { d->n = 0; return; }
! 262: d->a[i] = incloop(d->a[i]);
1.1 noro 263: }
264: else
1.2 ! noro 265: while (gcmp(d->a[i], d->M[i]) <= 0)
1.1 noro 266: {
1.2 ! noro 267: gpmem_t av = avma; fvloop_i(i+1, d); avma = av;
! 268: if (!d->n) return;
! 269: d->a[i] = incloop(d->a[i]);
1.1 noro 270: }
271: }
272:
273: void
274: forvec(entree *ep, GEN x, char *c, long flag)
275: {
1.2 ! noro 276: gpmem_t av = avma;
! 277: long tx = typ(x);
! 278: fvdat D, *d = &D;
1.1 noro 279:
280: if (!is_vec_t(tx)) err(talker,"not a vector in forvec");
1.2 ! noro 281: if (flag<0 || flag>2) err(flagerr);
! 282: d->n = lg(x);
! 283: d->ch = c;
! 284: d->a = (GEN*)cgetg(d->n,t_VEC); push_val(ep, (GEN)d->a);
! 285: if (d->n == 1) (void)lisseq(d->ch);
1.1 noro 286: else
287: {
1.2 ! noro 288: long i, t = t_INT;
! 289: d->fl = flag;
! 290: d->m = (GEN*)cgetg(d->n,t_VEC);
! 291: d->M = (GEN*)cgetg(d->n,t_VEC);
! 292: for (i=1; i<d->n; i++)
! 293: {
! 294: GEN *e = (GEN*) x[i];
! 295: tx = typ(e);
! 296: if (! is_vec_t(tx) || lg(e)!=3)
1.1 noro 297: err(talker,"not a vector of two-component vectors in forvec");
1.2 ! noro 298: if (gcmp(e[1],e[2]) > 0) d->n = 0;
! 299: if (typ(e[1]) != t_INT) t = t_REAL;
! 300: /* in case x is an ep->value and lisexpr(d->ch) kills it, have to copy */
! 301: d->m[i] = gcopy(e[1]);
! 302: d->M[i] = gcopy(e[2]);
1.1 noro 303: }
1.2 ! noro 304: if (t == t_INT) fvloop_i(1, d); else fvloop(1, d);
1.1 noro 305: }
1.2 ! noro 306: pop_val(ep); avma = av;
1.1 noro 307: }
308:
309: /********************************************************************/
310: /** **/
311: /** SUMS **/
312: /** **/
313: /********************************************************************/
314:
315: GEN
316: somme(entree *ep, GEN a, GEN b, char *ch, GEN x)
317: {
1.2 ! noro 318: gpmem_t av, av0 = avma, lim;
1.1 noro 319: GEN p1;
320:
321: if (typ(a) != t_INT) err(talker,"non integral index in sum");
322: if (!x) x = gzero;
323: if (gcmp(b,a) < 0) return gcopy(x);
324:
1.2 ! noro 325: b = gfloor(b);
1.1 noro 326: a = setloop(a);
327: av=avma; lim = stack_lim(av,1);
328: push_val(ep, a);
329: for(;;)
330: {
331: p1 = lisexpr(ch); if (did_break()) err(breaker,"sum");
332: x=gadd(x,p1); if (cmpii(a,b) >= 0) break;
333: a = incloop(a);
334: if (low_stack(lim, stack_lim(av,1)))
335: {
336: if (DEBUGMEM>1) err(warnmem,"sum");
337: x = gerepileupto(av,x);
338: }
339: ep->value = (void*) a;
340: }
341: pop_val(ep); return gerepileupto(av0,x);
342: }
343:
344: GEN
345: suminf(entree *ep, GEN a, char *ch, long prec)
346: {
1.2 ! noro 347: long fl, G;
! 348: gpmem_t tetpil, av0 = avma, av, lim;
1.1 noro 349: GEN p1,x = realun(prec);
350:
351: if (typ(a) != t_INT) err(talker,"non integral index in suminf");
352: a = setloop(a);
353: av = avma; lim = stack_lim(av,1);
354: push_val(ep, a);
355: fl=0; G = bit_accuracy(prec) + 5;
356: for(;;)
357: {
358: p1 = lisexpr(ch); if (did_break()) err(breaker,"suminf");
359: x = gadd(x,p1); a = incloop(a);
360: if (gcmp0(p1) || gexpo(p1) <= gexpo(x)-G)
361: { if (++fl==3) break; }
362: else
363: fl=0;
364: if (low_stack(lim, stack_lim(av,1)))
365: {
366: if (DEBUGMEM>1) err(warnmem,"suminf");
367: x = gerepileupto(av,x);
368: }
369: ep->value = (void*)a;
370: }
371: pop_val(ep); tetpil=avma;
372: return gerepile(av0,tetpil,gsub(x,gun));
373: }
374:
375: GEN
376: divsum(GEN num, entree *ep, char *ch)
377: {
1.2 ! noro 378: gpmem_t av = avma;
1.1 noro 379: GEN z, y = gzero, t = divisors(num);
380: long i, l = lg(t);
381:
382: push_val(ep, NULL);
383: for (i=1; i<l; i++)
384: {
1.2 ! noro 385: ep->value = (void*) t[i];
1.1 noro 386: z = lisseq(ch);
387: if (did_break()) err(breaker,"divsum");
388: y = gadd(y, z);
389: }
390: pop_val(ep); return gerepileupto(av,y);
391: }
392:
393: /********************************************************************/
394: /** **/
395: /** PRODUCTS **/
396: /** **/
397: /********************************************************************/
398:
399: GEN
400: produit(entree *ep, GEN a, GEN b, char *ch, GEN x)
401: {
1.2 ! noro 402: gpmem_t av, av0 = avma, lim;
1.1 noro 403: GEN p1;
404:
405: if (typ(a) != t_INT) err(talker,"non integral index in sum");
406: if (!x) x = gun;
407: if (gcmp(b,a) < 0) return gcopy(x);
408:
1.2 ! noro 409: b = gfloor(b);
1.1 noro 410: a = setloop(a);
411: av=avma; lim = stack_lim(av,1);
412: push_val(ep, a);
413: for(;;)
414: {
415: p1 = lisexpr(ch); if (did_break()) err(breaker,"prod");
416: x = gmul(x,p1); if (cmpii(a,b) >= 0) break;
417: a = incloop(a);
418: if (low_stack(lim, stack_lim(av,1)))
419: {
420: if (DEBUGMEM>1) err(warnmem,"prod");
421: x = gerepileupto(av,x);
422: }
423: ep->value = (void*) a;
424: }
425: pop_val(ep); return gerepileupto(av0,x);
426: }
427:
428: GEN
429: prodinf0(entree *ep, GEN a, char *ch, long flag, long prec)
430: {
431: switch(flag)
432: {
433: case 0: return prodinf(ep,a,ch,prec);
434: case 1: return prodinf1(ep,a,ch,prec);
435: }
436: err(flagerr);
437: return NULL; /* not reached */
438: }
439:
440: GEN
441: prodinf(entree *ep, GEN a, char *ch, long prec)
442: {
1.2 ! noro 443: gpmem_t av0 = avma, av, lim;
1.1 noro 444: long fl,G;
445: GEN p1,x = realun(prec);
446:
447: if (typ(a) != t_INT) err(talker,"non integral index in prodinf");
448: a = setloop(a);
449: av = avma; lim = stack_lim(av,1);
450: push_val(ep, a);
451: fl=0; G = -bit_accuracy(prec)-5;
452: for(;;)
453: {
454: p1 = lisexpr(ch); if (did_break()) err(breaker,"prodinf");
455: x=gmul(x,p1); a = incloop(a);
456: if (gexpo(gsubgs(p1,1)) <= G) { if (++fl==3) break; } else fl=0;
457: if (low_stack(lim, stack_lim(av,1)))
458: {
459: if (DEBUGMEM>1) err(warnmem,"prodinf");
460: x = gerepileupto(av,x);
461: }
462: ep->value = (void*)a;
463: }
464: pop_val(ep); return gerepilecopy(av0,x);
465: }
466:
467: GEN
468: prodinf1(entree *ep, GEN a, char *ch, long prec)
469: {
1.2 ! noro 470: gpmem_t av0 = avma, av, lim;
1.1 noro 471: long fl,G;
472: GEN p1,p2,x = realun(prec);
473:
474: if (typ(a) != t_INT) err(talker,"non integral index in prodinf1");
475: a = setloop(a);
476: av = avma; lim = stack_lim(av,1);
477: push_val(ep, a);
478: fl=0; G = -bit_accuracy(prec)-5;
479: for(;;)
480: {
481: p2 = lisexpr(ch); if (did_break()) err(breaker,"prodinf1");
482: p1 = gadd(p2,gun); x=gmul(x,p1); a = incloop(a);
483: if (gcmp0(p1) || gexpo(p2) <= G) { if (++fl==3) break; } else fl=0;
484: if (low_stack(lim, stack_lim(av,1)))
485: {
486: if (DEBUGMEM>1) err(warnmem,"prodinf1");
487: x = gerepileupto(av,x);
488: }
489: ep->value = (void*)a;
490: }
491: pop_val(ep); return gerepilecopy(av0,x);
492: }
493:
494: GEN
495: prodeuler(entree *ep, GEN ga, GEN gb, char *ch, long prec)
496: {
1.2 ! noro 497: long prime[] = {evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 0};
1.1 noro 498: long a,b;
1.2 ! noro 499: gpmem_t av, av0 = avma, lim;
1.1 noro 500: GEN p1,x = realun(prec);
501: byteptr p;
1.2 ! noro 502:
1.1 noro 503: av = avma;
504: p = prime_loop_init(ga,gb, &a,&b, prime);
505: if (!p) { avma = av; return x; }
506:
507: av = avma; push_val(ep, prime);
508: lim = stack_lim(avma,1);
509: while ((ulong)prime[2] < (ulong)b)
510: {
511: p1 = lisexpr(ch); if (did_break()) err(breaker,"prodeuler");
512: x = gmul(x,p1);
513: if (low_stack(lim, stack_lim(av,1)))
514: {
515: if (DEBUGMEM>1) err(warnmem,"prodeuler");
516: x = gerepilecopy(av, x);
517: }
518: if (ep->value == prime)
519: prime[2] += *p++;
520: else
521: update_p(ep, &p, prime);
522: }
523: /* cf forprime */
524: if (prime[2] == b)
525: {
526: p1 = lisexpr(ch); if (did_break()) err(breaker,"prodeuler");
527: x = gmul(x,p1);
528: }
529: pop_val(ep); return gerepilecopy(av0,x);
530: }
531:
532: GEN
533: direulerall(entree *ep, GEN ga, GEN gb, char *ch, GEN c)
534: {
1.2 ! noro 535: long prime[] = {evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 0};
! 536: gpmem_t av0 = avma, av, lim = stack_lim(av0, 1);
1.1 noro 537: long p,n,i,j,k,tx,lx,a,b;
538: GEN x,y,s,polnum,polden;
539: byteptr d;
540:
541: d = prime_loop_init(ga,gb, &a,&b, prime);
542: n = c? itos(c): b;
1.2 ! noro 543: if (!d || b < 2 || n <= 0) return _vec(gun);
1.1 noro 544: if (n < b) b = n;
545: push_val(ep, prime);
546:
547: y = cgetg(n+1,t_VEC); av = avma;
548: x = cgetg(n+1,t_VEC); x[1]=un; for (i=2; i<=n; i++) x[i]=zero;
549: p = prime[2];
550: while (p <= b)
551: {
552: s = lisexpr(ch); if (did_break()) err(breaker,"direuler");
553: polnum = numer(s);
554: polden = denom(s);
555: tx = typ(polnum);
556: if (is_scalar_t(tx))
557: {
558: if (!gcmp1(polnum))
559: {
560: if (!gcmp_1(polnum))
561: err(talker,"constant term not equal to 1 in direuler");
562: polden = gneg(polden);
563: }
564: }
565: else
566: {
567: ulong k1,q, qlim;
568: if (tx != t_POL) err(typeer,"direuler");
569: c = truecoeff(polnum,0);
570: if (!gcmp1(c))
571: {
572: if (!gcmp_1(c))
573: err(talker,"constant term not equal to 1 in direuler");
574: polnum = gneg(polnum);
575: polden = gneg(polden);
576: }
577: for (i=1; i<=n; i++) y[i]=x[i];
578: lx=degpol(polnum);
579: q=p; qlim = n/p; j=1;
580: while (q<=(ulong)n && j<=lx)
581: {
582: c=(GEN)polnum[j+2];
583: if (!gcmp0(c))
584: for (k=1,k1=q; k1<=(ulong)n; k1+=q,k++)
585: x[k1] = ladd((GEN)x[k1], gmul(c,(GEN)y[k]));
586: if (q > qlim) break;
587: q*=p; j++;
588: }
589: }
590: tx = typ(polden);
591: if (is_scalar_t(tx))
592: {
593: if (!gcmp1(polden))
594: err(talker,"constant term not equal to 1 in direuler");
595: }
596: else
597: {
598: if (tx != t_POL) err(typeer,"direuler");
599: c = truecoeff(polden,0);
600: if (!gcmp1(c)) err(talker,"constant term not equal to 1 in direuler");
601: lx=degpol(polden);
602: for (i=p; i<=n; i+=p)
603: {
604: s=gzero; k=i; j=1;
605: while (!(k%p) && j<=lx)
606: {
607: c=(GEN)polden[j+2]; k/=p; j++;
608: if (!gcmp0(c)) s=gadd(s,gmul(c,(GEN)x[k]));
609: }
610: x[i]=lsub((GEN)x[i],s);
611: }
612: }
613: if (low_stack(lim, stack_lim(av,1)))
614: {
615: if (DEBUGMEM>1) err(warnmem,"direuler");
616: x = gerepilecopy(av, x);
617: }
618: p += *d++; if (!*d) err(primer1);
619: prime[2] = p;
620: }
621: pop_val(ep); return gerepilecopy(av0,x);
622: }
623:
624: GEN
625: direuler(entree *ep, GEN a, GEN b, char *ch)
626: {
627: return direulerall(ep,a,b,ch,NULL);
628: }
629:
630: /********************************************************************/
631: /** **/
632: /** VECTORS & MATRICES **/
633: /** **/
634: /********************************************************************/
635:
636: GEN
637: vecteur(GEN nmax, entree *ep, char *ch)
638: {
639: GEN y,p1;
640: long i,m;
1.2 ! noro 641: long c[]={evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 0};
1.1 noro 642:
643: if (typ(nmax)!=t_INT || signe(nmax) < 0)
644: err(talker,"bad number of components in vector");
645: m=itos(nmax); y=cgetg(m+1,t_VEC);
646: if (!ep || !ch)
647: {
648: for (i=1; i<=m; i++) y[i] = zero;
649: return y;
650: }
651: push_val(ep, c);
652: for (i=1; i<=m; i++)
653: {
654: c[2]=i; p1 = lisseq(ch);
655: if (did_break()) err(breaker,"vector");
656: y[i] = isonstack(p1)? (long)p1 : (long)forcecopy(p1);
657: }
658: pop_val(ep); return y;
659: }
660:
661: GEN
1.2 ! noro 662: vecteursmall(GEN nmax, entree *ep, char *ch)
! 663: {
! 664: GEN y,p1;
! 665: long i,m;
! 666: long c[]={evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 0};
! 667:
! 668: if (typ(nmax)!=t_INT || signe(nmax) < 0)
! 669: err(talker,"bad number of components in vector");
! 670: m=itos(nmax); y=cgetg(m+1,t_VECSMALL);
! 671: if (!ep || !ch)
! 672: {
! 673: for (i=1; i<=m; i++) y[i] = 0;
! 674: return y;
! 675: }
! 676: push_val(ep, c);
! 677: for (i=1; i<=m; i++)
! 678: {
! 679: c[2]=i; p1 = lisseq(ch);
! 680: if (did_break()) err(breaker,"vector");
! 681: y[i] = itos(p1);
! 682: }
! 683: pop_val(ep); return y;
! 684: }
! 685:
! 686:
! 687: GEN
1.1 noro 688: vvecteur(GEN nmax, entree *ep, char *ch)
689: {
690: GEN y = vecteur(nmax,ep,ch);
691: settyp(y,t_COL); return y;
692: }
693:
694: GEN
695: matrice(GEN nlig, GEN ncol,entree *ep1, entree *ep2, char *ch)
696: {
697: GEN y,z,p1;
698: long i,j,m,n,s;
1.2 ! noro 699: long c1[]={evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 1};
! 700: long c2[]={evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 1};
1.1 noro 701:
702: s=signe(ncol);
1.2 ! noro 703: if (ep1 == ep2 && ep1) err(talker, "identical index variables in matrix");
1.1 noro 704: if (typ(ncol)!=t_INT || s<0) err(talker,"bad number of columns in matrix");
705: if (!s) return cgetg(1,t_MAT);
706:
707: s=signe(nlig);
708: if (typ(nlig)!=t_INT || s<0) err(talker,"bad number of rows in matrix");
709: m=itos(ncol)+1;
710: n=itos(nlig)+1; y=cgetg(m,t_MAT);
711: if (!s)
712: {
713: for (i=1; i<m; i++) y[i]=lgetg(1,t_COL);
714: return y;
715: }
716: if (!ep1 || !ep2 || !ch)
717: {
718: for (i=1; i<m; i++)
719: {
720: z=cgetg(n,t_COL); y[i]=(long)z;
721: for (j=1; j<n; j++) z[j] = zero;
722: }
723: return y;
724: }
725: push_val(ep1, c1);
726: push_val(ep2, c2);
727: for (i=1; i<m; i++)
728: {
729: c2[2]=i; z=cgetg(n,t_COL); y[i]=(long)z;
730: for (j=1; j<n; j++)
731: {
732: c1[2]=j; p1=lisseq(ch);
733: if (did_break()) err(breaker,"matrix");
734: z[j] = isonstack(p1)? (long)p1 : (long)forcecopy(p1);
735: }
736: }
737: pop_val(ep2);
738: pop_val(ep1); return y;
739: }
740:
741: /********************************************************************/
742: /** **/
1.2 ! noro 743: /** SUMMING SERIES **/
1.1 noro 744: /** **/
745: /********************************************************************/
746:
747: GEN
748: sumalt0(entree *ep, GEN a, char *ch, long flag, long prec)
749: {
750: switch(flag)
751: {
752: case 0: return sumalt(ep,a,ch,prec);
753: case 1: return sumalt2(ep,a,ch,prec);
754: default: err(flagerr);
755: }
756: return NULL; /* not reached */
757: }
758:
759: GEN
760: sumpos0(entree *ep, GEN a, char *ch, long flag, long prec)
761: {
762: switch(flag)
763: {
764: case 0: return sumpos(ep,a,ch,prec);
765: case 1: return sumpos2(ep,a,ch,prec);
766: default: err(flagerr);
767: }
768: return NULL; /* not reached */
769: }
770:
771: GEN
772: sumalt(entree *ep, GEN a, char *ch, long prec)
773: {
1.2 ! noro 774: long k, N;
! 775: gpmem_t av = avma, tetpil;
1.1 noro 776: GEN s,az,c,x,e1,d;
777:
778: if (typ(a) != t_INT) err(talker,"non integral index in sumalt");
779:
780: push_val(ep, a);
1.2 ! noro 781: e1 = addsr(3,gsqrt(stoi(8),prec));
! 782: N = (long)(0.4*(bit_accuracy(prec) + 7));
! 783: d = gpowgs(e1,N);
! 784: d = shiftr(addrr(d, ginv(d)),-1);
! 785: az = negi(gun); c = d;
! 786: s = gzero;
1.1 noro 787: for (k=0; ; k++)
788: {
789: x = lisexpr(ch); if (did_break()) err(breaker,"sumalt");
790: c = gadd(az,c); s = gadd(s,gmul(x,c));
791: az = divii(mulii(mulss(N-k,N+k),shifti(az,1)),mulss(k+1,k+k+1));
792: if (k==N-1) break;
793: a = addsi(1,a); ep->value = (void*) a;
794: }
1.2 ! noro 795: tetpil = avma; pop_val(ep);
1.1 noro 796: return gerepile(av,tetpil,gdiv(s,d));
797: }
798:
799: GEN
800: sumalt2(entree *ep, GEN a, char *ch, long prec)
801: {
1.2 ! noro 802: long k, N;
! 803: gpmem_t av = avma, tetpil;
1.1 noro 804: GEN x,s,dn,pol;
805:
806: if (typ(a) != t_INT) err(talker,"non integral index in sumalt");
807:
808: push_val(ep, a);
1.2 ! noro 809: N = (long)(0.31*(bit_accuracy(prec) + 5));
! 810: pol = polzagreel(N,N>>1,prec+1);
! 811: dn = poleval(pol,gun);
! 812: pol[2] = lsub((GEN)pol[2],dn);
! 813: pol = gdiv(pol, gsub(polx[0],gun));
! 814: N = degpol(pol);
! 815: s = gzero;
! 816: for (k=0; k<=N; k++)
1.1 noro 817: {
818: x = lisexpr(ch); if (did_break()) err(breaker,"sumalt2");
1.2 ! noro 819: s = gadd(s, gmul(x,(GEN)pol[k+2]));
! 820: if (k == N) break;
1.1 noro 821: a = addsi(1,a); ep->value = (void*) a;
822: }
1.2 ! noro 823: tetpil = avma; pop_val(ep);
! 824: return gerepile(av,tetpil, gdiv(s,dn));
1.1 noro 825: }
826:
827: GEN
828: sumpos(entree *ep, GEN a, char *ch, long prec)
829: {
1.2 ! noro 830: long k, kk, N, G;
! 831: gpmem_t av = avma, tetpil;
1.1 noro 832: GEN p1,r,q1,reel,s,az,c,x,e1,d, *stock;
833:
834: if (typ(a) != t_INT) err(talker,"non integral index in sumpos");
835:
836: push_val(ep, NULL);
1.2 ! noro 837: a = subis(a,1); reel = cgetr(prec);
! 838: e1 = addsr(3,gsqrt(stoi(8),prec));
! 839: N = (long)(0.4*(bit_accuracy(prec) + 7));
! 840: d = gpowgs(e1,N); d = shiftr(addrr(d, ginv(d)),-1);
! 841: az = negi(gun); c = d; s = gzero;
! 842:
1.1 noro 843: G = -bit_accuracy(prec) - 5;
1.2 ! noro 844: stock = (GEN*)new_chunk(N+1); for (k=1; k<=N; k++) stock[k] = NULL;
1.1 noro 845: for (k=0; k<N; k++)
846: {
1.2 ! noro 847: if (odd(k) && stock[k]) x = stock[k];
1.1 noro 848: else
849: {
1.2 ! noro 850: x = gzero; r = stoi(2*k+2);
1.1 noro 851: for(kk=0;;kk++)
852: {
853: long ex;
854: q1 = addii(r,a); ep->value = (void*) q1;
855: p1 = lisexpr(ch); if (did_break()) err(breaker,"sumpos");
856: gaffect(p1,reel); ex = expo(reel)+kk; setexpo(reel,ex);
857: x = gadd(x,reel); if (kk && ex < G) break;
1.2 ! noro 858: r = shifti(r,1);
1.1 noro 859: }
1.2 ! noro 860: if (2*k < N) stock[2*k+1] = x;
1.1 noro 861: q1 = addsi(k+1,a); ep->value = (void*) q1;
862: p1 = lisexpr(ch); if (did_break()) err(breaker,"sumpos");
863: gaffect(p1,reel); x = gadd(reel, gmul2n(x,1));
864: }
1.2 ! noro 865: c = gadd(az,c); p1 = k&1? gneg_i(c): c;
1.1 noro 866: s = gadd(s,gmul(x,p1));
867: az = divii(mulii(mulss(N-k,N+k),shifti(az,1)),mulss(k+1,k+k+1));
868: }
869: tetpil=avma; pop_val(ep);
870: return gerepile(av,tetpil,gdiv(s,d));
871: }
872:
873: GEN
874: sumpos2(entree *ep, GEN a, char *ch, long prec)
875: {
1.2 ! noro 876: long k, kk, N, G;
! 877: gpmem_t av = avma, tetpil;
1.1 noro 878: GEN p1,r,q1,reel,s,pol,dn,x, *stock;
879:
880: if (typ(a) != t_INT) err(talker,"non integral index in sumpos2");
881:
882: push_val(ep, a);
1.2 ! noro 883: a = subis(a,1); reel = cgetr(prec);
! 884: N = (long)(0.31*(bit_accuracy(prec) + 5));
! 885:
1.1 noro 886: G = -bit_accuracy(prec) - 5;
1.2 ! noro 887: stock = (GEN*)new_chunk(N+1); for (k=1; k<=N; k++) stock[k] = NULL;
1.1 noro 888: for (k=1; k<=N; k++)
889: {
890: if (odd(k) || !stock[k])
891: {
1.2 ! noro 892: x = gzero; r = stoi(2*k);
1.1 noro 893: for(kk=0;;kk++)
894: {
895: long ex;
896: q1 = addii(r,a); ep->value = (void*) q1;
897: p1 = lisexpr(ch); if (did_break()) err(breaker,"sumpos2");
898: gaffect(p1,reel); ex = expo(reel)+kk; setexpo(reel,ex);
899: x=gadd(x,reel); if (kk && ex < G) break;
1.2 ! noro 900: r = shifti(r,1);
1.1 noro 901: }
1.2 ! noro 902: if (2*k-1 < N) stock[2*k] = x;
1.1 noro 903: q1 = addsi(k,a); ep->value = (void*) q1;
904: p1 = lisexpr(ch); if (did_break()) err(breaker,"sumpos2");
905: gaffect(p1,reel); stock[k] = gadd(reel, gmul2n(x,1));
906: }
907: }
908: pop_val(ep); s = gzero;
1.2 ! noro 909: pol = polzagreel(N,N>>1,prec+1);
! 910: dn = poleval(pol,gun);
! 911: pol[2] = lsub((GEN)pol[2],dn);
! 912: pol = gdiv(pol, gsub(gun,polx[0]));
1.1 noro 913: for (k=1; k<=lgef(pol)-2; k++)
914: {
915: p1 = gmul((GEN)pol[k+1],stock[k]);
1.2 ! noro 916: if (odd(k)) p1 = gneg_i(p1);
1.1 noro 917: s = gadd(s,p1);
918: }
919: tetpil=avma; return gerepile(av,tetpil,gdiv(s,dn));
920: }
921:
922: /********************************************************************/
923: /** **/
924: /** NUMERICAL INTEGRATION (Romberg) **/
925: /** **/
926: /********************************************************************/
1.2 ! noro 927: typedef struct {
! 928: entree *ep;
! 929: char *ch;
! 930: } exprdat;
! 931:
! 932: typedef struct {
! 933: GEN (*f)(void *, GEN);
! 934: void *E;
! 935: } invfun;
! 936:
! 937: /* we need to make a copy in any case, cf forpari */
! 938: static GEN
! 939: fix(GEN a, long prec)
! 940: {
! 941: GEN p = cgetr(prec);
! 942: gaffect(a,p); return p;
! 943: }
! 944:
! 945: #if 0
1.1 noro 946: GEN
1.2 ! noro 947: int_loop(entree *ep, char *ch)
1.1 noro 948: {
1.2 ! noro 949: gpmem_t av = avma;
! 950: intstruct T;
! 951:
! 952: T.in = NULL;
! 953: for(;;)
1.1 noro 954: {
1.2 ! noro 955: GEN x = Next(&T);
! 956: if (!x) return gerepileupto(av, T.out);
! 957: ep->value = (void*)x;
! 958: T.in = lisexpr(ch);
1.1 noro 959: }
960: }
1.2 ! noro 961: #endif
1.1 noro 962:
1.2 ! noro 963: /* f(x) */
! 964: static GEN
! 965: _gp_eval(void *dat, GEN x)
! 966: {
! 967: exprdat *E = (exprdat*)dat;
! 968: E->ep->value = x;
! 969: return lisexpr(E->ch);
! 970: }
! 971: /* 1/x^2 f(1/x) */
! 972: static GEN
! 973: _invf(void *dat, GEN x)
! 974: {
! 975: invfun *S = (invfun*)dat;
! 976: GEN y = ginv(x);
! 977: return gmul(S->f(S->E, y), gsqr(y));
! 978: }
1.1 noro 979:
1.2 ! noro 980: #define swap(a,b) { GEN _x = a; a = b; b = _x; }
1.1 noro 981: static GEN
1.2 ! noro 982: interp(GEN h, GEN s, long j, long lim, long KLOC)
1.1 noro 983: {
1.2 ! noro 984: gpmem_t av = avma;
! 985: long e1,e2;
! 986: GEN dss, ss = polint_i(h+j-KLOC,s+j-KLOC,gzero,KLOC+1,&dss);
! 987:
! 988: e1 = gexpo(ss);
! 989: e2 = gexpo(dss);
! 990: if (e1-e2 <= lim && e1 >= -lim) { avma = av; return NULL; }
! 991: if (gcmp0(gimag(ss))) ss = greal(ss);
! 992: return ss;
1.1 noro 993: }
994:
1.2 ! noro 995: static GEN
! 996: qrom3(void *dat, GEN (*eval)(void *, GEN), GEN a, GEN b, long prec)
1.1 noro 997: {
1.2 ! noro 998: const long JMAX = 25, KLOC = 4;
! 999: GEN ss,s,h,p1,p2,qlint,del,x,sum;
! 1000: long j, j1, it, sig;
! 1001: gpmem_t av;
1.1 noro 1002:
1003: a = fix(a,prec);
1004: b = fix(b,prec);
1.2 ! noro 1005: qlint = subrr(b,a); sig = signe(qlint);
! 1006: if (!sig) return gzero;
! 1007: if (sig < 0) { setsigne(qlint,1); swap(a,b); }
1.1 noro 1008:
1.2 ! noro 1009: s = new_chunk(JMAX+KLOC-1);
! 1010: h = new_chunk(JMAX+KLOC-1);
1.1 noro 1011: h[0] = (long)realun(prec);
1012:
1.2 ! noro 1013: p1 = eval(dat, a); if (p1 == a) p1 = rcopy(p1);
! 1014: p2 = eval(dat, b);
! 1015: s[0] = lmul2n(gmul(qlint,gadd(p1,p2)),-1);
! 1016: for (it=1,j=1; j<JMAX; j++, it<<=1)
! 1017: {
! 1018: h[j] = lshiftr((GEN)h[j-1],-2);
! 1019: av = avma; del = divrs(qlint,it);
! 1020: x = addrr(a, shiftr(del,-1));
! 1021: for (sum = gzero, j1 = 1; j1 <= it; j1++, x = addrr(x,del))
! 1022: sum = gadd(sum, eval(dat, x));
! 1023: sum = gmul(sum,del); p1 = gadd((GEN)s[j-1], sum);
! 1024: s[j] = lpileupto(av, gmul2n(p1,-1));
! 1025:
! 1026: if (j >= KLOC && (ss = interp(h, s, j, bit_accuracy(prec)-j-6, KLOC)))
! 1027: return gmulsg(sig,ss);
1.1 noro 1028: }
1.2 ! noro 1029: return NULL;
1.1 noro 1030: }
1031:
1.2 ! noro 1032: static GEN
! 1033: qrom2(void *dat, GEN (*eval)(void *, GEN), GEN a, GEN b, long prec)
1.1 noro 1034: {
1.2 ! noro 1035: const long JMAX = 16, KLOC = 4;
! 1036: GEN ss,s,h,p1,qlint,del,ddel,x,sum;
! 1037: long j, j1, it, sig;
! 1038: gpmem_t av;
1.1 noro 1039:
1040: a = fix(a, prec);
1041: b = fix(b, prec);
1.2 ! noro 1042: qlint = subrr(b,a); sig = signe(qlint);
! 1043: if (!sig) return gzero;
! 1044: if (sig < 0) { setsigne(qlint,1); swap(a,b); }
1.1 noro 1045:
1.2 ! noro 1046: s = new_chunk(JMAX+KLOC-1);
! 1047: h = new_chunk(JMAX+KLOC-1);
1.1 noro 1048: h[0] = (long)realun(prec);
1049:
1.2 ! noro 1050: p1 = shiftr(addrr(a,b),-1);
! 1051: s[0] = lmul(qlint, eval(dat, p1));
1.1 noro 1052: for (it=1, j=1; j<JMAX; j++, it*=3)
1053: {
1054: h[j] = ldivrs((GEN)h[j-1],9);
1.2 ! noro 1055: av = avma; del = divrs(qlint,3*it); ddel = shiftr(del,1);
! 1056: x = addrr(a, shiftr(del,-1));
! 1057: for (sum = gzero, j1 = 1; j1 <= it; j1++)
1.1 noro 1058: {
1.2 ! noro 1059: sum = gadd(sum, eval(dat, x)); x = addrr(x,ddel);
! 1060: sum = gadd(sum, eval(dat, x)); x = addrr(x,del);
1.1 noro 1061: }
1062: sum = gmul(sum,del); p1 = gdivgs((GEN)s[j-1],3);
1.2 ! noro 1063: s[j] = lpileupto(av, gadd(p1,sum));
1.1 noro 1064:
1.2 ! noro 1065: if (j >= KLOC && (ss = interp(h, s, j, bit_accuracy(prec)-(3*j/2)-6, KLOC)))
! 1066: return gmulsg(sig, ss);
1.1 noro 1067: }
1.2 ! noro 1068: return NULL;
1.1 noro 1069: }
1070:
1.2 ! noro 1071: /* integrate after change of variables x --> 1/x */
! 1072: static GEN
! 1073: qromi(void *E, GEN (*eval)(void*, GEN), GEN a, GEN b, long prec)
! 1074: {
! 1075: GEN A = ginv(b), B = ginv(a);
! 1076: invfun S;
! 1077: S.f = eval;
! 1078: S.E = E; return qrom2(&S, &_invf, A, B, prec);
! 1079: }
1.1 noro 1080:
1.2 ! noro 1081: /* a < b, assume b "small" (< 100 say) */
! 1082: static GEN
! 1083: rom_bsmall(void *E, GEN (*eval)(void*, GEN), GEN a, GEN b, long prec)
1.1 noro 1084: {
1.2 ! noro 1085: if (gcmpgs(a,-100) >= 0) return qrom2(E,eval,a,b,prec);
! 1086: if (b == gun || gcmpgs(b, -1) >= 0)
! 1087: { /* a < -100, b >= -1 */
! 1088: GEN _1 = negi(gun); /* split at -1 */
! 1089: return gadd(qromi(E,eval,a,_1,prec),
! 1090: qrom2(E,eval,_1,b,prec));
! 1091: }
! 1092: /* a < -100, b < -1 */
! 1093: return qromi(E,eval,a,b,prec);
! 1094: }
1.1 noro 1095:
1.2 ! noro 1096: static GEN
! 1097: rombint(void *E, GEN (*eval)(void*, GEN), GEN a, GEN b, long prec)
! 1098: {
! 1099: long l = gcmp(b,a);
! 1100: GEN z;
1.1 noro 1101:
1.2 ! noro 1102: if (!l) return gzero;
! 1103: if (l < 0) swap(a,b);
! 1104: if (gcmpgs(b,100) >= 0)
! 1105: {
! 1106: if (gcmpgs(a,1) >= 0)
! 1107: z = qromi(E,eval,a,b,prec);
! 1108: else /* split at 1 */
! 1109: z = gadd(rom_bsmall(E,eval,a,gun,prec), qromi(E,eval,gun,b,prec));
! 1110: }
! 1111: else
! 1112: z = rom_bsmall(E,eval,a,b,prec);
! 1113: if (l < 0) z = gneg(z);
! 1114: return z;
! 1115: }
1.1 noro 1116:
1.2 ! noro 1117: GEN
! 1118: intnum(void *E, GEN (*eval)(void*,GEN), GEN a, GEN b, long flag, long prec)
! 1119: {
! 1120: gpmem_t av = avma;
! 1121: GEN z;
! 1122: switch(flag)
1.1 noro 1123: {
1.2 ! noro 1124: case 0: z = qrom3 (E,eval,a,b,prec); break;
! 1125: case 1: z = rombint(E,eval,a,b,prec); break;
! 1126: case 2: z = qromi (E,eval,a,b,prec); break;
! 1127: case 3: z = qrom2 (E,eval,a,b,prec); break;
! 1128: default: err(flagerr); z = NULL;
1.1 noro 1129: }
1.2 ! noro 1130: if (!z) err(intger2);
! 1131: return gerepileupto(av, z);
1.1 noro 1132: }
1133:
1134: GEN
1.2 ! noro 1135: intnum0(entree *ep, GEN a, GEN b, char *ch, long flag, long prec)
1.1 noro 1136: {
1.2 ! noro 1137: exprdat E;
! 1138: GEN z;
1.1 noro 1139:
1.2 ! noro 1140: E.ch = ch;
! 1141: E.ep = ep; push_val(ep, NULL);
! 1142: z = intnum(&E, &_gp_eval, a,b, flag, prec);
! 1143: pop_val(ep); return z;
1.1 noro 1144: }
1145: /********************************************************************/
1146: /** **/
1.2 ! noro 1147: /** ZAGIER POLYNOMIALS (for sumalt) **/
1.1 noro 1148: /** **/
1149: /********************************************************************/
1150:
1151: GEN
1152: polzag(long n, long m)
1153: {
1.2 ! noro 1154: gpmem_t av = avma;
! 1155: long d1, d, r, k;
! 1156: GEN A, B, Bx, g, s;
1.1 noro 1157:
1.2 ! noro 1158: if (m >= n || m < 0)
1.1 noro 1159: err(talker,"first index must be greater than second in polzag");
1.2 ! noro 1160: d1 = n-m; d = d1<<1; d1--;
! 1161: A = gsub(gun, gmul2n(polx[0],1)); /* 1 - 2x */
! 1162: B = gsub(gun, polx[0]); /* 1 - x */
! 1163: Bx = gmul(polx[0],B); /* x - x^2 */
! 1164: r = (m+1)>>1;
! 1165: g = gzero;
1.1 noro 1166: for (k=0; k<=d1; k++)
1167: {
1.2 ! noro 1168: s = binome(stoi(d), (k<<1)+1); if (k&1) s = negi(s);
! 1169: g = gadd(g, gmul(s, gmul(gpowgs(polx[0],k), gpowgs(B,d1-k))));
1.1 noro 1170: }
1.2 ! noro 1171: g = gmul(g, gpowgs(Bx,r));
! 1172: if (!(m&1)) g = gadd(gmul(A,g), gmul2n(gmul(Bx,derivpol(g)),1));
1.1 noro 1173: for (k=1; k<=r; k++)
1174: {
1.2 ! noro 1175: g = derivpol(g);
! 1176: g = gadd(gmul(A,g), gmul2n(gmul(Bx,derivpol(g)),1));
1.1 noro 1177: }
1.2 ! noro 1178: g = m? gmul2n(g,(m-1)>>1): gmul2n(g,-1);
! 1179: s = mulsi(n-m, mpfact(m+1));
! 1180: return gerepileupto(av, gdiv(g,s));
1.1 noro 1181: }
1182:
1183: #ifdef _MSC_VER /* Bill Daly: work around a MSVC bug */
1184: #pragma optimize("g",off)
1185: #endif
1186: GEN
1187: polzagreel(long n, long m, long prec)
1188: {
1.2 ! noro 1189: long d1, d, r, j, k, k2;
! 1190: gpmem_t av = avma;
! 1191: GEN Bx,B,g,h,v,b,s;
1.1 noro 1192:
1.2 ! noro 1193: if (m >= n || m < 0)
1.1 noro 1194: err(talker,"first index must be greater than second in polzag");
1.2 ! noro 1195: d1 = n-m; d = d1<<1; d1--;
! 1196: B = gadd(gun,polx[0]);
! 1197: Bx = gmul(polx[0],B);
! 1198: r = (m+1)>>1;
! 1199: v = cgetg(d1+2,t_VEC);
! 1200: g = cgetg(d1+2,t_VEC);
! 1201: v[d1+1] = un; b = stor(d, prec);
! 1202: g[d1+1] = (long)b;
1.1 noro 1203: for (k=1; k<=d1; k++)
1204: {
1.2 ! noro 1205: v[d1-k+1] = un;
1.1 noro 1206: for (j=1; j<k; j++)
1.2 ! noro 1207: v[d1-k+j+1] = laddii((GEN)v[d1-k+j+1], (GEN)v[d1-k+j+2]);
! 1208: k2 = k+k; b = divri(mulri(b,mulss(d-k2+1,d-k2)), mulss(k2,k2+1));
1.1 noro 1209: for (j=1; j<=k; j++)
1.2 ! noro 1210: g[d1-k+j+1] = lmpadd((GEN)g[d1-k+j+1], mulri(b,(GEN)v[d1-k+j+1]));
! 1211: g[d1-k+1] = (long)b;
1.1 noro 1212: }
1.2 ! noro 1213: g = gmul(vec_to_pol(g,0), gpowgs(Bx,r));
1.1 noro 1214: for (j=0; j<=r; j++)
1215: {
1.2 ! noro 1216: if (j) g = derivpol(g);
1.1 noro 1217: if (j || !(m&1))
1218: {
1.2 ! noro 1219: h = cgetg(n+3,t_POL);
! 1220: h[1] = evalsigne(1)|evallgef(n+3);
! 1221: h[2] = g[2];
1.1 noro 1222: for (k=1; k<n; k++)
1.2 ! noro 1223: h[k+2] = ladd(gmulsg(k+k+1,(GEN)g[k+2]), gmulsg(k<<1,(GEN)g[k+1]));
! 1224: h[n+2] = lmulsg(n<<1, (GEN)g[n+1]);
! 1225: g = h;
1.1 noro 1226: }
1227: }
1.2 ! noro 1228: g = m? gmul2n(g,(m-1)>>1): gmul2n(g,-1);
! 1229: s = mulsi(n-m, mpfact(m+1));
! 1230: return gerepileupto(av, gdiv(g,s));
1.1 noro 1231: }
1232: #ifdef _MSC_VER
1233: #pragma optimize("g",on)
1234: #endif
1235:
1236: /********************************************************************/
1237: /** **/
1238: /** SEARCH FOR REAL ZEROS of an expression **/
1239: /** **/
1240: /********************************************************************/
1241: /* Brent's method, [a,b] bracketing interval */
1242: GEN
1243: zbrent(entree *ep, GEN a, GEN b, char *ch, long prec)
1244: {
1.2 ! noro 1245: long sig, iter, itmax;
! 1246: gpmem_t av = avma;
1.1 noro 1247: GEN c,d,e,tol,tol1,min1,min2,fa,fb,fc,p,q,r,s,xm;
1248:
1249: a = fix(a,prec);
1250: b = fix(b,prec); sig=cmprr(b,a);
1251: if (!sig) { avma = av; return gzero; }
1252: if (sig < 0) { c=a; a=b; b=c; } else c = b;
1253:
1254: push_val(ep, a); fa = lisexpr(ch);
1255: ep->value = (void*)b; fb = lisexpr(ch);
1256: if (gsigne(fa)*gsigne(fb) > 0)
1257: err(talker,"roots must be bracketed in solve");
1258: itmax = (prec<<(TWOPOTBITS_IN_LONG+1)) + 1;
1259: tol = realun(3); setexpo(tol, 5-bit_accuracy(prec));
1260: fc=fb;
1261: e = d = NULL; /* gcc -Wall */
1262: for (iter=1; iter<=itmax; iter++)
1263: {
1264: if (gsigne(fb)*gsigne(fc) > 0)
1265: {
1266: c = a; fc = fa; e = d = subrr(b,a);
1267: }
1268: if (gcmp(gabs(fc,0),gabs(fb,0)) < 0)
1269: {
1270: a = b; b = c; c = a; fa = fb; fb = fc; fc = fa;
1271: }
1272: tol1 = mulrr(tol, gmax(tol,absr(b)));
1273: xm = shiftr(subrr(c,b),-1);
1274: if (cmprr(absr(xm),tol1) <= 0 || gcmp0(fb)) break; /* SUCCESS */
1275:
1276: if (cmprr(absr(e),tol1) >= 0 && gcmp(gabs(fa,0),gabs(fb,0)) > 0)
1277: { /* attempt interpolation */
1278: s = gdiv(fb,fa);
1279: if (cmprr(a,c)==0)
1280: {
1281: p = gmul2n(gmul(xm,s),1); q = gsubsg(1,s);
1282: }
1283: else
1284: {
1285: q = gdiv(fa,fc); r = gdiv(fb,fc);
1286: p = gmul2n(gmul(gsub(q,r),gmul(xm,q)),1);
1287: p = gmul(s, gsub(p, gmul(gsub(b,a),gsubgs(r,1))));
1288: q = gmul(gmul(gsubgs(q,1),gsubgs(r,1)),gsubgs(s,1));
1289: }
1290: if (gsigne(p) > 0) q = gneg_i(q); else p = gneg_i(p);
1291: min1 = gsub(gmulsg(3,gmul(xm,q)), gabs(gmul(q,tol1),0));
1292: min2 = gabs(gmul(e,q),0);
1293: if (gcmp(gmul2n(p,1), gmin(min1,min2)) < 0)
1294: { e = d; d = gdiv(p,q); } /* interpolation OK */
1295: else
1296: { d = xm; e = d; } /* failed, use bisection */
1297: }
1298: else { d = xm; e = d; } /* bound decreasing too slowly, use bisection */
1299: a = b; fa = fb;
1300: if (gcmp(gabs(d,0),tol1) > 0) b = gadd(b,d);
1.2 ! noro 1301: else if (gsigne(xm) > 0) b = addrr(b,tol1);
! 1302: else b = subrr(b,tol1);
1.1 noro 1303: ep->value = (void*)b; fb = lisexpr(ch);
1304: }
1305: if (iter > itmax) err(talker,"too many iterations in solve");
1306: pop_val(ep);
1307: return gerepileuptoleaf(av, rcopy(b));
1308: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>