[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.1.1.1

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

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