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

Annotation of OpenXM_contrib/pari-2.2/src/basemath/gen3.c, Revision 1.2

1.2     ! noro        1: /* $Id: gen3.c,v 1.75 2002/09/07 20:56:18 karim Exp $
1.1       noro        2:
                      3: Copyright (C) 2000  The PARI group.
                      4:
                      5: This file is part of the PARI/GP package.
                      6:
                      7: PARI/GP is free software; you can redistribute it and/or modify it under the
                      8: terms of the GNU General Public License as published by the Free Software
                      9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
                     10: ANY WARRANTY WHATSOEVER.
                     11:
                     12: Check the License for details. You should have received a copy of it, along
                     13: with the package; see the file 'COPYING'. If not, write to the Free Software
                     14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
                     15:
                     16: /********************************************************************/
                     17: /**                                                                **/
                     18: /**                      GENERIC OPERATIONS                        **/
                     19: /**                         (third part)                           **/
                     20: /**                                                                **/
                     21: /********************************************************************/
                     22: #include "pari.h"
                     23:
                     24: /********************************************************************/
                     25: /**                                                                **/
                     26: /**                 PRINCIPAL VARIABLE NUMBER                      **/
                     27: /**                                                                **/
                     28: /********************************************************************/
                     29:
                     30: int
                     31: gvar(GEN x)
                     32: {
                     33:   long tx=typ(x),i,v,w;
                     34:
                     35:   if (is_polser_t(tx)) return varn(x);
                     36:   if (tx==t_POLMOD) return varn(x[1]);
                     37:   if (is_const_t(tx) || is_qf_t(tx) || is_noncalc_t(tx)) return BIGINT;
                     38:   v=BIGINT;
                     39:   for (i=1; i < lg(x); i++) { w=gvar((GEN)x[i]); if (w<v) v=w; }
                     40:   return v;
                     41: }
                     42:
                     43: /* assume x POLMOD */
                     44: static int
                     45: _varPOLMOD(GEN x)
                     46: {
                     47:   long v = gvar2((GEN)x[1]);
                     48:   long w = gvar2((GEN)x[2]); if (w<v) v=w;
                     49:   return v;
                     50:
                     51: }
                     52:
                     53: int
                     54: gvar2(GEN x)
                     55: {
                     56:   long tx=typ(x),i,v,w;
                     57:
                     58:   if (is_const_t(tx) || is_qf_t(tx) || is_noncalc_t(tx)) return BIGINT;
                     59:   v = BIGINT;
                     60:   switch(tx)
                     61:   {
                     62:     case t_POLMOD:
                     63:       return _varPOLMOD(x);
                     64:
                     65:     case t_SER:
                     66:       for (i=2; i < lg(x); i++) { w=gvar((GEN)x[i]); if (w<v) v=w; }
                     67:       return v;
                     68:
                     69:     case t_POL:
                     70:       for (i=2; i<lgef(x); i++) { w=gvar((GEN)x[i]); if (w<v) v=w; }
                     71:       return v;
                     72:   }
                     73:   for (i=1; i<lg(x); i++) { w=gvar2((GEN)x[i]); if (w<v) v=w; }
                     74:   return v;
                     75: }
                     76:
                     77: int
                     78: gvar9(GEN x)
                     79: {
                     80:   return (typ(x) == t_POLMOD)? _varPOLMOD(x): gvar(x);
                     81: }
                     82:
                     83: GEN
                     84: gpolvar(GEN x)
                     85: {
                     86:   if (typ(x)==t_PADIC) x = (GEN)x[2];
                     87:   else
                     88:   {
                     89:     long v=gvar(x);
                     90:     if (v==BIGINT) err(typeer,"polvar");
                     91:     x = polx[v];
                     92:   }
                     93:   return gcopy(x);
                     94: }
                     95:
                     96: /*******************************************************************/
                     97: /*                                                                 */
                     98: /*                    PRECISION OF SCALAR OBJECTS                  */
                     99: /*                                                                 */
                    100: /*******************************************************************/
                    101:
                    102: long
                    103: precision(GEN x)
                    104: {
                    105:   long tx=typ(x),k,l;
                    106:
                    107:   if (tx==t_REAL)
                    108:   {
                    109:     k=2-(expo(x)>>TWOPOTBITS_IN_LONG);
                    110:     l=lg(x); if (l>k) k=l;
                    111:     return k;
                    112:   }
                    113:   if (tx==t_COMPLEX)
                    114:   {
                    115:     k=precision((GEN)x[1]);
                    116:     l=precision((GEN)x[2]); if (l && (!k || l<k)) k=l;
                    117:     return k;
                    118:   }
                    119:   return 0;
                    120: }
                    121:
                    122: long
                    123: gprecision(GEN x)
                    124: {
                    125:   long tx=typ(x),lx=lg(x),i,k,l;
                    126:
                    127:   if (is_scalar_t(tx)) return precision(x);
                    128:   switch(tx)
                    129:   {
                    130:     case t_POL: lx=lgef(x);
                    131:     case t_VEC: case t_COL: case t_MAT:
                    132:       k=VERYBIGINT;
                    133:       for (i=lontyp[tx]; i<lx; i++)
                    134:       {
                    135:         l = gprecision((GEN)x[i]);
                    136:        if (l && l<k) k = l;
                    137:       }
                    138:       return (k==VERYBIGINT)? 0: k;
                    139:
                    140:     case t_RFRAC: case t_RFRACN:
                    141:     {
                    142:       k=gprecision((GEN)x[1]);
                    143:       l=gprecision((GEN)x[2]); if (l && (!k || l<k)) k=l;
                    144:       return k;
                    145:     }
                    146:     case t_QFR:
                    147:       return gprecision((GEN)x[4]);
                    148:   }
                    149:   return 0;
                    150: }
                    151:
                    152: GEN
                    153: ggprecision(GEN x)
                    154: {
                    155:   long a=gprecision(x);
                    156:   return stoi(a ? (long) ((a-2)*pariK): VERYBIGINT);
                    157: }
                    158:
                    159: GEN
                    160: precision0(GEN x, long n)
                    161: {
                    162:   if (n) return gprec(x,n);
                    163:   return ggprecision(x);
                    164: }
                    165:
                    166: /* attention: precision p-adique absolue */
                    167: long
                    168: padicprec(GEN x, GEN p)
                    169: {
                    170:   long i,s,t,lx=lg(x),tx=typ(x);
                    171:
                    172:   switch(tx)
                    173:   {
                    174:     case t_INT: case t_FRAC: case t_FRACN:
                    175:       return VERYBIGINT;
                    176:
                    177:     case t_INTMOD:
                    178:       return ggval((GEN)x[1],p);
                    179:
                    180:     case t_PADIC:
                    181:       if (!gegal((GEN)x[2],p))
                    182:        err(talker,"not the same prime in padicprec");
                    183:       return precp(x)+valp(x);
                    184:
                    185:     case t_POL:
                    186:       lx=lgef(x);
                    187:
                    188:     case t_COMPLEX: case t_QUAD: case t_POLMOD: case t_SER: case t_RFRAC:
                    189:     case t_RFRACN: case t_VEC: case t_COL: case t_MAT:
                    190:       for (s=VERYBIGINT, i=lontyp[tx]; i<lx; i++)
                    191:       {
                    192:         t = padicprec((GEN)x[i],p); if (t<s) s = t;
                    193:       }
                    194:       return s;
                    195:   }
                    196:   err(typeer,"padicprec");
                    197:   return 0; /* not reached */
                    198: }
                    199:
1.2     ! noro      200: /* Degree of x (scalar, t_POL, t_RFRAC) wrt variable v if v >= 0,
        !           201:  * wrt to main variable if v < 0.  Convention: deg(0) = -1.
1.1       noro      202:  */
                    203: long
                    204: poldegree(GEN x, long v)
                    205: {
1.2     ! noro      206:   long tx = typ(x), lx,w,i,d;
1.1       noro      207:
                    208:   if (is_scalar_t(tx)) return gcmp0(x)? -1: 0;
                    209:   switch(tx)
                    210:   {
                    211:     case t_POL:
                    212:       w = varn(x);
                    213:       if (v < 0 || v == w) return degpol(x);
                    214:       if (v < w) return signe(x)? 0: -1;
1.2     ! noro      215:       lx = lgef(x); d = -1;
        !           216:       for (i=2; i<lx; i++)
        !           217:       {
        !           218:         long e = poldegree((GEN)x[i], v);
        !           219:         if (e > d) d = e;
        !           220:       }
        !           221:       return d;
1.1       noro      222:
                    223:     case t_RFRAC: case t_RFRACN:
                    224:       if (gcmp0((GEN)x[1])) return -1;
                    225:       return poldegree((GEN)x[1],v) - poldegree((GEN)x[2],v);
                    226:   }
                    227:   err(typeer,"degree");
                    228:   return 0; /* not reached  */
                    229: }
                    230:
                    231: long
                    232: degree(GEN x)
                    233: {
                    234:   return poldegree(x,-1);
                    235: }
                    236:
                    237: /* si v<0, par rapport a la variable principale, sinon par rapport a v.
                    238:  * On suppose que x est un polynome ou une serie.
                    239:  */
                    240: GEN
                    241: pollead(GEN x, long v)
                    242: {
1.2     ! noro      243:   long l, tx = typ(x), w;
        !           244:   gpmem_t av, tetpil;
1.1       noro      245:   GEN xinit;
                    246:
                    247:   if (is_scalar_t(tx)) return gcopy(x);
                    248:   w = varn(x);
                    249:   switch(tx)
                    250:   {
                    251:     case t_POL:
                    252:       if (v < 0 || v == w)
                    253:       {
                    254:        l=lgef(x);
                    255:        return (l==2)? gzero: gcopy((GEN)x[l-1]);
                    256:       }
                    257:       if (v < w) return gcopy(x);
                    258:       av = avma; xinit = x;
                    259:       x = gsubst(gsubst(x,w,polx[MAXVARN]),v,polx[0]);
                    260:       if (gvar(x)) { avma = av; return gcopy(xinit); }
                    261:       l = lgef(x); if (l == 2) { avma = av; return gzero; }
                    262:       tetpil = avma; x = gsubst((GEN)x[l-1],MAXVARN,polx[w]);
                    263:       return gerepile(av,tetpil,x);
                    264:
                    265:     case t_SER:
                    266:       if (v < 0 || v == w) return (!signe(x))? gzero: gcopy((GEN)x[2]);
                    267:       if (v < w) return gcopy(x);
                    268:       av = avma; xinit = x;
                    269:       x = gsubst(gsubst(x,w,polx[MAXVARN]),v,polx[0]);
                    270:       if (gvar(x)) { avma = av; return gcopy(xinit);}
                    271:       if (!signe(x)) { avma = av; return gzero;}
                    272:       tetpil = avma; x = gsubst((GEN)x[2],MAXVARN,polx[w]);
                    273:       return gerepile(av,tetpil,x);
                    274:   }
                    275:   err(typeer,"pollead");
                    276:   return NULL; /* not reached */
                    277: }
                    278:
                    279: /* returns 1 if there's a real component in the structure, 0 otherwise */
                    280: int
                    281: isinexactreal(GEN x)
                    282: {
                    283:   long tx=typ(x),lx,i;
                    284:
                    285:   if (is_scalar_t(tx))
                    286:   {
                    287:     switch(tx)
                    288:     {
                    289:       case t_REAL:
                    290:         return 1;
                    291:
                    292:       case t_COMPLEX: case t_QUAD:
                    293:         return (typ(x[1])==t_REAL || typ(x[2])==t_REAL);
                    294:     }
                    295:     return 0;
                    296:   }
                    297:   switch(tx)
                    298:   {
                    299:     case t_QFR: case t_QFI:
                    300:       return 0;
                    301:
                    302:     case t_RFRAC: case t_RFRACN:
                    303:       return isinexactreal((GEN)x[1]) || isinexactreal((GEN)x[2]);
                    304:   }
                    305:   if (is_noncalc_t(tx)) return 0;
                    306:   lx = (tx==t_POL)? lgef(x): lg(x);
                    307:   for (i=lontyp[tx]; i<lx; i++)
                    308:     if (isinexactreal((GEN)x[i])) return 1;
                    309:   return 0;
                    310: }
                    311:
                    312: int
                    313: isexactzero(GEN g)
                    314: {
                    315:   long i;
                    316:   switch (typ(g))
                    317:   {
                    318:     case t_INT:
                    319:       return !signe(g);
                    320:     case t_REAL: case t_PADIC: case t_SER:
                    321:       return 0;
                    322:     case t_INTMOD: case t_POLMOD:
                    323:       return isexactzero((GEN)g[2]);
                    324:     case t_FRAC: case t_FRACN: case t_RFRAC: case t_RFRACN:
                    325:       return isexactzero((GEN)g[1]);
                    326:     case t_COMPLEX:
                    327:       return isexactzero((GEN)g[1]) && isexactzero((GEN)g[2]);
                    328:     case t_QUAD:
                    329:       return isexactzero((GEN)g[2]) && isexactzero((GEN)g[3]);
                    330:
                    331:     case t_POL:
                    332:       for (i=lgef(g)-1; i>1; i--)
                    333:         if (!isexactzero((GEN)g[i])) return 0;
                    334:       return 1;
                    335:     case t_VEC: case t_COL: case t_MAT:
                    336:       for (i=lg(g)-1; i; i--)
                    337:        if (!isexactzero((GEN)g[i])) return 0;
                    338:       return 1;
                    339:   }
                    340:   return 0;
                    341: }
                    342:
                    343: int
                    344: iscomplex(GEN x)
                    345: {
                    346:   switch(typ(x))
                    347:   {
                    348:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
                    349:       return 0;
                    350:     case t_COMPLEX:
                    351:       return !gcmp0((GEN)x[2]);
                    352:     case t_QUAD:
                    353:       return signe(mael(x,1,2)) > 0;
                    354:   }
                    355:   err(typeer,"iscomplex");
                    356:   return 0; /* not reached */
                    357: }
                    358:
                    359: int
                    360: ismonome(GEN x)
                    361: {
                    362:   long i;
                    363:   if (typ(x)!=t_POL || !signe(x)) return 0;
                    364:   for (i=lgef(x)-2; i>1; i--)
                    365:     if (!isexactzero((GEN)x[i])) return 0;
                    366:   return 1;
                    367: }
                    368:
                    369: /********************************************************************/
                    370: /**                                                                **/
                    371: /**                     MULTIPLICATION SIMPLE                      **/
                    372: /**                                                                **/
                    373: /********************************************************************/
                    374: #define fix_frac(z) if (signe(z[2])<0)\
                    375: {\
                    376:   setsigne(z[1],-signe(z[1]));\
                    377:   setsigne(z[2],1);\
                    378: }
                    379:
                    380: /* assume z[1] was created last */
                    381: #define fix_frac_if_int(z) if (is_pm1(z[2]))\
1.2     ! noro      382:   z = gerepileuptoint((gpmem_t)(z+3), (GEN)z[1]);
1.1       noro      383:
                    384: GEN
                    385: gmulsg(long s, GEN y)
                    386: {
1.2     ! noro      387:   long ty=typ(y), ly=lg(y), i;
        !           388:   gpmem_t av, tetpil;
1.1       noro      389:   GEN z,p1,p2;
                    390:
                    391:   switch(ty)
                    392:   {
                    393:     case t_INT:
                    394:       return mulsi(s,y);
                    395:
                    396:     case t_REAL:
                    397:       return mulsr(s,y);
                    398:
                    399:     case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
                    400:       (void)new_chunk(lgefint(p2)<<2); /* HACK */
1.2     ! noro      401:       p1=mulsi(s,(GEN)y[2]); avma=(gpmem_t)z;
1.1       noro      402:       z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
                    403:
                    404:     case t_FRAC:
                    405:       if (!s) return gzero;
                    406:       z = cgetg(3,t_FRAC);
                    407:       i = cgcd(s, smodis((GEN)y[2], s));
                    408:       if (i == 1)
                    409:       {
                    410:         z[2] = licopy((GEN)y[2]);
                    411:         z[1] = lmulis((GEN)y[1], s);
                    412:       }
                    413:       else
                    414:       {
                    415:         z[2] = ldivis((GEN)y[2], i);
                    416:         z[1] = lmulis((GEN)y[1], s/i);
                    417:         fix_frac_if_int(z);
                    418:       }
                    419:       return z;
                    420:
                    421:     case t_FRACN: z=cgetg(3,ty);
                    422:       z[1]=lmulsi(s,(GEN)y[1]);
                    423:       z[2]=licopy((GEN)y[2]);
                    424:       return z;
                    425:
                    426:     case t_COMPLEX: z=cgetg(ly,ty);
                    427:       z[1]=lmulsg(s,(GEN)y[1]);
                    428:       z[2]=lmulsg(s,(GEN)y[2]); return z;
                    429:
                    430:     case t_PADIC:
                    431:       if (!s) return gzero;
                    432:       av=avma; p1=cgetp(y); gaffsg(s,p1); tetpil=avma;
                    433:       return gerepile(av,tetpil,gmul(p1,y));
                    434:
                    435:     case t_QUAD: z=cgetg(ly,ty);
                    436:       copyifstack(y[1],z[1]);
                    437:       z[2]=lmulsg(s,(GEN)y[2]);
                    438:       z[3]=lmulsg(s,(GEN)y[3]); return z;
                    439:
                    440:     case t_POLMOD: z=cgetg(ly,ty);
                    441:       z[2]=lmulsg(s,(GEN)y[2]);
                    442:       copyifstack(y[1],z[1]); return z;
                    443:
                    444:     case t_POL:
                    445:       if (!s || !signe(y)) return zeropol(varn(y));
                    446:       ly=lgef(y); z=cgetg(ly,t_POL); z[1]=y[1];
                    447:       for (i=2; i<ly; i++) z[i]=lmulsg(s,(GEN)y[i]);
                    448:       return normalizepol_i(z, ly);
                    449:
                    450:     case t_SER:
                    451:       if (!s) return zeropol(varn(y));
                    452:       if (gcmp0(y)) return gcopy(y);
                    453:       z=cgetg(ly,ty);
                    454:       for (i=2; i<ly; i++) z[i]=lmulsg(s,(GEN)y[i]);
                    455:       z[1]=y[1]; return normalize(z);
                    456:
                    457:     case t_RFRAC:
                    458:       if (!s) return zeropol(gvar(y));
                    459:       z = cgetg(3, t_RFRAC);
                    460:       i = ggcd(stoi(s),(GEN)y[2])[2];
1.2     ! noro      461:       avma = (gpmem_t)z;
1.1       noro      462:       if (i == 1)
                    463:       {
                    464:         z[1]=lmulgs((GEN)y[1], s);
                    465:         z[2]= lcopy((GEN)y[2]);
                    466:       }
                    467:       else
                    468:       {
                    469:         z[1] = lmulgs((GEN)y[1], s/i);
                    470:         z[2] = ldivgs((GEN)y[2], i);
                    471:       }
                    472:       return z;
                    473:
                    474:     case t_RFRACN:
                    475:       if (!s) return zeropol(gvar(y));
                    476:       z=cgetg(ly,t_RFRACN);
                    477:       z[1]=lmulsg(s,(GEN)y[1]);
                    478:       z[2]=lcopy((GEN)y[2]); return z;
                    479:
                    480:     case t_VEC: case t_COL: case t_MAT:
                    481:       z=cgetg(ly,ty);
                    482:       for (i=1; i<ly; i++) z[i]=lmulsg(s,(GEN)y[i]);
                    483:       return z;
                    484:   }
                    485:   err(typeer,"gmulsg");
                    486:   return NULL; /* not reached */
                    487: }
                    488:
                    489: /********************************************************************/
                    490: /**                                                                **/
                    491: /**                       DIVISION SIMPLE                          **/
                    492: /**                                                                **/
                    493: /********************************************************************/
                    494:
                    495: GEN
                    496: gdivgs(GEN x, long s)
                    497: {
1.2     ! noro      498:   static long court[] = { evaltyp(t_INT) | _evallg(3),0,0 };
        !           499:   long tx=typ(x), lx=lg(x), i;
        !           500:   gpmem_t av;
1.1       noro      501:   GEN z,p1;
                    502:
                    503:   if (!s) err(gdiver2);
                    504:   switch(tx)
                    505:   {
                    506:     case t_INT:
                    507:       av=avma; z=dvmdis(x,s,&p1);
                    508:       if (p1==gzero) return z;
                    509:
                    510:       i = cgcd(s, smodis(x,s));
                    511:       avma=av; z=cgetg(3,t_FRAC);
                    512:       if (i == 1)
                    513:         x = icopy(x);
                    514:       else
                    515:       {
                    516:         s /= i;
                    517:         x = divis(x, i);
                    518:       }
                    519:       z[1]=(long)x; z[2]=lstoi(s);
                    520:       fix_frac(z); return z;
                    521:
                    522:     case t_REAL:
                    523:       return divrs(x,s);
                    524:
                    525:     case t_FRAC: z=cgetg(3,tx);
                    526:       i = cgcd(s, smodis((GEN)x[1], s));
                    527:       if (i == 1)
                    528:       {
                    529:         z[2] = lmulsi(s, (GEN)x[2]);
                    530:         z[1] = licopy((GEN)x[1]);
                    531:       }
                    532:       else
                    533:       {
                    534:         z[2] = lmulsi(s/i, (GEN)x[2]);
                    535:         z[1] = ldivis((GEN)x[1], i);
                    536:       }
                    537:       fix_frac(z);
                    538:       fix_frac_if_int(z); return z;
                    539:
                    540:     case t_FRACN: z = cgetg(3,tx);
                    541:       z[1]=licopy((GEN)x[1]);
                    542:       z[2]=lmulsi(s,(GEN)x[2]);
                    543:       fix_frac(z); return z;
                    544:
                    545:     case t_COMPLEX: z=cgetg(lx,tx);
                    546:       z[1]=ldivgs((GEN)x[1],s);
                    547:       z[2]=ldivgs((GEN)x[2],s);
                    548:       return z;
                    549:
                    550:     case t_QUAD: z=cgetg(lx,tx);
                    551:       copyifstack(x[1],z[1]);
                    552:       for (i=2; i<4; i++) z[i]=ldivgs((GEN)x[i],s);
                    553:       return z;
                    554:
                    555:     case t_POLMOD: z=cgetg(lx,tx);
                    556:       copyifstack(x[1],z[1]);
                    557:       z[2]=ldivgs((GEN)x[2],s);
                    558:       return z;
                    559:
                    560:     case t_POL: lx=lgef(x); z=cgetg(lx,tx);
                    561:       for (i=2; i<lx; i++) z[i]=ldivgs((GEN)x[i],s);
                    562:       z[1]=x[1]; return z;
                    563:
                    564:     case t_SER: z=cgetg(lx,tx);
                    565:       for (i=2; i<lx; i++) z[i]=ldivgs((GEN)x[i],s);
                    566:       z[1]=x[1]; return z;
                    567:
                    568:     case t_RFRAC:
1.2     ! noro      569:       av = avma;
        !           570:       p1 = ggcd(stoi(s),(GEN)x[1]);
        !           571:       if (typ(p1) == t_INT)
        !           572:       {
        !           573:         avma = av;
        !           574:         z = cgetg(3, t_RFRAC);
        !           575:         i = p1[2];
        !           576:         if (i == 1)
        !           577:         {
        !           578:           z[1] = lcopy((GEN)x[1]);
        !           579:           z[2] = lmulsg(s,(GEN)x[2]);
        !           580:         }
        !           581:         else
        !           582:         {
        !           583:           z[1] = ldivgs((GEN)x[1], i);
        !           584:           z[2] = lmulgs((GEN)x[2], s/i);
        !           585:         }
        !           586:       }
        !           587:       else /* t_FRAC */
1.1       noro      588:       {
1.2     ! noro      589:         z = cgetg(3, t_RFRAC);
        !           590:         z[1] = ldiv((GEN)x[1], p1);
        !           591:         z[2] = lmul((GEN)x[2], gdivsg(s,p1));
        !           592:         z = gerepilecopy(av, z);
1.1       noro      593:       }
1.2     ! noro      594:       return z;
1.1       noro      595:
                    596:     case t_RFRACN: z=cgetg(3,t_RFRACN);
1.2     ! noro      597:       z[1]=lcopy((GEN)x[1]);
        !           598:       z[2]=lmulsg(s,(GEN)x[2]); return z;
1.1       noro      599:
                    600:     case t_VEC: case t_COL: case t_MAT: z=cgetg(lx,tx);
                    601:       for (i=1; i<lx; i++) z[i]=ldivgs((GEN)x[i],s);
                    602:       return z;
                    603:   }
                    604:   affsi(s,court); return gdiv(x,court);
                    605: }
                    606:
                    607: /*******************************************************************/
                    608: /*                                                                 */
1.2     ! noro      609: /*                    GENERIC REMAINDER                            */
1.1       noro      610: /*                                                                 */
                    611: /*******************************************************************/
1.2     ! noro      612: /* euclidean quotient for scalars of admissible types */
        !           613: static GEN
        !           614: _quot(GEN x, GEN y)
        !           615: {
        !           616:   GEN q = gdiv(x,y), f = gfloor(q);
        !           617:   if (gsigne(y) < 0 && !gegal(f,q)) f = gadd(f,gun);
        !           618:   return f;
        !           619: }
        !           620: static GEN
        !           621: quot(GEN x, GEN y)
        !           622: {
        !           623:   gpmem_t av = avma;
        !           624:   return gerepileupto(av, _quot(x, y));
        !           625: }
1.1       noro      626:
                    627: GEN
                    628: gmod(GEN x, GEN y)
                    629: {
1.2     ! noro      630:   gpmem_t av, tetpil;
        !           631:   long i,lx,ty, tx = typ(x);
1.1       noro      632:   GEN z,p1;
                    633:
                    634:   if (is_matvec_t(tx))
                    635:   {
1.2     ! noro      636:     lx=lg(x); z=cgetg(lx,tx);
        !           637:     for (i=1; i<lx; i++) z[i] = lmod((GEN)x[i],y);
1.1       noro      638:     return z;
                    639:   }
1.2     ! noro      640:   ty = typ(y);
1.1       noro      641:   switch(ty)
                    642:   {
                    643:     case t_INT:
                    644:       switch(tx)
                    645:       {
                    646:        case t_INT:
                    647:          return modii(x,y);
                    648:
                    649:        case t_INTMOD: z=cgetg(3,tx);
                    650:           z[1]=lmppgcd((GEN)x[1],y);
                    651:          z[2]=lmodii((GEN)x[2],(GEN)z[1]); return z;
                    652:
1.2     ! noro      653:         case t_FRACN:
        !           654:          av=avma; x = gred(x);
        !           655:           return gerepileupto(av, gmod(x,y));
        !           656:        case t_FRAC:
        !           657:          av=avma;
1.1       noro      658:          p1=mulii((GEN)x[1],mpinvmod((GEN)x[2],y));
                    659:          tetpil=avma; return gerepile(av,tetpil,modii(p1,y));
                    660:
                    661:        case t_QUAD: z=cgetg(4,tx);
                    662:           copyifstack(x[1],z[1]);
                    663:          z[2]=lmod((GEN)x[2],y);
                    664:           z[3]=lmod((GEN)x[3],y); return z;
                    665:
                    666:        case t_PADIC:
                    667:         {
1.2     ! noro      668:           long p1[] = {evaltyp(t_INTMOD)|_evallg(3),0,0};
1.1       noro      669:           p1[1] = (long)y;
                    670:           p1[2] = lgeti(lgefint(y));
                    671:           gaffect(x,p1); return (GEN)p1[2];
                    672:         }
                    673:        case t_POLMOD: case t_POL:
                    674:          return gzero;
1.2     ! noro      675:       /* case t_REAL could be defined as below, but conlicting semantic
        !           676:        * with lift(x * Mod(1,y)). */
1.1       noro      677:
1.2     ! noro      678:        default: err(operf,"%",x,y);
1.1       noro      679:       }
                    680:
                    681:     case t_REAL: case t_FRAC: case t_FRACN:
                    682:       switch(tx)
                    683:       {
                    684:        case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
1.2     ! noro      685:          av = avma;
        !           686:           return gerepileupto(av, gsub(x, gmul(_quot(x,y),y)));
1.1       noro      687:
                    688:        case t_POLMOD: case t_POL:
                    689:          return gzero;
                    690:
1.2     ! noro      691:        default: err(operf,"%",x,y);
1.1       noro      692:       }
                    693:
                    694:     case t_POL:
                    695:       if (is_scalar_t(tx))
                    696:       {
                    697:         if (tx!=t_POLMOD || varn(x[1]) > varn(y))
1.2     ! noro      698:           return degpol(y)? gcopy(x): gzero;
1.1       noro      699:        if (varn(x[1])!=varn(y)) return gzero;
                    700:         z=cgetg(3,t_POLMOD);
                    701:         z[1]=lgcd((GEN)x[1],y);
                    702:         z[2]=lres((GEN)x[2],(GEN)z[1]); return z;
                    703:       }
                    704:       switch(tx)
                    705:       {
                    706:        case t_POL:
                    707:          return gres(x,y);
                    708:
1.2     ! noro      709:         case t_RFRACN:
        !           710:          av=avma; return gerepileupto(av, gmod(gred_rfrac(x), y));
        !           711:        case t_RFRAC:
        !           712:          av=avma;
1.1       noro      713:          p1=gmul((GEN)x[1],ginvmod((GEN)x[2],y)); tetpil=avma;
                    714:           return gerepile(av,tetpil,gres(p1,y));
                    715:
                    716:         case t_SER:
                    717:           if (ismonome(y) && varn(x) == varn(y))
                    718:           {
                    719:             long d = degpol(y);
1.2     ! noro      720:             if (lg(x)-2 + valp(x) < d) err(operi,"%",x,y);
1.1       noro      721:             av = avma;
                    722:             return gerepileupto(av, gmod(gtrunc(x), y));
                    723:           }
1.2     ! noro      724:        default: err(operf,"%",x,y);
1.1       noro      725:       }
                    726:   }
1.2     ! noro      727:   err(operf,"%",x,y);
1.1       noro      728:   return NULL; /* not reached */
                    729: }
                    730:
                    731: GEN
                    732: gmodulsg(long x, GEN y)
                    733: {
                    734:   GEN z;
                    735:
                    736:   switch(typ(y))
                    737:   {
                    738:     case t_INT: z=cgetg(3,t_INTMOD);
                    739:       z[1]=labsi(y); z[2]=lmodsi(x,y); return z;
                    740:
                    741:     case t_POL: z=cgetg(3,t_POLMOD);
                    742:       z[1]=lcopy(y); z[2]=lstoi(x); return z;
                    743:   }
1.2     ! noro      744:   err(operf,"%",stoi(x),y); return NULL; /* not reached */
1.1       noro      745: }
                    746:
                    747: GEN
                    748: gmodulss(long x, long y)
                    749: {
                    750:   GEN z=cgetg(3,t_INTMOD);
                    751:
                    752:   y=labs(y); z[1]=lstoi(y); z[2]=lstoi(x % y); return z;
                    753: }
                    754:
                    755: static GEN
                    756: specialmod(GEN x, GEN y)
                    757: {
                    758:   GEN z = gmod(x,y);
                    759:   if (gvar(z) < varn(y)) z = gzero;
                    760:   return z;
                    761: }
                    762:
                    763: GEN
                    764: gmodulo(GEN x,GEN y)
                    765: {
                    766:   long tx=typ(x),l,i;
                    767:   GEN z;
                    768:
                    769:   if (is_matvec_t(tx))
                    770:   {
                    771:     l=lg(x); z=cgetg(l,tx);
                    772:     for (i=1; i<l; i++) z[i] = lmodulo((GEN)x[i],y);
                    773:     return z;
                    774:   }
                    775:   switch(typ(y))
                    776:   {
                    777:     case t_INT:
                    778:       if (tx!=t_INT && !is_frac_t(tx) && tx!=t_PADIC) break;
                    779:       z=cgetg(3,t_INTMOD);
                    780:       if (!signe(y)) err(talker,"zero modulus in gmodulo");
                    781:       y = gclone(y); setsigne(y,1);
                    782:       z[1]=(long)y;
                    783:       z[2]=lmod(x,y); return z;
                    784:
                    785:     case t_POL: z=cgetg(3,t_POLMOD);
                    786:       z[1] = lclone(y);
                    787:       if (is_scalar_t(tx)) { z[2]=lcopy(x); return z; }
                    788:       if (tx!=t_POL && !is_rfrac_t(tx) && tx!=t_SER) break;
                    789:       z[2]=(long)specialmod(x,y); return z;
                    790:   }
1.2     ! noro      791:   err(operf,"%",x,y); return NULL; /* not reached */
1.1       noro      792: }
                    793:
                    794: GEN
                    795: gmodulcp(GEN x,GEN y)
                    796: {
                    797:   long tx=typ(x),l,i;
                    798:   GEN z;
                    799:
                    800:   if (is_matvec_t(tx))
                    801:   {
                    802:     l=lg(x); z=cgetg(l,tx);
                    803:     for (i=1; i<l; i++) z[i] = lmodulcp((GEN)x[i],y);
                    804:     return z;
                    805:   }
                    806:   switch(typ(y))
                    807:   {
                    808:     case t_INT:
                    809:       if (tx!=t_INT && !is_frac_t(tx) && tx!=t_PADIC) break;
                    810:       z=cgetg(3,t_INTMOD);
                    811:       z[1]=labsi(y);
                    812:       z[2]=lmod(x,y); return z;
                    813:
                    814:     case t_POL: z=cgetg(3,t_POLMOD);
                    815:       z[1]=lcopy(y);
                    816:       if (is_scalar_t(tx))
                    817:       {
                    818:         z[2] = (lgef(y) > 3)? lcopy(x): lmod(x,y);
                    819:         return z;
                    820:       }
                    821:       if (tx!=t_POL && !is_rfrac_t(tx) && tx!=t_SER) break;
                    822:       z[2]=(long)specialmod(x,y); return z;
                    823:   }
1.2     ! noro      824:   err(operf,"%",x,y); return NULL; /* not reached */
1.1       noro      825: }
                    826:
                    827: GEN
                    828: Mod0(GEN x,GEN y,long flag)
                    829: {
                    830:   switch(flag)
                    831:   {
                    832:     case 0: return gmodulcp(x,y);
                    833:     case 1: return gmodulo(x,y);
                    834:     default: err(flagerr,"Mod");
                    835:   }
                    836:   return NULL; /* not reached */
                    837: }
                    838:
                    839: /*******************************************************************/
                    840: /*                                                                 */
1.2     ! noro      841: /*                 GENERIC EUCLIDEAN DIVISION                      */
1.1       noro      842: /*                                                                 */
                    843: /*******************************************************************/
                    844:
                    845: GEN
                    846: gdivent(GEN x, GEN y)
                    847: {
1.2     ! noro      848:   long tx = typ(x);
1.1       noro      849:
1.2     ! noro      850:   if (is_matvec_t(tx))
        !           851:   {
        !           852:     long i, lx = lg(x);
        !           853:     GEN z = cgetg(lx,tx);
        !           854:     for (i=1; i<lx; i++) z[i] = (long)gdivent((GEN)x[i],y);
        !           855:     return z;
        !           856:   }
        !           857:   switch(typ(y))
1.1       noro      858:   {
1.2     ! noro      859:     case t_INT:
        !           860:       switch(tx)
        !           861:       { /* equal to, but more efficient than, quot(x,y) */
        !           862:         case t_INT: return truedvmdii(x,y,NULL);
        !           863:         case t_REAL:
        !           864:         case t_FRAC:
        !           865:         case t_FRACN: return quot(x,y);
        !           866:         case t_POL: return gdiv(x,y);
        !           867:       }
        !           868:       break;
        !           869:     case t_REAL:
        !           870:     case t_FRAC:
        !           871:     case t_FRACN: return quot(x,y);
        !           872:     case t_POL:
        !           873:       if (is_scalar_t(tx))
        !           874:       {
        !           875:         if (tx == t_POLMOD) break;
        !           876:         return degpol(y)? gzero: gdiv(x,y);
        !           877:       }
        !           878:       if (tx == t_POL) return gdeuc(x,y);
1.1       noro      879:   }
1.2     ! noro      880:   err(operf,"\\",x,y);
        !           881:   return NULL; /* not reached */
        !           882: }
        !           883:
        !           884: /* with remainder */
        !           885: static GEN
        !           886: quotrem(GEN x, GEN y, GEN *r)
        !           887: {
        !           888:   gpmem_t av;
        !           889:   GEN q = quot(x,y);
        !           890:   av = avma;
        !           891:   *r = gerepileupto(av, gsub(x, gmul(q,y)));
        !           892:   return q;
1.1       noro      893: }
                    894:
                    895: GEN
                    896: gdiventres(GEN x, GEN y)
                    897: {
1.2     ! noro      898:   long tx = typ(x);
        !           899:   GEN z,q,r;
        !           900:
        !           901:   if (is_matvec_t(tx))
        !           902:   {
        !           903:     long i, lx = lg(x);
        !           904:     z = cgetg(lx,tx);
        !           905:     for (i=1; i<lx; i++) z[i] = (long)gdiventres((GEN)x[i],y);
        !           906:     return z;
        !           907:   }
        !           908:   z = cgetg(3,t_COL);
        !           909:   switch(typ(y))
        !           910:   {
        !           911:     case t_INT:
        !           912:       switch(tx)
        !           913:       { /* equal to, but more efficient than next case */
        !           914:         case t_INT:
        !           915:           z[1] = (long)truedvmdii(x,y,(GEN*)(z+2));
        !           916:           return z;
        !           917:         case t_REAL:
        !           918:         case t_FRAC:
        !           919:         case t_FRACN:
        !           920:           q = quotrem(x,y,&r);
        !           921:           z[1] = (long)q;
        !           922:           z[2] = (long)r; return z;
        !           923:         case t_POL: return gdiv(x,y);
        !           924:       }
        !           925:       break;
        !           926:     case t_REAL:
        !           927:     case t_FRAC:
        !           928:     case t_FRACN:
        !           929:           q = quotrem(x,y,&r);
        !           930:           z[1] = (long)q;
        !           931:           z[2] = (long)r; return z;
        !           932:     case t_POL:
        !           933:       if (is_scalar_t(tx))
        !           934:       {
        !           935:         if (tx == t_POLMOD) break;
        !           936:         if (degpol(y))
        !           937:         {
        !           938:           q = gzero;
        !           939:           r = gcopy(x);
        !           940:         }
        !           941:         else
        !           942:         {
        !           943:           q = gdiv(x,y);
        !           944:           r = gzero;
        !           945:         }
        !           946:         return q;
        !           947:       }
        !           948:       if (tx == t_POL)
        !           949:       {
        !           950:         z[1]=ldivres(x,y,(GEN *)(z+2));
        !           951:         return z;
        !           952:       }
        !           953:   }
        !           954:   err(operf,"\\",x,y);
        !           955:   return NULL; /* not reached */
        !           956: }
        !           957:
        !           958: extern GEN swap_vars(GEN b0, long v);
        !           959:
        !           960: GEN
        !           961: divrem(GEN x, GEN y, long v)
        !           962: {
        !           963:   gpmem_t av = avma;
        !           964:   long vx,vy;
        !           965:   GEN z,q,r;
        !           966:   if (v < 0 || typ(y) != t_POL || typ(x) != t_POL) return gdiventres(x,y);
        !           967:   vx = varn(x); if (vx != v) x = swap_vars(x,v);
        !           968:   vy = varn(y); if (vy != v) y = swap_vars(y,v);
        !           969:   q = poldivres(x,y, &r);
        !           970:   if (v && (vx != v || vy != v))
        !           971:   {
        !           972:     q = poleval(q, polx[v]);
        !           973:     r = poleval(r, polx[v]);
        !           974:   }
        !           975:   z = cgetg(3,t_COL);
        !           976:   z[1] = (long)q;
        !           977:   z[2] = (long)r; return gerepilecopy(av, z);
        !           978: }
        !           979:
        !           980: static int
        !           981: is_scal(long t) { return t==t_INT || t==t_FRAC || t==t_FRACN; }
        !           982:
        !           983: GEN
        !           984: diviiround(GEN x, GEN y)
        !           985: {
        !           986:   gpmem_t av1, av = avma;
        !           987:   GEN q,r;
        !           988:   int fl;
        !           989:
        !           990:   q = dvmdii(x,y,&r); /* q = x/y rounded towards 0, sgn(r)=sgn(x) */
        !           991:   if (r==gzero) return q;
        !           992:   av1 = avma;
        !           993:   fl = absi_cmp(shifti(r,1),y);
        !           994:   avma = av1; cgiv(r);
        !           995:   if (fl >= 0) /* If 2*|r| >= |y| */
        !           996:   {
        !           997:     long sz = signe(x)*signe(y);
        !           998:     if (fl || sz > 0) q = gerepileuptoint(av, addis(q,sz));
        !           999:   }
        !          1000:   return q;
        !          1001: }
        !          1002:
        !          1003: /* If x and y are not both scalars, same as gdivent.
        !          1004:  * Otherwise, compute the quotient x/y, rounded to the nearest integer
        !          1005:  * (towards +oo in case of tie). */
        !          1006: GEN
        !          1007: gdivround(GEN x, GEN y)
        !          1008: {
        !          1009:   gpmem_t av1, av;
1.1       noro     1010:   long tx=typ(x),ty=typ(y);
1.2     ! noro     1011:   GEN q,r;
        !          1012:   int fl;
1.1       noro     1013:
1.2     ! noro     1014:   if (tx==t_INT && ty==t_INT) return diviiround(x,y);
        !          1015:   av = avma;
        !          1016:   if (is_scal(tx) && is_scal(ty))
        !          1017:   { /* same as diviiround but less efficient */
        !          1018:     q = quotrem(x,y,&r);
        !          1019:     av1 = avma;
        !          1020:     fl = gcmp(gmul2n(gabs(r,0),1), gabs(y,0));
        !          1021:     avma = av1; cgiv(r);
        !          1022:     if (fl >= 0) /* If 2*|r| >= |y| */
1.1       noro     1023:     {
1.2     ! noro     1024:       long sz = gsigne(y);
        !          1025:       if (fl || sz > 0) q = gerepileupto(av, gaddgs(q, sz));
1.1       noro     1026:     }
1.2     ! noro     1027:     return q;
1.1       noro     1028:   }
1.2     ! noro     1029:   if (is_matvec_t(tx))
1.1       noro     1030:   {
1.2     ! noro     1031:     long i,lx = lg(x);
        !          1032:     GEN z = cgetg(lx,tx);
        !          1033:     for (i=1; i<lx; i++) z[i] = (long)gdivround((GEN)x[i],y);
1.1       noro     1034:     return z;
                   1035:   }
1.2     ! noro     1036:   return gdivent(x,y);
1.1       noro     1037: }
                   1038:
                   1039: GEN
                   1040: gdivmod(GEN x, GEN y, GEN *pr)
                   1041: {
                   1042:   long ty,tx=typ(x);
                   1043:
                   1044:   if (tx==t_INT)
                   1045:   {
                   1046:     ty=typ(y);
                   1047:     if (ty==t_INT) return dvmdii(x,y,pr);
                   1048:     if (ty==t_POL) { *pr=gcopy(x); return gzero; }
                   1049:     err(typeer,"gdivmod");
                   1050:   }
                   1051:   if (tx!=t_POL) err(typeer,"gdivmod");
                   1052:   return poldivres(x,y,pr);
                   1053: }
                   1054:
                   1055: /*******************************************************************/
                   1056: /*                                                                 */
                   1057: /*                       SHIFT D'UN GEN                            */
                   1058: /*                                                                 */
                   1059: /*******************************************************************/
                   1060:
                   1061: /* Shift tronque si n<0 (multiplication tronquee par 2^n)  */
                   1062: GEN
                   1063: gshift(GEN x, long n)
                   1064: {
1.2     ! noro     1065:   return gshift3(x, n, 0);
        !          1066: }
        !          1067:
        !          1068: GEN
        !          1069: gshift3(GEN x, long n, long flag)
        !          1070: {
1.1       noro     1071:   long i,l,lx, tx = typ(x);
                   1072:   GEN y;
                   1073:
                   1074:   switch(tx)
                   1075:   {
                   1076:     case t_INT:
1.2     ! noro     1077:       return shifti3(x,n,flag);
1.1       noro     1078:     case t_REAL:
                   1079:       return shiftr(x,n);
                   1080:
                   1081:     case t_VEC: case t_COL: case t_MAT:
                   1082:       lx=lg(x); y=cgetg(lx,tx); l=lontyp[tx];
                   1083:       for (i=1; i<l ; i++) y[i]=x[i];
                   1084:       for (   ; i<lx; i++) y[i]=lshift((GEN)x[i],n);
                   1085:       return y;
                   1086:   }
                   1087:   return gmul2n(x,n);
                   1088: }
                   1089:
                   1090: extern GEN mulscalrfrac(GEN x, GEN y);
                   1091:
                   1092: /* Shift vrai (multiplication exacte par 2^n) */
                   1093: GEN
                   1094: gmul2n(GEN x, long n)
                   1095: {
1.2     ! noro     1096:   long tx, lx, i, k, l;
        !          1097:   gpmem_t av, tetpil;
1.1       noro     1098:   GEN p2,p1,y;
                   1099:
                   1100:   tx=typ(x);
                   1101:   switch(tx)
                   1102:   {
                   1103:     case t_INT:
                   1104:       if (n>=0) return shifti(x,n);
                   1105:       if (!signe(x)) return gzero;
                   1106:       l = vali(x); n = -n;
                   1107:       if (n<=l) return shifti(x,-n);
                   1108:       y=cgetg(3,t_FRAC);
                   1109:       y[1]=lshifti(x,-l);
                   1110:       y[2]=lshifti(gun,n-l); return y;
                   1111:
                   1112:     case t_REAL:
                   1113:       return shiftr(x,n);
                   1114:
                   1115:     case t_INTMOD:
                   1116:       if (n > 0)
                   1117:       {
                   1118:         y=cgetg(3,t_INTMOD); p2=(GEN)x[1];
1.2     ! noro     1119:         av=avma; (void)new_chunk(2 * lgefint(p2) + n); /* HACK */
1.1       noro     1120:         p1 = shifti((GEN)x[2],n); avma=av;
                   1121:         y[2]=lmodii(p1,p2); icopyifstack(p2,y[1]); return y;
                   1122:       }
1.2     ! noro     1123:       av=avma; y=gmul2n(gun,n); tetpil=avma;
        !          1124:       return gerepile(av,tetpil,gmul(y,x));
1.1       noro     1125:
                   1126:     case t_FRAC: case t_FRACN:
                   1127:       l = vali((GEN)x[1]);
                   1128:       k = vali((GEN)x[2]);
                   1129:       if (n+l-k>=0)
                   1130:       {
                   1131:         if (expi((GEN)x[2]) == k) /* x[2] power of 2 */
                   1132:           return shifti((GEN)x[1],n-k);
                   1133:         l = n-k; k = -k;
                   1134:       }
                   1135:       else
                   1136:       {
                   1137:         k = -l-n; l = -l;
                   1138:       }
                   1139:       y=cgetg(3,t_FRAC);
                   1140:       y[1]=lshifti((GEN)x[1],l);
                   1141:       y[2]=lshifti((GEN)x[2],k); return y;
                   1142:
                   1143:     case t_QUAD: y=cgetg(4,t_QUAD);
                   1144:       copyifstack(x[1],y[1]);
                   1145:       for (i=2; i<4; i++) y[i]=lmul2n((GEN)x[i],n);
                   1146:       return y;
                   1147:
                   1148:     case t_POLMOD: y=cgetg(3,t_POLMOD);
                   1149:       copyifstack(x[1],y[1]);
                   1150:       y[2]=lmul2n((GEN)x[2],n); return y;
                   1151:
                   1152:     case t_POL: case t_COMPLEX: case t_SER:
                   1153:     case t_VEC: case t_COL: case t_MAT:
                   1154:       lx = (tx==t_POL)? lgef(x): lg(x);
                   1155:       y=cgetg(lx,tx); l=lontyp[tx];
                   1156:       for (i=1; i<l ; i++) y[i]=x[i];
                   1157:       for (   ; i<lx; i++) y[i]=lmul2n((GEN)x[i],n);
                   1158:       return y;
                   1159:
                   1160:     case t_RFRAC: av=avma; p1 = gmul2n(gun,n); tetpil = avma;
                   1161:       return gerepile(av,tetpil, mulscalrfrac(p1,x));
                   1162:
                   1163:     case t_RFRACN: y=cgetg(3,tx);
                   1164:       if (n>=0)
                   1165:       {
                   1166:         y[1]=lmul2n((GEN)x[1],n);  y[2]=lcopy((GEN)x[2]);
                   1167:       }
                   1168:       else
                   1169:       {
                   1170:         y[2]=lmul2n((GEN)x[2],-n); y[1]=lcopy((GEN)x[1]);
                   1171:       }
                   1172:       return y;
                   1173:
                   1174:     case t_PADIC:
1.2     ! noro     1175:       av=avma; y=gmul2n(gun,n); tetpil=avma;
        !          1176:       return gerepile(av,tetpil,gmul(y,x));
1.1       noro     1177:   }
                   1178:   err(typeer,"gmul2n");
                   1179:   return NULL; /* not reached */
                   1180: }
                   1181:
1.2     ! noro     1182: GEN
        !          1183: real2n(long n, long prec) { GEN z = realun(prec); setexpo(z, n); return z; }
        !          1184:
1.1       noro     1185: /*******************************************************************/
                   1186: /*                                                                 */
                   1187: /*                      INVERSE D'UN GEN                           */
                   1188: /*                                                                 */
                   1189: /*******************************************************************/
                   1190: extern GEN fix_rfrac_if_pol(GEN x, GEN y);
                   1191:
                   1192: GEN
                   1193: ginv(GEN x)
                   1194: {
1.2     ! noro     1195:   long tx=typ(x), s;
        !          1196:   gpmem_t av, tetpil;
1.1       noro     1197:   GEN z,y,p1,p2;
                   1198:
                   1199:   switch(tx)
                   1200:   {
                   1201:     case t_INT:
                   1202:       if (is_pm1(x)) return icopy(x);
                   1203:       if (!signe(x)) err(gdiver2);
                   1204:       z=cgetg(3,t_FRAC);
                   1205:       z[1] = (signe(x)<0)? lnegi(gun): un;
                   1206:       z[2]=labsi(x); return z;
                   1207:
                   1208:     case t_REAL:
                   1209:       return divsr(1,x);
                   1210:
                   1211:     case t_INTMOD: z=cgetg(3,t_INTMOD);
                   1212:       icopyifstack(x[1],z[1]);
                   1213:       z[2]=lmpinvmod((GEN)x[2],(GEN)x[1]); return z;
                   1214:
                   1215:     case t_FRAC: case t_FRACN:
                   1216:       s = signe(x[1]);
                   1217:       if (!s) err(gdiver2);
                   1218:       if (is_pm1(x[1]))
                   1219:         return s>0? icopy((GEN)x[2]): negi((GEN)x[2]);
                   1220:       z = cgetg(3,tx);
                   1221:       z[1] = licopy((GEN)x[2]);
                   1222:       z[2] = licopy((GEN)x[1]);
                   1223:       if (s < 0)
                   1224:       {
                   1225:        setsigne(z[1],-signe(z[1]));
                   1226:        setsigne(z[2],1);
                   1227:       }
                   1228:       return z;
                   1229:
                   1230:     case t_COMPLEX: case t_QUAD:
                   1231:       av=avma; p1=gnorm(x); p2=gconj(x); tetpil=avma;
                   1232:       return gerepile(av,tetpil,gdiv(p2,p1));
                   1233:
                   1234:     case t_PADIC: z = cgetg(5,t_PADIC);
                   1235:       if (!signe(x[4])) err(gdiver2);
                   1236:       z[1] = evalprecp(precp(x)) | evalvalp(-valp(x));
                   1237:       icopyifstack(x[2], z[2]);
                   1238:       z[3] = licopy((GEN)x[3]);
                   1239:       z[4] = lmpinvmod((GEN)x[4],(GEN)z[3]); return z;
                   1240:
                   1241:     case t_POLMOD: z=cgetg(3,t_POLMOD);
                   1242:       copyifstack(x[1],z[1]);
                   1243:       z[2]=linvmod((GEN)x[2],(GEN)x[1]); return z;
                   1244:
                   1245:     case t_POL: case t_SER:
                   1246:       return gdiv(gun,x);
                   1247:
                   1248:     case t_RFRAC: case t_RFRACN:
                   1249:       if (gcmp0((GEN) x[1])) err(gdiver2);
                   1250:       p1 = fix_rfrac_if_pol((GEN)x[2],(GEN)x[1]);
                   1251:       if (p1) return p1;
                   1252:       z=cgetg(3,tx);
                   1253:       z[1]=lcopy((GEN)x[2]);
                   1254:       z[2]=lcopy((GEN)x[1]); return z;
                   1255:
                   1256:     case t_QFR:
                   1257:     {
                   1258:       long k,l;
                   1259:       l=signe(x[2]); setsigne(x[2],-l);
                   1260:       k=signe(x[4]); setsigne(x[4],-k); z=redreal(x);
                   1261:       setsigne(x[2],l); setsigne(x[4],k); return z;
                   1262:     }
                   1263:     case t_QFI:
                   1264:       y=gcopy(x);
                   1265:       if (!egalii((GEN)x[1],(GEN)x[2]) && !egalii((GEN)x[1],(GEN)x[3]))
                   1266:        setsigne(y[2],-signe(y[2]));
                   1267:       return y;
                   1268:     case t_MAT:
                   1269:       return (lg(x)==1)? cgetg(1,t_MAT): invmat(x);
1.2     ! noro     1270:     case t_VECSMALL:
        !          1271:     {
        !          1272:       long i,lx = lg(x);
        !          1273:       y = cgetg(lx,t_VECSMALL);
        !          1274:       for (i=1; i<lx; i++)
        !          1275:       {
        !          1276:         long xi=x[i];
        !          1277:          if (xi<1 || xi>=lx) err(talker,"incorrect permtuation to inverse");
        !          1278:         y[xi] = i;
        !          1279:       }
        !          1280:       return y;
        !          1281:     }
1.1       noro     1282:   }
                   1283:   err(typeer,"inverse");
                   1284:   return NULL; /* not reached */
                   1285: }
                   1286:
                   1287: /*******************************************************************/
                   1288: /*                                                                 */
                   1289: /*           SUBSTITUTION DANS UN POLYNOME OU UNE SERIE            */
                   1290: /*                                                                 */
                   1291: /*******************************************************************/
                   1292:
                   1293: /* Convert t_SER --> t_POL / t_RFRAC */
                   1294: static GEN
                   1295: gconvsp(GEN x, int flpile)
                   1296: {
1.2     ! noro     1297:   long v = varn(x), i;
        !          1298:   gpmem_t av, tetpil;
1.1       noro     1299:   GEN p1,y;
                   1300:
                   1301:   if (gcmp0(x)) return zeropol(v);
                   1302:   av=avma; y=dummycopy(x); settyp(y,t_POL);
                   1303:   i=lg(x)-1; while (i>1 && gcmp0((GEN)y[i])) i--;
                   1304:   setlgef(y,i+1);
1.2     ! noro     1305:   p1=gpowgs(polx[v],valp(x));
1.1       noro     1306:   tetpil=avma; p1=gmul(p1,y);
                   1307:   return flpile? gerepile(av,tetpil,p1): p1;
                   1308: }
                   1309:
                   1310: GEN
                   1311: gsubst0(GEN x, GEN T, GEN y)
                   1312: {
1.2     ! noro     1313:   gpmem_t av;
1.1       noro     1314:   long d, v;
                   1315:   if (typ(T) != t_POL || !ismonome(T) || !gcmp1(leading_term(T)))
                   1316:     err(talker,"variable number expected in subst");
                   1317:   d = degpol(T); v = varn(T);
                   1318:   if (d == 1) return gsubst(x, v, y);
                   1319:   av = avma;
                   1320:   return gerepilecopy(av, gsubst(gdeflate(x, v, d), v, y));
                   1321: }
                   1322:
                   1323: GEN
                   1324: gsubst(GEN x, long v, GEN y)
                   1325: {
                   1326:   long tx = typ(x), ty = typ(y), lx = lg(x), ly = lg(y);
1.2     ! noro     1327:   long l, vx, vy, e, ex, ey, i, j, k, jb;
        !          1328:   gpmem_t tetpil, av, limite;
1.1       noro     1329:   GEN t,p1,p2,z;
                   1330:
                   1331:   if (ty==t_MAT)
                   1332:   {
                   1333:     if (ly==1) return cgetg(1,t_MAT);
                   1334:     if (ly != lg(y[1]))
                   1335:       err(talker,"forbidden substitution by a non square matrix");
                   1336:   } else if (is_graphicvec_t(ty))
                   1337:     err(talker,"forbidden substitution by a vector");
                   1338:
                   1339:   if (is_scalar_t(tx))
                   1340:   {
                   1341:     if (tx!=t_POLMOD || v <= varn(x[1]))
                   1342:     {
                   1343:       if (ty==t_MAT) return gscalmat(x,ly-1);
                   1344:       return gcopy(x);
                   1345:     }
                   1346:     av=avma;
                   1347:     p1=gsubst((GEN)x[1],v,y); vx=varn(p1);
                   1348:     p2=gsubst((GEN)x[2],v,y); vy=gvar(p2);
                   1349:     if (typ(p1)!=t_POL)
                   1350:       err(talker,"forbidden substitution in a scalar type");
                   1351:     if (vy>=vx)
                   1352:     {
                   1353:       tetpil=avma;
                   1354:       return gerepile(av,tetpil,gmodulcp(p2,p1));
                   1355:     }
                   1356:     lx=lgef(p2); tetpil=avma; z=cgetg(lx,t_POL); z[1]=p2[1];
                   1357:     for (i=2; i<lx; i++) z[i]=lmodulcp((GEN)p2[i],p1);
                   1358:     return gerepile(av,tetpil, normalizepol_i(z,lx));
                   1359:   }
                   1360:
                   1361:   switch(tx)
                   1362:   {
                   1363:     case t_POL:
1.2     ! noro     1364:       l = lgef(x);
1.1       noro     1365:       if (l==2)
                   1366:         return (ty==t_MAT)? gscalmat(gzero,ly-1): gzero;
                   1367:
1.2     ! noro     1368:       vx = varn(x);
        !          1369:       if (vx < v)
1.1       noro     1370:       {
1.2     ! noro     1371:         if (gvar(y) > vx)
        !          1372:         { /* easy special case */
        !          1373:           z = cgetg(l, t_POL); z[1] = x[1];
        !          1374:           for (i=2; i<l; i++) z[i] = lsubst((GEN)x[i],v,y);
        !          1375:           return normalizepol_i(z,l);
        !          1376:         }
        !          1377:         /* general case */
1.1       noro     1378:        av=avma; p1=polx[vx]; z= gsubst((GEN)x[l-1],v,y);
                   1379:        for (i=l-1; i>2; i--) z=gadd(gmul(z,p1),gsubst((GEN)x[i-1],v,y));
                   1380:        return gerepileupto(av,z);
                   1381:       }
1.2     ! noro     1382:       /* v <= vx */
1.1       noro     1383:       if (ty!=t_MAT)
1.2     ! noro     1384:         return (vx > v)? gcopy(x): poleval(x,y);
1.1       noro     1385:
1.2     ! noro     1386:       if (vx > v) return gscalmat(x,ly-1);
1.1       noro     1387:       if (l==3) return gscalmat((GEN)x[2],ly-1);
                   1388:       av=avma; z=(GEN)x[l-1];
                   1389:       for (i=l-1; i>2; i--) z=gaddmat((GEN)x[i-1],gmul(z,y));
                   1390:       return gerepileupto(av,z);
                   1391:
                   1392:     case t_SER:
                   1393:       vx=varn(x);
                   1394:       if (vx > v)
                   1395:         return (ty==t_MAT)? gscalmat(x,ly-1): gcopy(x);
                   1396:       ex = valp(x);
                   1397:       if (vx < v)
                   1398:       {
                   1399:         if (!signe(x)) return gcopy(x);
                   1400:         /* a ameliorer */
                   1401:         av=avma; setvalp(x,0); p1=gconvsp(x,0); setvalp(x,ex);
                   1402:         p2=gsubst(p1,v,y); tetpil=avma; z=tayl(p2,vx,lx-2);
                   1403:         if (ex)
                   1404:         {
1.2     ! noro     1405:           p1=gpowgs(polx[vx],ex); tetpil=avma; z=gmul(z,p1);
1.1       noro     1406:         }
                   1407:         return gerepile(av,tetpil,z);
                   1408:       }
                   1409:       switch(ty) /* here vx == v */
                   1410:       {
                   1411:         case t_SER:
                   1412:          ey=valp(y); vy=varn(y);
                   1413:          if (ey<1) return zeroser(vy,ey*(ex+lx-2));
                   1414:          l=(lx-2)*ey+2;
                   1415:          if (ex) { if (l>ly) l=ly; }
                   1416:          else
                   1417:          {
                   1418:            if (gcmp0(y)) l=ey+2;
                   1419:            else { if (l>ly) l=ey+ly; }
                   1420:          }
                   1421:          if (vy!=vx)
                   1422:          {
                   1423:            av=avma; z = zeroser(vy,0);
                   1424:            for (i=lx-1; i>=2; i--)
                   1425:               z = gadd((GEN)x[i], gmul(y,z));
1.2     ! noro     1426:            if (ex) z = gmul(z, gpowgs(y,ex));
1.1       noro     1427:            return gerepileupto(av,z);
                   1428:          }
                   1429:
                   1430:          av=avma; limite=stack_lim(av,1);
                   1431:           t=cgetg(ly,t_SER);
                   1432:           z = scalarser((GEN)x[2],varn(y),l-2);
                   1433:          for (i=2; i<ly; i++) t[i]=y[i];
                   1434:
                   1435:          for (i=3,jb=ey; jb<=l-2; i++,jb+=ey)
                   1436:          {
                   1437:            for (j=jb+2; j<l; j++)
                   1438:            {
                   1439:              p1=gmul((GEN)x[i],(GEN)t[j-jb]);
                   1440:              z[j]=ladd((GEN)z[j],p1);
                   1441:            }
                   1442:            for (j=l-1-jb-ey; j>1; j--)
                   1443:            {
                   1444:              p1=gzero;
                   1445:              for (k=2; k<j; k++)
                   1446:                p1=gadd(p1,gmul((GEN)t[j-k+2],(GEN)y[k]));
                   1447:              p2=gmul((GEN)t[2],(GEN)y[j]);
                   1448:              t[j]=ladd(p1,p2);
                   1449:            }
                   1450:             if (low_stack(limite, stack_lim(av,1)))
                   1451:            {
                   1452:              GEN *gptr[2];
                   1453:              if(DEBUGMEM>1) err(warnmem,"gsubst");
                   1454:              gptr[0]=&z; gptr[1]=&t; gerepilemany(av,gptr,2);
                   1455:            }
                   1456:          }
                   1457:          if (!ex) return gerepilecopy(av,z);
                   1458:
1.2     ! noro     1459:           if (l<ly) { setlg(y,l); p1=gpowgs(y,ex); setlg(y,ly); }
        !          1460:           else p1=gpowgs(y,ex);
1.1       noro     1461:           tetpil=avma; return gerepile(av,tetpil,gmul(z,p1));
                   1462:
                   1463:         case t_POL: case t_RFRAC: case t_RFRACN:
                   1464:           if (isexactzero(y)) return scalarser((GEN)x[2],v,lx-2);
                   1465:           vy=gvar(y); e=gval(y,vy);
                   1466:           if (e<=0)
                   1467:             err(talker,"non positive valuation in a series substitution");
                   1468:          av=avma; p1=gconvsp(x,0); p2=gsubst(p1,v,y); tetpil=avma;
                   1469:          return gerepile(av,tetpil,tayl(p2,vy,e*(lx-2+ex)));
                   1470:
                   1471:         default:
                   1472:           err(talker,"non polynomial or series type substituted in a series");
                   1473:       }
                   1474:       break;
                   1475:
                   1476:     case t_RFRAC: case t_RFRACN: av=avma;
                   1477:       p1=gsubst((GEN)x[1],v,y);
                   1478:       p2=gsubst((GEN)x[2],v,y); tetpil=avma;
                   1479:       return gerepile(av,tetpil,gdiv(p1,p2));
                   1480:
                   1481:     case t_VEC: case t_COL: case t_MAT: z=cgetg(lx,tx);
                   1482:       for (i=1; i<lx; i++) z[i]=lsubst((GEN)x[i],v,y);
1.2     ! noro     1483:       return z;
1.1       noro     1484:   }
1.2     ! noro     1485:   return gcopy(x);
1.1       noro     1486: }
                   1487:
                   1488: /*******************************************************************/
                   1489: /*                                                                 */
                   1490: /*                SERIE RECIPROQUE D'UNE SERIE                     */
                   1491: /*                                                                 */
                   1492: /*******************************************************************/
                   1493:
                   1494: GEN
                   1495: recip(GEN x)
                   1496: {
1.2     ! noro     1497:   long v=varn(x), lx = lg(x);
        !          1498:   gpmem_t tetpil, av=avma;
1.1       noro     1499:   GEN p1,p2,a,y,u;
                   1500:
                   1501:   if (typ(x)!=t_SER) err(talker,"not a series in serreverse");
1.2     ! noro     1502:   if (valp(x)!=1 || lx < 3)
        !          1503:     err(talker,"valuation not equal to 1 in serreverse");
1.1       noro     1504:
                   1505:   a=(GEN)x[2];
                   1506:   if (gcmp1(a))
                   1507:   {
1.2     ! noro     1508:     long i, j, k, mi;
        !          1509:     gpmem_t lim=stack_lim(av, 2);
1.1       noro     1510:
1.2     ! noro     1511:     mi = lx-1; while (mi>=3 && gcmp0((GEN)x[mi])) mi--;
        !          1512:     u = cgetg(lx,t_SER);
        !          1513:     y = cgetg(lx,t_SER);
        !          1514:     u[1] = y[1] = evalsigne(1) | evalvalp(1) | evalvarn(v);
        !          1515:     u[2] = y[2] = un;
        !          1516:     if (lx > 3)
        !          1517:     {
        !          1518:       u[3] = lmulsg(-2,(GEN)x[3]);
        !          1519:       y[3] = lneg((GEN)x[3]);
        !          1520:     }
1.1       noro     1521:     for (i=3; i<lx-1; )
                   1522:     {
                   1523:       for (j=3; j<i+1; j++)
                   1524:       {
1.2     ! noro     1525:         p1 = (GEN)x[j];
        !          1526:         for (k=max(3,j+2-mi); k<j; k++)
        !          1527:           p1 = gadd(p1, gmul((GEN)u[k],(GEN)x[j-k+2]));
        !          1528:         u[j] = lsub((GEN)u[j], p1);
        !          1529:       }
        !          1530:       p1 = gmulsg(i,(GEN)x[i+1]);
        !          1531:       for (k=2; k<min(i,mi); k++)
        !          1532:       {
        !          1533:         p2 = gmul((GEN)x[k+1],(GEN)u[i-k+2]);
        !          1534:         p1 = gadd(p1, gmulsg(k,p2));
        !          1535:       }
        !          1536:       i++;
        !          1537:       u[i] = lneg(p1);
        !          1538:       y[i] = ldivgs((GEN)u[i],i-1);
1.1       noro     1539:       if (low_stack(lim, stack_lim(av,2)))
                   1540:       {
                   1541:        GEN *gptr[2];
                   1542:        if(DEBUGMEM>1) err(warnmem,"recip");
                   1543:        for(k=i+1; k<lx; k++) u[k]=y[k]=zero; /* dummy */
                   1544:        gptr[0]=&u; gptr[1]=&y; gerepilemany(av,gptr,2);
                   1545:       }
                   1546:     }
                   1547:     return gerepilecopy(av,y);
                   1548:   }
1.2     ! noro     1549:   y = gdiv(x,a); y[2] = un; y = recip(y);
        !          1550:   a = gdiv(polx[v],a); tetpil = avma;
        !          1551:   return gerepile(av,tetpil, gsubst(y,v,a));
1.1       noro     1552: }
                   1553:
                   1554: /*******************************************************************/
                   1555: /*                                                                 */
                   1556: /*                    DERIVATION ET INTEGRATION                    */
                   1557: /*                                                                 */
                   1558: /*******************************************************************/
                   1559: GEN
                   1560: derivpol(GEN x)
                   1561: {
                   1562:   long i,lx = lgef(x)-1;
                   1563:   GEN y;
                   1564:
1.2     ! noro     1565:   if (lx<3) return zeropol(varn(x));
1.1       noro     1566:   y = cgetg(lx,t_POL);
                   1567:   for (i=2; i<lx ; i++) y[i] = lmulsg(i-1,(GEN)x[i+1]);
                   1568:   y[1] = x[1]; return normalizepol_i(y,i);
                   1569: }
                   1570:
                   1571: GEN
                   1572: derivser(GEN x)
                   1573: {
                   1574:   long i,j,vx = varn(x), e = valp(x), lx = lg(x);
                   1575:   GEN y;
1.2     ! noro     1576:   if (gcmp0(x)) return zeroser(vx,e? e-1: 0);
1.1       noro     1577:   if (e)
                   1578:   {
                   1579:     y=cgetg(lx,t_SER); y[1] = evalsigne(1) | evalvalp(e-1) | evalvarn(vx);
                   1580:     for (i=2; i<lx; i++) y[i]=lmulsg(i+e-2,(GEN)x[i]);
                   1581:     return y;
                   1582:   }
                   1583:   i=3; while (i<lx && gcmp0((GEN)x[i])) i++;
                   1584:   if (i==lx) return zeroser(vx,lx-3);
                   1585:   lx--; if (lx<3) lx=3;
                   1586:   lx = lx-i+3; y=cgetg(lx,t_SER);
                   1587:   y[1]=evalsigne(1) | evalvalp(i-3) | evalvarn(vx);
                   1588:   for (j=2; j<lx; j++) y[j]=lmulsg(j+i-4,(GEN)x[i+j-2]);
                   1589:   return y;
                   1590: }
                   1591:
                   1592: GEN
                   1593: deriv(GEN x, long v)
                   1594: {
1.2     ! noro     1595:   long lx, vx, tx, e, i, j;
        !          1596:   gpmem_t av, tetpil;
1.1       noro     1597:   GEN y,p1,p2;
                   1598:
                   1599:   tx=typ(x); if (is_const_t(tx)) return gzero;
                   1600:   if (v < 0) v = gvar(x);
                   1601:   switch(tx)
                   1602:   {
                   1603:     case t_POLMOD:
                   1604:       if (v<=varn(x[1])) return gzero;
                   1605:       y=cgetg(3,t_POLMOD); copyifstack(x[1],y[1]);
                   1606:       y[2]=lderiv((GEN)x[2],v); return y;
                   1607:
                   1608:     case t_POL:
                   1609:       vx=varn(x); if (vx>v) return gzero;
                   1610:       if (vx<v)
                   1611:       {
                   1612:         lx = lgef(x);
                   1613:         y = cgetg(lx,t_POL);
                   1614:         for (i=2; i<lx; i++) y[i] = lderiv((GEN)x[i],v);
                   1615:         y[1] = evalvarn(vx);
                   1616:         return normalizepol_i(y,i);
                   1617:       }
                   1618:       return derivpol(x);
                   1619:
                   1620:     case t_SER:
                   1621:       vx=varn(x); if (vx>v) return gzero;
                   1622:       if (vx<v)
                   1623:       {
                   1624:         if (!signe(x)) return gcopy(x);
                   1625:         lx=lg(x); e=valp(x);
1.2     ! noro     1626:        av=avma;
1.1       noro     1627:        for (i=2; i<lx; i++)
                   1628:         {
                   1629:           if (!gcmp0(deriv((GEN)x[i],v))) break;
1.2     ! noro     1630:           avma=av;
1.1       noro     1631:         }
                   1632:        if (i==lx) return ggrando(polx[vx],e+lx-2);
                   1633:        y=cgetg(lx-i+2,t_SER);
                   1634:         y[1] = evalsigne(1) | evalvalp(e+i-2) | evalvarn(vx);
                   1635:        for (j=2; i<lx; j++,i++) y[j]=lderiv((GEN)x[i],v);
                   1636:         return y;
                   1637:       }
                   1638:       return derivser(x);
                   1639:
                   1640:     case t_RFRAC: case t_RFRACN: av=avma; y=cgetg(3,tx);
1.2     ! noro     1641:       y[2]=lsqr((GEN)x[2]); av=avma;
1.1       noro     1642:       p1=gmul((GEN)x[2],deriv((GEN)x[1],v));
                   1643:       p2=gmul(gneg_i((GEN)x[1]),deriv((GEN)x[2],v));
                   1644:       tetpil=avma; p1=gadd(p1,p2);
1.2     ! noro     1645:       if (tx==t_RFRACN) { y[1]=lpile(av,tetpil,p1); return y; }
1.1       noro     1646:       y[1]=(long)p1; return gerepileupto(av,gred_rfrac(y));
                   1647:
                   1648:     case t_VEC: case t_COL: case t_MAT: lx=lg(x); y=cgetg(lx,tx);
                   1649:       for (i=1; i<lx; i++) y[i]=lderiv((GEN)x[i],v);
                   1650:       return y;
                   1651:   }
                   1652:   err(typeer,"deriv");
                   1653:   return NULL; /* not reached */
                   1654: }
                   1655:
                   1656: /*******************************************************************/
                   1657: /*                                                                 */
                   1658: /*                    INTEGRATION FORMELLE                         */
                   1659: /*                                                                 */
                   1660: /*******************************************************************/
                   1661:
                   1662: static GEN
                   1663: triv_integ(GEN x, long v, long tx, long lx)
                   1664: {
                   1665:   GEN y=cgetg(lx,tx);
                   1666:   long i;
                   1667:
                   1668:   y[1]=x[1];
                   1669:   for (i=2; i<lx; i++) y[i]=linteg((GEN)x[i],v);
                   1670:   return y;
                   1671: }
                   1672:
                   1673: GEN
                   1674: integ(GEN x, long v)
                   1675: {
1.2     ! noro     1676:   long lx, tx, e, i, j, vx, n;
        !          1677:   gpmem_t av=avma, tetpil;
1.1       noro     1678:   GEN y,p1;
                   1679:
                   1680:   tx = typ(x);
                   1681:   if (v < 0) v = gvar(x);
                   1682:   if (is_scalar_t(tx))
                   1683:   {
                   1684:     if (tx == t_POLMOD && v>varn(x[1]))
                   1685:     {
                   1686:       y=cgetg(3,t_POLMOD); copyifstack(x[1],y[1]);
                   1687:       y[2]=linteg((GEN)x[2],v); return y;
                   1688:     }
                   1689:     if (gcmp0(x)) return gzero;
                   1690:
                   1691:     y=cgetg(4,t_POL); y[1] = evalsigne(1) | evallgef(4) | evalvarn(v);
                   1692:     y[2]=zero; y[3]=lcopy(x); return y;
                   1693:   }
                   1694:
                   1695:   switch(tx)
                   1696:   {
                   1697:     case t_POL:
                   1698:       vx=varn(x); lx=lgef(x);
                   1699:       if (lx==2) return zeropol(min(v,vx));
                   1700:       if (vx>v)
                   1701:       {
                   1702:         y=cgetg(4,t_POL);
                   1703:        y[1] = signe(x)? evallgef(4) | evalvarn(v) | evalsigne(1)
                   1704:                       : evallgef(4) | evalvarn(v);
                   1705:         y[2]=zero; y[3]=lcopy(x); return y;
                   1706:       }
                   1707:       if (vx<v) return triv_integ(x,v,tx,lx);
                   1708:       y=cgetg(lx+1,tx); y[2]=zero;
                   1709:       for (i=3; i<=lx; i++)
                   1710:         y[i]=ldivgs((GEN)x[i-1],i-2);
                   1711:       y[1] = signe(x)? evallgef(lx+1) | evalvarn(v) | evalsigne(1)
                   1712:                      : evallgef(lx+1) | evalvarn(v);
                   1713:       return y;
                   1714:
                   1715:     case t_SER:
                   1716:       lx=lg(x); e=valp(x); vx=varn(x);
                   1717:       if (!signe(x))
                   1718:       {
                   1719:         if (vx == v) e++; else if (vx < v) v = vx;
                   1720:         return zeroser(v,e);
                   1721:       }
                   1722:       if (vx>v)
                   1723:       {
                   1724:         y=cgetg(4,t_POL);
                   1725:         y[1] = evallgef(4) | evalvarn(v) | evalsigne(1);
                   1726:         y[2]=zero; y[3]=lcopy(x); return y;
                   1727:       }
                   1728:       if (vx<v) return triv_integ(x,v,tx,lx);
                   1729:       y=cgetg(lx,tx);
                   1730:       for (i=2; i<lx; i++)
                   1731:       {
                   1732:        j=i+e-1;
                   1733:         if (!j)
                   1734:        {
                   1735:          if (!gcmp0((GEN)x[i])) err(inter2);
                   1736:          y[i]=zero;
                   1737:        }
                   1738:        else y[i] = ldivgs((GEN)x[i],j);
                   1739:       }
                   1740:       y[1]=x[1]+1; return y;
                   1741:
                   1742:     case t_RFRAC: case t_RFRACN:
                   1743:       vx = gvar(x);
                   1744:       if (vx>v)
                   1745:       {
                   1746:        y=cgetg(4,t_POL);
                   1747:        y[1] = signe(x[1])? evallgef(4) | evalvarn(v) | evalsigne(1)
                   1748:                          : evallgef(4) | evalvarn(v);
                   1749:         y[2]=zero; y[3]=lcopy(x); return y;
                   1750:       }
                   1751:       if (vx<v)
                   1752:       {
                   1753:        p1=cgetg(v+2,t_VEC);
                   1754:        for (i=0; i<vx; i++)   p1[i+1] = lpolx[i];
                   1755:        for (i=vx+1; i<v; i++) p1[i+1] = lpolx[i];
                   1756:         p1[v+1] = lpolx[vx]; p1[vx+1] = lpolx[v];
                   1757:        y=integ(changevar(x,p1),vx); tetpil=avma;
                   1758:        return gerepile(av,tetpil,changevar(y,p1));
                   1759:       }
                   1760:
                   1761:       tx = typ(x[1]); i = is_scalar_t(tx)? 0: degpol(x[1]);
                   1762:       tx = typ(x[2]); j = is_scalar_t(tx)? 0: degpol(x[2]);
                   1763:       n = i+j + 2;
                   1764:       y = gdiv(gtrunc(gmul((GEN)x[2], integ(tayl(x,v,n),v))), (GEN)x[2]);
                   1765:       if (!gegal(deriv(y,v),x)) err(inter2);
                   1766:       if (typ(y)==t_RFRAC && lgef(y[1]) == lgef(y[2]))
                   1767:       {
                   1768:         GEN p2;
                   1769:        tx=typ(y[1]); p1=is_scalar_t(tx)? (GEN)y[1]: leading_term(y[1]);
                   1770:        tx=typ(y[2]); p2=is_scalar_t(tx)? (GEN)y[2]: leading_term(y[2]);
                   1771:        y=gsub(y, gdiv(p1,p2));
                   1772:       }
                   1773:       return gerepileupto(av,y);
                   1774:
                   1775:     case t_VEC: case t_COL: case t_MAT:
                   1776:       lx=lg(x); y=cgetg(lx,tx);
                   1777:       for (i=1; i<lg(x); i++) y[i]=linteg((GEN)x[i],v);
                   1778:       return y;
                   1779:   }
                   1780:   err(typeer,"integ");
                   1781:   return NULL; /* not reached */
                   1782: }
                   1783:
                   1784: /*******************************************************************/
                   1785: /*                                                                 */
                   1786: /*                    PARTIES ENTIERES                             */
                   1787: /*                                                                 */
                   1788: /*******************************************************************/
                   1789:
                   1790: GEN
                   1791: gfloor(GEN x)
                   1792: {
                   1793:   GEN y;
                   1794:   long i,lx, tx = typ(x);
                   1795:
                   1796:   switch(tx)
                   1797:   {
                   1798:     case t_INT: case t_POL:
                   1799:       return gcopy(x);
                   1800:
                   1801:     case t_REAL:
                   1802:       return mpent(x);
                   1803:
                   1804:     case t_FRAC: case t_FRACN:
                   1805:       return truedvmdii((GEN)x[1],(GEN)x[2],NULL);
                   1806:
                   1807:     case t_RFRAC: case t_RFRACN:
                   1808:       return gdeuc((GEN)x[1],(GEN)x[2]);
                   1809:
                   1810:     case t_VEC: case t_COL: case t_MAT:
                   1811:       lx=lg(x); y=cgetg(lx,tx);
                   1812:       for (i=1; i<lx; i++) y[i]=lfloor((GEN)x[i]);
                   1813:       return y;
                   1814:   }
                   1815:   err(typeer,"gfloor");
                   1816:   return NULL; /* not reached */
                   1817: }
                   1818:
                   1819: GEN
                   1820: gfrac(GEN x)
                   1821: {
1.2     ! noro     1822:   gpmem_t av = avma, tetpil;
1.1       noro     1823:   GEN p1 = gneg_i(gfloor(x));
                   1824:
                   1825:   tetpil=avma; return gerepile(av,tetpil,gadd(x,p1));
                   1826: }
                   1827:
                   1828: GEN
                   1829: gceil(GEN x)
                   1830: {
                   1831:   GEN y,p1;
1.2     ! noro     1832:   long i, lx, tx=typ(x);
        !          1833:   gpmem_t av, tetpil;
1.1       noro     1834:
                   1835:   switch(tx)
                   1836:   {
                   1837:     case t_INT: case t_POL:
                   1838:       return gcopy(x);
                   1839:
                   1840:     case t_REAL:
                   1841:       av=avma; y=mpent(x);
                   1842:       if (!gegal(x,y))
                   1843:       {
                   1844:         tetpil=avma; return gerepile(av,tetpil,addsi(1,y));
                   1845:       }
                   1846:       return y;
                   1847:
                   1848:     case t_FRAC: case t_FRACN:
                   1849:       av=avma; y=dvmdii((GEN)x[1],(GEN)x[2],&p1);
                   1850:       if (p1 != gzero && gsigne(x)>0)
                   1851:       {
                   1852:         cgiv(p1); tetpil=avma;
                   1853:         return gerepile(av,tetpil,addsi(1,y));
                   1854:       }
                   1855:       return y;
                   1856:
                   1857:     case t_RFRAC: case t_RFRACN:
                   1858:       return gdeuc((GEN)x[1],(GEN)x[2]);
                   1859:
                   1860:     case t_VEC: case t_COL: case t_MAT:
                   1861:       lx=lg(x); y=cgetg(lx,tx);
                   1862:       for (i=1; i<lx; i++) y[i]=lceil((GEN)x[i]);
                   1863:       return y;
                   1864:   }
                   1865:   err(typeer,"gceil");
                   1866:   return NULL; /* not reached */
                   1867: }
                   1868:
                   1869: GEN
                   1870: round0(GEN x, GEN *pte)
                   1871: {
                   1872:   if (pte) { long e; x = grndtoi(x,&e); *pte = stoi(e); }
                   1873:   return ground(x);
                   1874: }
                   1875:
                   1876: GEN
                   1877: ground(GEN x)
                   1878: {
                   1879:   GEN y,p1;
1.2     ! noro     1880:   long i, lx, tx=typ(x);
        !          1881:   gpmem_t av;
1.1       noro     1882:
                   1883:   switch(tx)
                   1884:   {
                   1885:     case t_INT: case t_INTMOD: case t_QUAD:
                   1886:       return gcopy(x);
                   1887:
                   1888:     case t_REAL:
                   1889:     {
                   1890:       long ex, s = signe(x);
                   1891:       if (s==0 || (ex=expo(x)) < -1) return gzero;
                   1892:       if (ex < 0) return s>0? gun: negi(gun);
1.2     ! noro     1893:       av = avma;
        !          1894:       p1 = real2n(-1, 3 + (ex>>TWOPOTBITS_IN_LONG)); /* = 0.5 */
        !          1895:       p1 = addrr(x,p1);
        !          1896:       return gerepileuptoint(av, mpent(p1));
1.1       noro     1897:     }
                   1898:     case t_FRAC: case t_FRACN:
1.2     ! noro     1899:       return diviiround((GEN)x[1], (GEN)x[2]);
1.1       noro     1900:
                   1901:     case t_POLMOD: y=cgetg(3,t_POLMOD);
                   1902:       copyifstack(x[1],y[1]);
                   1903:       y[2]=lround((GEN)x[2]); return y;
                   1904:
                   1905:     case t_COMPLEX: case t_POL: case t_SER: case t_RFRAC: case t_RFRACN:
                   1906:     case t_VEC: case t_COL: case t_MAT:
                   1907:       lx = (tx==t_POL)? lgef(x): lg(x);
                   1908:       y=cgetg(lx,tx);
                   1909:       for (i=1; i<lontyp[tx]; i++) y[i]=x[i];
                   1910:       for (   ; i<lx; i++) y[i]=lround((GEN)x[i]);
                   1911:       if (tx==t_POL) return normalizepol_i(y, lx);
                   1912:       if (tx==t_SER) return normalize(y);
                   1913:       return y;
                   1914:   }
                   1915:   err(typeer,"ground");
                   1916:   return NULL; /* not reached */
                   1917: }
                   1918:
                   1919: /* e = number of error bits on integral part */
                   1920: GEN
                   1921: grndtoi(GEN x, long *e)
                   1922: {
                   1923:   GEN y,p1;
1.2     ! noro     1924:   long i, tx=typ(x), lx, ex, e1;
        !          1925:   gpmem_t av;
1.1       noro     1926:
                   1927:   *e = -HIGHEXPOBIT;
                   1928:   switch(tx)
                   1929:   {
                   1930:     case t_INT: case t_INTMOD: case t_QUAD:
                   1931:     case t_FRAC: case t_FRACN:
                   1932:       return ground(x);
                   1933:
                   1934:     case t_REAL:
                   1935:       av=avma; p1=gadd(ghalf,x); ex=expo(p1);
                   1936:       if (ex<0)
                   1937:       {
                   1938:        if (signe(p1)>=0) { *e=expo(x); avma=av; return gzero; }
                   1939:         *e=expo(addsr(1,x)); avma=av; return negi(gun);
                   1940:       }
                   1941:       lx=lg(x); e1 = ex - bit_accuracy(lx) + 1;
                   1942:       settyp(p1,t_INT); setlgefint(p1,lx);
                   1943:       y=shifti(p1,e1); if (signe(x)<0) y=addsi(-1,y);
1.2     ! noro     1944:       y = gerepileuptoint(av,y);
1.1       noro     1945:
                   1946:       if (e1<=0) { av=avma; e1=expo(subri(x,y)); avma=av; }
                   1947:       *e=e1; return y;
                   1948:
                   1949:     case t_POLMOD: y=cgetg(3,t_POLMOD);
                   1950:       copyifstack(x[1],y[1]);
                   1951:       y[2]=lrndtoi((GEN)x[2],e); return y;
                   1952:
                   1953:     case t_COMPLEX: case t_POL: case t_SER: case t_RFRAC: case t_RFRACN:
                   1954:     case t_VEC: case t_COL: case t_MAT:
                   1955:       lx=(tx==t_POL)? lgef(x): lg(x);
                   1956:       y=cgetg(lx,tx);
                   1957:       for (i=1; i<lontyp[tx]; i++) y[i]=x[i];
                   1958:       for (   ; i<lx; i++)
                   1959:       {
                   1960:         y[i]=lrndtoi((GEN)x[i],&e1);
                   1961:         if (e1>*e) *e=e1;
                   1962:       }
                   1963:       return y;
                   1964:   }
                   1965:   err(typeer,"grndtoi");
                   1966:   return NULL; /* not reached */
                   1967: }
                   1968:
                   1969: /* e = number of error bits on integral part */
                   1970: GEN
                   1971: gcvtoi(GEN x, long *e)
                   1972: {
1.2     ! noro     1973:   long tx=typ(x), lx, i, ex, e1;
        !          1974:   gpmem_t av;
1.1       noro     1975:   GEN y;
                   1976:
                   1977:   *e = -HIGHEXPOBIT;
                   1978:   if (tx == t_REAL)
                   1979:   {
                   1980:     long x0,x1;
                   1981:     ex=expo(x); if (ex<0) { *e=ex; return gzero; }
                   1982:     lx=lg(x); e1 = ex - bit_accuracy(lx) + 1;
                   1983:     x0=x[0]; x1=x[1]; settyp(x,t_INT); setlgefint(x,lx);
                   1984:     y=shifti(x,e1); x[0]=x0; x[1]=x1;
                   1985:     if (e1<=0) { av=avma; e1=expo(subri(x,y)); avma=av; }
                   1986:     *e=e1; return y;
                   1987:   }
                   1988:   if (is_matvec_t(tx))
                   1989:   {
                   1990:     lx=lg(x); y=cgetg(lx,tx);
                   1991:     for (i=1; i<lx; i++)
                   1992:     {
                   1993:       y[i]=lcvtoi((GEN)x[i],&e1);
                   1994:       if (e1>*e) *e=e1;
                   1995:     }
                   1996:     return y;
                   1997:   }
                   1998:   return gtrunc(x);
                   1999: }
                   2000:
                   2001: /* smallest integer greater than any incarnations of the real x
                   2002:  * [avoid mpent() and "precision loss in truncation"] */
                   2003: GEN
                   2004: ceil_safe(GEN x)
                   2005: {
1.2     ! noro     2006:   gpmem_t av = avma;
1.1       noro     2007:   long e;
                   2008:   GEN y = gcvtoi(x,&e);
                   2009:   if (e < 0) e = 0;
                   2010:   y = addii(y, shifti(gun,e));
                   2011:   return gerepileuptoint(av, y);
                   2012: }
                   2013:
                   2014: GEN
                   2015: gtrunc(GEN x)
                   2016: {
1.2     ! noro     2017:   long tx=typ(x), i, v;
        !          2018:   gpmem_t av;
1.1       noro     2019:   GEN y;
                   2020:
                   2021:   switch(tx)
                   2022:   {
                   2023:     case t_INT: case t_POL:
                   2024:       return gcopy(x);
                   2025:
                   2026:     case t_REAL:
                   2027:       return mptrunc(x);
                   2028:
                   2029:     case t_FRAC: case t_FRACN:
                   2030:       return divii((GEN)x[1],(GEN)x[2]);
                   2031:
                   2032:     case t_PADIC:
                   2033:       if (!signe(x[4])) return gzero;
                   2034:       v = valp(x);
                   2035:       if (!v) return gcopy((GEN)x[4]);
                   2036:       if (v>0)
                   2037:       { /* here p^v is an integer */
1.2     ! noro     2038:         av = avma; y = gpowgs((GEN)x[2],v);
        !          2039:         return gerepileuptoint(av, mulii(y,(GEN)x[4]));
1.1       noro     2040:       }
                   2041:       y=cgetg(3,t_FRAC);
1.2     ! noro     2042:       y[1] = licopy((GEN)x[4]);
        !          2043:       y[2] = lpowgs((GEN)x[2],-v);
1.1       noro     2044:       return y;
                   2045:
                   2046:     case t_RFRAC: case t_RFRACN:
                   2047:       return gdeuc((GEN)x[1],(GEN)x[2]);
                   2048:
                   2049:     case t_SER:
                   2050:       return gconvsp(x,1);
                   2051:
                   2052:     case t_VEC: case t_COL: case t_MAT:
                   2053:     {
                   2054:       long lx=lg(x);
                   2055:
                   2056:       y=cgetg(lx,tx);
                   2057:       for (i=1; i<lx; i++) y[i]=ltrunc((GEN)x[i]);
                   2058:       return y;
                   2059:     }
                   2060:   }
                   2061:   err(typeer,"gtrunc");
                   2062:   return NULL; /* not reached */
                   2063: }
                   2064:
                   2065: GEN
                   2066: trunc0(GEN x, GEN *pte)
                   2067: {
                   2068:   if (pte) { long e; x = gcvtoi(x,&e); *pte = stoi(e); }
                   2069:   return gtrunc(x);
                   2070: }
                   2071:
                   2072: /*******************************************************************/
                   2073: /*                                                                 */
                   2074: /*                  CONVERSIONS -->  INT, POL & SER                */
                   2075: /*                                                                 */
                   2076: /*******************************************************************/
                   2077:
                   2078: /* return a_n B^n + ... + a_0, where B = 2^BIL. Assume n even if BIL=64 and
                   2079:  * the a_i are 32bits integers, one of which is non-zero */
                   2080: GEN
                   2081: coefs_to_int(long n, ...)
                   2082: {
                   2083:   va_list ap;
                   2084:   GEN x, y;
                   2085:   long i;
                   2086:   va_start(ap,n);
                   2087: #ifdef LONG_IS_64BIT
                   2088:   n >>= 1;
                   2089: #endif
                   2090:   x = cgetg(n+2, t_INT); y = x + 2;
                   2091:   x[1] = evallgefint(n+2) | evalsigne(1);
                   2092:   for (i=0; i <n; i++)
                   2093:   {
                   2094: #ifdef LONG_IS_64BIT
                   2095:     ulong a = va_arg(ap, long);
                   2096:     ulong b = va_arg(ap, long);
                   2097:     y[i] = (a << 32) | b;
                   2098: #else
                   2099:     y[i] = va_arg(ap, long);
                   2100: #endif
                   2101:   }
                   2102:   return x;
                   2103: }
                   2104:
                   2105: /* 2^32 a + b */
                   2106: GEN
                   2107: u2toi(ulong a, ulong b)
                   2108: {
                   2109:   GEN x;
                   2110:   if (!a && !b) return gzero;
                   2111: #ifdef LONG_IS_64BIT
                   2112:   x = cgetg(3, t_INT);
                   2113:   x[1] = evallgefint(3)|evalsigne(1);
                   2114:   x[2] = (a << 32) | b;
                   2115: #else
                   2116:   x = cgetg(4, t_INT);
                   2117:   x[1] = evallgefint(4)|evalsigne(1);
                   2118:   x[2] = a;
                   2119:   x[3] = b;
                   2120: #endif
                   2121:   return x;
                   2122: }
                   2123:
                   2124: /* return a_(n-1) x^(n-1) + ... + a_0 */
                   2125: GEN
                   2126: coefs_to_pol(long n, ...)
                   2127: {
                   2128:   va_list ap;
                   2129:   GEN x, y;
                   2130:   long i;
                   2131:   va_start(ap,n);
                   2132:   x = cgetg(n+2, t_POL); y = x + 2;
                   2133:   x[1] = evallgef(n+2) | evalvarn(0);
                   2134:   for (i=n-1; i >= 0; i--) y[i] = (long) va_arg(ap, GEN);
                   2135:   return normalizepol(x);
                   2136: }
                   2137:
                   2138: GEN
                   2139: zeropol(long v)
                   2140: {
                   2141:   GEN x = cgetg(2,t_POL);
                   2142:   x[1] = evallgef(2) | evalvarn(v); return x;
                   2143: }
                   2144:
                   2145: GEN
                   2146: scalarpol(GEN x, long v)
                   2147: {
                   2148:   GEN y=cgetg(3,t_POL);
                   2149:   y[1] = gcmp0(x)? evallgef(3) | evalvarn(v)
                   2150:                  : evallgef(3) | evalvarn(v) | evalsigne(1);
                   2151:   y[2]=lcopy(x); return y;
                   2152: }
                   2153:
                   2154: /* deg1pol(a,b,x)=a*x+b*/
                   2155: GEN
                   2156: deg1pol(GEN x1, GEN x0,long v)
                   2157: {
                   2158:   GEN x = cgetg(4,t_POL);
                   2159:   x[1] = evalsigne(1) | evalvarn(v) | evallgef(4);
                   2160:   x[2] = lcopy(x0); x[3] = lcopy(x1); return normalizepol_i(x,4);
                   2161: }
                   2162:
                   2163: /* same, no copy */
                   2164: GEN
                   2165: deg1pol_i(GEN x1, GEN x0,long v)
                   2166: {
                   2167:   GEN x = cgetg(4,t_POL);
                   2168:   x[1] = evalsigne(1) | evalvarn(v) | evallgef(4);
                   2169:   x[2] = (long)x0; x[3] = (long)x1; return normalizepol_i(x,4);
                   2170: }
                   2171:
                   2172: static GEN
                   2173: gtopoly0(GEN x, long v, int reverse)
                   2174: {
                   2175:   long tx=typ(x),lx,i,j;
                   2176:   GEN y;
                   2177:
                   2178:   if (v<0) v = 0;
                   2179:   if (isexactzero(x)) return zeropol(v);
                   2180:   if (is_scalar_t(tx)) return scalarpol(x,v);
                   2181:
                   2182:   switch(tx)
                   2183:   {
                   2184:     case t_POL:
                   2185:       y=gcopy(x); break;
                   2186:     case t_SER:
                   2187:       y=gconvsp(x,1);
                   2188:       if (typ(y) != t_POL)
                   2189:         err(talker,"t_SER with negative valuation in gtopoly");
                   2190:       break;
                   2191:     case t_RFRAC: case t_RFRACN:
                   2192:       y=gdeuc((GEN)x[1],(GEN)x[2]); break;
                   2193:     case t_QFR: case t_QFI: case t_VEC: case t_COL: case t_MAT:
                   2194:       lx=lg(x);
                   2195:       if (reverse)
                   2196:       {
                   2197:        while (lx-- && isexactzero((GEN)x[lx]));
                   2198:        i=lx+2; y=cgetg(i,t_POL);
                   2199:        y[1]=evallgef(i); if (!gcmp0(x)) y[1] |= evalsigne(1);
                   2200:        for (j=2; j<i; j++) y[j]=lcopy((GEN)x[j-1]);
                   2201:       }
                   2202:       else
                   2203:       {
                   2204:        i=1; j=lx; while (lx-- && isexactzero((GEN)x[i++]));
                   2205:        i=lx+2; y=cgetg(i,t_POL);
                   2206:        y[1]=evallgef(i); if (!gcmp0(x)) y[1] |= evalsigne(1);
                   2207:        lx = j-1;
                   2208:        for (j=2; j<i; j++) y[j]=lcopy((GEN)x[lx--]);
                   2209:       }
                   2210:       break;
                   2211:     default: err(typeer,"gtopoly");
                   2212:       return NULL; /* not reached */
                   2213:   }
                   2214:   setvarn(y,v); return y;
                   2215: }
                   2216:
                   2217: GEN
                   2218: gtopolyrev(GEN x, long v) { return gtopoly0(x,v,1); }
                   2219:
                   2220: GEN
                   2221: gtopoly(GEN x, long v) { return gtopoly0(x,v,0); }
                   2222:
                   2223: GEN
                   2224: zeroser(long v, long val)
                   2225: {
                   2226:   GEN x = cgetg(2,t_SER);
                   2227:   x[1]=evalvalp(val) | evalvarn(v); return x;
                   2228: }
                   2229:
                   2230: GEN
                   2231: scalarser(GEN x, long v, long prec)
                   2232: {
                   2233:   GEN y=cgetg(prec+2,t_SER);
                   2234:   long i;
                   2235:
                   2236:   y[1]=evalsigne(1) | evalvalp(0) | evalvarn(v);
                   2237:   y[2]=lcopy(x); for (i=3; i<=prec+1; i++) y[i]=zero;
                   2238:   return y;
                   2239: }
                   2240:
                   2241: GEN
                   2242: gtoser(GEN x, long v)
                   2243: {
1.2     ! noro     2244:   long tx=typ(x), lx, i, j, l;
        !          2245:   gpmem_t av, tetpil;
1.1       noro     2246:   GEN y,p1,p2;
                   2247:
                   2248:   if (v<0) v = 0;
                   2249:   if (tx==t_SER) { y=gcopy(x); setvarn(y,v); return y; }
                   2250:   if (isexactzero(x)) return zeroser(v,precdl);
                   2251:   if (is_scalar_t(tx)) return scalarser(x,v,precdl);
                   2252:
                   2253:   switch(tx)
                   2254:   {
                   2255:     case t_POL:
                   2256:       lx=lgef(x); i=2; while (i<lx && gcmp0((GEN)x[i])) i++;
                   2257:       l=lx-i; if (precdl>l) l=precdl;
                   2258:       y=cgetg(l+2,t_SER);
                   2259:       y[1] = evalsigne(1) | evalvalp(i-2) | evalvarn(v);
                   2260:       for (j=2; j<=lx-i+1; j++) y[j]=lcopy((GEN)x[j+i-2]);
                   2261:       for (   ; j<=l+1;    j++) y[j]=zero;
                   2262:       break;
                   2263:
                   2264:     case t_RFRAC: case t_RFRACN:
                   2265:       av=avma; p1=gtoser((GEN)x[1],v); p2=gtoser((GEN)x[2],v);
                   2266:       tetpil=avma; return gerepile(av,tetpil,gdiv(p1,p2));
                   2267:
                   2268:     case t_QFR: case t_QFI: case t_VEC: case t_COL: case t_MAT:
                   2269:       lx=lg(x); i=1; while (i<lx && isexactzero((GEN)x[i])) i++;
                   2270:       y = cgetg(lx-i+2,t_SER);
                   2271:       y[1] = evalsigne(1) | evalvalp(i-1) | evalvarn(v);
                   2272:       for (j=2; j<=lx-i+1; j++) y[j]=lcopy((GEN)x[j+i-2]);
                   2273:       break;
                   2274:
                   2275:     default: err(typeer,"gtoser");
                   2276:       return NULL; /* not reached */
                   2277:   }
                   2278:   return y;
                   2279: }
                   2280:
                   2281: GEN
                   2282: gtovec(GEN x)
                   2283: {
                   2284:   long tx,lx,i;
                   2285:   GEN y;
                   2286:
                   2287:   if (!x) return cgetg(1,t_VEC);
                   2288:   tx = typ(x);
                   2289:   if (is_scalar_t(tx) || is_rfrac_t(tx))
                   2290:   {
                   2291:     y=cgetg(2,t_VEC); y[1]=lcopy(x);
                   2292:     return y;
                   2293:   }
                   2294:   if (tx == t_STR)
                   2295:   {
                   2296:     char *s = GSTR(x);
                   2297:     char t[2];
                   2298:     lx = strlen(s); t[1] = 0;
                   2299:     y = cgetg(lx+1, t_VEC);
                   2300:     for (i=0; i<lx; i++)
                   2301:     {
                   2302:       t[0] = s[i];
                   2303:       y[i+1] = (long)strtoGENstr(t,0);
                   2304:     }
                   2305:     return y;
                   2306:   }
                   2307:   if (is_graphicvec_t(tx))
                   2308:   {
                   2309:     lx=lg(x); y=cgetg(lx,t_VEC);
                   2310:     for (i=1; i<lx; i++) y[i]=lcopy((GEN)x[i]);
                   2311:     return y;
                   2312:   }
                   2313:   if (tx==t_POL)
                   2314:   {
                   2315:     lx=lgef(x); y=cgetg(lx-1,t_VEC);
                   2316:     for (i=1; i<=lx-2; i++) y[i]=lcopy((GEN)x[lx-i]);
                   2317:     return y;
                   2318:   }
                   2319:   if (tx==t_LIST)
                   2320:   {
                   2321:     lx=lgef(x); y=cgetg(lx-1,t_VEC); x++;
                   2322:     for (i=1; i<=lx-2; i++) y[i]=lcopy((GEN)x[i]);
                   2323:     return y;
                   2324:   }
1.2     ! noro     2325:   if (tx == t_VECSMALL) return small_to_vec(x);
1.1       noro     2326:   if (!signe(x)) { y=cgetg(2,t_VEC); y[1]=zero; return y; }
                   2327:   lx=lg(x); y=cgetg(lx-1,t_VEC); x++;
                   2328:   for (i=1; i<=lx-2; i++) y[i]=lcopy((GEN)x[i]);
                   2329:   return y;
                   2330: }
                   2331:
                   2332: GEN
                   2333: gtovecsmall(GEN x)
                   2334: {
                   2335:   GEN V;
                   2336:   long tx, l,i;
                   2337:
                   2338:   if (!x) return cgetg(1,t_VECSMALL);
                   2339:   tx = typ(x);
                   2340:   if (tx == t_VECSMALL) return gcopy(x);
                   2341:   if (tx == t_INT)
                   2342:   {
                   2343:     GEN u = cgetg(2, t_VECSMALL);
                   2344:     u[1] = itos(x); return u;
                   2345:   }
                   2346:   if (!is_vec_t(tx)) err(typeer,"vectosmall");
                   2347:   l = lg(x);
                   2348:   V = cgetg(l,t_VECSMALL);
                   2349:   for(i=1;i<l;i++) V[i] = itos((GEN)x[i]);
                   2350:   return V;
                   2351: }
                   2352:
                   2353: GEN
                   2354: compo(GEN x, long n)
                   2355: {
                   2356:   long l,tx=typ(x);
                   2357:
                   2358:   if (tx==t_POL && n+1 >= lgef(x)) return gzero;
                   2359:   if (tx==t_SER && !signe(x)) return gzero;
                   2360:   if (!is_recursive_t(tx))
                   2361:     err(talker, "this object doesn't have components (is a leaf)");
                   2362:   l=lontyp[tx]+n-1;
                   2363:   if (n<1 || l>=lg(x))
                   2364:     err(talker,"nonexistent component");
                   2365:   return gcopy((GEN)x[l]);
                   2366: }
                   2367:
1.2     ! noro     2368: /* assume v > varn(x), extract coeff of polx[v]^n */
        !          2369: static GEN
        !          2370: multi_coeff(GEN x, long n, long v, long dx)
        !          2371: {
        !          2372:   long i;
        !          2373:   GEN z;
        !          2374:   if (dx == 0) return polcoeff_i((GEN)x[2], n, v);
        !          2375:   z = cgetg(dx+3, t_POL);
        !          2376:   z[1] = x[1];
        !          2377:   for (i=2; i<dx+3; i++) z[i] = (long)polcoeff_i((GEN)x[i], n, v);
        !          2378:   return normalizepol(z);
        !          2379: }
        !          2380:
        !          2381: /* assume x a t_POL */
        !          2382: static GEN
        !          2383: _polcoeff(GEN x, long n, long v)
        !          2384: {
        !          2385:   long w, dx;
        !          2386:   dx = degpol(x);
        !          2387:   if (dx < 0) return gzero;
        !          2388:   if (v < 0 || v == (w=varn(x)))
        !          2389:     return (n < 0 || n > dx)? gzero: (GEN)x[n+2];
        !          2390:   if (w > v) return n? gzero: x;
        !          2391:   /* w < v */
        !          2392:   return multi_coeff(x, n, v, dx);
        !          2393: }
        !          2394:
        !          2395: /* assume x a t_SER */
        !          2396: static GEN
        !          2397: _sercoeff(GEN x, long n, long v)
        !          2398: {
        !          2399:   long w, dx, ex;
        !          2400:   if (!signe(x)) return gzero;
        !          2401:   dx = lg(x)-3; ex = valp(x); n -= ex;
        !          2402:   if (v < 0 || v == (w=varn(x)))
        !          2403:   {
        !          2404:     if (n > dx) err(talker,"non existent component in truecoeff");
        !          2405:     return (n < 0)? gzero: (GEN)x[n+2];
        !          2406:   }
        !          2407:   if (w > v) return n? gzero: x;
        !          2408:   /* w < v */
        !          2409:   return multi_coeff(x, n, v, dx);
        !          2410: }
        !          2411:
        !          2412: /* assume x a t_RFRAC(n) */
        !          2413: static GEN
        !          2414: _rfraccoeff(GEN x, long n, long v)
        !          2415: {
        !          2416:   GEN P,Q, p = (GEN)x[1], q = (GEN)x[2];
        !          2417:   long vp = gvar(p), vq = gvar(q);
        !          2418:   if (v < 0) v = min(vp, vq);
        !          2419:   P = (vp == v)? p: swap_vars(p, v);
        !          2420:   Q = (vq == v)? q: swap_vars(q, v);
        !          2421:   if (!ismonome(Q)) err(typeer, "polcoeff");
        !          2422:   n += degpol(Q);
        !          2423:   return gdiv(_polcoeff(P, n, v), leading_term(Q));
        !          2424: }
        !          2425:
        !          2426: GEN
        !          2427: polcoeff_i(GEN x, long n, long v)
        !          2428: {
        !          2429:   switch(typ(x))
        !          2430:   {
        !          2431:     case t_POL: return _polcoeff(x,n,v);
        !          2432:     case t_SER: return _sercoeff(x,n,v);
        !          2433:     case t_RFRACN: err(typeer, "polcoeff"); /* too expensive to reduce */
        !          2434:     case t_RFRAC: return _rfraccoeff(x,n,v);
        !          2435:     default: return n? gzero: x;
        !          2436:   }
        !          2437: }
        !          2438:
1.1       noro     2439: /* with respect to the main variable if v<0, with respect to the variable v
                   2440:    otherwise. v ignored if x is not a polynomial/series. */
                   2441: GEN
                   2442: polcoeff0(GEN x, long n, long v)
                   2443: {
1.2     ! noro     2444:   long tx=typ(x);
        !          2445:   gpmem_t av;
1.1       noro     2446:
                   2447:   if (is_scalar_t(tx)) return n? gzero: gcopy(x);
                   2448:
1.2     ! noro     2449:   av = avma;
1.1       noro     2450:   switch(tx)
                   2451:   {
1.2     ! noro     2452:     case t_POL: x = _polcoeff(x,n,v); break;
        !          2453:     case t_SER: x = _sercoeff(x,n,v); break;
        !          2454:     case t_RFRAC:
        !          2455:     case t_RFRACN: x = _rfraccoeff(x,n,v); break;
        !          2456:
1.1       noro     2457:     case t_QFR: case t_QFI: case t_VEC: case t_COL: case t_MAT:
1.2     ! noro     2458:       if (n>=1 && n<lg(x)) return gcopy((GEN)x[n]);
        !          2459:     /* fall through */
1.1       noro     2460:
1.2     ! noro     2461:     default: err(talker,"nonexistent component in truecoeff");
1.1       noro     2462:   }
1.2     ! noro     2463:   if (x == gzero) return x;
        !          2464:   if (avma == av) return gcopy(x);
        !          2465:   return gerepilecopy(av, x);
1.1       noro     2466: }
                   2467:
                   2468: GEN
                   2469: truecoeff(GEN x, long n)
                   2470: {
                   2471:   return polcoeff0(x,n,-1);
                   2472: }
                   2473:
                   2474: GEN
                   2475: denom(GEN x)
                   2476: {
1.2     ! noro     2477:   long lx, i;
        !          2478:   gpmem_t av, tetpil;
1.1       noro     2479:   GEN s,t;
                   2480:
                   2481:   switch(typ(x))
                   2482:   {
                   2483:     case t_INT: case t_REAL: case t_INTMOD: case t_PADIC: case t_SER:
                   2484:       return gun;
                   2485:
                   2486:     case t_FRAC: case t_FRACN:
                   2487:       return absi((GEN)x[2]);
                   2488:
                   2489:     case t_COMPLEX:
                   2490:       av=avma; t=denom((GEN)x[1]); s=denom((GEN)x[2]); tetpil=avma;
                   2491:       return gerepile(av,tetpil,glcm(s,t));
                   2492:
                   2493:     case t_QUAD:
                   2494:       av=avma; t=denom((GEN)x[2]); s=denom((GEN)x[3]); tetpil=avma;
                   2495:       return gerepile(av,tetpil,glcm(s,t));
                   2496:
                   2497:     case t_POLMOD:
                   2498:       return denom((GEN)x[2]);
                   2499:
                   2500:     case t_RFRAC: case t_RFRACN:
                   2501:       return gcopy((GEN)x[2]);
                   2502:
                   2503:     case t_POL:
                   2504:       return polun[varn(x)];
                   2505:
                   2506:     case t_VEC: case t_COL: case t_MAT:
                   2507:       lx=lg(x); if (lx==1) return gun;
                   2508:       av = tetpil = avma; s = denom((GEN)x[1]);
                   2509:       for (i=2; i<lx; i++)
                   2510:       {
                   2511:         t = denom((GEN)x[i]);
                   2512:         /* t != gun est volontaire */
                   2513:         if (t != gun) { tetpil=avma; s=glcm(s,t); }
                   2514:       }
                   2515:       return gerepile(av,tetpil,s);
                   2516:   }
                   2517:   err(typeer,"denom");
                   2518:   return NULL; /* not reached */
                   2519: }
                   2520:
                   2521: GEN
                   2522: numer(GEN x)
                   2523: {
1.2     ! noro     2524:   gpmem_t av, tetpil;
1.1       noro     2525:   GEN s;
                   2526:
                   2527:   switch(typ(x))
                   2528:   {
                   2529:     case t_INT: case t_REAL: case t_INTMOD:
                   2530:     case t_PADIC: case t_POL: case t_SER:
                   2531:       return gcopy(x);
                   2532:
                   2533:     case t_FRAC: case t_FRACN:
                   2534:       return (signe(x[2])>0)? gcopy((GEN)x[1]): gneg((GEN)x[1]);
                   2535:
                   2536:     case t_POLMOD:
                   2537:       av=avma; s=numer((GEN)x[2]); tetpil=avma;
                   2538:       return gerepile(av,tetpil,gmodulcp(s,(GEN)x[1]));
                   2539:
                   2540:     case t_RFRAC: case t_RFRACN:
                   2541:       return gcopy((GEN)x[1]);
                   2542:
                   2543:     case t_COMPLEX: case t_QUAD: case t_VEC: case t_COL: case t_MAT:
                   2544:       av=avma; s=denom(x); tetpil=avma;
                   2545:       return gerepile(av,tetpil,gmul(s,x));
                   2546:   }
                   2547:   err(typeer,"numer");
                   2548:   return NULL; /* not reached */
                   2549: }
                   2550:
                   2551: /* Lift only intmods if v does not occur in x, lift with respect to main
                   2552:  * variable of x if v < 0, with respect to variable v otherwise.
                   2553:  */
                   2554: GEN
                   2555: lift0(GEN x, long v)
                   2556: {
                   2557:   long lx,tx=typ(x),i;
                   2558:   GEN y;
                   2559:
                   2560:   switch(tx)
                   2561:   {
                   2562:     case t_INT: case t_REAL:
                   2563:       return gcopy(x);
                   2564:
                   2565:     case t_INTMOD:
                   2566:       return gcopy((GEN)x[2]);
                   2567:
                   2568:     case t_POLMOD:
                   2569:       if (v < 0 || v == varn((GEN)x[1])) return gcopy((GEN)x[2]);
                   2570:       y = cgetg(3,tx);
                   2571:       y[1] = (long)lift0((GEN)x[1],v);
                   2572:       y[2] = (long)lift0((GEN)x[2],v); return y;
                   2573:
                   2574:     case t_SER:
                   2575:       if (!signe(x)) return gcopy(x);
                   2576:       lx=lg(x); y=cgetg(lx,tx); y[1]=x[1];
                   2577:       for (i=2; i<lx; i++) y[i]=(long)lift0((GEN)x[i],v);
                   2578:       return y;
                   2579:
                   2580:     case t_PADIC:
                   2581:       return gtrunc(x);
                   2582:
                   2583:     case t_FRAC: case t_FRACN: case t_COMPLEX: case t_RFRAC:
                   2584:     case t_RFRACN: case t_VEC: case t_COL: case t_MAT:
                   2585:       lx=lg(x); y=cgetg(lx,tx);
                   2586:       for (i=1; i<lx; i++) y[i]=(long)lift0((GEN)x[i],v);
                   2587:       return y;
                   2588:
                   2589:     case t_POL:
                   2590:       y=cgetg(lx=lgef(x),tx); y[1]=x[1];
                   2591:       for (i=2; i<lx; i++) y[i]=(long)lift0((GEN)x[i],v);
                   2592:       return y;
                   2593:
                   2594:     case t_QUAD:
                   2595:       y=cgetg(4,tx); copyifstack(x[1],y[1]);
                   2596:       for (i=2; i<4; i++) y[i]=(long)lift0((GEN)x[i],v);
                   2597:       return y;
                   2598:   }
                   2599:   err(typeer,"lift");
                   2600:   return NULL; /* not reached */
                   2601: }
                   2602:
                   2603: GEN
                   2604: lift(GEN x)
                   2605: {
                   2606:   return lift0(x,-1);
                   2607: }
                   2608:
                   2609: /* same as lift, without copy. May DESTROY x. For internal use only.
                   2610:    Conventions on v as for lift. */
                   2611: GEN
                   2612: lift_intern0(GEN x, long v)
                   2613: {
                   2614:   long i,lx,tx=typ(x);
                   2615:
                   2616:   switch(tx)
                   2617:   {
                   2618:     case t_INT: case t_REAL:
                   2619:       return x;
                   2620:
                   2621:     case t_INTMOD:
                   2622:       return (GEN)x[2];
                   2623:
                   2624:     case t_POLMOD:
                   2625:       if (v < 0 || v == varn((GEN)x[1])) return (GEN)x[2];
                   2626:       x[1]=(long)lift_intern0((GEN)x[1],v);
                   2627:       x[2]=(long)lift_intern0((GEN)x[2],v);
                   2628:       return x;
                   2629:
                   2630:     case t_SER: if (!signe(x)) return x; /* fall through */
                   2631:     case t_FRAC: case t_FRACN: case t_COMPLEX: case t_QUAD: case t_POL:
                   2632:     case t_RFRAC: case t_RFRACN: case t_VEC: case t_COL: case t_MAT:
                   2633:       lx = (tx==t_POL)? lgef(x): lg(x);
                   2634:       for (i = lx-1; i>=lontyp[tx]; i--)
                   2635:         x[i] = (long) lift_intern0((GEN)x[i],v);
                   2636:       return x;
                   2637:   }
                   2638:   err(typeer,"lift_intern");
                   2639:   return NULL; /* not reached */
                   2640: }
                   2641:
                   2642: /* memes conventions pour v que lift */
                   2643: GEN
                   2644: centerlift0(GEN x, long v)
                   2645: {
1.2     ! noro     2646:   long lx, tx=typ(x), i;
        !          2647:   gpmem_t av;
1.1       noro     2648:   GEN y;
                   2649:
                   2650:   switch(tx)
                   2651:   {
                   2652:     case t_INT:
                   2653:       return icopy(x);
                   2654:
                   2655:     case t_INTMOD:
                   2656:       av=avma; i=cmpii(shifti((GEN)x[2],1),(GEN)x[1]); avma=av;
                   2657:       return (i>0)? subii((GEN)x[2],(GEN)x[1]): icopy((GEN)x[2]);
                   2658:
                   2659:     case t_POLMOD:
                   2660:       if (v < 0 || v == varn((GEN)x[1])) return gcopy((GEN)x[2]);
                   2661:       y=cgetg(3,tx);
                   2662:       y[1]=(long)centerlift0((GEN)x[1],v); y[2]=(long)centerlift0((GEN)x[2],v);
                   2663:       return y;
                   2664:
                   2665:     case t_SER:
                   2666:       if (!signe(x)) return gcopy(x);
                   2667:       lx=lg(x); y=cgetg(lx,tx); y[1]=x[1];
                   2668:       for (i=2; i<lx; i++) y[i]=(long)centerlift0((GEN)x[i],v);
                   2669:       return y;
                   2670:
                   2671:     case t_POL:
                   2672:     case t_FRAC: case t_FRACN: case t_COMPLEX: case t_RFRAC:
                   2673:     case t_RFRACN: case t_VEC: case t_COL: case t_MAT:
                   2674:       lx = (tx==t_POL)? lgef(x): lg(x);
                   2675:       y=cgetg(lx,tx); y[1]=x[1];
                   2676:       for (i=lontyp[tx]; i<lx; i++) y[i]=(long)centerlift0((GEN)x[i],v);
                   2677:       return y;
                   2678:
                   2679:     case t_QUAD:
                   2680:       y=cgetg(4,tx); copyifstack(x[1],y[1]);
                   2681:       for (i=2; i<4; i++) y[i]=(long)centerlift0((GEN)x[i],v);
                   2682:       return y;
                   2683:   }
                   2684:   err(typeer,"centerlift");
                   2685:   return NULL; /* not reached */
                   2686: }
                   2687:
                   2688: GEN
                   2689: centerlift(GEN x)
                   2690: {
                   2691:   return centerlift0(x,-1);
                   2692: }
                   2693:
                   2694: /*******************************************************************/
                   2695: /*                                                                 */
                   2696: /*                  PARTIES REELLE ET IMAGINAIRES                  */
                   2697: /*                                                                 */
                   2698: /*******************************************************************/
                   2699:
                   2700: static GEN
                   2701: op_ReIm(GEN f(GEN), GEN x)
                   2702: {
1.2     ! noro     2703:   long lx, i, j, tx = typ(x);
        !          2704:   gpmem_t av;
1.1       noro     2705:   GEN z;
                   2706:
                   2707:   switch(tx)
                   2708:   {
                   2709:     case t_POL:
                   2710:       lx=lgef(x); av=avma;
                   2711:       for (i=lx-1; i>=2; i--)
                   2712:         if (!gcmp0(f((GEN)x[i]))) break;
                   2713:       avma=av; if (i==1) return zeropol(varn(x));
                   2714:
                   2715:       z=cgetg(i+1,t_POL); z[1]=evalsigne(1)|evallgef(1+i)|evalvarn(varn(x));
                   2716:       for (j=2; j<=i; j++) z[j] = (long)f((GEN)x[j]);
                   2717:       return z;
                   2718:
                   2719:     case t_SER:
                   2720:       if (gcmp0(x)) { z=cgetg(2,t_SER); z[1]=x[1]; return z; }
                   2721:       lx=lg(x); av=avma;
                   2722:       for (i=2; i<lx; i++)
                   2723:         if (!gcmp0(f((GEN)x[i]))) break;
                   2724:       avma=av; if (i==lx) return zeroser(varn(x),lx-2+valp(x));
                   2725:
                   2726:       z=cgetg(lx-i+2,t_SER); z[1]=x[1]; setvalp(z, valp(x)+i-2);
                   2727:       for (j=2; i<lx; j++,i++) z[j] = (long) f((GEN)x[i]);
                   2728:       return z;
                   2729:
                   2730:     case t_RFRAC: case t_RFRACN:
                   2731:     {
                   2732:       GEN dxb, n, d;
                   2733:       av = avma; dxb = gconj((GEN)x[2]);
                   2734:       n = gmul((GEN)x[1], dxb);
                   2735:       d = gmul((GEN)x[2], dxb);
                   2736:       return gerepileupto(av, gdiv(f(n), d));
                   2737:     }
                   2738:
                   2739:     case t_VEC: case t_COL: case t_MAT:
                   2740:       lx=lg(x); z=cgetg(lx,tx);
                   2741:       for (i=1; i<lx; i++) z[i] = (long) f((GEN)x[i]);
                   2742:       return z;
                   2743:   }
                   2744:   err(typeer,"greal/gimag");
                   2745:   return NULL; /* not reached */
                   2746: }
                   2747:
                   2748: GEN
                   2749: greal(GEN x)
                   2750: {
                   2751:   switch(typ(x))
                   2752:   {
                   2753:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
                   2754:       return gcopy(x);
                   2755:
                   2756:     case t_COMPLEX:
                   2757:       return gcopy((GEN)x[1]);
                   2758:
                   2759:     case t_QUAD:
                   2760:       return gcopy((GEN)x[2]);
                   2761:   }
                   2762:   return op_ReIm(greal,x);
                   2763: }
                   2764:
                   2765: GEN
                   2766: gimag(GEN x)
                   2767: {
                   2768:   switch(typ(x))
                   2769:   {
                   2770:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
                   2771:       return gzero;
                   2772:
                   2773:     case t_COMPLEX:
                   2774:       return gcopy((GEN)x[2]);
                   2775:
                   2776:     case t_QUAD:
                   2777:       return gcopy((GEN)x[3]);
                   2778:   }
                   2779:   return op_ReIm(gimag,x);
                   2780: }
                   2781:
                   2782: /*******************************************************************/
                   2783: /*                                                                 */
                   2784: /*                     LOGICAL OPERATIONS                          */
                   2785: /*                                                                 */
                   2786: /*******************************************************************/
                   2787: static long
                   2788: _egal(GEN x, GEN y)
                   2789: {
1.2     ! noro     2790:   gpmem_t av = avma;
1.1       noro     2791:   long r = gegal(simplify_i(x), simplify_i(y));
                   2792:   avma = av; return r;
                   2793: }
                   2794:
                   2795: GEN
                   2796: glt(GEN x, GEN y) { return gcmp(x,y)<0? gun: gzero; }
                   2797:
                   2798: GEN
                   2799: gle(GEN x, GEN y) { return gcmp(x,y)<=0? gun: gzero; }
                   2800:
                   2801: GEN
                   2802: gge(GEN x, GEN y) { return gcmp(x,y)>=0? gun: gzero; }
                   2803:
                   2804: GEN
                   2805: ggt(GEN x, GEN y) { return gcmp(x,y)>0? gun: gzero; }
                   2806:
                   2807: GEN
                   2808: geq(GEN x, GEN y) { return _egal(x,y)? gun: gzero; }
                   2809:
                   2810: GEN
                   2811: gne(GEN x, GEN y) { return _egal(x,y)? gzero: gun; }
                   2812:
                   2813: GEN
                   2814: gand(GEN x, GEN y) { return gcmp0(x)? gzero: (gcmp0(y)? gzero: gun); }
                   2815:
                   2816: GEN
                   2817: gor(GEN x, GEN y) { return gcmp0(x)? (gcmp0(y)? gzero: gun): gun; }
                   2818:
                   2819: GEN
                   2820: gnot(GEN x) { return gcmp0(x)? gun: gzero; }
                   2821:
                   2822: /*******************************************************************/
                   2823: /*                                                                 */
                   2824: /*                      FORMAL SIMPLIFICATIONS                     */
                   2825: /*                                                                 */
                   2826: /*******************************************************************/
                   2827:
                   2828: GEN
                   2829: geval(GEN x)
                   2830: {
1.2     ! noro     2831:   long lx, i, tx = typ(x);
        !          2832:   gpmem_t av, tetpil;
1.1       noro     2833:   GEN y,z;
                   2834:
                   2835:   if (is_const_t(tx)) return gcopy(x);
                   2836:   if (is_graphicvec_t(tx) || tx == t_RFRACN)
                   2837:   {
                   2838:     lx=lg(x); y=cgetg(lx, tx);
                   2839:     for (i=1; i<lx; i++) y[i] = (long)geval((GEN)x[i]);
                   2840:     return y;
                   2841:   }
                   2842:
                   2843:   switch(tx)
                   2844:   {
                   2845:     case t_STR:
                   2846:       return flisseq(GSTR(x));
                   2847:
                   2848:     case t_POLMOD: y=cgetg(3,tx);
                   2849:       y[1]=(long)geval((GEN)x[1]);
                   2850:       av=avma; z=geval((GEN)x[2]); tetpil=avma;
                   2851:       y[2]=lpile(av,tetpil,gmod(z,(GEN)y[1]));
                   2852:       return y;
                   2853:
                   2854:     case t_POL:
                   2855:       lx=lgef(x); if (lx==2) return gzero;
                   2856:       {
                   2857: #define initial_value(ep) (GEN)((ep)+1) /* cf anal.h */
                   2858:         entree *ep = varentries[varn(x)];
                   2859:         if (!ep) return gcopy(x);
                   2860:         z = (GEN)ep->value;
                   2861:         if (gegal(x, initial_value(ep))) return gcopy(z);
                   2862: #undef initial_value
                   2863:       }
                   2864:       y=gzero; av=avma;
                   2865:       for (i=lx-1; i>1; i--)
                   2866:         y = gadd(geval((GEN)x[i]), gmul(z,y));
                   2867:       return gerepileupto(av, y);
                   2868:
                   2869:     case t_SER:
                   2870:       err(impl, "evaluation of a power series");
                   2871:
                   2872:     case t_RFRAC:
                   2873:       return gdiv(geval((GEN)x[1]),geval((GEN)x[2]));
                   2874:   }
                   2875:   err(typeer,"geval");
                   2876:   return NULL; /* not reached */
                   2877: }
                   2878:
                   2879: GEN
                   2880: simplify_i(GEN x)
                   2881: {
                   2882:   long tx=typ(x),i,lx;
                   2883:   GEN y;
                   2884:
                   2885:   switch(tx)
                   2886:   {
                   2887:     case t_INT: case t_REAL: case t_FRAC:
                   2888:     case t_INTMOD: case t_PADIC: case t_QFR: case t_QFI:
                   2889:     case t_LIST: case t_STR: case t_VECSMALL:
                   2890:       return x;
                   2891:
                   2892:     case t_FRACN:
                   2893:       return gred(x);
                   2894:
                   2895:     case t_COMPLEX:
                   2896:       if (isexactzero((GEN)x[2])) return simplify_i((GEN)x[1]);
                   2897:       y=cgetg(3,t_COMPLEX);
                   2898:       y[1]=(long)simplify_i((GEN)x[1]);
                   2899:       y[2]=(long)simplify_i((GEN)x[2]); return y;
                   2900:
                   2901:     case t_QUAD:
                   2902:       if (isexactzero((GEN)x[3])) return simplify_i((GEN)x[2]);
                   2903:       y=cgetg(4,t_QUAD);
                   2904:       y[1]=x[1];
                   2905:       y[2]=(long)simplify_i((GEN)x[2]);
                   2906:       y[3]=(long)simplify_i((GEN)x[3]); return y;
                   2907:
                   2908:     case t_POLMOD: y=cgetg(3,t_POLMOD);
                   2909:       y[1]=(long)simplify_i((GEN)x[1]);
                   2910:       i = typ(y[1]);
                   2911:       if (i != t_POL)
                   2912:       {
                   2913:         if (i == t_INT) settyp(y, t_INTMOD);
                   2914:         else y[1] = x[1]; /* invalid object otherwise */
                   2915:       }
                   2916:       y[2]=lmod(simplify_i((GEN)x[2]),(GEN)y[1]); return y;
                   2917:
                   2918:     case t_POL:
                   2919:       lx=lgef(x); if (lx==2) return gzero;
                   2920:       if (lx==3) return simplify_i((GEN)x[2]);
                   2921:       y=cgetg(lx,t_POL); y[1]=x[1];
                   2922:       for (i=2; i<lx; i++) y[i]=(long)simplify_i((GEN)x[i]);
                   2923:       return y;
                   2924:
                   2925:     case t_SER:
                   2926:       if (!signe(x)) return gcopy(x);
                   2927:       lx=lg(x);
                   2928:       y=cgetg(lx,t_SER); y[1]=x[1];
                   2929:       for (i=2; i<lx; i++) y[i]=(long)simplify_i((GEN)x[i]);
                   2930:       return y;
                   2931:
                   2932:     case t_RFRAC: y=cgetg(3,t_RFRAC);
                   2933:       y[1]=(long)simplify_i((GEN)x[1]);
                   2934:       y[2]=(long)simplify_i((GEN)x[2]); return y;
                   2935:
                   2936:     case t_RFRACN: y=cgetg(3,t_RFRAC);
                   2937:       y[1]=(long)simplify_i((GEN)x[1]);
                   2938:       y[2]=(long)simplify_i((GEN)x[2]); return gred_rfrac(y);
                   2939:
                   2940:     case t_VEC: case t_COL: case t_MAT:
                   2941:       lx=lg(x); y=cgetg(lx,tx);
                   2942:       for (i=1; i<lx; i++) y[i]=(long)simplify_i((GEN)x[i]);
                   2943:       return y;
                   2944:   }
                   2945:   err(typeer,"simplify_i");
                   2946:   return NULL; /* not reached */
                   2947: }
                   2948:
                   2949: GEN
                   2950: simplify(GEN x)
                   2951: {
1.2     ! noro     2952:   gpmem_t av = avma;
1.1       noro     2953:   return gerepilecopy(av, simplify_i(x));
                   2954: }
                   2955:
                   2956: /*******************************************************************/
                   2957: /*                                                                 */
                   2958: /*                EVALUATION OF SOME SIMPLE OBJECTS                */
                   2959: /*                                                                 */
                   2960: /*******************************************************************/
                   2961: static GEN
                   2962: qfeval0_i(GEN q, GEN x, long n)
                   2963: {
1.2     ! noro     2964:   long i, j;
        !          2965:   gpmem_t av=avma;
1.1       noro     2966:   GEN res=gzero;
                   2967:
                   2968:   for (i=2;i<n;i++)
                   2969:     for (j=1;j<i;j++)
                   2970:       res = gadd(res, gmul(gcoeff(q,i,j), mulii((GEN)x[i],(GEN)x[j])) );
                   2971:   res=gshift(res,1);
                   2972:   for (i=1;i<n;i++)
                   2973:     res = gadd(res, gmul(gcoeff(q,i,i), sqri((GEN)x[i])) );
                   2974:   return gerepileupto(av,res);
                   2975: }
                   2976:
                   2977: #if 0
                   2978: static GEN
                   2979: qfeval0(GEN q, GEN x, long n)
                   2980: {
1.2     ! noro     2981:   long i, j;
        !          2982:   gpmem_t av=avma;
1.1       noro     2983:   GEN res=gzero;
                   2984:
                   2985:   for (i=2;i<n;i++)
                   2986:     for (j=1;j<i;j++)
                   2987:       res = gadd(res, gmul(gcoeff(q,i,j), gmul((GEN)x[i],(GEN)x[j])) );
                   2988:   res=gshift(res,1);
                   2989:   for (i=1;i<n;i++)
                   2990:     res = gadd(res, gmul(gcoeff(q,i,i), gsqr((GEN)x[i])) );
                   2991:   return gerepileupto(av,res);
                   2992: }
                   2993: #else
                   2994: static GEN
                   2995: qfeval0(GEN q, GEN x, long n)
                   2996: {
1.2     ! noro     2997:   long i, j;
        !          2998:   gpmem_t av=avma;
1.1       noro     2999:   GEN res = gmul(gcoeff(q,1,1), gsqr((GEN)x[1]));
                   3000:
                   3001:   for (i=2; i<n; i++)
                   3002:   {
                   3003:     GEN l = (GEN)q[i];
                   3004:     GEN sx = gmul((GEN)l[1], (GEN)x[1]);
                   3005:     for (j=2; j<i; j++)
                   3006:       sx = gadd(sx, gmul((GEN)l[j],(GEN)x[j]));
                   3007:     sx = gadd(gshift(sx,1), gmul((GEN)l[i],(GEN)x[i]));
                   3008:
                   3009:     res = gadd(res, gmul((GEN)x[i], sx));
                   3010:   }
                   3011:   return gerepileupto(av,res);
                   3012: }
                   3013: #endif
                   3014:
                   3015: /* We assume q is a real symetric matrix */
                   3016: GEN
                   3017: qfeval(GEN q, GEN x)
                   3018: {
                   3019:   long n=lg(q);
                   3020:
                   3021:   if (n==1)
                   3022:   {
                   3023:     if (typ(q) != t_MAT || lg(x) != 1)
                   3024:       err(talker,"invalid data in qfeval");
                   3025:     return gzero;
                   3026:   }
                   3027:   if (typ(q) != t_MAT || lg(q[1]) != n)
                   3028:     err(talker,"invalid quadratic form in qfeval");
                   3029:   if (typ(x) != t_COL || lg(x) != n)
                   3030:     err(talker,"invalid vector in qfeval");
                   3031:
                   3032:   return qfeval0(q,x,n);
                   3033: }
                   3034:
                   3035: /* the Horner-type evaluation (mul x 2/3) would force us to use gmul and not
                   3036:  * mulii (more than 4 x slower for small entries). Not worth it.
                   3037:  */
                   3038: static GEN
                   3039: qfbeval0_i(GEN q, GEN x, GEN y, long n)
                   3040: {
1.2     ! noro     3041:   long i, j;
        !          3042:   gpmem_t av=avma;
1.1       noro     3043:   GEN res = gmul(gcoeff(q,1,1), mulii((GEN)x[1],(GEN)y[1]));
                   3044:
                   3045:   for (i=2;i<n;i++)
                   3046:   {
                   3047:     for (j=1;j<i;j++)
                   3048:     {
                   3049:       GEN p1 = addii(mulii((GEN)x[i],(GEN)y[j]), mulii((GEN)x[j],(GEN)y[i]));
                   3050:       res = gadd(res, gmul(gcoeff(q,i,j),p1));
                   3051:     }
                   3052:     res = gadd(res, gmul(gcoeff(q,i,i), mulii((GEN)x[i],(GEN)y[i])));
                   3053:   }
                   3054:   return gerepileupto(av,res);
                   3055: }
                   3056:
                   3057: #if 0
                   3058: static GEN
                   3059: qfbeval0(GEN q, GEN x, GEN y, long n)
                   3060: {
1.2     ! noro     3061:   long i, j;
        !          3062:   gpmem_t av=avma;
1.1       noro     3063:   GEN res = gmul(gcoeff(q,1,1), gmul((GEN)x[1],(GEN)y[1]));
                   3064:
                   3065:   for (i=2;i<n;i++)
                   3066:   {
                   3067:     for (j=1;j<i;j++)
                   3068:     {
                   3069:       GEN p1 = gadd(gmul((GEN)x[i],(GEN)y[j]), gmul((GEN)x[j],(GEN)y[i]));
                   3070:       res = gadd(res, gmul(gcoeff(q,i,j),p1));
                   3071:     }
                   3072:     res = gadd(res, gmul(gcoeff(q,i,i), gmul((GEN)x[i],(GEN)y[i])));
                   3073:   }
                   3074:   return gerepileupto(av,res);
                   3075: }
                   3076: #else
                   3077: static GEN
                   3078: qfbeval0(GEN q, GEN x, GEN y, long n)
                   3079: {
1.2     ! noro     3080:   long i, j;
        !          3081:   gpmem_t av=avma;
1.1       noro     3082:   GEN res = gmul(gcoeff(q,1,1), gmul((GEN)x[1], (GEN)y[1]));
                   3083:
                   3084:   for (i=2; i<n; i++)
                   3085:   {
                   3086:     GEN l = (GEN)q[i];
                   3087:     GEN sx = gmul((GEN)l[1], (GEN)y[1]);
                   3088:     GEN sy = gmul((GEN)l[1], (GEN)x[1]);
                   3089:     for (j=2; j<i; j++)
                   3090:     {
                   3091:       sx = gadd(sx, gmul((GEN)l[j],(GEN)y[j]));
                   3092:       sy = gadd(sy, gmul((GEN)l[j],(GEN)x[j]));
                   3093:     }
                   3094:     sx = gadd(sx, gmul((GEN)l[i],(GEN)y[i]));
                   3095:
                   3096:     sx = gmul((GEN)x[i], sx);
                   3097:     sy = gmul((GEN)y[i], sy);
                   3098:     res = gadd(res, gadd(sx,sy));
                   3099:   }
                   3100:   return gerepileupto(av,res);
                   3101: }
                   3102: #endif
                   3103:
                   3104: /* We assume q is a real symetric matrix */
                   3105: GEN
                   3106: qfbeval(GEN q, GEN x, GEN y)
                   3107: {
                   3108:   long n=lg(q);
                   3109:
                   3110:   if (n==1)
                   3111:   {
                   3112:     if (typ(q) != t_MAT || lg(x) != 1 || lg(y) != 1)
                   3113:       err(talker,"invalid data in qfbeval");
                   3114:     return gzero;
                   3115:   }
                   3116:   if (typ(q) != t_MAT || lg(q[1]) != n)
                   3117:     err(talker,"invalid quadratic form in qfbeval");
                   3118:   if (typ(x) != t_COL || lg(x) != n || typ(y) != t_COL || lg(y) != n)
                   3119:     err(talker,"invalid vector in qfbeval");
                   3120:
                   3121:   return qfbeval0(q,x,y,n);
                   3122: }
                   3123:
                   3124: /* yield X = M'.q.M, assuming q is symetric.
                   3125:  * X_ij are X_ji identical, not copies
                   3126:  * if flag is set, M has integer entries
                   3127:  */
                   3128: GEN
                   3129: qf_base_change(GEN q, GEN M, int flag)
                   3130: {
                   3131:   long i,j, k = lg(M), n=lg(q);
                   3132:   GEN res = cgetg(k,t_MAT);
                   3133:   GEN (*qf)(GEN,GEN,long)  = flag? qfeval0_i:  qfeval0;
                   3134:   GEN (*qfb)(GEN,GEN,GEN,long) = flag? qfbeval0_i: qfbeval0;
                   3135:
                   3136:   if (n==1)
                   3137:   {
                   3138:     if (typ(q) != t_MAT || k != 1)
                   3139:       err(talker,"invalid data in qf_base_change");
                   3140:     return res;
                   3141:   }
                   3142:   if (typ(M) != t_MAT || k == 1 || lg(M[1]) != n)
                   3143:     err(talker,"invalid base change matrix in qf_base_change");
                   3144:
                   3145:   for (i=1;i<k;i++)
                   3146:   {
                   3147:     res[i] = lgetg(k,t_COL);
                   3148:     coeff(res,i,i) = (long) qf(q,(GEN)M[i],n);
                   3149:   }
                   3150:   for (i=2;i<k;i++)
                   3151:     for (j=1;j<i;j++)
                   3152:       coeff(res,i,j)=coeff(res,j,i) = (long) qfb(q,(GEN)M[i],(GEN)M[j],n);
                   3153:   return res;
                   3154: }
                   3155:
                   3156: /* return Re(x * y), x and y scalars */
                   3157: GEN
                   3158: mul_real(GEN x, GEN y)
                   3159: {
                   3160:   if (typ(x) == t_COMPLEX)
                   3161:   {
                   3162:     if (typ(y) == t_COMPLEX)
                   3163:     {
1.2     ! noro     3164:       gpmem_t av=avma, tetpil;
1.1       noro     3165:       GEN p1 = gmul((GEN)x[1], (GEN) y[1]);
                   3166:       GEN p2 = gneg(gmul((GEN)x[2], (GEN) y[2]));
                   3167:       tetpil=avma; return gerepile(av,tetpil,gadd(p1,p2));
                   3168:     }
                   3169:     x = (GEN)x[1];
                   3170:   }
                   3171:   else if (typ(y) == t_COMPLEX) y = (GEN)y[1];
                   3172:   return gmul(x,y);
                   3173: }
                   3174:
                   3175: /* Compute Re(x * y), x and y matrices of compatible dimensions
                   3176:  * assume lx, ly > 1, and scalar entries */
                   3177: GEN
                   3178: mulmat_real(GEN x, GEN y)
                   3179: {
1.2     ! noro     3180:   long i, j, k, lx = lg(x), ly = lg(y), l = lg(x[1]);
        !          3181:   gpmem_t av;
1.1       noro     3182:   GEN p1, z = cgetg(ly,t_MAT);
                   3183:
                   3184:   for (j=1; j<ly; j++)
                   3185:   {
                   3186:     z[j] = lgetg(l,t_COL);
                   3187:     for (i=1; i<l; i++)
                   3188:     {
                   3189:       p1 = gzero; av=avma;
                   3190:       for (k=1; k<lx; k++)
                   3191:         p1 = gadd(p1, mul_real(gcoeff(x,i,k),gcoeff(y,k,j)));
                   3192:       coeff(z,i,j)=lpileupto(av, p1);
                   3193:     }
                   3194:   }
                   3195:   return z;
                   3196: }
                   3197:
                   3198: static GEN
                   3199: hqfeval0(GEN q, GEN x, long n)
                   3200: {
1.2     ! noro     3201:   long i, j;
        !          3202:   gpmem_t av=avma;
1.1       noro     3203:   GEN res=gzero;
                   3204:
                   3205:   for (i=2;i<n;i++)
                   3206:     for (j=1;j<i;j++)
                   3207:     {
                   3208:       GEN p1 = gmul((GEN)x[i],gconj((GEN)x[j]));
                   3209:       res = gadd(res, mul_real(gcoeff(q,i,j),p1));
                   3210:     }
                   3211:   res=gshift(res,1);
                   3212:   for (i=1;i<n;i++)
                   3213:     res = gadd(res, gmul(gcoeff(q,i,i), gnorm((GEN)x[i])) );
                   3214:   return gerepileupto(av,res);
                   3215: }
                   3216:
                   3217: /* We assume q is a hermitian complex matrix */
                   3218: GEN
                   3219: hqfeval(GEN q, GEN x)
                   3220: {
                   3221:   long n=lg(q);
                   3222:
                   3223:   if (n==1)
                   3224:   {
                   3225:     if (typ(q) != t_MAT || lg(x) != 1)
                   3226:       err(talker,"invalid data in hqfeval");
                   3227:     return gzero;
                   3228:   }
                   3229:   if (typ(q) != t_MAT || lg(q[1]) != n)
                   3230:     err(talker,"invalid quadratic form in hqfeval");
                   3231:   if (typ(x) != t_COL || lg(x) != n)
                   3232:     err(talker,"invalid vector in hqfeval");
                   3233:
                   3234:   return hqfeval0(q,x,n);
                   3235: }
                   3236:
                   3237: GEN
                   3238: poleval(GEN x, GEN y)
                   3239: {
1.2     ! noro     3240:   long i, j, imin, tx = typ(x);
        !          3241:   gpmem_t av0 = avma, av, lim;
        !          3242:   GEN p1, p2, r, s;
1.1       noro     3243:
                   3244:   if (is_scalar_t(tx)) return gcopy(x);
                   3245:   switch(tx)
                   3246:   {
                   3247:     case t_POL:
1.2     ! noro     3248:       i = lgef(x)-1; imin = 2; break;
1.1       noro     3249:
1.2     ! noro     3250:     case t_RFRAC: case t_RFRACN:
        !          3251:       p1 = poleval((GEN)x[1],y);
        !          3252:       p2 = poleval((GEN)x[2],y);
        !          3253:       return gerepileupto(av0, gdiv(p1,p2));
1.1       noro     3254:
                   3255:     case t_VEC: case t_COL:
1.2     ! noro     3256:       i = lg(x)-1; imin = 1; break;
1.1       noro     3257:     default: err(typeer,"poleval");
                   3258:       return NULL; /* not reached */
                   3259:   }
                   3260:   if (i<=imin)
                   3261:     return (i==imin)? gcopy((GEN)x[imin]): gzero;
                   3262:
1.2     ! noro     3263:   lim = stack_lim(av0,2);
        !          3264:   p1 = (GEN)x[i]; i--;
1.1       noro     3265:   if (typ(y)!=t_COMPLEX)
                   3266:   {
                   3267: #if 0 /* standard Horner's rule */
                   3268:     for ( ; i>=imin; i--)
                   3269:       p1 = gadd(gmul(p1,y),(GEN)x[i]);
                   3270: #endif
                   3271:     /* specific attention to sparse polynomials */
                   3272:     for ( ; i>=imin; i=j-1)
                   3273:     {
                   3274:       for (j=i; gcmp0((GEN)x[j]); j--)
                   3275:         if (j==imin)
                   3276:         {
1.2     ! noro     3277:           if (i!=j) y = gpowgs(y, i-j+1);
        !          3278:           return gerepileupto(av0, gmul(p1,y));
1.1       noro     3279:         }
1.2     ! noro     3280:       r = (i==j)? y: gpowgs(y, i-j+1);
1.1       noro     3281:       p1 = gadd(gmul(p1,r), (GEN)x[j]);
1.2     ! noro     3282:       if (low_stack(lim, stack_lim(av0,2)))
        !          3283:       {
        !          3284:         if (DEBUGMEM>1) err(warnmem,"poleval: i = %ld",i);
        !          3285:         p1 = gerepileupto(av0, p1);
        !          3286:       }
1.1       noro     3287:     }
1.2     ! noro     3288:     return gerepileupto(av0,p1);
1.1       noro     3289:   }
                   3290:
1.2     ! noro     3291:   p2 = (GEN)x[i]; i--; r = gtrace(y); s = gneg_i(gnorm(y));
        !          3292:   av = avma;
1.1       noro     3293:   for ( ; i>=imin; i--)
                   3294:   {
1.2     ! noro     3295:     GEN p3 = gadd(p2, gmul(r, p1));
        !          3296:     p2 = gadd((GEN)x[i], gmul(s, p1)); p1 = p3;
        !          3297:     if (low_stack(lim, stack_lim(av0,2)))
        !          3298:     {
        !          3299:       if (DEBUGMEM>1) err(warnmem,"poleval: i = %ld",i);
        !          3300:       gerepileall(av, 2, &p1, &p2);
        !          3301:     }
1.1       noro     3302:   }
1.2     ! noro     3303:   return gerepileupto(av0, gadd(p2, gmul(y,p1)));
1.1       noro     3304: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>