[BACK]Return to sumiter.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari-2.2 / src / language

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>