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

Annotation of OpenXM_contrib/pari-2.2/src/basemath/gen2.c, Revision 1.1.1.1

1.1       noro        1: /* $Id: gen2.c,v 1.33 2001/10/01 12:11:30 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: /**                        (second part)                           **/
                     20: /**                                                                **/
                     21: /********************************************************************/
                     22: #include "pari.h"
                     23:
                     24: /*******************************************************************/
                     25: /*                                                                 */
                     26: /*                    OPERATIONS BY VALUE                          */
                     27: /*            f is a pointer to the function called.               */
                     28: /*            result is gaffect-ed to last parameter               */
                     29: /*                                                                 */
                     30: /*******************************************************************/
                     31:
                     32: void
                     33: gop1z(GEN (*f)(GEN), GEN x, GEN y)
                     34: {
                     35:   long av=avma; gaffect(f(x),y); avma=av;
                     36: }
                     37:
                     38: void
                     39: gop2z(GEN (*f)(GEN, GEN), GEN x, GEN y, GEN z)
                     40: {
                     41:   long av=avma; gaffect(f(x,y),z); avma=av;
                     42: }
                     43:
                     44: void
                     45: gops2gsz(GEN (*f)(GEN, long), GEN x, long s, GEN z)
                     46: {
                     47:   long av=avma; gaffect(f(x,s),z); avma=av;
                     48: }
                     49:
                     50: void
                     51: gops2sgz(GEN (*f)(long, GEN), long s, GEN y, GEN z)
                     52: {
                     53:   long av=avma; gaffect(f(s,y),z); avma=av;
                     54: }
                     55:
                     56: void
                     57: gops2ssz(GEN (*f)(long, long), long s, long y, GEN z)
                     58: {
                     59:   long av=avma; gaffect(f(s,y),z); avma=av;
                     60: }
                     61:
                     62: /*******************************************************************/
                     63: /*                                                                 */
                     64: /*                OPERATIONS USING SMALL INTEGERS                  */
                     65: /*                                                                 */
                     66: /*******************************************************************/
                     67:
                     68: /* small int prototype */
                     69: static long court_p[] = { evaltyp(t_INT) | m_evallg(3),0,0 };
                     70:
                     71: GEN
                     72: gopsg2(GEN (*f)(GEN, GEN), long s, GEN y)
                     73: {
                     74:   affsi(s,court_p); return f(court_p,y);
                     75: }
                     76:
                     77: GEN
                     78: gopgs2(GEN (*f)(GEN, GEN), GEN y, long s)
                     79: {
                     80:   affsi(s,court_p); return f(y,court_p);
                     81: }
                     82:
                     83: long
                     84: opgs2(int (*f)(GEN, GEN), GEN y, long s)
                     85: {
                     86:   affsi(s,court_p); return f(y,court_p);
                     87: }
                     88:
                     89: void
                     90: gopsg2z(GEN (*f)(GEN, GEN), long s, GEN y, GEN z)
                     91: {
                     92:   long av=avma;
                     93:   affsi(s,court_p); gaffect(f(court_p,y),z); avma=av;
                     94: }
                     95:
                     96: void
                     97: gopgs2z(GEN (*f)(GEN, GEN), GEN y, long s, GEN z)
                     98: {
                     99:   long av=avma;
                    100:   affsi(s,court_p); gaffect(f(y,court_p),z); avma=av;
                    101: }
                    102:
                    103: /*******************************************************************/
                    104: /*                                                                 */
                    105: /*                    CREATION OF A P-ADIC GEN                     */
                    106: /*                                                                 */
                    107: /*******************************************************************/
                    108:
                    109: /* y[4] not filled */
                    110: static GEN
                    111: cgetp2(GEN x, long v)
                    112: {
                    113:   GEN y = cgetg(5,t_PADIC);
                    114:   y[1] = evalprecp(precp(x)) | evalvalp(v);
                    115:   icopyifstack(x[2], y[2]);
                    116:   y[3] = licopy((GEN)x[3]); return y;
                    117: }
                    118:
                    119: GEN
                    120: cgetp(GEN x)
                    121: {
                    122:   GEN y = cgetp2(x, 0);
                    123:   y[4] = lgeti(lgefint(x[3])); return y;
                    124: }
                    125:
                    126: GEN
                    127: pureimag(GEN x)
                    128: {
                    129:   GEN y = cgetg(3,t_COMPLEX);
                    130:   y[1] = zero;
                    131:   y[2] = (long)x; return y;
                    132: }
                    133:
                    134: /*******************************************************************/
                    135: /*                                                                 */
                    136: /*                            SIZES                                */
                    137: /*                                                                 */
                    138: /*******************************************************************/
                    139:
                    140: long
                    141: glength(GEN x)
                    142: {
                    143:   switch(typ(x))
                    144:   {
                    145:     case t_INT: return lgefint(x)-2;
                    146:     case t_POL: case t_LIST: return lgef(x)-2;
                    147:     case t_REAL: return signe(x)? lg(x)-2: 0;
                    148:     case t_STR: return strlen(GSTR(x));
                    149:   }
                    150:   return lg(x)-lontyp[typ(x)];
                    151: }
                    152:
                    153: GEN
                    154: matsize(GEN x)
                    155: {
                    156:   GEN y=cgetg(3,t_VEC);
                    157:
                    158:   switch(typ(x))
                    159:   {
                    160:     case t_VEC:
                    161:       y[1]=un; y[2]=lstoi(lg(x)-1); break;
                    162:     case t_COL:
                    163:       y[1]=lstoi(lg(x)-1); y[2]=un; break;
                    164:     case t_MAT:
                    165:       y[2]=lstoi(lg(x)-1);
                    166:       y[1]=(lg(x)==1)? zero: lstoi(lg(x[1])-1); break;
                    167:     default: err(typeer,"matsize");
                    168:   }
                    169:   return y;
                    170: }
                    171:
                    172: long
                    173: taille(GEN x)
                    174: {
                    175:   long i,n,lx, tx = typ(x);
                    176:   n = lg(x);
                    177:   if (is_recursive_t(tx))
                    178:   {
                    179:     lx = (tx==t_POL || tx==t_LIST)? lgef(x): n;
                    180:     for (i=lontyp[tx]; i<lx; i++) n += taille((GEN)x[i]);
                    181:   }
                    182:   return n;
                    183: }
                    184:
                    185: long
                    186: taille2(GEN x) { return taille(x)<<TWOPOTBYTES_IN_LONG; }
                    187:
                    188: /*******************************************************************/
                    189: /*                                                                 */
                    190: /*                            GREFFE                               */
                    191: /*              Greffe d'une serie sur un polynome                 */
                    192: /*                                                                 */
                    193: /*******************************************************************/
                    194:
                    195: GEN
                    196: greffe(GEN x, long l, long use_stack)
                    197: {
                    198:   long i,e,k,vx;
                    199:   GEN y;
                    200:
                    201:   if (typ(x)!=t_POL) err(notpoler,"greffe");
                    202:   if (use_stack) y = cgetg(l,t_SER);
                    203:   else
                    204:   {
                    205:     y = (GEN) gpmalloc(l*sizeof(long));
                    206:     y[0] = evaltyp(t_SER) | evallg(l);
                    207:   }
                    208:   if (gcmp0(x))
                    209:   {
                    210:     y[1]=evalvalp(l-2) | evalvarn(varn(x));
                    211:     i=2; while(i<l) { y[i]=x[2]; i++; }
                    212:     return y;
                    213:   }
                    214:   vx=varn(x); e=gval(x,vx);
                    215:   y[1]=evalsigne(1) | evalvalp(e) | evalvarn(vx);
                    216:   k=lgef(x)-e-1; i=l-1;
                    217:   if (k<l)
                    218:     while (i>k) { y[i]=zero; i--; }
                    219:   while (i>=2) { y[i]=x[i+e]; i--; }
                    220:   return y;
                    221: }
                    222:
                    223: /*******************************************************************/
                    224: /*                                                                 */
                    225: /*                 CONVERSION GEN --> long                         */
                    226: /*                                                                 */
                    227: /*******************************************************************/
                    228:
                    229: long
                    230: gtolong(GEN x)
                    231: {
                    232:   long y,tx=typ(x),av=avma;
                    233:
                    234:   switch(tx)
                    235:   {
                    236:     case t_INT:
                    237:       return itos(x);
                    238:     case t_REAL: case t_FRAC: case t_FRACN:
                    239:       y=itos(ground(x)); avma=av; return y;
                    240:     case t_COMPLEX:
                    241:       if (gcmp0((GEN)x[2])) return gtolong((GEN)x[1]); break;
                    242:     case t_QUAD:
                    243:       if (gcmp0((GEN)x[3])) return gtolong((GEN)x[2]); break;
                    244:   }
                    245:   err(typeer,"gtolong");
                    246:   return 0; /* not reached */
                    247: }
                    248:
                    249: /*******************************************************************/
                    250: /*                                                                 */
                    251: /*                         COMPARISONS                             */
                    252: /*                                                                 */
                    253: /*******************************************************************/
                    254:
                    255: /* returns 1 whenever x = 0, and 0 otherwise */
                    256: int
                    257: gcmp0(GEN x)
                    258: {
                    259:   switch(typ(x))
                    260:   {
                    261:     case t_INT: case t_REAL: case t_POL: case t_SER:
                    262:       return !signe(x);
                    263:
                    264:     case t_INTMOD: case t_POLMOD:
                    265:       return gcmp0((GEN)x[2]);
                    266:
                    267:     case t_FRAC: case t_FRACN:
                    268:       return !signe(x[1]);
                    269:
                    270:     case t_COMPLEX:
                    271:      /* is 0 iff norm(x) would be 0 (can happen with Re(x) and Im(x) != 0
                    272:       * only if Re(x) and Im(x) are of type t_REAL). See mp.c:addrr().
                    273:       */
                    274:       if (gcmp0((GEN)x[1]))
                    275:       {
                    276:        if (gcmp0((GEN)x[2])) return 1;
                    277:        if (typ(x[1])!=t_REAL || typ(x[2])!=t_REAL) return 0;
                    278:        return (expo(x[1])>expo(x[2]));
                    279:       }
                    280:       if (gcmp0((GEN)x[2]))
                    281:       {
                    282:        if (typ(x[1])!=t_REAL || typ(x[2])!=t_REAL) return 0;
                    283:        return (expo(x[2])>expo(x[1]));
                    284:       }
                    285:       return 0;
                    286:
                    287:     case t_PADIC:
                    288:       return !signe(x[4]);
                    289:
                    290:     case t_QUAD:
                    291:       return gcmp0((GEN)x[2]) && gcmp0((GEN)x[3]);
                    292:
                    293:     case t_RFRAC: case t_RFRACN:
                    294:       return gcmp0((GEN)x[1]);
                    295:
                    296:     case t_VEC: case t_COL: case t_MAT:
                    297:     {
                    298:       long i;
                    299:       for (i=lg(x)-1; i; i--)
                    300:         if (!gcmp0((GEN)x[i])) return 0;
                    301:       return 1;
                    302:     }
                    303:   }
                    304:   return 0;
                    305: }
                    306:
                    307: /* returns 1 whenever x = 1, 0 otherwise */
                    308: int
                    309: gcmp1(GEN x)
                    310: {
                    311:   switch(typ(x))
                    312:   {
                    313:     case t_INT:
                    314:       return is_pm1(x) && signe(x)==1;
                    315:
                    316:     case t_REAL:
                    317:       if (signe(x) > 0 && expo(x)==0 && (ulong)x[2]==HIGHBIT)
                    318:       {
                    319:         long i,lx = lg(x);
                    320:         for (i=3; i<lx; i++)
                    321:           if (x[i]) return 0;
                    322:         return 1;
                    323:       }
                    324:       return 0;
                    325:
                    326:     case t_INTMOD: case t_POLMOD:
                    327:       return gcmp1((GEN)x[2]);
                    328:
                    329:     case t_FRAC:
                    330:       return gcmp1((GEN)x[1]) && gcmp1((GEN)x[2]);
                    331:
                    332:     case t_FRACN:
                    333:       return egalii((GEN)x[1],(GEN)x[2]);
                    334:
                    335:     case t_COMPLEX:
                    336:       return gcmp1((GEN)x[1]) && gcmp0((GEN)x[2]);
                    337:
                    338:     case t_PADIC:
                    339:       return !valp(x) && gcmp1((GEN)x[4]);
                    340:
                    341:     case t_QUAD:
                    342:       return gcmp1((GEN)x[2]) && gcmp0((GEN)x[3]);
                    343:
                    344:     case t_POL:
                    345:       return lgef(x)==3 && gcmp1((GEN)x[2]);
                    346:   }
                    347:   return 0;
                    348: }
                    349:
                    350: /* returns 1 whenever the x = -1, 0 otherwise */
                    351: int
                    352: gcmp_1(GEN x)
                    353: {
                    354:   long l,y;
                    355:   GEN p1;
                    356:
                    357:   switch(typ(x))
                    358:   {
                    359:     case t_INT:
                    360:       return is_pm1(x) && signe(x)== -1;
                    361:
                    362:     case t_REAL:
                    363:       if (signe(x) < 0 && expo(x)==0 && (ulong)x[2]==HIGHBIT)
                    364:       {
                    365:         long i,lx = lg(x);
                    366:         for (i=3; i<lx; i++)
                    367:           if (x[i]) return 0;
                    368:         return 1;
                    369:       }
                    370:       return 0;
                    371:
                    372:     case t_INTMOD:
                    373:       l=avma; y=egalii(addsi(1,(GEN)x[2]), (GEN)x[1]); avma=l; return y;
                    374:
                    375:     case t_FRAC: case t_FRACN:
                    376:       l = signe(x[1]);
                    377:       return l && l == -signe(x[2]) && !absi_cmp((GEN)x[1],(GEN)x[2]);
                    378:
                    379:     case t_COMPLEX:
                    380:       return gcmp_1((GEN)x[1]) && gcmp0((GEN)x[2]);
                    381:
                    382:     case t_QUAD:
                    383:       return gcmp_1((GEN)x[2]) && gcmp0((GEN)x[3]);
                    384:
                    385:     case t_PADIC:
                    386:       l=avma; y=gegal(addsi(1,(GEN)x[4]), (GEN)x[3]); avma=l; return y;
                    387:
                    388:     case t_POLMOD:
                    389:       l=avma; p1=gadd(gun,(GEN)x[2]);
                    390:       y = signe(p1) && !gegal(p1,(GEN)x[1]); avma=l; return !y;
                    391:
                    392:     case t_POL:
                    393:       return lgef(x)==3 && gcmp_1((GEN)x[2]);
                    394:   }
                    395:   return 0;
                    396: }
                    397:
                    398: /* returns the sign of x - y when it makes sense. 0 otherwise */
                    399: int
                    400: gcmp(GEN x, GEN y)
                    401: {
                    402:   long tx,ty,f,av;
                    403:
                    404:   tx=typ(x); ty=typ(y);
                    405:   if (is_intreal_t(tx))
                    406:     { if (is_intreal_t(ty)) return mpcmp(x,y); }
                    407:   else
                    408:   {
                    409:     if (tx==t_STR)
                    410:     {
                    411:       if (ty != t_STR) return 1;
                    412:       return strcmp(GSTR(x),GSTR(y));
                    413:     }
                    414:     if (!is_frac_t(tx)) err(typeer,"comparison");
                    415:   }
                    416:   if (ty == t_STR) return -1;
                    417:   if (!is_intreal_t(ty) && !is_frac_t(ty)) err(typeer,"comparison");
                    418:   av=avma; y=gneg_i(y); f=gsigne(gadd(x,y)); avma=av; return f;
                    419: }
                    420:
                    421: /* as gcmp for vector/matrices, using lexicographic ordering on components */
                    422: int
                    423: lexcmp(GEN x, GEN y)
                    424: {
                    425:   const long tx=typ(x), ty=typ(y);
                    426:   long lx,ly,l,fl,i;
                    427:
                    428:   ly=lg(y);
                    429:   if (!is_matvec_t(tx))
                    430:   {
                    431:     if (!is_matvec_t(ty)) return gcmp(x,y);
                    432:     if (ly==1) return 1;
                    433:     fl = lexcmp(x,(GEN)y[1]);
                    434:     if (fl) return fl;
                    435:     return (ly>2)? -1:0;
                    436:   }
                    437:
                    438:   lx=lg(x);
                    439:   if (!is_matvec_t(ty))
                    440:   {
                    441:     if (lx==1) return -1;
                    442:     fl = lexcmp(y,(GEN)x[1]);
                    443:     if (fl) return -fl;
                    444:     return (lx>2)? 1:0;
                    445:   }
                    446:
                    447:   /* x and y are matvec_t */
                    448:   if (ly==1) return (lx==1)?0:1;
                    449:   if (lx==1) return -1;
                    450:   if (ty==t_MAT)
                    451:   {
                    452:     if (tx != t_MAT)
                    453:     {
                    454:       fl = lexcmp(x,(GEN)y[1]);
                    455:       if (fl) return fl;
                    456:       return (ly>2)?-1:0;
                    457:     }
                    458:   }
                    459:   else if (tx==t_MAT)
                    460:   {
                    461:     fl = lexcmp(y,(GEN)x[1]);
                    462:     if (fl) return -fl;
                    463:     return (ly>2)?1:0;
                    464:   }
                    465:
                    466:   /* tx = ty = t_MAT, or x and y are both vect_t */
                    467:   l=min(lx,ly);
                    468:   for (i=1; i<l; i++)
                    469:   {
                    470:     fl = lexcmp((GEN)x[i],(GEN)y[i]);
                    471:     if (fl) return fl;
                    472:   }
                    473:   return (ly != lx)? -1 : 0;
                    474: }
                    475:
                    476: /*****************************************************************/
                    477: /*                                                               */
                    478: /*                          EQUALITY                             */
                    479: /*                returns 1 if x == y, 0 otherwise               */
                    480: /*                                                               */
                    481: /*****************************************************************/
                    482:
                    483: /* x,y t_POL */
                    484: static int
                    485: polegal(GEN x, GEN y)
                    486: {
                    487:   long i, lx = lgef(x);
                    488:
                    489:   if (x[1] != y[1] && (lgef(y) != lx || lx > 3)) return 0;
                    490:   for (i = 2; i < lx; i++)
                    491:     if (!gegal((GEN)x[i],(GEN)y[i])) return 0;
                    492:   return 1;
                    493: }
                    494:
                    495: #define MASK(x) (((ulong)(x)) & (TYPBITS | LGBITS))
                    496: /* typ(x) = typ(y) = t_VEC/COL/MAT */
                    497: static int
                    498: vecegal(GEN x, GEN y)
                    499: {
                    500:   long i;
                    501:
                    502:   if (MASK(x[0]) != MASK(y[0])) return 0;
                    503:
                    504:   i = lg(x)-1;
                    505:   if (typ(x) != t_MAT)
                    506:   {
                    507:     for ( ; i; i--)
                    508:       if (! gegal((GEN)x[i],(GEN)y[i]) ) return 0;
                    509:     return 1;
                    510:   }
                    511:   for ( ; i; i--)
                    512:     if (! vecegal((GEN)x[i],(GEN)y[i]) ) return 0;
                    513:   return 1;
                    514: }
                    515:
                    516: int
                    517: gegal(GEN x, GEN y)
                    518: {
                    519:   ulong av,tx;
                    520:   long i;
                    521:
                    522:   if (x == y) return 1;
                    523:   tx = typ(x);
                    524:   if (tx==typ(y))
                    525:     switch(tx)
                    526:     {
                    527:       case t_INT:
                    528:         return egalii(x,y);
                    529:
                    530:       case t_POL:
                    531:         return polegal(x,y);
                    532:
                    533:       case t_COMPLEX:
                    534:        return gegal((GEN)x[1],(GEN)y[1]) && gegal((GEN)x[2],(GEN)y[2]);
                    535:
                    536:       case t_INTMOD: case t_POLMOD:
                    537:        return gegal((GEN)x[2],(GEN)y[2])
                    538:             && (x[1]==y[1] || gegal((GEN)x[1],(GEN)y[1]));
                    539:
                    540:       case t_QFR:
                    541:            if (!gegal((GEN)x[4],(GEN)y[4])) return 0; /* fall through */
                    542:       case t_QUAD: case t_QFI:
                    543:        return gegal((GEN)x[1],(GEN)y[1])
                    544:            && gegal((GEN)x[2],(GEN)y[2])
                    545:            && gegal((GEN)x[3],(GEN)y[3]);
                    546:
                    547:       case t_FRAC:
                    548:        return gegal((GEN)x[1], (GEN)y[1])
                    549:             && gegal((GEN)x[2], (GEN)y[2]);
                    550:
                    551:       case t_FRACN: case t_RFRAC: case t_RFRACN:
                    552:        av=avma; i=gegal(gmul((GEN)x[1],(GEN)y[2]),gmul((GEN)x[2],(GEN)y[1]));
                    553:        avma=av; return i;
                    554:
                    555:       case t_STR:
                    556:         return !strcmp(GSTR(x),GSTR(y));
                    557:
                    558:       case t_VEC: case t_COL: case t_MAT:
                    559:         return vecegal(x,y);
                    560:       case t_VECSMALL:
                    561:         if (MASK(x[0]) != MASK(y[0])) return 0;
                    562:         for (i = lg(x)-1; i; i--)
                    563:           if (x[i] != y[i]) return 0;
                    564:         return 1;
                    565:     }
                    566:   {
                    567:     jmp_buf env;
                    568:     VOLATILE long av = avma;
                    569:     void *c;
                    570:     if (setjmp(env)) i = 0;
                    571:     else
                    572:     {
                    573:       c = err_catch(-1, env, NULL);
                    574:       i = gcmp0(gadd(x, gneg_i(y)));
                    575:     }
                    576:     err_leave(&c);
                    577:     avma = av;
                    578:   }
                    579:   return i;
                    580: }
                    581: #undef MASK
                    582:
                    583: /*******************************************************************/
                    584: /*                                                                 */
                    585: /*                          VALUATION                              */
                    586: /*             p is either an int or a polynomial.                 */
                    587: /*  returns the largest exponent of p dividing x when this makes   */
                    588: /*  sense : error for types real, integermod and polymod if p does */
                    589: /*  not divide the modulus, q-adic if q!=p.                        */
                    590: /*                                                                 */
                    591: /*******************************************************************/
                    592:
                    593: static long
                    594: minval(GEN x, GEN p, long first, long lx)
                    595: {
                    596:   long i,k, val = VERYBIGINT;
                    597:   for (i=first; i<lx; i++)
                    598:   {
                    599:     k = ggval((GEN)x[i],p);
                    600:     if (k < val) val = k;
                    601:   }
                    602:   return val;
                    603: }
                    604:
                    605: long
                    606: ggval(GEN x, GEN p)
                    607: {
                    608:   long tx=typ(x), tp=typ(p), av, limit,vx,v,i,val;
                    609:   GEN p1,p2;
                    610:
                    611:   if (isexactzero(x)) return VERYBIGINT;
                    612:   if (is_const_t(tx) && tp==t_POL) return 0;
                    613:   switch(tx)
                    614:   {
                    615:     case t_INT:
                    616:       if (tp != t_INT) break;
                    617:       av=avma; val = pvaluation(x,p, &p1);
                    618:       avma=av; return val;
                    619:
                    620:     case t_INTMOD:
                    621:       av=avma;
                    622:       p1=cgeti(lgefint(x[1]));
                    623:       p2=cgeti(lgefint(x[2]));
                    624:       if (tp!=t_INT || !mpdivis((GEN)x[1],p,p1)) break;
                    625:       if (!mpdivis((GEN)x[2],p,p2)) { avma=av; return 0; }
                    626:       val=1; while (mpdivis(p1,p,p1) && mpdivis(p2,p,p2)) val++;
                    627:       avma=av; return val;
                    628:
                    629:     case t_PADIC:
                    630:       if (tp!=t_INT || !gegal(p,(GEN)x[2])) break;
                    631:       return valp(x);
                    632:
                    633:     case t_POLMOD:
                    634:       if (tp==t_INT) return ggval((GEN)x[2],p);
                    635:       av = avma;
                    636:       if (tp!=t_POL || !poldivis((GEN)x[1],p,&p1)) break;
                    637:       if (!poldivis((GEN)x[2],p,&p2)) { avma=av; return 0; }
                    638:       val=1; while (poldivis(p1,p,&p1)&&poldivis(p2,p,&p2)) val++;
                    639:       avma = av; return val;
                    640:
                    641:     case t_POL:
                    642:       if (tp==t_POL)
                    643:       {
                    644:        v=varn(p); vx=varn(x);
                    645:        if (vx == v)
                    646:        {
                    647:          if ((p>=(GEN)polx && p <= (GEN)(polx+MAXVARN)) || ismonome(p))
                    648:           {
                    649:             i=2; while (isexactzero((GEN)x[i])) i++;
                    650:             return i-2;
                    651:           }
                    652:          av = avma; limit=stack_lim(av,1);
                    653:          for (val=0; ; val++)
                    654:          {
                    655:            if (!poldivis(x,p,&x)) break;
                    656:             if (low_stack(limit, stack_lim(av,1)))
                    657:            {
                    658:              if(DEBUGMEM>1) err(warnmem,"ggval");
                    659:              x = gerepilecopy(av, x);
                    660:            }
                    661:          }
                    662:          avma = av; return val;
                    663:        }
                    664:        if (vx > v) return 0;
                    665:       }
                    666:       else if (tp!=t_INT) break;
                    667:       i=2; while (isexactzero((GEN)x[i])) i++;
                    668:       return minval(x,p,i,lgef(x));
                    669:
                    670:     case t_SER:
                    671:       if (tp!=t_POL && tp!=t_SER && tp!=t_INT) break;
                    672:       v=gvar(p); vx=varn(x);
                    673:       if (vx==v) return (long)(valp(x)/ggval(p,polx[v]));
                    674:       if (vx>v) return 0;
                    675:       return minval(x,p,2,lg(x));
                    676:
                    677:     case t_FRAC: case t_FRACN: case t_RFRAC: case t_RFRACN:
                    678:       return ggval((GEN)x[1],p) - ggval((GEN)x[2],p);
                    679:
                    680:     case t_COMPLEX: case t_QUAD: case t_VEC: case t_COL: case t_MAT:
                    681:       return minval(x,p,1,lg(x));
                    682:   }
                    683:   err(talker,"forbidden or conflicting type in gval");
                    684:   return 0; /* not reached */
                    685: }
                    686:
                    687: /* x is non-zero */
                    688: long
                    689: svaluation(ulong x, ulong p, long *py)
                    690: {
                    691:   ulong v = 0;
                    692:   for(;;)
                    693:   {
                    694:     if (x%p) { *py = x; return v; }
                    695:     v++; x/=p;
                    696:   }
                    697: }
                    698:
                    699: /* x is a non-zero integer */
                    700: long
                    701: pvaluation(GEN x, GEN p, GEN *py)
                    702: {
                    703:   long av,v;
                    704:   GEN p1,p2;
                    705:
                    706:   if (egalii(p,gdeux))
                    707:   {
                    708:     v = vali(x);
                    709:     if (py) *py = shifti(x, -v);
                    710:     return v;
                    711:   }
                    712:   if (is_pm1(p))
                    713:   {
                    714:     v = (signe(p) < 0 && signe(x) < 0);
                    715:     if (py) { *py = v? negi(x): icopy(x); }
                    716:     return v;
                    717:   }
                    718:   if (!is_bigint(x))
                    719:   {
                    720:     long y;
                    721:     if (!is_bigint(p))
                    722:     {
                    723:       v = svaluation(x[2],p[2], &y);
                    724:       if (signe(x) < 0) y = -y;
                    725:       if (py) *py = stoi(y);
                    726:     }
                    727:     else
                    728:     {
                    729:       v = 0;
                    730:       if (py) *py = icopy(x);
                    731:     }
                    732:     return v;
                    733:   }
                    734:   av = avma; v = 0; (void)new_chunk(lgefint(x));
                    735:   for(;;)
                    736:   {
                    737:     p1 = dvmdii(x,p,&p2);
                    738:     if (p2 != gzero) { avma=av; if (py) *py = icopy(x); return v; }
                    739:     v++; x = p1;
                    740:   }
                    741: }
                    742:
                    743: /*******************************************************************/
                    744: /*                                                                 */
                    745: /*                       NEGATION: Create -x                       */
                    746: /*                                                                 */
                    747: /*******************************************************************/
                    748:
                    749: GEN
                    750: gneg(GEN x)
                    751: {
                    752:   long tx=typ(x),lx,i;
                    753:   GEN y;
                    754:
                    755:   if (gcmp0(x)) return gcopy(x);
                    756:   switch(tx)
                    757:   {
                    758:     case t_INT: case t_REAL:
                    759:       return mpneg(x);
                    760:
                    761:     case t_INTMOD: y=cgetg(3,t_INTMOD);
                    762:       icopyifstack(x[1],y[1]);
                    763:       y[2] = lsubii((GEN)y[1],(GEN)x[2]);
                    764:       break;
                    765:
                    766:     case t_POLMOD: y=cgetg(3,t_POLMOD);
                    767:       copyifstack(x[1],y[1]);
                    768:       y[2]=lneg((GEN)x[2]); break;
                    769:
                    770:     case t_FRAC: case t_FRACN: case t_RFRAC: case t_RFRACN:
                    771:       y=cgetg(3,tx);
                    772:       y[1]=lneg((GEN)x[1]);
                    773:       y[2]=lcopy((GEN)x[2]); break;
                    774:
                    775:     case t_PADIC:
                    776:       y=cgetp2(x,valp(x));
                    777:       y[4]=lsubii((GEN)x[3],(GEN)x[4]);
                    778:       break;
                    779:
                    780:     case t_QUAD:
                    781:       y=cgetg(4,t_QUAD); copyifstack(x[1],y[1]);
                    782:       y[2]=lneg((GEN)x[2]);
                    783:       y[3]=lneg((GEN)x[3]); break;
                    784:
                    785:     case t_COMPLEX: case t_VEC: case t_COL: case t_MAT:
                    786:       lx=lg(x); y=cgetg(lx,tx);
                    787:       for (i=1; i<lx; i++) y[i]=lneg((GEN)x[i]);
                    788:       break;
                    789:
                    790:     case t_POL:
                    791:       lx=lgef(x); y=cgetg(lx,tx); y[1]=x[1];
                    792:       for (i=2; i<lx; i++) y[i]=lneg((GEN)x[i]);
                    793:       break;
                    794:
                    795:     case t_SER:
                    796:       lx=lg(x); y=cgetg(lx,tx); y[1]=x[1];
                    797:       for (i=2; i<lx; i++) y[i]=lneg((GEN)x[i]);
                    798:       break;
                    799:
                    800:     default:
                    801:       err(typeer,"negation");
                    802:       return NULL; /* not reached */
                    803:   }
                    804:   return y;
                    805: }
                    806:
                    807: GEN
                    808: gneg_i(GEN x)
                    809: {
                    810:   long tx=typ(x),lx,i;
                    811:   GEN y;
                    812:
                    813:   if (gcmp0(x)) return x;
                    814:   switch(tx)
                    815:   {
                    816:     case t_INT: case t_REAL:
                    817:       return mpneg(x);
                    818:
                    819:     case t_INTMOD: y=cgetg(3,t_INTMOD); y[1]=x[1];
                    820:       y[2] = lsubii((GEN)y[1],(GEN)x[2]);
                    821:       break;
                    822:
                    823:     case t_FRAC: case t_FRACN: case t_RFRAC: case t_RFRACN:
                    824:       y=cgetg(3,tx); y[2]=x[2];
                    825:       y[1]=(long)gneg_i((GEN)x[1]); break;
                    826:
                    827:     case t_PADIC: y = cgetg(5,t_PADIC); y[2]=x[2]; y[3]=x[3];
                    828:       y[1] = evalprecp(precp(x)) | evalvalp(valp(x));
                    829:       y[4]=lsubii((GEN)x[3],(GEN)x[4]); break;
                    830:
                    831:     case t_POLMOD: y=cgetg(3,t_POLMOD); y[1]=x[1];
                    832:       y[2]=(long)gneg_i((GEN)x[2]); break;
                    833:
                    834:     case t_QUAD: y=cgetg(4,t_QUAD); y[1]=x[1];
                    835:       y[2]=(long)gneg_i((GEN)x[2]);
                    836:       y[3]=(long)gneg_i((GEN)x[3]); break;
                    837:
                    838:     case t_COMPLEX: case t_VEC: case t_COL: case t_MAT:
                    839:       lx=lg(x); y=cgetg(lx,tx);
                    840:       for (i=1; i<lx; i++) y[i]=(long)gneg_i((GEN)x[i]);
                    841:       break;
                    842:
                    843:     case t_POL: lx=lgef(x); y=cgetg(lx,tx); y[1]=x[1];
                    844:       for (i=2; i<lx; i++) y[i]=(long)gneg_i((GEN)x[i]);
                    845:       break;
                    846:
                    847:     case t_SER: lx=lg(x); y=cgetg(lx,tx); y[1]=x[1];
                    848:       for (i=2; i<lx; i++) y[i]=(long)gneg_i((GEN)x[i]);
                    849:       break;
                    850:
                    851:     default:
                    852:       err(typeer,"negation");
                    853:       return NULL; /* not reached */
                    854:   }
                    855:   return y;
                    856: }
                    857:
                    858: /******************************************************************/
                    859: /*                                                                */
                    860: /*                       ABSOLUTE VALUE                           */
                    861: /*    Create abs(x) if x is integer, real, fraction or complex.   */
                    862: /*                       Error otherwise.                         */
                    863: /*                                                                */
                    864: /******************************************************************/
                    865:
                    866: GEN
                    867: gabs(GEN x, long prec)
                    868: {
                    869:   long tx=typ(x),lx,i,l,tetpil;
                    870:   GEN y,p1;
                    871:
                    872:   switch(tx)
                    873:   {
                    874:     case t_INT: case t_REAL:
                    875:       return mpabs(x);
                    876:
                    877:     case t_FRAC: case t_FRACN: y=cgetg(lg(x),tx);
                    878:       y[1]=labsi((GEN)x[1]);
                    879:       y[2]=labsi((GEN)x[2]); return y;
                    880:
                    881:     case t_COMPLEX:
                    882:       l=avma; p1=gnorm(x);
                    883:       switch(typ(p1))
                    884:       {
                    885:         case t_INT:
                    886:           if (!carrecomplet(p1, &y)) break;
                    887:           return gerepileupto(l, y);
                    888:         case t_FRAC:
                    889:         case t_FRACN:
                    890:         {
                    891:           GEN a,b;
                    892:           if (!carrecomplet((GEN)p1[1], &a)) break;
                    893:           if (!carrecomplet((GEN)p1[2], &b)) break;
                    894:           return gerepileupto(l, gdiv(a,b));
                    895:         }
                    896:       }
                    897:       tetpil=avma;
                    898:       return gerepile(l,tetpil,gsqrt(p1,prec));
                    899:
                    900:     case t_QUAD:
                    901:       l=avma; p1=gmul(x, realun(prec)); tetpil=avma;
                    902:       return gerepile(l,tetpil,gabs(p1,prec));
                    903:
                    904:     case t_POL:
                    905:       lx=lgef(x); if (lx<=2) return gcopy(x);
                    906:       p1=(GEN)x[lx-1];
                    907:       switch(typ(p1))
                    908:       {
                    909:        case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
                    910:          if (gsigne(p1)<0) return gneg(x);
                    911:       }
                    912:       return gcopy(x);
                    913:
                    914:    case t_SER:
                    915:      if (valp(x) || !signe(x) || lg(x)<3)
                    916:        err(talker,"abs is not analytic at 0");
                    917:      if (gsigne((GEN) x[2])<0) return gneg(x);
                    918:      return gcopy(x);
                    919:
                    920:     case t_VEC: case t_COL: case t_MAT:
                    921:       lx=lg(x); y=cgetg(lx,tx);
                    922:       for (i=1; i<lx; i++)
                    923:         y[i]=(long)gabs((GEN)x[i],prec);
                    924:       return y;
                    925:   }
                    926:   err(typeer,"gabs");
                    927:   return NULL; /* not reached */
                    928: }
                    929:
                    930: GEN
                    931: gmax(GEN x, GEN y)
                    932: {
                    933:   if (gcmp(x,y)>0) y=x; return gcopy(y);
                    934: }
                    935:
                    936: GEN
                    937: gmin(GEN x, GEN y)
                    938: {
                    939:   if (gcmp(x,y)<0) y=x; return gcopy(y);
                    940: }
                    941:
                    942: GEN
                    943: vecmax(GEN x)
                    944: {
                    945:   long tx=typ(x),lx,lx2,i,j;
                    946:   GEN *p1,s;
                    947:
                    948:   if (!is_matvec_t(tx)) return gcopy(x);
                    949:   lx=lg(x); if (lx==1) return stoi(-VERYBIGINT);
                    950:   if (tx!=t_MAT)
                    951:   {
                    952:     s=(GEN)x[1];
                    953:     for (i=2; i<lx; i++)
                    954:       if (gcmp((GEN)x[i],s) > 0) s=(GEN)x[i];
                    955:   }
                    956:   else
                    957:   {
                    958:     lx2 = lg(x[1]);
                    959:     if (lx2==1) return stoi(-VERYBIGINT);
                    960:     s=gmael(x,1,1); i=2;
                    961:     for (j=1; j<lx; j++)
                    962:     {
                    963:       p1 = (GEN *) x[j];
                    964:       for (; i<lx2; i++)
                    965:        if (gcmp(p1[i],s) > 0) s=p1[i];
                    966:       i=1;
                    967:     }
                    968:   }
                    969:   return gcopy(s);
                    970: }
                    971:
                    972: GEN
                    973: vecmin(GEN x)
                    974: {
                    975:   long tx=typ(x),lx,lx2,i,j;
                    976:   GEN *p1,s;
                    977:
                    978:   if (!is_matvec_t(tx)) return gcopy(x);
                    979:   lx=lg(x); if (lx==1) return stoi(VERYBIGINT);
                    980:   if (tx!=t_MAT)
                    981:   {
                    982:     s=(GEN)x[1];
                    983:     for (i=2; i<lx; i++)
                    984:       if (gcmp((GEN)x[i],s) < 0) s=(GEN)x[i];
                    985:   }
                    986:   else
                    987:   {
                    988:     lx2 = lg(x[1]);
                    989:     if (lx2==1) return stoi(VERYBIGINT);
                    990:     s=gmael(x,1,1); i=2;
                    991:     for (j=1; j<lx; j++)
                    992:     {
                    993:       p1 = (GEN *) x[j];
                    994:       for (; i<lx2; i++)
                    995:        if (gcmp(p1[i],s) < 0) s=p1[i];
                    996:       i=1;
                    997:     }
                    998:   }
                    999:   return gcopy(s);
                   1000: }
                   1001:
                   1002: /*******************************************************************/
                   1003: /*                                                                 */
                   1004: /*                      AFFECT long --> GEN                        */
                   1005: /*         affect long s to GEN x. Useful for initialization.      */
                   1006: /*                                                                 */
                   1007: /*******************************************************************/
                   1008:
                   1009: static void
                   1010: padicaff0(GEN x)
                   1011: {
                   1012:   if (signe(x[4]))
                   1013:   {
                   1014:     setvalp(x, valp(x)|precp(x));
                   1015:     affsi(0,(GEN)x[4]);
                   1016:   }
                   1017: }
                   1018:
                   1019: void
                   1020: gaffsg(long s, GEN x)
                   1021: {
                   1022:   long l,i,v;
                   1023:   GEN p;
                   1024:
                   1025:   switch(typ(x))
                   1026:   {
                   1027:     case t_INT:
                   1028:       affsi(s,x); break;
                   1029:
                   1030:     case t_REAL:
                   1031:       affsr(s,x); break;
                   1032:
                   1033:     case t_INTMOD:
                   1034:       modsiz(s,(GEN)x[1],(GEN)x[2]); break;
                   1035:
                   1036:     case t_FRAC: case t_FRACN:
                   1037:       affsi(s,(GEN)x[1]); affsi(1,(GEN)x[2]); break;
                   1038:
                   1039:     case t_COMPLEX:
                   1040:       gaffsg(s,(GEN)x[1]); gaffsg(0,(GEN)x[2]); break;
                   1041:
                   1042:     case t_PADIC:
                   1043:       if (!s) { padicaff0(x); break; }
                   1044:       p = (GEN)x[2];
                   1045:       v = (is_bigint(p))? 0: svaluation(s,p[2], &i);
                   1046:       setvalp(x,v); modsiz(i,(GEN)x[3],(GEN)x[4]);
                   1047:       break;
                   1048:
                   1049:     case t_QUAD:
                   1050:       gaffsg(s,(GEN)x[2]); gaffsg(0,(GEN)x[3]); break;
                   1051:
                   1052:     case t_POLMOD:
                   1053:       gaffsg(s,(GEN)x[2]); break;
                   1054:
                   1055:     case t_POL:
                   1056:       v=varn(x);
                   1057:       if (!s) x[1]=evallgef(2) | evalvarn(v);
                   1058:       else
                   1059:       {
                   1060:         x[1]=evalsigne(1) | evallgef(3) | evalvarn(v);
                   1061:        gaffsg(s,(GEN)x[2]);
                   1062:       }
                   1063:       break;
                   1064:
                   1065:     case t_SER:
                   1066:       v=varn(x); gaffsg(s,(GEN)x[2]); l=lg(x);
                   1067:       if (!s)
                   1068:         x[1] = evalvalp(l-2) | evalvarn(v);
                   1069:       else
                   1070:         x[1] = evalsigne(1) | evalvalp(0) | evalvarn(v);
                   1071:       for (i=3; i<l; i++) gaffsg(0,(GEN)x[i]);
                   1072:       break;
                   1073:
                   1074:     case t_RFRAC: case t_RFRACN:
                   1075:       gaffsg(s,(GEN)x[1]); gaffsg(1,(GEN)x[2]); break;
                   1076:
                   1077:     case t_VEC: case t_COL: case t_MAT:
                   1078:       if (lg(x)!=2) err(operi,"",t_INT,typ(x));
                   1079:       gaffsg(s,(GEN)x[1]); break;
                   1080:
                   1081:     default: err(operf,"",t_INT,typ(x));
                   1082:   }
                   1083: }
                   1084:
                   1085: /*******************************************************************/
                   1086: /*                                                                 */
                   1087: /*                     GENERIC AFFECTATION                         */
                   1088: /*         Affect the content of x to y, whenever possible         */
                   1089: /*                                                                 */
                   1090: /*******************************************************************/
                   1091: void
                   1092: gaffect(GEN x, GEN y)
                   1093: {
                   1094:   long i,j,k,l,v,vy,lx,ly,tx,ty,av;
                   1095:   GEN p1,num,den;
                   1096:
                   1097:
                   1098:   tx=typ(x); ty=typ(y); lx=lg(x); ly=lg(y);
                   1099:   if (is_scalar_t(tx))
                   1100:   {
                   1101:     if (is_scalar_t(ty))
                   1102:     {
                   1103:       switch(tx)
                   1104:       {
                   1105:        case t_INT:
                   1106:          switch(ty)
                   1107:          {
                   1108:            case t_INT:
                   1109:              /* y = gzero, gnil, gun or gdeux */
                   1110:              if (is_universal_constant(y))
                   1111:              {
                   1112:                if (y==gzero) err(overwriter,"gaffect (gzero)");
                   1113:                if (y==gun)   err(overwriter,"gaffect (gun)");
                   1114:                if (y==gdeux) err(overwriter,"gaffect (gdeux)");
                   1115:                err(overwriter,"gaffect (gnil)");
                   1116:              }
                   1117:              affii(x,y); break;
                   1118:
                   1119:            case t_REAL:
                   1120:               if (y ==  gpi) err(overwriter,"gaffect (gpi)");
                   1121:               if (y==geuler) err(overwriter,"gaffect (geuler)");
                   1122:              affir(x,y); break;
                   1123:
                   1124:            case t_INTMOD:
                   1125:              modiiz(x,(GEN)y[1],(GEN)y[2]); break;
                   1126:
                   1127:            case t_FRAC:
                   1128:              if (y == ghalf) err(overwriter,"gaffect (ghalf)");
                   1129:            case t_FRACN:
                   1130:              affii(x,(GEN)y[1]); affsi(1,(GEN)y[2]); break;
                   1131:
                   1132:            case t_COMPLEX:
                   1133:              if (y == gi) err(overwriter,"gaffect (gi)");
                   1134:              gaffect(x,(GEN)y[1]); gaffsg(0,(GEN)y[2]); break;
                   1135:
                   1136:            case t_PADIC:
                   1137:               if (!signe(x)) { padicaff0(y); break; }
                   1138:              l=avma;
                   1139:              setvalp(y, pvaluation(x,(GEN)y[2],&p1));
                   1140:              modiiz(p1,(GEN)y[3],(GEN)y[4]);
                   1141:              avma=l; break;
                   1142:
                   1143:            case t_QUAD:
                   1144:              gaffect(x,(GEN)y[2]); gaffsg(0,(GEN)y[3]); break;
                   1145:
                   1146:            case t_POLMOD:
                   1147:              gaffect(x,(GEN)y[2]); break;
                   1148:
                   1149:            default: err(operf,"",tx,ty);
                   1150:          }
                   1151:          break;
                   1152:
                   1153:        case t_REAL:
                   1154:          switch(ty)
                   1155:          {
                   1156:            case t_REAL:
                   1157:              affrr(x,y); break;
                   1158:
                   1159:            case t_COMPLEX:
                   1160:              gaffect(x,(GEN)y[1]); gaffsg(0,(GEN)y[2]); break;
                   1161:
                   1162:            case t_POLMOD:
                   1163:              gaffect(x,(GEN)y[2]); break;
                   1164:
                   1165:            case t_INT: case t_INTMOD: case t_FRAC:
                   1166:            case t_FRACN: case t_PADIC: case t_QUAD:
                   1167:               err(operf,"",tx,ty);
                   1168:
                   1169:            default: err(operf,"",tx,ty);
                   1170:          }
                   1171:          break;
                   1172:
                   1173:        case t_INTMOD:
                   1174:          switch(ty)
                   1175:          {
                   1176:            case t_INTMOD:
                   1177:              if (!divise((GEN)x[1],(GEN)y[1]))
                   1178:                 err(operi,"",tx,ty);
                   1179:              modiiz((GEN)x[2],(GEN)y[1],(GEN)y[2]); break;
                   1180:
                   1181:            case t_POLMOD:
                   1182:              gaffect(x,(GEN)y[2]); break;
                   1183:
                   1184:            default: err(operf,"",tx,ty);
                   1185:          }
                   1186:          break;
                   1187:
                   1188:        case t_FRAC:
                   1189:          switch(ty)
                   1190:          {
                   1191:            case t_INT:
                   1192:              if (! mpdivis((GEN)x[1],(GEN)x[2],y))
                   1193:                 err(operi,"",tx,ty);
                   1194:              break;
                   1195:
                   1196:            case t_REAL:
                   1197:              diviiz((GEN)x[1],(GEN)x[2],y); break;
                   1198:
                   1199:            case t_INTMOD:
                   1200:              av=avma; p1=mpinvmod((GEN)x[2],(GEN)y[1]);
                   1201:              modiiz(mulii((GEN)x[1],p1),(GEN)y[1],(GEN)y[2]);
                   1202:              avma=av; break;
                   1203:
                   1204:            case t_FRAC: case t_FRACN:
                   1205:              affii((GEN)x[1],(GEN)y[1]);
                   1206:              affii((GEN)x[2],(GEN)y[2]);
                   1207:              break;
                   1208:
                   1209:            case t_COMPLEX:
                   1210:              gaffect(x,(GEN)y[1]); gaffsg(0,(GEN)y[2]); break;
                   1211:
                   1212:            case t_PADIC:
                   1213:              if (!signe(x[1])) { padicaff0(y); break; }
                   1214:              av=avma; num=(GEN)x[1]; den=(GEN)x[2];
                   1215:              v = pvaluation(num, (GEN) y[2], &num);
                   1216:              if (!v) v = -pvaluation(den,(GEN)y[2],&den);
                   1217:              p1=mulii(num,mpinvmod(den,(GEN)y[3]));
                   1218:              modiiz(p1,(GEN)y[3],(GEN)y[4]); avma=av;
                   1219:              setvalp(y,v); break;
                   1220:
                   1221:            case t_QUAD:
                   1222:              gaffect(x,(GEN)y[2]); gaffsg(0,(GEN)y[3]); break;
                   1223:            case t_POLMOD:
                   1224:              gaffect(x,(GEN)y[2]); break;
                   1225:            default: err(operf,"",tx,ty);
                   1226:          }
                   1227:          break;
                   1228:
                   1229:        case t_FRACN:
                   1230:          switch(ty)
                   1231:          {
                   1232:            case t_INT:
                   1233:              if (! mpdivis((GEN)x[1],(GEN)x[2],y)) err(operi,"",tx,ty);
                   1234:              break;
                   1235:
                   1236:            case t_REAL:
                   1237:              diviiz((GEN)x[1],(GEN)x[2],y); break;
                   1238:            case t_INTMOD:
                   1239:              av=avma; gaffect(gred(x),y); avma=av; break;
                   1240:            case t_FRAC:
                   1241:              gredz(x,y); break;
                   1242:            case t_FRACN:
                   1243:              affii((GEN)x[1],(GEN)y[1]);
                   1244:              affii((GEN)x[2],(GEN)y[2]); break;
                   1245:            case t_COMPLEX:
                   1246:              gaffect(x,(GEN)y[1]); gaffsg(0,(GEN)y[2]); break;
                   1247:            case t_PADIC:
                   1248:              if (!signe(x[1])) { padicaff0(y); break; }
                   1249:              av=avma; num=(GEN)x[1]; den=(GEN)x[2];
                   1250:              v =  pvaluation(num,(GEN)y[2],&num)
                   1251:                 - pvaluation(den,(GEN)y[2],&den);
                   1252:              p1=mulii(num,mpinvmod(den,(GEN)y[3]));
                   1253:              modiiz(p1,(GEN)y[3],(GEN)y[4]); avma=av;
                   1254:              setvalp(y,v); break;
                   1255:
                   1256:            case t_QUAD:
                   1257:              gaffect(x,(GEN)y[2]); gaffsg(0,(GEN)y[3]); break;
                   1258:            case t_POLMOD:
                   1259:              gaffect(x,(GEN)y[2]); break;
                   1260:            default: err(operf,"",tx,ty);
                   1261:          }
                   1262:          break;
                   1263:
                   1264:        case t_COMPLEX:
                   1265:          switch(ty)
                   1266:          {
                   1267:            case t_INT: case t_REAL: case t_INTMOD:
                   1268:            case t_FRAC: case t_FRACN: case t_PADIC: case t_QUAD:
                   1269:              if (!gcmp0((GEN)x[2])) err(operi,"",tx,ty);
                   1270:              gaffect((GEN)x[1],y); break;
                   1271:
                   1272:            case t_COMPLEX:
                   1273:              gaffect((GEN)x[1],(GEN)y[1]);
                   1274:              gaffect((GEN)x[2],(GEN)y[2]);
                   1275:              break;
                   1276:
                   1277:            case t_POLMOD:
                   1278:              gaffect(x,(GEN)y[2]); break;
                   1279:
                   1280:            default: err(operf,"",tx,ty);
                   1281:          }
                   1282:          break;
                   1283:
                   1284:        case t_PADIC:
                   1285:          switch(ty)
                   1286:          {
                   1287:            case t_INTMOD:
                   1288:              if (valp(x)<0) err(operi,"",tx,ty);
                   1289:              av=avma;
                   1290:              v = pvaluation((GEN)y[1],(GEN)x[2],&p1);
                   1291:               k = signe(x[4])? (precp(x)+valp(x)): valp(x)+1;
                   1292:              if (!gcmp1(p1) || v > k) err(operi,"",tx,ty);
                   1293:              modiiz(gtrunc(x),(GEN)y[1],(GEN)y[2]); avma=av; break;
                   1294:
                   1295:            case t_PADIC:
                   1296:              if (!egalii((GEN)x[2],(GEN)y[2])) err(operi,"",tx,ty);
                   1297:              modiiz((GEN)x[4],(GEN)y[3],(GEN)y[4]);
                   1298:              setvalp(y,valp(x)); break;
                   1299:
                   1300:            case t_POLMOD:
                   1301:              gaffect(x,(GEN)y[2]); break;
                   1302:
                   1303:            default: err(operf,"",tx,ty);
                   1304:          }
                   1305:          break;
                   1306:
                   1307:        case t_QUAD:
                   1308:          switch(ty)
                   1309:          {
                   1310:            case t_INT: case t_INTMOD: case t_FRAC:
                   1311:            case t_FRACN: case t_PADIC:
                   1312:              if (!gcmp0((GEN)x[3])) err(operi,"",tx,ty);
                   1313:              gaffect((GEN)x[2],y); break;
                   1314:
                   1315:            case t_REAL:
                   1316:              av=avma; p1=co8(x,ly); gaffect(p1,y); avma=av; break;
                   1317:            case t_COMPLEX:
                   1318:              ly=precision(y);
                   1319:              if (ly)
                   1320:              {
                   1321:                av=avma; p1=co8(x,ly); gaffect(p1,y); avma=av;
                   1322:              }
                   1323:              else
                   1324:              {
                   1325:                 if (!gcmp0((GEN)x[3])) err(operi,"",tx,ty);
                   1326:                gaffect((GEN)x[2],y);
                   1327:              }
                   1328:              break;
                   1329:
                   1330:            case t_QUAD:
                   1331:              if (! gegal((GEN)x[1],(GEN)y[1])) err(operi,"",tx,ty);
                   1332:              affii((GEN)x[2],(GEN)y[2]);
                   1333:              affii((GEN)x[3],(GEN)y[3]);
                   1334:              break;
                   1335:            case t_POLMOD:
                   1336:              gaffect(x,(GEN)y[2]); break;
                   1337:            default: err(operf,"",tx,ty);
                   1338:          }
                   1339:          break;
                   1340:
                   1341:        case t_POLMOD:
                   1342:          if (ty!=t_POLMOD) err(operf,"",tx,ty);
                   1343:          if (! gdivise((GEN)x[1],(GEN)y[1])) err(operi,"",tx,ty);
                   1344:          gmodz((GEN)x[2],(GEN)y[1],(GEN)y[2]); break;
                   1345:
                   1346:         default: err(operf,"",tx,ty);
                   1347:       }
                   1348:       return;
                   1349:     }
                   1350:
                   1351:     /* here y is not scalar */
                   1352:     switch(ty)
                   1353:     {
                   1354:       case t_POL:
                   1355:        v=varn(y);
                   1356:        if (y==polun[v] || y==polx[v])
                   1357:          err(talker,"trying to overwrite a universal polynomial");
                   1358:        gaffect(x,(GEN)y[2]);
                   1359:        for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
                   1360:        if (gcmp0(x)) y[1]=evallgef(2)+evalvarn(v);
                   1361:        else y[1]=evalsigne(1)+evallgef(3)+evalvarn(v);
                   1362:        break;
                   1363:
                   1364:       case t_SER:
                   1365:        v=varn(y); gaffect(x,(GEN)y[2]);
                   1366:        if (gcmp0(x))
                   1367:           y[1] = evalvalp(ly-2) | evalvarn(v);
                   1368:        else
                   1369:          y[1] = evalsigne(1) | evalvalp(0) | evalvarn(v);
                   1370:         for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
                   1371:        break;
                   1372:
                   1373:       case t_RFRAC: case t_RFRACN:
                   1374:        gaffect(x,(GEN)y[1]); gaffsg(1,(GEN)y[2]); break;
                   1375:
                   1376:       default: err(operf,"",tx,ty);
                   1377:     }
                   1378:     return;
                   1379:   }
                   1380:
                   1381:   if (is_const_t(ty)) {
                   1382: #define initial_value(ep) ((ep)+1)
                   1383:       if (tx == t_POL) {
                   1384:          entree *var = varentries[ordvar[varn(x)]];
                   1385:          /* Is a bound expression, thus should not loop: */
                   1386:          if (var && var->value != (void*)initial_value(var)) {
                   1387:              gaffect(geval(x),y);
                   1388:              return;
                   1389:          }
                   1390:       } else if (is_rfrac_t(tx)) {
                   1391:          GEN num = (GEN)x[1], den = (GEN)x[2];
                   1392:          entree *varnum = varentries[ordvar[varn(num)]];
                   1393:          entree *varden = varentries[ordvar[varn(den)]];
                   1394:
                   1395:          /* Are bound expressions, thus should not loop: */
                   1396:          if (varnum && varnum->value != (void*)initial_value(varnum)
                   1397:           && varden && varden->value != (void*)initial_value(varden)) {
                   1398:              gaffect(geval(x),y);
                   1399:              return;
                   1400:          }
                   1401:       }
                   1402: #undef initial_value
                   1403:       err(operf,"",tx,ty);
                   1404:   }
                   1405:
                   1406:   switch(tx)
                   1407:   {
                   1408:     case t_POL:
                   1409:       v=varn(x);
                   1410:       switch(ty)
                   1411:       {
                   1412:        case t_POL:
                   1413:          vy=varn(y); if (vy>v) err(operf,"",tx,ty);
                   1414:          if (vy==v)
                   1415:          {
                   1416:            l=lgef(x); if (l>ly) err(operi,"",tx,ty);
                   1417:            y[1]=x[1]; for (i=2; i<l; i++) gaffect((GEN)x[i],(GEN)y[i]);
                   1418:          }
                   1419:          else
                   1420:          {
                   1421:            gaffect(x,(GEN)y[2]);
                   1422:            for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
                   1423:            if (signe(x)) y[1]=evalsigne(1)+evallgef(3)+evalvarn(vy);
                   1424:            else y[1]=evallgef(2)+evalvarn(vy);
                   1425:          }
                   1426:          break;
                   1427:
                   1428:        case t_SER:
                   1429:          vy=varn(y); if (vy>v) err(operf,"",tx,ty);
                   1430:          if (!signe(x)) { gaffsg(0,y); return; }
                   1431:          if (vy==v)
                   1432:          {
                   1433:            i=gval(x,v); y[1]=evalvarn(v) | evalvalp(i) | evalsigne(1);
                   1434:            k=lgef(x)-i; if (k>ly) k=ly;
                   1435:            for (j=2; j<k; j++) gaffect((GEN)x[i+j],(GEN)y[j]);
                   1436:            for (   ; j<ly; j++) gaffsg(0,(GEN)y[j]);
                   1437:          }
                   1438:          else
                   1439:          {
                   1440:            gaffect(x,(GEN)y[2]);
                   1441:            if (!signe(x))
                   1442:               y[1] = evalvalp(ly-2) | evalvarn(vy);
                   1443:            else
                   1444:              y[1] = evalsigne(1) | evalvalp(0) | evalvarn(vy);
                   1445:             for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
                   1446:          }
                   1447:          break;
                   1448:
                   1449:        case t_POLMOD:
                   1450:          gmodz(x,(GEN)y[1],(GEN)y[2]); break;
                   1451:
                   1452:        case t_RFRAC: case t_RFRACN:
                   1453:          gaffect(x,(GEN)y[1]); gaffsg(1,(GEN)y[2]); break;
                   1454:
                   1455:         default: err(operf,"",tx,ty);
                   1456:       }
                   1457:       break;
                   1458:
                   1459:     case t_SER:
                   1460:       if (ty!=t_SER) err(operf,"",tx,ty);
                   1461:       v=varn(x); vy=varn(y); if (vy>v) err(operf,"",tx,ty);
                   1462:       if (vy==v)
                   1463:       {
                   1464:        y[1]=x[1]; k=lx; if (k>ly) k=ly;
                   1465:         for (i=2; i< k; i++) gaffect((GEN)x[i],(GEN)y[i]);
                   1466:         for (   ; i<ly; i++) gaffsg(0,(GEN)y[i]);
                   1467:       }
                   1468:       else
                   1469:       {
                   1470:        gaffect(x,(GEN)y[2]);
                   1471:        if (!signe(x))
                   1472:           y[1] = evalvalp(ly-2) | evalvarn(vy);
                   1473:        else
                   1474:          y[1] = evalsigne(1) | evalvalp(0) | evalvarn(vy);
                   1475:         for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
                   1476:       }
                   1477:       break;
                   1478:
                   1479:     case t_RFRAC: case t_RFRACN:
                   1480:       switch(ty)
                   1481:       {
                   1482:        case t_POL: case t_VEC: case t_COL: case t_MAT:
                   1483:          err(operf,"",tx,ty);
                   1484:
                   1485:        case t_POLMOD:
                   1486:          av=avma; p1=ginvmod((GEN)x[2],(GEN)y[1]);
                   1487:          gmodz(gmul((GEN)x[1],p1),(GEN)y[1],(GEN)y[2]);
                   1488:          avma=av; break;
                   1489:
                   1490:        case t_SER:
                   1491:          gdivz((GEN)x[1],(GEN)x[2],y); break;
                   1492:
                   1493:        case t_RFRAC:
                   1494:          if (tx==t_RFRACN) gredz(x,y);
                   1495:          else
                   1496:          {
                   1497:            gaffect((GEN)x[1],(GEN)y[1]);
                   1498:            gaffect((GEN)x[2],(GEN)y[2]);
                   1499:          }
                   1500:          break;
                   1501:
                   1502:        case t_RFRACN:
                   1503:          gaffect((GEN)x[1],(GEN)y[1]);
                   1504:          gaffect((GEN)x[2],(GEN)y[2]); break;
                   1505:
                   1506:         default: err(operf,"",tx,ty);
                   1507:       }
                   1508:       break;
                   1509:
                   1510:     case t_QFR: case t_QFI: case t_VEC: case t_COL: case t_MAT:
                   1511:       if (ty != tx || ly != lx) err(operi,"",tx,ty);
                   1512:       for (i=1; i<lx; i++) gaffect((GEN)x[i],(GEN)y[i]);
                   1513:       break;
                   1514:
                   1515:     default: err(operf,"",tx,ty);
                   1516:   }
                   1517: }
                   1518:
                   1519: /*******************************************************************/
                   1520: /*                                                                 */
                   1521: /*           CONVERSION QUAD --> REAL, COMPLEX OR P-ADIC           */
                   1522: /*                                                                 */
                   1523: /*******************************************************************/
                   1524:
                   1525: GEN
                   1526: co8(GEN x, long prec)
                   1527: {
                   1528:   long av=avma,tetpil;
                   1529:   GEN p1, p = (GEN) x[1];
                   1530:
                   1531:   p1 = subii(sqri((GEN)p[3]), shifti((GEN)p[2],2));
                   1532:   if (signe(p1) > 0)
                   1533:   {
                   1534:     p1 = subri(gsqrt(p1,prec), (GEN)p[3]);
                   1535:     setexpo(p1, expo(p1)-1);
                   1536:   }
                   1537:   else
                   1538:   {
                   1539:     p1 = gsub(gsqrt(p1,prec), (GEN)p[3]);
                   1540:     p1[1] = lmul2n((GEN)p1[1],-1);
                   1541:     setexpo(p1[2], expo(p1[2])-1);
                   1542:   }/* p1 = (-b + sqrt(D)) / 2 */
                   1543:   p1 = gmul((GEN)x[3],p1); tetpil=avma;
                   1544:   return gerepile(av,tetpil,gadd((GEN)x[2],p1));
                   1545: }
                   1546:
                   1547: GEN
                   1548: cvtop(GEN x, GEN p, long l)
                   1549: {
                   1550:   GEN p1,p2,p3;
                   1551:   long av,tetpil,n;
                   1552:
                   1553:   if (typ(p)!=t_INT)
                   1554:     err(talker,"not an integer modulus in cvtop or gcvtop");
                   1555:   if (gcmp0(x)) return ggrandocp(p,l);
                   1556:   switch(typ(x))
                   1557:   {
                   1558:     case t_INT:
                   1559:       return gadd(x,ggrandocp(p,ggval(x,p)+l));
                   1560:
                   1561:     case t_INTMOD:
                   1562:       n=ggval((GEN)x[1],p); if (n>l) n=l;
                   1563:       return gadd((GEN)x[2],ggrandocp(p,n));
                   1564:
                   1565:     case t_FRAC: case t_FRACN:
                   1566:       n = ggval((GEN)x[1],p) - ggval((GEN)x[2],p);
                   1567:       return gadd(x,ggrandocp(p,n+l));
                   1568:
                   1569:     case t_COMPLEX:
                   1570:       av=avma; p1=gsqrt(gaddgs(ggrandocp(p,l),-1),0);
                   1571:       p1=gmul(p1,(GEN)x[2]); tetpil=avma;
                   1572:       return gerepile(av,tetpil,gadd(p1,(GEN)x[1]));
                   1573:
                   1574:     case t_PADIC:
                   1575:       return gprec(x,l);
                   1576:
                   1577:     case t_QUAD:
                   1578:       av=avma; p1=(GEN)x[1]; p3=gmul2n((GEN)p1[3],-1);
                   1579:       p2=gsub(gsqr(p3),(GEN)p1[2]);
                   1580:       switch(typ(p2))
                   1581:       {
                   1582:        case t_INT:
                   1583:          n=ggval(p2,p); p2=gadd(p2,ggrandocp(p,n+l)); break;
                   1584:
                   1585:        case t_INTMOD: case t_PADIC:
                   1586:          break;
                   1587:
                   1588:        case t_FRAC: case t_FRACN:
                   1589:          n = ggval((GEN)p2[1],p) - ggval((GEN)p2[2],p);
                   1590:          p2=gadd(p2,ggrandocp(p,n+l)); break;
                   1591:
                   1592:        default: err(operi,"",t_QUAD,t_QUAD);
                   1593:       }
                   1594:       p2=gsqrt(p2,0); p1=gmul((GEN)x[3],gsub(p2,p3)); tetpil=avma;
                   1595:       return gerepile(av,tetpil,gadd((GEN)x[2],p1));
                   1596:
                   1597:   }
                   1598:   err(typeer,"cvtop");
                   1599:   return NULL; /* not reached */
                   1600: }
                   1601:
                   1602: GEN
                   1603: gcvtop(GEN x, GEN p, long r)
                   1604: {
                   1605:   long i,lx, tx=typ(x);
                   1606:   GEN y;
                   1607:
                   1608:   if (is_const_t(tx)) return cvtop(x,p,r);
                   1609:   switch(tx)
                   1610:   {
                   1611:     case t_POL:
                   1612:       lx=lgef(x); y=cgetg(lx,t_POL); y[1]=x[1];
                   1613:       for (i=2; i<lx; i++)
                   1614:        y[i]=(long)gcvtop((GEN)x[i],p,r);
                   1615:       break;
                   1616:
                   1617:     case t_SER:
                   1618:       lx=lg(x); y=cgetg(lx,t_SER); y[1]=x[1];
                   1619:       for (i=2; i<lx; i++)
                   1620:        y[i]=(long)gcvtop((GEN)x[i],p,r);
                   1621:       break;
                   1622:
                   1623:     case t_POLMOD: case t_RFRAC: case t_RFRACN:
                   1624:     case t_VEC: case t_COL: case t_MAT:
                   1625:       lx=lg(x); y=cgetg(lx,tx);
                   1626:       for (i=1; i<lx; i++)
                   1627:        y[i]=(long)gcvtop((GEN)x[i],p,r);
                   1628:       break;
                   1629:
                   1630:     default: err(typeer,"gcvtop");
                   1631:       return NULL; /* not reached */
                   1632:   }
                   1633:   return y;
                   1634: }
                   1635:
                   1636: long
                   1637: gexpo(GEN x)
                   1638: {
                   1639:   long tx=typ(x),lx,e,i,y,av;
                   1640:
                   1641:   switch(tx)
                   1642:   {
                   1643:     case t_INT:
                   1644:       return expi(x);
                   1645:
                   1646:     case t_FRAC: case t_FRACN:
                   1647:       if (!signe(x[1])) return -HIGHEXPOBIT;
                   1648:       return expi((GEN)x[1]) - expi((GEN)x[2]);
                   1649:
                   1650:     case t_REAL:
                   1651:       return expo(x);
                   1652:
                   1653:     case t_COMPLEX:
                   1654:       e = gexpo((GEN)x[1]);
                   1655:       y = gexpo((GEN)x[2]); return max(e,y);
                   1656:
                   1657:     case t_QUAD:
                   1658:       av=avma; e = gexpo(co8(x,3)); avma=av; return e;
                   1659:
                   1660:     case t_POL: case t_SER: case t_VEC: case t_COL: case t_MAT:
                   1661:       lx=(tx==t_POL)? lgef(x): lg(x);
                   1662:       y = -HIGHEXPOBIT;
                   1663:       for (i=lontyp[tx]; i<lx; i++) { e=gexpo((GEN)x[i]); if (e>y) y=e; }
                   1664:       return y;
                   1665:   }
                   1666:   err(typeer,"gexpo");
                   1667:   return 0; /* not reached */
                   1668: }
                   1669:
                   1670: long
                   1671: sizedigit(GEN x)
                   1672: {
                   1673:   return gcmp0(x)? 0: (long) ((gexpo(x)+1) * L2SL10) + 1;
                   1674: }
                   1675:
                   1676: /* Normalize series x in place.
                   1677:  * Assumption: x,x[2],...,x[lg(x)-1] have been created in that order.
                   1678:  * All intermediate objects will be destroyed.
                   1679:  */
                   1680: GEN
                   1681: normalize(GEN x)
                   1682: {
                   1683:   long i,j, lx = lg(x);
                   1684:
                   1685:   if (typ(x)!=t_SER) err(typeer,"normalize");
                   1686:   if (lx==2) { setsigne(x,0); avma = (long) x; return x; }
                   1687:   if (! isexactzero((GEN)x[2])) { setsigne(x,1); return x; }
                   1688:
                   1689:   for (i=3; i<lx; i++)
                   1690:     if (! isexactzero((GEN)x[i]))
                   1691:     {
                   1692:       long tetpil = avma;
                   1693:       GEN p1 = cgetg(lx-i+2,t_SER);
                   1694:       p1[1] = evalsigne(1) | evalvalp(valp(x)+i-2) | evalvarn(varn(x));
                   1695:       j=i; i=2; while (j<lx) p1[i++] = lcopy((GEN)x[j++]);
                   1696:       return gerepile((long) (x+lx),tetpil,p1);
                   1697:     }
                   1698:   avma = (long) (x+lx); return zeroser(varn(x),lx-2);
                   1699: }
                   1700:
                   1701: GEN
                   1702: normalizepol_i(GEN x, long lx)
                   1703: {
                   1704:   long i;
                   1705:   for (i=lx-1; i>1; i--)
                   1706:     if (! isexactzero((GEN)x[i])) break;
                   1707:   setlgef(x,i+1);
                   1708:   for (; i>1; i--)
                   1709:     if (! gcmp0((GEN)x[i]) ) { setsigne(x,1); return x; }
                   1710:   setsigne(x,0); return x;
                   1711: }
                   1712:
                   1713: /* Normalize polynomial x in place. See preceding comment */
                   1714: GEN
                   1715: normalizepol(GEN x)
                   1716: {
                   1717:   if (typ(x)!=t_POL) err(typeer,"normalizepol");
                   1718:   return normalizepol_i(x, lgef(x));
                   1719: }
                   1720:
                   1721: int
                   1722: gsigne(GEN x)
                   1723: {
                   1724:   switch(typ(x))
                   1725:   {
                   1726:     case t_INT: case t_REAL:
                   1727:       return signe(x);
                   1728:
                   1729:     case t_FRAC: case t_FRACN:
                   1730:       return (signe(x[2])>0) ? signe(x[1]) : -signe(x[1]);
                   1731:   }
                   1732:   err(typeer,"gsigne");
                   1733:   return 0; /* not reached */
                   1734: }
                   1735:
                   1736: /*******************************************************************/
                   1737: /*                                                                 */
                   1738: /*                              LISTS                              */
                   1739: /*                                                                 */
                   1740: /*******************************************************************/
                   1741:
                   1742: GEN
                   1743: listcreate(long n)
                   1744: {
                   1745:   GEN list;
                   1746:
                   1747:   if (n<0) err(talker,"negative length in listcreate");
                   1748:   n += 2;
                   1749:   if (n & ~LGEFBITS) err(talker,"list too long (max = %ld)",LGEFBITS-2);
                   1750:   list=cgetg(n,t_LIST); list[1]=evallgef(2);
                   1751:   return list;
                   1752: }
                   1753:
                   1754: static void
                   1755: listaffect(GEN list, long index, GEN object)
                   1756: {
                   1757:   if (index<lgef(list) && isclone(list[index]))
                   1758:     gunclone((GEN)list[index]);
                   1759:   list[index]=lclone(object);
                   1760: }
                   1761:
                   1762: void
                   1763: listkill(GEN list)
                   1764: {
                   1765:   long lx,i;
                   1766:
                   1767:   if (typ(list)!=t_LIST) err(typeer,"listkill");
                   1768:   lx=lgef(list);
                   1769:   for (i=2; i<lx; i++)
                   1770:     if (isclone(list[i])) gunclone((GEN)list[i]);
                   1771:   list[1]=evallgef(2); return;
                   1772: }
                   1773:
                   1774: GEN
                   1775: listput(GEN list, GEN object, long index)
                   1776: {
                   1777:   long lx=lgef(list);
                   1778:
                   1779:   if (typ(list)!=t_LIST) err(typeer,"listput");
                   1780:   if (index < 0) err(talker,"negative index (%ld) in listput", index);
                   1781:   if (!index || index >= lx-1)
                   1782:   {
                   1783:     index = lx-1; lx++;
                   1784:     if (lx > lg(list))
                   1785:       err(talker,"no more room in this list (size %ld)", lg(list)-2);
                   1786:   }
                   1787:   listaffect(list,index+1,object);
                   1788:   list[1]=evallgef(lx);
                   1789:   return (GEN)list[index+1];
                   1790: }
                   1791:
                   1792: GEN
                   1793: listinsert(GEN list, GEN object, long index)
                   1794: {
                   1795:   long lx = lgef(list), i;
                   1796:
                   1797:   if (typ(list)!=t_LIST) err(typeer,"listinsert");
                   1798:   if (index <= 0 || index > lx-1) err(talker,"bad index in listinsert");
                   1799:   lx++; if (lx > lg(list)) err(talker,"no more room in this list");
                   1800:
                   1801:   for (i=lx-2; i > index; i--) list[i+1]=list[i];
                   1802:   list[index+1] = lclone(object);
                   1803:   list[1] = evallgef(lx); return (GEN)list[index+1];
                   1804: }
                   1805:
                   1806: GEN
                   1807: gtolist(GEN x)
                   1808: {
                   1809:   long tx,lx,i;
                   1810:   GEN list;
                   1811:
                   1812:   if (!x) { list = cgetg(2, t_LIST); list[1] = evallgef(2); return list; }
                   1813:
                   1814:   tx = typ(x);
                   1815:   lx = (tx==t_LIST)? lgef(x): lg(x);
                   1816:   switch(tx)
                   1817:   {
                   1818:     case t_VEC: case t_COL:
                   1819:       lx++; x--; /* fall through */
                   1820:     case t_LIST:
                   1821:       list = cgetg(lx,t_LIST);
                   1822:       for (i=2; i<lx; i++) list[i] = lclone((GEN)x[i]);
                   1823:       break;
                   1824:     default: err(typeer,"gtolist");
                   1825:       return NULL; /* not reached */
                   1826:   }
                   1827:   list[1] = evallgef(lx); return list;
                   1828: }
                   1829:
                   1830: GEN
                   1831: listconcat(GEN list1, GEN list2)
                   1832: {
                   1833:   long i,l1,lx;
                   1834:   GEN list;
                   1835:
                   1836:   if (typ(list1)!=t_LIST || typ(list2)!=t_LIST)
                   1837:     err(typeer,"listconcat");
                   1838:   l1=lgef(list1)-2; lx=l1+lgef(list2);
                   1839:   list = listcreate(lx-2);
                   1840:   for (i=2; i<=l1+1; i++) listaffect(list,i,(GEN)list1[i]);
                   1841:   for (   ; i<lx; i++) listaffect(list,i,(GEN)list2[i-l1]);
                   1842:   list[1]=evallgef(lx); return list;
                   1843: }
                   1844:
                   1845: GEN
                   1846: listsort(GEN list, long flag)
                   1847: {
                   1848:   long i,av=avma, c=list[1], lx = lgef(list)-1;
                   1849:   GEN perm,vec,l;
                   1850:
                   1851:   if (typ(list) != t_LIST) err(typeer,"listsort");
                   1852:   vec = list+1;
                   1853:   vec[0] = evaltyp(t_VEC) | evallg(lx);
                   1854:   perm = sindexsort(vec);
                   1855:   list[1] = c; l = cgetg(lx,t_VEC);
                   1856:   for (i=1; i<lx; i++) l[i] = vec[perm[i]];
                   1857:   if (flag)
                   1858:   {
                   1859:     c=1; vec[1] = l[1];
                   1860:     for (i=2; i<lx; i++)
                   1861:       if (!gegal((GEN)l[i], (GEN)vec[c]))
                   1862:         vec[++c] = l[i];
                   1863:       else
                   1864:         if (isclone(l[i])) gunclone((GEN)l[i]);
                   1865:     setlgef(list,c+2);
                   1866:   }
                   1867:   else
                   1868:     for (i=1; i<lx; i++) vec[i] = l[i];
                   1869:
                   1870:   avma=av; return list;
                   1871: }

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