[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     ! 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>