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