Annotation of OpenXM_contrib/pari-2.2/src/language/sumiter.c, Revision 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>