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

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

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

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