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

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

1.1       maekawa     1: /********************************************************************/
                      2: /**                                                                **/
                      3: /**                      GENERIC OPERATIONS                        **/
                      4: /**                         (first part)                           **/
                      5: /**                                                                **/
                      6: /********************************************************************/
                      7: /* $Id: gen1.c,v 1.2 1999/09/21 10:57:55 karim Exp $ */
                      8: #include "pari.h"
                      9:
                     10: #define swapspec(x,y, nx,ny) {long _a=nx;GEN _z=x; nx=ny; ny=_a; x=y; y=_z;}
                     11: GEN quickmul(GEN a, GEN b, long na, long nb);
                     12:
                     13: #define cpifstack(x) isonstack(x)?gcopy(x):x
                     14: /* y is a polmod, f is gadd or gmul */
                     15: static GEN
                     16: op_polmod(GEN f(GEN,GEN), GEN x, GEN y, long tx)
                     17: {
                     18:   GEN mod,k,l, z=cgetg(3,t_POLMOD);
                     19:   long av,tetpil;
                     20:
                     21:   l=(GEN)y[1];
                     22:   if (tx==t_POLMOD)
                     23:   {
                     24:     k=(GEN)x[1];
                     25:     if (gegal(k,l))
                     26:       { mod=cpifstack(k); x=(GEN)x[2]; y=(GEN)y[2]; }
                     27:     else
                     28:     {
                     29:       long vx=varn(k), vy=varn(l);
                     30:       if (vx==vy) { mod=srgcd(k,l); x=(GEN)x[2]; y=(GEN)y[2]; }
                     31:       else
                     32:         if (vx<vy) { mod=cpifstack(k); x=(GEN)x[2]; }
                     33:         else       { mod=cpifstack(l); y=(GEN)y[2]; }
                     34:     }
                     35:   }
                     36:   else
                     37:   {
                     38:     mod=cpifstack(l); y=(GEN)y[2];
                     39:     if (is_scalar_t(tx))
                     40:     {
                     41:       z[2] = (long)f(x,y);
                     42:       z[1] = (long)mod; return z;
                     43:     }
                     44:   }
                     45:   av=avma; x = f(x,y); tetpil=avma;
                     46:   z[2] = lpile(av,tetpil,gmod(x,mod));
                     47:   z[1] = (long)mod; return z;
                     48: }
                     49: #undef cpifstack
                     50:
                     51: /********************************************************************/
                     52: /**                                                                **/
                     53: /**                          SUBTRACTION                           **/
                     54: /**                                                                **/
                     55: /********************************************************************/
                     56:
                     57: GEN
                     58: gsub(GEN x, GEN y)
                     59: {
                     60:   long tetpil, av = avma;
                     61:   y=gneg_i(y); tetpil=avma;
                     62:   return gerepile(av,tetpil,gadd(x,y));
                     63: }
                     64:
                     65: /********************************************************************/
                     66: /**                                                                **/
                     67: /**                           ADDITION                             **/
                     68: /**                                                                **/
                     69: /********************************************************************/
                     70:
                     71: static GEN
                     72: addpadic(GEN x, GEN y)
                     73: {
                     74:   long c,e,r,d,r1,r2,av,tetpil;
                     75:   GEN z,p1,p2, p = (GEN)x[2];
                     76:
                     77:   z=cgetg(5,t_PADIC); icopyifstack(p, z[2]); av=avma;
                     78:   e=valp(x); r=valp(y); d = r-e;
                     79:   if (d<0) { p1=x; x=y; y=p1; e=r; d = -d; }
                     80:   r1=precp(x); r2=precp(y);
                     81:   if (d)
                     82:   {
                     83:     r = d+r2;
                     84:     p1 = (d==1)? p: gclone(gpuigs(p,d));
                     85:     avma=av;
                     86:     if (r<r1) z[3]=lmulii(p1,(GEN)y[3]);
                     87:     else
                     88:     {
                     89:       r=r1; z[3]=licopy((GEN)x[3]);
                     90:     }
                     91:     av=avma; p2=mulii(p1,(GEN)y[4]);
                     92:     if (d!=1) gunclone(p1);
                     93:     p1=addii(p2,(GEN)x[4]); tetpil=avma;
                     94:     z[4]=lpile(av,tetpil, modii(p1,(GEN)z[3]));
                     95:     z[1]=evalprecp(r) | evalvalp(e); return z;
                     96:   }
                     97:   if (r2<r1) { r=r2; p1=x; x=y; y=p1; } else r=r1;
                     98:   p1 = addii((GEN)x[4],(GEN)y[4]);
                     99:   if (!signe(p1) || (c = pvaluation(p1,p,&p2)) >=r)
                    100:   {
                    101:     avma=av; z[4]=zero; z[3]=un;
                    102:     z[1]=evalvalp(e+r); return z;
                    103:   }
                    104:   if (c)
                    105:   {
                    106:     p2=gclone(p2); avma=av;
                    107:     if (c==1)
                    108:       z[3] = ldivii((GEN)x[3], p);
                    109:     else
                    110:     {
                    111:       p1 = gpuigs(p,c); tetpil=avma;
                    112:       z[3] = lpile(av,tetpil, divii((GEN)x[3], p1));
                    113:     }
                    114:     z[4]=lmodii(p2,(GEN)z[3]); gunclone(p2);
                    115:     z[1]=evalprecp(r-c) | evalvalp(e+c); return z;
                    116:   }
                    117:   tetpil=avma;
                    118:   z[4]=lpile(av,tetpil,modii(p1,(GEN)x[3]));
                    119:   z[3]=licopy((GEN)x[3]);
                    120:   z[1]=evalprecp(r) | evalvalp(e); return z;
                    121: }
                    122:
                    123: /* return x + y, where x is t_INT or t_FRAC(N), y t_PADIC */
                    124: static GEN
                    125: gaddpex(GEN x, GEN y)
                    126: {
                    127:   long tx,e1,e2,e3,av,tetpil;
                    128:   GEN z,p,p1,p2;
                    129:
                    130:   if (gcmp0(x)) return gcopy(y);
                    131:
                    132:   av=avma; p=(GEN)y[2]; tx=typ(x);
                    133:   z=cgetg(5,t_PADIC); z[2]=(long)p;
                    134:   e3 = (tx == t_INT)? pvaluation(x,p,&p1)
                    135:                     : pvaluation((GEN)x[1],p,&p1) -
                    136:                       pvaluation((GEN)x[2],p,&p2);
                    137:   e1 = valp(y)-e3; e2 = signe(y[4])? e1+precp(y): e1;
                    138:   if (e2<=0)
                    139:   {
                    140:     z[1] = evalprecp(0) | evalvalp(e3);
                    141:     z[3] = un;
                    142:     z[4] = zero;
                    143:   }
                    144:   else
                    145:   {
                    146:     if (tx != t_INT && !is_pm1(p2)) p1 = gdiv(p1,p2);
                    147:     z[1] = evalprecp(e2) | evalvalp(e3);
                    148:     z[3] = e1? lmul((GEN)y[3], gpuigs(p,e1)): y[3];
                    149:     z[4] = lmod(p1,(GEN)z[3]);
                    150:   }
                    151:   tetpil=avma; return gerepile(av,tetpil,addpadic(z,y));
                    152: }
                    153:
                    154: static long
                    155: kro_quad(GEN x, GEN y)
                    156: {
                    157:   long k, av=avma;
                    158:
                    159:   x = subii(sqri((GEN)x[3]), shifti((GEN)x[2],2));
                    160:   k = kronecker(x,y); avma=av; return k;
                    161: }
                    162:
                    163: static GEN
                    164: addfrac(GEN x, GEN y)
                    165: {
                    166:   GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
                    167:   GEN y1 = (GEN)y[1], y2 = (GEN)y[2], p1,p2,n,d,delta,z;
                    168:
                    169:   z = cgetg(3,t_FRAC);
                    170:   (void)new_chunk((lgefint(x1) + lgefint(x2) +
                    171:                    lgefint(y1) + lgefint(y2)) << 1);
                    172:   delta = mppgcd(x2,y2);
                    173:   if (is_pm1(delta))
                    174:   {
                    175:     p1 = mulii(x1,y2);
                    176:     p2 = mulii(y1,x2); avma = (long)z;
                    177:     z[1] = laddii(p1,p2);
                    178:     z[2] = lmulii(x2,y2); return z;
                    179:   }
                    180:   x2 = divii(x2,delta);
                    181:   y2 = divii(y2,delta);
                    182:   n = addii(mulii(x1,y2), mulii(y1,x2));
                    183:   if (!signe(n)) { avma = (long)(z+3); return gzero; }
                    184:   d = mulii(x2, y2);
                    185:   p1 = dvmdii(n, delta, &p2);
                    186:   if (p2 == gzero)
                    187:   {
                    188:     if (is_pm1(d)) { avma = (long)(z+3); return icopy(p1); }
                    189:     avma = (long)z;
                    190:     z[1] = licopy(p1);
                    191:     z[2] = licopy(d); return z;
                    192:   }
                    193:   p1 = mppgcd(delta, p2);
                    194:   if (is_pm1(p1))
                    195:   {
                    196:     avma = (long)z;
                    197:     z[1] = licopy(n);
                    198:   }
                    199:   else
                    200:   {
                    201:     delta = divii(delta, p1);
                    202:     avma = (long)z;
                    203:     z[1] = ldivii(n,p1);
                    204:   }
                    205:   z[2] = lmulii(d,delta); return z;
                    206: }
                    207:
                    208: static GEN
                    209: addrfrac(GEN x, GEN y)
                    210: {
                    211:   GEN z = cgetg(3,t_RFRAC);
                    212:   GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
                    213:   GEN y1 = (GEN)y[1], y2 = (GEN)y[2], p1,p2,n,d,delta;
                    214:   long tetpil;
                    215:
                    216:   delta = ggcd(x2,y2);
                    217:   if (gcmp1(delta))
                    218:   {
                    219:     p1 = gmul(x1,y2);
                    220:     p2 = gmul(y1,x2);
                    221:     tetpil = avma; /* numerator is non-zero */
                    222:     z[1] = lpile((long)z,tetpil, gadd(p1,p2));
                    223:     z[2] = lmul(x2, y2); return z;
                    224:   }
                    225:   x2 = gdeuc(x2,delta);
                    226:   y2 = gdeuc(y2,delta);
                    227:   n = gadd(gmul(x1,y2), gmul(y1,x2));
                    228:   if (!signe(n)) return gerepileupto((long)(z+3), n);
                    229:   tetpil = avma; d = gmul(x2, y2);
                    230:   p1 = poldivres(n, delta, &p2);
                    231:   if (!signe(p2))
                    232:   {
                    233:     if (gcmp1(d)) return gerepileupto((long)(z+3), p1);
                    234:     z[1]=(long)p1; z[2]=(long)d;
                    235:     gerepilemanyvec((long)z,tetpil,z+1,2); return z;
                    236:   }
                    237:   p1 = ggcd(delta, p2);
                    238:   if (gcmp1(p1))
                    239:   {
                    240:     tetpil = avma;
                    241:     z[1] = lcopy(n);
                    242:   }
                    243:   else
                    244:   {
                    245:     delta = gdeuc(delta, p1);
                    246:     tetpil = avma;
                    247:     z[1] = ldeuc(n,p1);
                    248:   }
                    249:   z[2] = lmul(d,delta);
                    250:   gerepilemanyvec((long)z,tetpil,z+1,2); return z;
                    251: }
                    252:
                    253: static GEN
                    254: addscalrfrac(GEN x, GEN y)
                    255: {
                    256:   GEN p1,num, z = cgetg(3,t_RFRAC);
                    257:   long tetpil, av;
                    258:
                    259:   p1 = gmul(x,(GEN)y[2]); tetpil = avma;
                    260:   num = gadd(p1,(GEN)y[1]);
                    261:   av = avma;
                    262:   p1 = content((GEN)y[2]);
                    263:   if (!gcmp1(p1))
                    264:   {
                    265:     p1 = ggcd(p1, content(num));
                    266:     if (!gcmp1(p1))
                    267:     {
                    268:       tetpil = avma;
                    269:       z[1] = ldiv(num, p1);
                    270:       z[2] = ldiv((GEN)y[2], p1);
                    271:       gerepilemanyvec((long)z,tetpil,z+1,2); return z;
                    272:     }
                    273:   }
                    274:   avma = av;
                    275:   z[1]=lpile((long)z,tetpil, num);
                    276:   z[2]=lcopy((GEN)y[2]); return z;
                    277: }
                    278:
                    279: /* assume gvar(x) = varn(mod) */
                    280: static GEN
                    281: to_polmod(GEN x, GEN mod)
                    282: {
                    283:   long tx = typ(x);
                    284:   GEN z = cgetg(3, t_POLMOD);
                    285:
                    286:   if (tx == t_RFRACN) { x = gred_rfrac(x); tx = t_RFRAC; }
                    287:   if (tx == t_RFRAC) x = gmul((GEN)x[1], ginvmod((GEN)x[2],mod));
                    288:   z[1] = (long)mod;
                    289:   z[2] = (long)x;
                    290:   return z;
                    291: }
                    292:
                    293: GEN
                    294: gadd(GEN x, GEN y)
                    295: {
                    296:   long vx,vy,lx,ly,tx,ty,i,j,k,l,av,tetpil;
                    297:   GEN z,p1,p2;
                    298:
                    299:   tx=typ(x); ty=typ(y);
                    300:   if (is_const_t(tx) && is_const_t(ty))
                    301:   {
                    302:     if (tx>ty) { p1=x; x=y; y=p1; i=tx; tx=ty; ty=i; }
                    303:   }
                    304:   else
                    305:   {
                    306:     vx=gvar(x); vy=gvar(y);
                    307:     if (vx<vy || (vx==vy && tx>ty))
                    308:     {
                    309:       p1=x; x=y; y=p1;
                    310:       i=tx; tx=ty; ty=i;
                    311:       i=vx; vx=vy; vy=i;
                    312:     }
                    313:     if (ty==t_POLMOD) return op_polmod(gadd,x,y,tx);
                    314:   }
                    315:
                    316:   /* here vx >= vy */
                    317:   if (is_scalar_t(ty))
                    318:   {
                    319:     switch(tx)
                    320:     {
                    321:       case t_INT:
                    322:         switch(ty)
                    323:        {
                    324:          case t_INT:  return addii(x,y);
                    325:           case t_REAL: return addir(x,y);
                    326:
                    327:          case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
                    328:            (void)new_chunk(lgefint(p2)+1);
                    329:             p1 = addii(modii(x,p2),(GEN)y[2]); avma = (long)z;
                    330:             z[2] = (cmpii(p1,p2) >=0)? lsubii(p1,p2): licopy(p1);
                    331:            icopyifstack(p2,z[1]); return z;
                    332:
                    333:          case t_FRAC: case t_FRACN: z=cgetg(3,ty);
                    334:             (void)new_chunk(lgefint(x) + lgefint(y[1]) + lgefint(y[2]) + 1);
                    335:             p1 = mulii((GEN)y[2],x); avma = (long)z;
                    336:            z[1] = laddii((GEN)y[1], p1);
                    337:            z[2] = licopy((GEN)y[2]); return z;
                    338:
                    339:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                    340:            z[1]=ladd(x,(GEN)y[1]);
                    341:            z[2]=lcopy((GEN)y[2]); return z;
                    342:
                    343:          case t_PADIC:
                    344:            return gaddpex(x,y);
                    345:
                    346:          case t_QUAD: z=cgetg(4,t_QUAD);
                    347:            copyifstack(y[1], z[1]);
                    348:            z[2]=ladd(x,(GEN)y[2]);
                    349:            z[3]=lcopy((GEN)y[3]); return z;
                    350:        }
                    351:
                    352:       case t_REAL:
                    353:         switch(ty)
                    354:        {
                    355:          case t_REAL: return addrr(x,y);
                    356:
                    357:          case t_FRAC: case t_FRACN:
                    358:            if (!signe(y[1])) return rcopy(x);
                    359:             if (!signe(x))
                    360:             {
                    361:               lx = expi((GEN)y[1]) - expi((GEN)y[2]) - expo(x);
                    362:               if (lx < 0) return rcopy(x);
                    363:               lx >>= TWOPOTBITS_IN_LONG;
                    364:               z=cgetr(lx+3); diviiz((GEN)y[1],(GEN)y[2],z);
                    365:               return z;
                    366:             }
                    367:             av=avma; z=addir((GEN)y[1],mulir((GEN)y[2],x)); tetpil=avma;
                    368:             return gerepile(av,tetpil,divri(z,(GEN)y[2]));
                    369:
                    370:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                    371:            z[1]=ladd(x,(GEN)y[1]);
                    372:            z[2]=lcopy((GEN)y[2]); return z;
                    373:
                    374:          case t_QUAD:
                    375:            if (gcmp0(y)) return rcopy(x);
                    376:
                    377:            av=avma; i=gexpo(y)-expo(x);
                    378:            if (i<=0) i=0; else i >>= TWOPOTBITS_IN_LONG;
                    379:            p1=co8(y,lg(x)+i); tetpil=avma;
                    380:            return gerepile(av,tetpil,gadd(p1,x));
                    381:
                    382:          case t_INTMOD: case t_PADIC: err(gadderf,tx,ty);
                    383:        }
                    384:
                    385:       case t_INTMOD:
                    386:         switch(ty)
                    387:        {
                    388:          case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)x[1]; p1=(GEN)y[1];
                    389:            if (p1==p2 || egalii(p1,p2))
                    390:             {
                    391:               icopyifstack(p2,z[1]);
                    392:               if (!is_bigint(p2))
                    393:               {
                    394:                 z[2] = lstoi(addssmod(itos((GEN)x[2]),itos((GEN)y[2]), p2[2]));
                    395:                 return z;
                    396:               }
                    397:             }
                    398:             else
                    399:             { p2 = mppgcd(p1,p2); z[1] = (long)p2; }
                    400:            av=avma; (void)new_chunk((lgefint(p1)<<1) + lgefint(x[1]));
                    401:             p1=addii((GEN)x[2],(GEN)y[2]); avma=av;
                    402:            z[2]=lmodii(p1,p2); return z;
                    403:
                    404:          case t_FRAC: case t_FRACN: z=cgetg(3,t_INTMOD); p2=(GEN)x[1];
                    405:            (void)new_chunk(lgefint(p2)<<2);
                    406:             p1 = mulii((GEN)y[1], mpinvmod((GEN)y[2],p2));
                    407:             p1 = addii(modii(p1,p2), (GEN)x[2]); avma=(long)z;
                    408:             z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
                    409:
                    410:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                    411:            z[1]=ladd(x,(GEN)y[1]);
                    412:             z[2]=lcopy((GEN)y[2]); return z;
                    413:
                    414:          case t_PADIC:
                    415:            l=avma; p1=cgetg(3,t_INTMOD);
                    416:            p1[1]=x[1]; p1[2]=lgeti(lgefint(x[1]));
                    417:            gaffect(y,p1); tetpil=avma;
                    418:            return gerepile(l,tetpil,gadd(p1,x));
                    419:
                    420:          case t_QUAD: z=cgetg(4,t_QUAD);
                    421:             copyifstack(y[1], z[1]);
                    422:            z[2]=ladd(x,(GEN)y[2]);
                    423:             z[3]=lcopy((GEN)y[3]); return z;
                    424:        }
                    425:
                    426:       case t_FRAC: case t_FRACN:
                    427:         switch (ty)
                    428:        {
                    429:          case t_FRAC: return addfrac(x,y);
                    430:          case t_FRACN: z=cgetg(3,t_FRACN); l=avma;
                    431:            p1=mulii((GEN)x[1],(GEN)y[2]);
                    432:            p2=mulii((GEN)x[2],(GEN)y[1]);
                    433:            tetpil=avma; z[1]=lpile(l,tetpil,addii(p1,p2));
                    434:            z[2]=lmulii((GEN)x[2],(GEN)y[2]);
                    435:            return z;
                    436:
                    437:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                    438:            z[1]=ladd((GEN)y[1],x);
                    439:            z[2]=lcopy((GEN)y[2]); return z;
                    440:
                    441:          case t_PADIC:
                    442:            return gaddpex(x,y);
                    443:
                    444:          case t_QUAD: z=cgetg(4,t_QUAD);
                    445:            z[1]=lcopy((GEN)y[1]);
                    446:            z[2]=ladd((GEN)y[2],x);
                    447:            z[3]=lcopy((GEN)y[3]); return z;
                    448:        }
                    449:
                    450:       case t_COMPLEX:
                    451:         switch(ty)
                    452:        {
                    453:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                    454:            z[1]=ladd((GEN)x[1],(GEN)y[1]);
                    455:            z[2]=ladd((GEN)x[2],(GEN)y[2]); return z;
                    456:
                    457:          case t_PADIC:
                    458:            if (krosg(-1,(GEN)y[2])== -1)
                    459:            {
                    460:              z=cgetg(3,t_COMPLEX);
                    461:               z[1]=ladd((GEN)x[1],y);
                    462:              z[2]=lcopy((GEN)x[2]); return z;
                    463:            }
                    464:            av=avma; l = signe(y[4])? precp(y): 1;
                    465:            p1=cvtop(x,(GEN)y[2], l + valp(y)); tetpil=avma;
                    466:             return gerepile(av,tetpil,gadd(p1,y));
                    467:
                    468:          case t_QUAD:
                    469:            lx=precision(x); if (!lx) err(gadderi,tx,ty);
                    470:            if (gcmp0(y)) return gcopy(x);
                    471:
                    472:            av=avma; i=gexpo(y)-gexpo(x);
                    473:            if (i<=0) i=0; else i >>= TWOPOTBITS_IN_LONG;
                    474:            p1=co8(y,lx+i); tetpil=avma;
                    475:            return gerepile(av,tetpil,gadd(p1,x));
                    476:        }
                    477:
                    478:       case t_PADIC:
                    479:         switch(ty)
                    480:        {
                    481:          case t_PADIC:
                    482:             if (!egalii((GEN)x[2],(GEN)y[2])) err(gadderi,tx,ty);
                    483:             return addpadic(x,y);
                    484:
                    485:          case t_QUAD:
                    486:            if (kro_quad((GEN)y[1],(GEN)x[2]) == -1)
                    487:            {
                    488:              z=cgetg(4,t_QUAD);
                    489:              copyifstack(y[1], z[1]);
                    490:              z[2]=ladd((GEN)y[2],x);
                    491:              z[3]=lcopy((GEN)y[3]); return z;
                    492:            }
                    493:            av=avma; l = signe(x[4])? precp(x): 1;
                    494:            p1=cvtop(y,(GEN)x[2],valp(x)+l); tetpil=avma;
                    495:            return gerepile(av,tetpil,gadd(p1,x));
                    496:        }
                    497:
                    498:       case t_QUAD: z=cgetg(4,t_QUAD); k=x[1]; l=y[1];
                    499:         if (!gegal((GEN)k,(GEN)l)) err(gadderi,tx,ty);
                    500:         copyifstack(l, z[1]);
                    501:         z[2]=ladd((GEN)x[2],(GEN)y[2]);
                    502:         z[3]=ladd((GEN)x[3],(GEN)y[3]); return z;
                    503:     }
                    504:     err(bugparier,"gadd");
                    505:   }
                    506:
                    507:   /* here !isscalar(y) */
                    508:   if ( (vx>vy && (!is_matvec_t(tx) || !is_matvec_t(ty)))
                    509:     || (vx==vy && is_scalar_t(tx)) )
                    510:   {
                    511:     if (tx == t_POLMOD && vx == vy && ty != t_SER)
                    512:     {
                    513:       av = avma;
                    514:       return gerepileupto(av, op_polmod(gadd, x, to_polmod(y,(GEN)x[1]), tx));
                    515:     }
                    516:
                    517:     switch(ty)
                    518:     {
                    519:       case t_POL: ly=lgef(y);
                    520:        if (ly==2) return isexactzero(x)? zeropol(vy): scalarpol(x,vy);
                    521:
                    522:        z = cgetg(ly,t_POL); z[1] = y[1];
                    523:         z[2] = ladd(x,(GEN)y[2]);
                    524:         for (i=3; i<ly; i++) z[i]=lcopy((GEN)y[i]);
                    525:        return normalizepol_i(z, ly);
                    526:
                    527:       case t_SER: l=valp(y); ly=lg(y);
                    528:         if (l<3-ly) return gcopy(y);
                    529:        if (l<0)
                    530:        {
                    531:          z=cgetg(ly,t_SER); z[1]=y[1];
                    532:          for (i=2; i<=1-l; i++) z[i]=lcopy((GEN)y[i]);
                    533:          for (i=3-l; i<ly; i++) z[i]=lcopy((GEN)y[i]);
                    534:          z[2-l]=ladd(x,(GEN)y[2-l]); return z;
                    535:        }
                    536:        if (l>0)
                    537:        {
                    538:          if (gcmp0(x)) return gcopy(y);
                    539:          if (gcmp0(y)) ly=2;
                    540:
                    541:           ly += l; z=cgetg(ly,t_SER);
                    542:          z[1]=evalsigne(1) | evalvalp(0) | evalvarn(vy);
                    543:          for (i=3; i<=l+1; i++) z[i]=zero;
                    544:          for (   ; i<ly; i++) z[i]=lcopy((GEN)y[i-l]);
                    545:          z[2]=lcopy(x); return z;
                    546:        }
                    547:        av=avma; z=cgetg(ly,t_SER);
                    548:        p1=signe(y)? gadd(x,(GEN)y[2]): x;
                    549:        if (!isexactzero(p1))
                    550:         {
                    551:           z[1] = evalvalp(0) | evalvarn(vy);
                    552:           if (signe(y))
                    553:           {
                    554:             z[1] |= evalsigne(1); z[2]=(long)p1;
                    555:             for (i=3; i<ly; i++) z[i]=lcopy((GEN)y[i]);
                    556:           }
                    557:           return z;
                    558:         }
                    559:         avma=av; /* first coeff is 0 */
                    560:         i=3; while (i<ly && gcmp0((GEN)y[i])) i++;
                    561:         if (i==ly) return zeroser(vy,i-2);
                    562:
                    563:         z=cgetg(ly-i+2,t_SER); z[1]=evalvalp(i-2)|evalvarn(vy)|evalsigne(1);
                    564:         for (j=2; j<=ly-i+1; j++) z[j]=lcopy((GEN)y[j+i-2]);
                    565:         return z;
                    566:
                    567:       case t_RFRAC: return addscalrfrac(x,y);
                    568:       case t_RFRACN: z=cgetg(3,t_RFRACN);
                    569:         av=avma; p1=gmul(x,(GEN)y[2]); tetpil=avma;
                    570:         z[1]=lpile(av,tetpil, gadd(p1,(GEN)y[1]));
                    571:         z[2]=lcopy((GEN)y[2]); return z;
                    572:
                    573:       case t_VEC: case t_COL: case t_MAT:
                    574:        if (isexactzero(x)) return gcopy(y);
                    575:        if (ty == t_MAT) return gaddmat(x,y);
                    576:         /* fall through */
                    577:       case t_QFR: case t_QFI: err(gadderf,tx,ty);
                    578:     }
                    579:     err(typeer,"addition");
                    580:   }
                    581:
                    582:   /* here !isscalar(x) && isscalar(y) && (vx=vy || ismatvec(x and y)) */
                    583:   if (tx>ty) { p1=x; x=y; y=p1; i=tx; tx=ty; ty=i; }
                    584:   switch(tx)
                    585:   {
                    586:     case t_POL:
                    587:       switch (ty)
                    588:       {
                    589:        case t_POL:
                    590:           lx = lgef(x); ly = lgef(y); if (lx < ly) swapspec(x,y, lx,ly);
                    591:           z = cgetg(lx,t_POL); z[1] = x[1];
                    592:           for (i=2; i<ly; i++) z[i]=ladd((GEN)x[i],(GEN)y[i]);
                    593:           for (   ; i<lx; i++) z[i]=lcopy((GEN)x[i]);
                    594:           (void)normalizepol_i(z, lx);
                    595:           if (lgef(z) == 2) { avma = (long)(z + lx); z = zeropol(vx); }
                    596:           return z;
                    597:
                    598:        case t_SER:
                    599:          if (gcmp0(x)) return gcopy(y);
                    600:           ly = signe(y)? lg(y): 3;
                    601:          i = ly+valp(y)-gval(x,vx);
                    602:          if (i<3) return gcopy(y);
                    603:
                    604:          p1=greffe(x,i,0); y=gadd(p1,y);
                    605:           free(p1); return y;
                    606:
                    607:         case t_RFRAC: return addscalrfrac(x,y);
                    608:         case t_RFRACN: z=cgetg(3,t_RFRACN);
                    609:           av=avma; p1=gmul(x,(GEN)y[2]); tetpil=avma;
                    610:           z[1]=lpile(av,tetpil, gadd(p1,(GEN)y[1]));
                    611:           z[2]=lcopy((GEN)y[2]); return z;
                    612:
                    613:        case t_QFR: case t_QFI:
                    614:        case t_VEC: case t_COL: case t_MAT: err(gadderf,tx,ty);
                    615:        default: err(typeer,"addition");
                    616:       }
                    617:
                    618:     case t_SER:
                    619:       switch(ty)
                    620:       {
                    621:        case t_SER:
                    622:          l=valp(y)-valp(x);
                    623:          if (l<0) { l= -l; p1=x; x=y; y=p1; }
                    624:          if (gcmp0(x)) return gcopy(x);
                    625:           lx = lg(x);
                    626:           ly = signe(y)? lg(y): 2;
                    627:          ly += l; if (lx<ly) ly=lx;
                    628:           z=cgetg(ly,t_SER);
                    629:          if (l)
                    630:          {
                    631:            if (l>=ly-2)
                    632:              for (i=2; i<ly; i++) z[i]=lcopy((GEN)x[i]);
                    633:             else
                    634:            {
                    635:              for (i=2; i<=l+1; i++) z[i]=lcopy((GEN)x[i]);
                    636:              for (   ; i<ly; i++) z[i]=ladd((GEN)x[i],(GEN)y[i-l]);
                    637:            }
                    638:            z[1]=x[1]; return z;
                    639:          }
                    640:           if (ly>2)
                    641:           {
                    642:             l=avma;
                    643:             for (i=2; i<ly; i++)
                    644:             {
                    645:               p1 = gadd((GEN)x[i],(GEN)y[i]);
                    646:               if (!isexactzero(p1))
                    647:               {
                    648:                 l = i-2; stackdummy(z,l); z += l;
                    649:                 z[0]=evaltyp(t_SER) | evallg(ly-l);
                    650:                 z[1]=evalvalp(valp(x)+i-2) | evalsigne(1) | evalvarn(vx);
                    651:                 for (j=i+1; j<ly; j++)
                    652:                   z[j-l]=ladd((GEN)x[j],(GEN)y[j]);
                    653:                 z[2]=(long)p1; return z;
                    654:               }
                    655:               avma=l;
                    656:             }
                    657:           }
                    658:           return zeroser(vx,ly-2+valp(y));
                    659:
                    660:        case t_RFRAC: case t_RFRACN:
                    661:          if (gcmp0(y)) return gcopy(x);
                    662:
                    663:          l = valp(x)-gval(y,vy); l += gcmp0(x)? 3: lg(x);
                    664:          if (l<3) return gcopy(x);
                    665:
                    666:          av=avma; ty=typ(y[2]);
                    667:           p1 = is_scalar_t(ty)? (GEN)y[2]: greffe((GEN)y[2],l,1);
                    668:           p1 = gdiv((GEN)y[1], p1); tetpil=avma;
                    669:           return gerepile(av,tetpil,gadd(p1,x));
                    670:
                    671:        case t_QFR: case t_QFI: case t_VEC: case t_COL: case t_MAT:
                    672:          err(gadderf,tx,ty);
                    673:
                    674:        default: err(typeer,"addition");
                    675:       }
                    676:
                    677:     case t_RFRAC:
                    678:       if (!is_rfrac_t(ty)) err(gadderi,tx,ty);
                    679:       return addrfrac(x,y);
                    680:     case t_RFRACN:
                    681:       if (!is_rfrac_t(ty)) err(gadderi,tx,ty);
                    682:       z=cgetg(3,t_RFRACN); av=avma;
                    683:       p1=gmul((GEN)x[1],(GEN)y[2]);
                    684:       p2=gmul((GEN)x[2],(GEN)y[1]); tetpil=avma;
                    685:       z[1]=lpile(av,tetpil, gadd(p1,p2));
                    686:       z[2]=lmul((GEN)x[2],(GEN)y[2]); return z;
                    687:
                    688:     case t_VEC: case t_COL: case t_MAT:
                    689:       lx = lg(x); ly = lg(y);
                    690:       if (lx!=ly || tx!=ty) err(gadderi,tx,ty);
                    691:       z=cgetg(ly,ty);
                    692:       for (i=1; i<ly; i++)
                    693:        z[i]=ladd((GEN)x[i],(GEN)y[i]);
                    694:       return z;
                    695:
                    696:     case t_QFR: case t_QFI: err(gadderf,tx,ty);
                    697:   }
                    698:   err(typeer,"addition");
                    699:   return NULL; /* not reached */
                    700: }
                    701:
                    702: /********************************************************************/
                    703: /**                                                                **/
                    704: /**                        MULTIPLICATION                          **/
                    705: /**                                                                **/
                    706: /********************************************************************/
                    707: #define fix_frac(z) if (signe(z[2])<0)\
                    708: {\
                    709:   setsigne(z[1],-signe(z[1]));\
                    710:   setsigne(z[2],1);\
                    711: }
                    712:
                    713: /* assume z[1] was created last */
                    714: #define fix_frac_if_int(z) if (is_pm1(z[2]))\
                    715:   z = gerepileupto((long)(z+3), (GEN)z[1]);
                    716:
                    717: /* assume z[1] was created last */
                    718: #define fix_frac_if_int_GC(z,tetpil) { if (is_pm1(z[2]))\
                    719:   z = gerepileupto((long)(z+3), (GEN)z[1]);\
                    720: else\
                    721:   gerepilemanyvec((long)z, tetpil, z+1, 2); }
                    722:
                    723: GEN
                    724: fix_rfrac_if_pol(GEN x, GEN y)
                    725: {
                    726:   if (gcmp1(y)) return x;
                    727:   if (typ(y) != t_POL)
                    728:   {
                    729:     if (typ(x) != t_POL || gvar2(y) > varn(x))
                    730:       return gdiv(x,y);
                    731:   }
                    732:   else if (varn(y) > varn(x)) return gdiv(x,y);
                    733:   return NULL;
                    734: }
                    735:
                    736: static long
                    737: mingvar(GEN x, GEN y)
                    738: {
                    739:   long i = gvar(x);
                    740:   long j = gvar(y);
                    741:   return min(i,j);
                    742: }
                    743:
                    744: GEN
                    745: mulscalrfrac(GEN x, GEN y)
                    746: {
                    747:   GEN p1,z,y1,y2,cx,cy1,cy2;
                    748:   long tetpil,tx;
                    749:
                    750:   if (gcmp0(x)) return gcopy(x);
                    751:
                    752:   y1=(GEN)y[1]; if (gcmp0(y1)) return gcopy(y1);
                    753:   y2=(GEN)y[2]; tx = typ(x);
                    754:   z = cgetg(3, t_RFRAC);
                    755:   if (is_const_t(tx) || varn(x) > mingvar(y1,y2)) { cx = x; x = gun; }
                    756:   else
                    757:   {
                    758:     p1 = ggcd(x,y2); if (isnonscalar(p1)) { x=gdeuc(x,p1); y2=gdeuc(y2,p1); }
                    759:     cx = content(x); if (!gcmp1(cx)) x = gdiv(x,cx);
                    760:   }
                    761:   cy1 = content(y1); if (!gcmp1(cy1)) y1 = gdiv(y1,cy1);
                    762:   cy2 = content(y2); if (!gcmp1(cy2)) y2 = gdiv(y2,cy2);
                    763:   if (x != gun) y1 = gmul(y1,x);
                    764:   x = gdiv(gmul(cx,cy1), cy2);
                    765:   cy1 = numer(x);
                    766:   cy2 = denom(x); tetpil = avma;
                    767:   z[2] = lmul(y2, cy2);
                    768:   z[1] = lmul(y1, cy1);
                    769:   p1 = fix_rfrac_if_pol((GEN)z[1],(GEN)z[2]);
                    770:   if (p1) return gerepileupto((long)(z+3), p1);
                    771:   gerepilemanyvec((long)z,tetpil,z+1,2); return z;
                    772: }
                    773:
                    774: static GEN
                    775: mulrfrac(GEN x, GEN y)
                    776: {
                    777:   GEN z = cgetg(3,t_RFRAC), p1;
                    778:   GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
                    779:   GEN y1 = (GEN)y[1], y2 = (GEN)y[2];
                    780:   long tetpil;
                    781:
                    782:   p1 = ggcd(x1, y2); if (!gcmp1(p1)) { x1 = gdiv(x1,p1); y2 = gdiv(y2,p1); }
                    783:   p1 = ggcd(x2, y1); if (!gcmp1(p1)) { x2 = gdiv(x2,p1); y1 = gdiv(y1,p1); }
                    784:   tetpil = avma;
                    785:   z[2] = lmul(x2,y2);
                    786:   z[1] = lmul(x1,y1);
                    787:   p1 = fix_rfrac_if_pol((GEN)z[1],(GEN)z[2]);
                    788:   if (p1) return gerepileupto((long)(z+3), p1);
                    789:   gerepilemanyvec((long)z,tetpil,z+1,2); return z;
                    790: }
                    791:
                    792: GEN
                    793: to_Kronecker(GEN P, GEN Q)
                    794: {
                    795:   /* P(X) = sum Mod(.,Q(Y)) * X^i, lift then set X := Y^(2n-1) */
                    796:   long i,j,k,l, lx = lgef(P), N = ((lgef(Q)-3)<<1) + 1, vQ = varn(Q);
                    797:   GEN p1, y = cgetg((N-2)*(lx-2) + 2, t_POL);
                    798:   for (k=i=2; i<lx; i++)
                    799:   {
                    800:     p1 = (GEN)P[i];
                    801:     if ((l=typ(p1)) == t_POLMOD) { p1 = (GEN)p1[2]; l = typ(p1); }
                    802:     if (is_scalar_t(l) || varn(p1)<vQ) { y[k++] = (long)p1; j = 3; }
                    803:     else
                    804:     {
                    805:       l = lgef(p1);
                    806:       for (j=2; j < l; j++) y[k++] = p1[j];
                    807:     }
                    808:     if (i == lx-1) break;
                    809:     for (   ; j < N; j++) y[k++] = zero;
                    810:   }
                    811:   y[1] = evalsigne(1)|evalvarn(vQ)|evallgef(k);
                    812:   return y;
                    813: }
                    814:
                    815: int
                    816: ff_poltype(GEN *x, GEN *p, GEN *pol)
                    817: {
                    818:   GEN Q, P = *x, pr,p1,p2,y;
                    819:   long i, lx;
                    820:
                    821:   if (!signe(P)) return 0;
                    822:   lx = lgef(P); Q = *pol;
                    823:   for (i=2; i<lx; i++)
                    824:   {
                    825:     p1 = (GEN)P[i]; if (typ(p1) != t_POLMOD) { Q = NULL; break; }
                    826:     p2 = (GEN)p1[1];
                    827:     if (Q==NULL) Q = p2;
                    828:     else if (p2 != Q)
                    829:     {
                    830:       if (!gegal(p2, Q))
                    831:       {
                    832:         if (DEBUGMEM) err(warner,"different modulus in ff_poltype");
                    833:         return 0;
                    834:       }
                    835:       if (DEBUGMEM > 2) err(warner,"different pointers in ff_poltype");
                    836:     }
                    837:   }
                    838:   if (Q) {
                    839:     *x = P = to_Kronecker(P, Q);
                    840:     *pol = Q; lx = lgef(P);
                    841:   }
                    842:   pr = *p; y = cgetg(lx, t_POL);
                    843:   for (i=lx-1; i>1; i--)
                    844:   {
                    845:     p1 = (GEN)P[i];
                    846:     switch(typ(p1))
                    847:     {
                    848:       case t_INTMOD: break;
                    849:       case t_INT:
                    850:         if (*p) p1 = modii(p1, *p);
                    851:         y[i] = (long)p1; continue;
                    852:       default:
                    853:         return (Q && !pr)? 1: 0;
                    854:     }
                    855:     p2 = (GEN)p1[1];
                    856:     if (pr==NULL) pr = p2;
                    857:     else if (p2 != pr)
                    858:     {
                    859:       if (!egalii(p2, pr))
                    860:       {
                    861:         if (DEBUGMEM) err(warner,"different modulus in ff_poltype");
                    862:         return 0;
                    863:       }
                    864:       if (DEBUGMEM > 2) err(warner,"different pointers in ff_poltype");
                    865:     }
                    866:     y[i] = p1[2];
                    867:   }
                    868:   y[1] = evalsigne(1)|evalvarn(varn(P))|evallgef(lx);
                    869:   *x = y; *p = pr; return (Q || pr);
                    870: }
                    871:
                    872: GEN
                    873: gmul(GEN x, GEN y)
                    874: {
                    875:   long tx,ty,lx,ly,vx,vy,i,j,k,l,av,tetpil;
                    876:   GEN z,p1,p2,p3,p4;
                    877:
                    878:   if (x == y) return gsqr(x);
                    879:   tx=typ(x); ty=typ(y);
                    880:   if (is_const_t(tx) && is_const_t(ty))
                    881:   {
                    882:     if (tx>ty) { p1=x; x=y; y=p1; i=tx; tx=ty; ty=i; }
                    883:   }
                    884:   else
                    885:   {
                    886:     vx=gvar(x); vy=gvar(y);
                    887:     if (!is_matvec_t(ty))
                    888:       if (is_matvec_t(tx) || vx<vy || (vx==vy && tx>ty))
                    889:       {
                    890:        p1=x; x=y; y=p1;
                    891:         i=tx; tx=ty; ty=i;
                    892:        i=vx; vx=vy; vy=i;
                    893:       }
                    894:     if (ty==t_POLMOD) return op_polmod(gmul,x,y,tx);
                    895:   }
                    896:
                    897:   if (is_scalar_t(ty))
                    898:   {
                    899:     switch(tx)
                    900:     {
                    901:       case t_INT:
                    902:         switch(ty)
                    903:        {
                    904:          case t_INT:  return mulii(x,y);
                    905:          case t_REAL: return mulir(x,y);
                    906:
                    907:          case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
                    908:            (void)new_chunk(lgefint(p2)<<2);
                    909:             p1=mulii(modii(x,p2),(GEN)y[2]); avma=(long)z;
                    910:            z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
                    911:
                    912:          case t_FRAC:
                    913:             if (!signe(x)) return gzero;
                    914:             z=cgetg(3,t_FRAC);
                    915:             p1 = mppgcd(x,(GEN)y[2]);
                    916:             if (is_pm1(p1))
                    917:             {
                    918:               avma = (long)z;
                    919:               z[2] = licopy((GEN)y[2]);
                    920:               z[1] = lmulii((GEN)y[1], x);
                    921:             }
                    922:             else
                    923:             {
                    924:               x = divii(x,p1); tetpil = avma;
                    925:               z[2] = ldivii((GEN)y[2], p1);
                    926:               z[1] = lmulii((GEN)y[1], x);
                    927:               fix_frac_if_int_GC(z,tetpil);
                    928:             }
                    929:             return z;
                    930:
                    931:           case t_FRACN: z=cgetg(3,t_FRACN);
                    932:            z[1]=lmulii(x,(GEN)y[1]);
                    933:            z[2]=licopy((GEN)y[2]); return z;
                    934:
                    935:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                    936:            z[1]=lmul(x,(GEN)y[1]);
                    937:            z[2]=lmul(x,(GEN)y[2]); return z;
                    938:
                    939:          case t_PADIC:
                    940:            if (!signe(x)) return gzero;
                    941:            l=avma; p1=cgetp(y); gaffect(x,p1); tetpil=avma;
                    942:            return gerepile(l,tetpil,gmul(p1,y));
                    943:
                    944:          case t_QUAD: z=cgetg(4,t_QUAD);
                    945:            copyifstack(y[1], z[1]);
                    946:            z[2]=lmul(x,(GEN)y[2]);
                    947:            z[3]=lmul(x,(GEN)y[3]); return z;
                    948:        }
                    949:
                    950:       case t_REAL:
                    951:         switch(ty)
                    952:        {
                    953:          case t_REAL: return mulrr(x,y);
                    954:
                    955:          case t_FRAC: case t_FRACN:
                    956:            l=avma; p1=cgetr(lg(x)); tetpil=avma; gaffect(y,p1);
                    957:            p2=mulrr(p1,x); return gerepile(l,tetpil,p2);
                    958:
                    959:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                    960:            z[1]=lmul(x,(GEN)y[1]);
                    961:            z[2]=lmul(x,(GEN)y[2]); return z;
                    962:
                    963:          case t_QUAD:
                    964:            l=avma; p1=co8(y,lg(x)); tetpil=avma;
                    965:            return gerepile(l,tetpil,gmul(p1,x));
                    966:
                    967:          case t_INTMOD: err(gmulerf,tx,ty);
                    968:        }
                    969:
                    970:       case t_INTMOD:
                    971:         switch(ty)
                    972:        {
                    973:          case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)x[1]; p1=(GEN)y[1];
                    974:            if (p1==p2 || egalii(p1,p2))
                    975:             {
                    976:               icopyifstack(p2,z[1]);
                    977:               if (!is_bigint(p2))
                    978:               {
                    979:                 z[2] = lstoi(mulssmod(itos((GEN)x[2]),itos((GEN)y[2]), p2[2]));
                    980:                 return z;
                    981:               }
                    982:             }
                    983:             else
                    984:             { p2 = mppgcd(p1,p2); z[1] = (long)p2; }
                    985:             av=avma;
                    986:             (void)new_chunk(lgefint(x[1]) + (lgefint(p1)<<1));
                    987:            p1=mulii((GEN)x[2],(GEN)y[2]); avma=av;
                    988:            z[2]=lmodii(p1,p2); return z;
                    989:
                    990:          case t_FRAC: case t_FRACN: z=cgetg(3,t_INTMOD); p2=(GEN)x[1];
                    991:             (void)new_chunk(lgefint(p2)<<2);
                    992:             p1 = mulii((GEN)y[1], mpinvmod((GEN)y[2],p2));
                    993:             p1 = mulii(modii(p1,p2),(GEN)x[2]); avma=(long)z;
                    994:             z[2] = lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
                    995:
                    996:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                    997:            z[1]=lmul(x,(GEN)y[1]);
                    998:            z[2]=lmul(x,(GEN)y[2]); return z;
                    999:
                   1000:          case t_PADIC:
                   1001:            l=avma; p1=cgetg(3,t_INTMOD);
                   1002:            p1[1]=x[1]; p1[2]=lgeti(lg(x[1]));
                   1003:            gaffect(y,p1); tetpil=avma;
                   1004:            return gerepile(l,tetpil,gmul(x,p1));
                   1005:
                   1006:          case t_QUAD: z=cgetg(4,t_QUAD);
                   1007:             copyifstack(y[1], z[1]);
                   1008:            z[2]=lmul(x,(GEN)y[2]);
                   1009:             z[3]=lmul(x,(GEN)y[3]); return z;
                   1010:        }
                   1011:
                   1012:       case t_FRAC: case t_FRACN:
                   1013:         switch(ty)
                   1014:        {
                   1015:          case t_FRAC:
                   1016:           {
                   1017:             GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
                   1018:             GEN y1 = (GEN)y[1], y2 = (GEN)y[2];
                   1019:             z=cgetg(3,t_FRAC);
                   1020:             p1 = mppgcd(x1, y2);
                   1021:             if (!is_pm1(p1)) { x1 = divii(x1,p1); y2 = divii(y2,p1); }
                   1022:             p1 = mppgcd(x2, y1);
                   1023:             if (!is_pm1(p1)) { x2 = divii(x2,p1); y1 = divii(y1,p1); }
                   1024:             tetpil = avma;
                   1025:             z[2] = lmulii(x2,y2);
                   1026:             z[1] = lmulii(x1,y1);
                   1027:             fix_frac_if_int_GC(z,tetpil); return z;
                   1028:           }
                   1029:          case t_FRACN: z=cgetg(3,t_FRACN);
                   1030:            z[1]=lmulii((GEN)x[1],(GEN)y[1]);
                   1031:            z[2]=lmulii((GEN)x[2],(GEN)y[2]); return z;
                   1032:
                   1033:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                   1034:            z[1]=lmul((GEN)y[1],x);
                   1035:            z[2]=lmul((GEN)y[2],x); return z;
                   1036:
                   1037:          case t_PADIC:
                   1038:            if (!signe(x[1])) return gzero;
                   1039:            l=avma; p1=cgetp(y); gaffect(x,p1); tetpil=avma;
                   1040:             return gerepile(l,tetpil,gmul(p1,y));
                   1041:
                   1042:          case t_QUAD: z=cgetg(4,t_QUAD);
                   1043:            copyifstack(y[1], z[1]);
                   1044:            z[2]=lmul((GEN)y[2],x);
                   1045:            z[3]=lmul((GEN)y[3],x); return z;
                   1046:        }
                   1047:
                   1048:       case t_COMPLEX:
                   1049:         switch(ty)
                   1050:        {
                   1051:          case t_COMPLEX: z=cgetg(3,t_COMPLEX); l=avma;
                   1052:             p1=gmul((GEN)x[1],(GEN)y[1]);
                   1053:             p2=gmul((GEN)x[2],(GEN)y[2]);
                   1054:            x=gadd((GEN)x[1],(GEN)x[2]);
                   1055:             y=gadd((GEN)y[1],(GEN)y[2]);
                   1056:            y=gmul(x,y); x=gadd(p1,p2);
                   1057:            tetpil=avma; z[1]=lsub(p1,p2); z[2]=lsub(y,x);
                   1058:            gerepilemanyvec(l,tetpil,z+1,2); return z;
                   1059:
                   1060:          case t_PADIC:
                   1061:            if (krosg(-1,(GEN)y[2]))
                   1062:            {
                   1063:              z=cgetg(3,t_COMPLEX);
                   1064:              z[1]=lmul((GEN)x[1],y);
                   1065:              z[2]=lmul((GEN)x[2],y); return z;
                   1066:            }
                   1067:            av=avma;
                   1068:             if (signe(y[4])) l=precp(y);
                   1069:             else
                   1070:             {
                   1071:               l=valp(y)+1; if (l<=0) l=1;
                   1072:             }
                   1073:             p1=cvtop(x,(GEN)y[2],l); tetpil=avma;
                   1074:             return gerepile(av,tetpil,gmul(p1,y));
                   1075:
                   1076:          case t_QUAD:
                   1077:            lx=precision(x); if (!lx) err(gmuleri,tx,ty);
                   1078:            l=avma; p1=co8(y,lx); tetpil=avma;
                   1079:            return gerepile(l,tetpil,gmul(p1,x));
                   1080:        }
                   1081:
                   1082:       case t_PADIC:
                   1083:         switch(ty)
                   1084:        {
                   1085:          case t_PADIC:
                   1086:            if (!egalii((GEN)x[2],(GEN)y[2])) err(gmuleri,tx,ty);
                   1087:             l = valp(x)+valp(y);
                   1088:            if (!signe(x[4])) { z=gcopy(x); setvalp(z,l); return z; }
                   1089:            if (!signe(y[4])) { z=gcopy(y); setvalp(z,l); return z; }
                   1090:
                   1091:            p1 = (precp(x) > precp(y))? y: x;
                   1092:            z=cgetp(p1); setvalp(z,l); av=avma;
                   1093:            modiiz(mulii((GEN)x[4],(GEN)y[4]),(GEN)p1[3],(GEN)z[4]);
                   1094:            avma=av; return z;
                   1095:
                   1096:          case t_QUAD:
                   1097:            if (kro_quad((GEN)y[1],(GEN)x[2])== -1)
                   1098:            {
                   1099:              z=cgetg(4,t_QUAD);
                   1100:              copyifstack(y[1], z[1]);
                   1101:              z[2]=lmul((GEN)y[2],x);
                   1102:              z[3]=lmul((GEN)y[3],x); return z;
                   1103:            }
                   1104:             l = signe(x[4])? precp(x): valp(x)+1;
                   1105:            av=avma; p1=cvtop(y,(GEN)x[2],l); tetpil=avma;
                   1106:             return gerepile(av,tetpil,gmul(p1,x));
                   1107:        }
                   1108:
                   1109:       case t_QUAD: z=cgetg(4,t_QUAD);
                   1110:         p1=(GEN)x[1]; p2=(GEN)y[1];
                   1111:         if (!gegal(p1,p2)) err(gmuleri,tx,ty);
                   1112:
                   1113:         copyifstack(p2, z[1]); l=avma;
                   1114:         p2=gmul((GEN)x[2],(GEN)y[2]);
                   1115:         p3=gmul((GEN)x[3],(GEN)y[3]);
                   1116:         p4=gmul(gneg_i((GEN)p1[2]),p3);
                   1117:
                   1118:         if (gcmp0((GEN)p1[3]))
                   1119:         {
                   1120:           tetpil=avma;
                   1121:           z[2]=lpile(l,tetpil,gadd(p4,p2)); l=avma;
                   1122:           p2=gmul((GEN)x[2],(GEN)y[3]);
                   1123:           p3=gmul((GEN)x[3],(GEN)y[2]); tetpil=avma;
                   1124:           z[3]=lpile(l,tetpil,gadd(p2,p3)); return z;
                   1125:         }
                   1126:
                   1127:         p1 = gadd(gmul((GEN)x[2],(GEN)y[3]), gmul((GEN)x[3],(GEN)y[2]));
                   1128:         tetpil=avma;
                   1129:         z[2]=ladd(p2,p4);
                   1130:         z[3]=ladd(p1,p3);
                   1131:         gerepilemanyvec(l,tetpil,z+2,2); return z;
                   1132:     }
                   1133:     err(bugparier,"multiplication");
                   1134:   }
                   1135:
                   1136:   /* here !isscalar(y) */
                   1137:   if (is_matvec_t(ty))
                   1138:   {
                   1139:     ly=lg(y);
                   1140:     if (!is_matvec_t(tx))
                   1141:     {
                   1142:       z=cgetg(ly,ty);
                   1143:       for (i=1; i<ly; i++) z[i]=lmul(x,(GEN)y[i]);
                   1144:       return z;
                   1145:     }
                   1146:     lx=lg(x);
                   1147:
                   1148:     switch(tx)
                   1149:     {
                   1150:       case t_VEC:
                   1151:         switch(ty)
                   1152:         {
                   1153:           case t_COL:
                   1154:             if (lx!=ly) err(gmuleri,tx,ty);
                   1155:             z=gzero; l=avma;
                   1156:             for (i=1; i<lx; i++)
                   1157:             {
                   1158:               p1=gmul((GEN)x[i],(GEN)y[i]);
                   1159:               tetpil=avma; z=gadd(z,p1);
                   1160:             }
                   1161:             return gerepile(l,tetpil,z);
                   1162:
                   1163:           case t_MAT:
                   1164:             if (ly==1) return cgetg(1,t_VEC);
                   1165:             l=lg(y[1]); if (lx!=l) err(gmuleri,tx,ty);
                   1166:
                   1167:             z=cgetg(ly,tx);
                   1168:             for (i=1; i<ly; i++)
                   1169:             {
                   1170:               p1=gzero; av=avma;
                   1171:               for (j=1; j<lx; j++)
                   1172:               {
                   1173:                 p2=gmul((GEN)x[j],gcoeff(y,j,i));
                   1174:                 tetpil=avma; p1=gadd(p1,p2);
                   1175:               }
                   1176:               z[i]=lpile(av,tetpil,p1);
                   1177:             }
                   1178:             return z;
                   1179:
                   1180:           case t_VEC: err(gmulerf,tx,ty);
                   1181:           default: err(typeer,"multiplication");
                   1182:         }
                   1183:
                   1184:       case t_COL:
                   1185:         switch(ty)
                   1186:         {
                   1187:           case t_VEC:
                   1188:             z=cgetg(ly,t_MAT);
                   1189:             for (i=1; i<ly; i++)
                   1190:             {
                   1191:               p1 = gmul((GEN)y[i],x);
                   1192:               if (typ(p1) != t_COL) err(gmuleri,tx,ty);
                   1193:               z[i]=(long)p1;
                   1194:             }
                   1195:             return z;
                   1196:
                   1197:           case t_MAT:
                   1198:             if (ly!=1 && lg(y[1])!=2) err(gmuleri,tx,ty);
                   1199:
                   1200:             z=cgetg(ly,t_MAT);
                   1201:             for (i=1; i<ly; i++) z[i]=lmul(gcoeff(y,1,i),x);
                   1202:             return z;
                   1203:
                   1204:           case t_COL: err(gmulerf,tx,ty);
                   1205:           default: err(typeer,"multiplication");
                   1206:         }
                   1207:
                   1208:       case t_MAT:
                   1209:         switch(ty)
                   1210:         {
                   1211:           case t_VEC:
                   1212:             if (lx!=2) err(gmuleri,tx,ty);
                   1213:             z=cgetg(ly,t_MAT);
                   1214:             for (i=1; i<ly; i++) z[i]=lmul((GEN)y[i],(GEN)x[1]);
                   1215:             return z;
                   1216:
                   1217:           case t_COL:
                   1218:             if (lx!=ly) err(gmuleri,tx,ty);
                   1219:             if (lx==1) return gcopy(y);
                   1220:
                   1221:             lx=lg(x[1]); z=cgetg(lx,t_COL);
                   1222:             for (i=1; i<lx; i++)
                   1223:             {
                   1224:               p1=gzero; l=avma;
                   1225:               for (j=1; j<ly; j++)
                   1226:               {
                   1227:                 p2=gmul(gcoeff(x,i,j),(GEN)y[j]);
                   1228:                 tetpil=avma; p1=gadd(p1,p2);
                   1229:               }
                   1230:               z[i]=lpile(l,tetpil,p1);
                   1231:             }
                   1232:             return z;
                   1233:
                   1234:           case t_MAT:
                   1235:             if (ly==1) return cgetg(ly,t_MAT);
                   1236:             if (lx != lg(y[1])) err(gmuleri,tx,ty);
                   1237:             z=cgetg(ly,t_MAT);
                   1238:             if (lx==1)
                   1239:             {
                   1240:               for (i=1; i<ly; i++) z[i]=lgetg(1,t_COL);
                   1241:               return z;
                   1242:             }
                   1243:             l=lg(x[1]);
                   1244:             for (j=1; j<ly; j++)
                   1245:             {
                   1246:               z[j] = lgetg(l,t_COL);
                   1247:               for (i=1; i<l; i++)
                   1248:               {
                   1249:                 p1=gzero; av=avma;
                   1250:                 for (k=1; k<lx; k++)
                   1251:                 {
                   1252:                   p2=gmul(gcoeff(x,i,k),gcoeff(y,k,j));
                   1253:                   tetpil=avma; p1=gadd(p1,p2);
                   1254:                 }
                   1255:                 coeff(z,i,j)=lpile(av,tetpil,p1);
                   1256:               }
                   1257:             }
                   1258:             return z;
                   1259:         }
                   1260:     }
                   1261:     err(bugparier,"multiplication");
                   1262:   }
                   1263:   /* now !ismatvec(x and y) */
                   1264:
                   1265:   if (vx>vy || (vx==vy && is_scalar_t(tx)))
                   1266:   {
                   1267:     if (isexactzero(x)) return zeropol(vy);
                   1268:     if (tx == t_INT && is_pm1(x))
                   1269:       return (signe(x)>0) ? gcopy(y): gneg(y);
                   1270:     if (tx == t_POLMOD && vx == vy && ty != t_SER)
                   1271:     {
                   1272:       av = avma;
                   1273:       return gerepileupto(av, op_polmod(gmul, x, to_polmod(y,(GEN)x[1]), tx));
                   1274:     }
                   1275:     switch(ty)
                   1276:     {
                   1277:       case t_POL:
                   1278:        if (isexactzero(y)) return zeropol(vy);
                   1279:         ly = lgef(y); z = cgetg(ly,t_POL); z[1]=y[1];
                   1280:         for (i=2; i<ly; i++) z[i]=lmul(x,(GEN)y[i]);
                   1281:         return normalizepol_i(z,ly);
                   1282:
                   1283:       case t_SER:
                   1284:        if (!signe(y)) return gcopy(y);
                   1285:        ly=lg(y); z=cgetg(ly,t_SER);
                   1286:        for (i=2; i<ly; i++) z[i]=lmul(x,(GEN)y[i]);
                   1287:        z[1]=y[1]; return normalize(z);
                   1288:
                   1289:       case t_RFRAC: return mulscalrfrac(x,y);
                   1290:       case t_RFRACN: av=avma; z=cgetg(3,t_RFRACN);
                   1291:         z[1]=lmul(x,(GEN)y[1]);
                   1292:         z[2]=lcopy((GEN)y[2]); return z;
                   1293:     }
                   1294:     err(typeer,"multiplication");
                   1295:   }
                   1296:
                   1297:   if (tx>ty) { p1=x; x=y; y=p1; i=tx; tx=ty; ty=i; }
                   1298:   switch(tx)
                   1299:   {
                   1300:     case t_POL:
                   1301:       switch (ty)
                   1302:       {
                   1303:        case t_POL:
                   1304:         {
                   1305:           GEN a = x,b = y, p = NULL, pol = NULL;
                   1306:           long av = avma;
                   1307:           if (ff_poltype(&x,&p,&pol) && ff_poltype(&y,&p,&pol))
                   1308:           {
                   1309:             /* fprintferr("HUM"); */
                   1310:             if (pol && varn(x) != varn(y))
                   1311:               x = to_Kronecker(x,pol);
                   1312:             z = quickmul(x+2, y+2, lgef(x)-2, lgef(y)-2);
                   1313:             if (p) z = Fp_pol(z,p);
                   1314:             if (pol) z = from_Kronecker(z,pol);
                   1315:             z = gerepileupto(av, z);
                   1316:           }
                   1317:           else
                   1318:           {
                   1319:             avma = av;
                   1320:             z = quickmul(a+2, b+2, lgef(a)-2, lgef(b)-2);
                   1321:           }
                   1322:           setvarn(z,vx); return z;
                   1323:         }
                   1324:        case t_SER:
                   1325:          if (gcmp0(x)) return zeropol(vx);
                   1326:          if (gcmp0(y)) return zeroser(vx, valp(y)+gval(x,vx));
                   1327:          p1=greffe(x,lg(y),0); p2=gmul(p1,y);
                   1328:           free(p1); return p2;
                   1329:
                   1330:         case t_RFRAC: return mulscalrfrac(x,y);
                   1331:         case t_RFRACN: av=avma; z=cgetg(3,t_RFRACN);
                   1332:           z[1]=lmul(x,(GEN)y[1]);
                   1333:           z[2]=lcopy((GEN)y[2]); return z;
                   1334:
                   1335:        default: err(typeer,"multiplication");
                   1336:       }
                   1337:
                   1338:     case t_SER:
                   1339:       switch (ty)
                   1340:       {
                   1341:        case t_SER:
                   1342:          if (gcmp0(x) || gcmp0(y)) return zeroser(vx, valp(x)+valp(y));
                   1343:           lx=lg(x); ly=lg(y);
                   1344:          if (lx>ly) { k=ly; ly=lx; lx=k; p1=y; y=x; x=p1; }
                   1345:           z = cgetg(lx,t_SER);
                   1346:          z[1] = evalvalp(valp(x)+valp(y)) | evalvarn(vx) | evalsigne(1);
                   1347:           x += 2; y += 2; z += 2; lx -= 3;
                   1348:           p2 = (GEN)gpmalloc((lx+1)*sizeof(long));
                   1349:          for (i=0; i<=lx; i++)
                   1350:           {
                   1351:            p2[i] = !isexactzero((GEN)y[i]);
                   1352:             p1 = gzero; av = avma;
                   1353:             for (j=0; j<=i; j++)
                   1354:               if (p2[j])
                   1355:                 p1 = gadd(p1, gmul((GEN)y[j],(GEN)x[i-j]));
                   1356:             z[i] = lpileupto(av,p1);
                   1357:           }
                   1358:           z -= 2; /* back to normalcy */
                   1359:           free(p2); return normalize(z);
                   1360:
                   1361:        case t_RFRAC: case t_RFRACN:
                   1362:          if (gcmp0(y)) return zeropol(vx);
                   1363:          if (gcmp0(x)) return zeroser(vx, valp(x)+gval(y,vx));
                   1364:          l=avma; p1=gmul((GEN)y[1],x); tetpil=avma;
                   1365:           return gerepile(l,tetpil,gdiv(p1,(GEN)y[2]));
                   1366:
                   1367:        default: err(typeer,"multiplication");
                   1368:       }
                   1369:
                   1370:     /* (tx,ty) == t_RFRAC <==> ty == t_RFRAC */
                   1371:     case t_RFRAC: return mulrfrac(x,y);
                   1372:     case t_RFRACN:
                   1373:       if (!is_rfrac_t(ty)) err(typeer,"multiplication");
                   1374:       av=avma; z=cgetg(3,ty);
                   1375:       z[1]=lmul((GEN)x[1],(GEN)y[1]);
                   1376:       z[2]=lmul((GEN)x[2],(GEN)y[2]); return z;
                   1377:   }
                   1378:   if (tx==ty)
                   1379:     switch(tx)
                   1380:     {
                   1381:       case t_QFI: return compimag(x,y);
                   1382:       case t_QFR: return compreal(x,y);
                   1383:     }
                   1384:   err(typeer,"multiplication");
                   1385:   return NULL; /* not reached */
                   1386: }
                   1387:
                   1388: /********************************************************************/
                   1389: /**                                                                **/
                   1390: /**                           DIVISION                             **/
                   1391: /**                                                                **/
                   1392: /********************************************************************/
                   1393:
                   1394: static
                   1395: GEN divrfracscal(GEN x, GEN y)
                   1396: {
                   1397:   long Y[3]; Y[1]=un; Y[2]=(long)y;
                   1398:   return mulrfrac(x,Y);
                   1399: }
                   1400:
                   1401: static
                   1402: GEN divscalrfrac(GEN x, GEN y)
                   1403: {
                   1404:   long Y[3]; Y[1]=y[2]; Y[2]=y[1];
                   1405:   return mulscalrfrac(x,Y);
                   1406: }
                   1407:
                   1408: static
                   1409: GEN divrfrac(GEN x, GEN y)
                   1410: {
                   1411:   long Y[3]; Y[1]=y[2]; Y[2]=y[1];
                   1412:   return mulrfrac(x,Y);
                   1413: }
                   1414:
                   1415: GEN
                   1416: gdiv(GEN x, GEN y)
                   1417: {
                   1418:   long tx = typ(x), ty = typ(y), lx,ly,vx,vy,i,j,k,l,av,tetpil;
                   1419:   GEN z,p1,p2,p3;
                   1420:
                   1421:   if (tx==t_INT && is_const_t(ty))
                   1422:   {
                   1423:     switch (signe(x))
                   1424:     {
                   1425:       case 0:
                   1426:         if (gcmp0(y)) err(gdiver2);
                   1427:         if (ty != t_INTMOD) return gzero;
                   1428:         z = cgetg(3,t_INTMOD); icopyifstack(y[1],z[1]); z[2]=zero;
                   1429:         return z;
                   1430:       case  1:
                   1431:         if (is_pm1(x)) return ginv(y);
                   1432:         break;
                   1433:       case -1:
                   1434:         if (is_pm1(x)) { av = avma; return gerepileupto(av, ginv(gneg(y))); }
                   1435:     }
                   1436:     switch(ty)
                   1437:     {
                   1438:       case t_INT:
                   1439:         av=avma; z=dvmdii(x,y,&p1);
                   1440:         if (p1==gzero) return z;
                   1441:         (void)new_chunk((lgefint(x) + lgefint(y)) << 2);
                   1442:         p1 = mppgcd(y,p1);
                   1443:         avma=av; z=cgetg(3,t_FRAC);
                   1444:         if (is_pm1(p1)) {
                   1445:           z[1]=licopy(x);
                   1446:           z[2]=licopy(y);
                   1447:         }
                   1448:         else {
                   1449:           z[1]=ldivii(x,p1);
                   1450:           z[2]=ldivii(y,p1);
                   1451:         }
                   1452:         fix_frac(z); return z;
                   1453:
                   1454:       case t_REAL:
                   1455:         return divir(x,y);
                   1456:
                   1457:       case t_INTMOD:
                   1458:         z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
                   1459:         (void)new_chunk(lgefint(p2)<<2);
                   1460:         p1=mulii(modii(x,p2), mpinvmod((GEN)y[2],p2)); avma=(long)z;
                   1461:         z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
                   1462:
                   1463:       case t_FRAC:
                   1464:         z=cgetg(3,t_FRAC);
                   1465:         p1 = mppgcd(x,(GEN)y[1]);
                   1466:         if (is_pm1(p1))
                   1467:         {
                   1468:           avma = (long)z; tetpil = 0;
                   1469:           z[2] = licopy((GEN)y[1]);
                   1470:         }
                   1471:         else
                   1472:         {
                   1473:           x = divii(x,p1); tetpil = avma;
                   1474:           z[2] = ldivii((GEN)y[1], p1);
                   1475:         }
                   1476:         z[1] = lmulii((GEN)y[2], x);
                   1477:         fix_frac(z);
                   1478:         if (tetpil)
                   1479:         { fix_frac_if_int_GC(z,tetpil); }
                   1480:         else
                   1481:           fix_frac_if_int(z);
                   1482:         return z;
                   1483:
                   1484:       case t_FRACN:
                   1485:         z=cgetg(3,t_FRACN);
                   1486:         z[1]=lmulii((GEN)y[2], x);
                   1487:         z[2]=licopy((GEN)y[1]);
                   1488:         fix_frac(z); return z;
                   1489:
                   1490:       case t_PADIC:
                   1491:         l=avma; p1=cgetp(y); gaffect(x,p1); tetpil=avma;
                   1492:         return gerepile(l,tetpil,gdiv(p1,y));
                   1493:
                   1494:       case t_COMPLEX: case t_QUAD:
                   1495:         l=avma; p1=gnorm(y); p2=gmul(x,gconj(y)); tetpil=avma;
                   1496:         return gerepile(l,tetpil,gdiv(p2,p1));
                   1497:     }
                   1498:   }
                   1499:   if (gcmp0(y)) err(gdiver2);
                   1500:
                   1501:   if (is_const_t(tx) && is_const_t(ty))
                   1502:   {
                   1503:     switch(tx)
                   1504:     {
                   1505:       case t_REAL:
                   1506:        switch(ty)
                   1507:        {
                   1508:          case t_INT:
                   1509:            return divri(x,y);
                   1510:
                   1511:          case t_REAL:
                   1512:            return divrr(x,y);
                   1513:
                   1514:          case t_FRAC: case t_FRACN:
                   1515:            l=avma; p1=cgetg(lg(x),t_REAL); gaffect(y,p1);
                   1516:            return gerepile(l,(long)p1,divrr(x,p1));
                   1517:
                   1518:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                   1519:             l=avma; p1=gnorm(y);
                   1520:            p2=gmul(x,(GEN)y[1]);
                   1521:             p3=gmul(x,(GEN)y[2]);
                   1522:            if (!gcmp0(p3)) p3 = gneg_i(p3);
                   1523:             tetpil=avma;
                   1524:            z[1]=ldiv(p2,p1);
                   1525:             z[2]=ldiv(p3,p1);
                   1526:            gerepilemanyvec(l,tetpil,z+1,2); return z;
                   1527:
                   1528:          case t_QUAD:
                   1529:            l=avma; p1=co8(y,lg(x)); tetpil=avma;
                   1530:            return gerepile(l,tetpil,gdiv(x,p1));
                   1531:
                   1532:          case t_INTMOD: case t_PADIC: err(gdiverf,tx,ty);
                   1533:        }
                   1534:
                   1535:       case t_INTMOD:
                   1536:        switch(ty)
                   1537:        {
                   1538:          case t_INT: z=cgetg(3,t_INTMOD); p2=(GEN)x[1];
                   1539:            (void)new_chunk(lgefint(p2)<<2);
                   1540:            p1=mulii((GEN)x[2], mpinvmod(y,p2)); avma=(long)z;
                   1541:             z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
                   1542:
                   1543:          case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)x[1]; p1=(GEN)y[1];
                   1544:            if (p1==p2 || egalii(p1,p2))
                   1545:             { icopyifstack(p2,z[1]); }
                   1546:             else
                   1547:             { p2 = mppgcd(p1,p2); z[1] = (long)p2; }
                   1548:             av=avma; (void)new_chunk(lgefint(x[1]) + (lgefint(p1) << 1));
                   1549:            p1=mulii((GEN)x[2], mpinvmod((GEN)y[2],p2)); avma=av;
                   1550:             z[2]=lmodii(p1,p2); return z;
                   1551:
                   1552:          case t_FRAC: z=cgetg(3,t_INTMOD); p2=(GEN)x[1];
                   1553:             (void)new_chunk(lgefint(p2)<<2);
                   1554:             p1=mulii((GEN)y[2], mpinvmod((GEN)y[1],p2));
                   1555:             p1=mulii(modii(p1,p2),(GEN)x[2]); avma=(long)z;
                   1556:             z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
                   1557:
                   1558:          case t_FRACN:
                   1559:            l=avma; p1=gred(y); tetpil=avma;
                   1560:            return gerepile(l,tetpil,gdiv(x,p1));
                   1561:
                   1562:          case t_COMPLEX: case t_QUAD:
                   1563:            l=avma; p1=gnorm(y); p2=gmul(x,gconj(y)); tetpil=avma;
                   1564:            return gerepile(l,tetpil,gdiv(p2,p1));
                   1565:
                   1566:          case t_PADIC:
                   1567:            l=avma; p1=cgetg(3,t_INTMOD); p1[1]=x[1]; p1[2]=lgeti(lg(x[1]));
                   1568:            gaffect(y,p1); tetpil=avma; return gerepile(l,tetpil,gdiv(x,p1));
                   1569:
                   1570:          case t_REAL: err(gdiverf,tx,ty);
                   1571:        }
                   1572:
                   1573:       case t_FRAC: case t_FRACN:
                   1574:        switch(ty)
                   1575:        {
                   1576:          case t_INT:
                   1577:           z = cgetg(3, tx);
                   1578:          if (tx == t_FRAC)
                   1579:           {
                   1580:             p1 = mppgcd(y,(GEN)x[1]);
                   1581:             if (is_pm1(p1))
                   1582:             {
                   1583:               avma = (long)z; tetpil = 0;
                   1584:               z[1] = licopy((GEN)x[1]);
                   1585:             }
                   1586:             else
                   1587:             {
                   1588:               y = divii(y,p1); tetpil = avma;
                   1589:               z[1] = ldivii((GEN)x[1], p1);
                   1590:             }
                   1591:           }
                   1592:           else
                   1593:           {
                   1594:             tetpil = 0;
                   1595:             z[1] = licopy((GEN)x[1]);
                   1596:           }
                   1597:           z[2] = lmulii((GEN)x[2],y);
                   1598:           fix_frac(z);
                   1599:           if (tetpil) fix_frac_if_int_GC(z,tetpil);
                   1600:           return z;
                   1601:
                   1602:          case t_REAL:
                   1603:            l=avma; p1=cgetg(lg(y),t_REAL); gaffect(x,p1);
                   1604:            p2=divrr(p1,y); return gerepile(l,(long)p1,p2);
                   1605:
                   1606:          case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
                   1607:             (void)new_chunk(lgefint(p2)<<2);
                   1608:            p1=mulii((GEN)y[2],(GEN)x[2]);
                   1609:            p1=mulii(mpinvmod(p1,p2), modii((GEN)x[1],p2)); avma=(long)z;
                   1610:            z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
                   1611:
                   1612:          case t_FRAC: if (tx == t_FRACN) ty=t_FRACN;
                   1613:           case t_FRACN:
                   1614:            z = cgetg(3,ty);
                   1615:             if (ty == t_FRAC)
                   1616:             {
                   1617:               GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
                   1618:               GEN y1 = (GEN)y[1], y2 = (GEN)y[2];
                   1619:               p1 = mppgcd(x1, y1);
                   1620:               if (!is_pm1(p1)) { x1 = divii(x1,p1); y1 = divii(y1,p1); }
                   1621:               p1 = mppgcd(x2, y2);
                   1622:               if (!is_pm1(p1)) { x2 = divii(x2,p1); y2 = divii(y2,p1); }
                   1623:               tetpil = avma;
                   1624:               z[2] = lmulii(x2,y1);
                   1625:               z[1] = lmulii(x1,y2);
                   1626:               fix_frac(z);
                   1627:               fix_frac_if_int_GC(z,tetpil);
                   1628:             }
                   1629:             else
                   1630:             {
                   1631:               z[1]=lmulii((GEN)x[1],(GEN)y[2]);
                   1632:               z[2]=lmulii((GEN)x[2],(GEN)y[1]);
                   1633:               fix_frac(z);
                   1634:             }
                   1635:             return z;
                   1636:
                   1637:          case t_COMPLEX: z=cgetg(3,t_COMPLEX);
                   1638:             l=avma; p1=gnorm(y);
                   1639:            p2=gmul(x,(GEN)y[1]);
                   1640:            p3=gmul(x,(GEN)y[2]);
                   1641:             if(!gcmp0(p3)) p3 = gneg_i(p3);
                   1642:            tetpil=avma;
                   1643:            z[1]=ldiv(p2,p1); z[2]=ldiv(p3,p1);
                   1644:            gerepilemanyvec(l,tetpil,z+1,2); return z;
                   1645:
                   1646:          case t_PADIC:
                   1647:            if (!signe(x[1])) return gzero;
                   1648:
                   1649:            l=avma; p1=cgetp(y); gaffect(x,p1);
                   1650:            tetpil=avma; return gerepile(l,tetpil,gdiv(p1,y));
                   1651:
                   1652:          case t_QUAD:
                   1653:            l=avma; p1=gnorm(y); p2=gmul(x,gconj(y)); tetpil=avma;
                   1654:            return gerepile(l,tetpil,gdiv(p2,p1));
                   1655:        }
                   1656:
                   1657:       case t_COMPLEX:
                   1658:        switch(ty)
                   1659:        {
                   1660:          case t_INT: case t_REAL: case t_INTMOD: case t_FRAC: case t_FRACN:
                   1661:            z=cgetg(3,t_COMPLEX);
                   1662:            z[1]=ldiv((GEN)x[1],y);
                   1663:            z[2]=ldiv((GEN)x[2],y); return z;
                   1664:
                   1665:          case t_COMPLEX:
                   1666:            l=avma; p1=gnorm(y); p2=gconj(y); p2=gmul(x,p2); tetpil=avma;
                   1667:            return gerepile(l,tetpil, gdiv(p2,p1));
                   1668:
                   1669:          case t_PADIC:
                   1670:            if (krosg(-1,(GEN)y[2])== -1)
                   1671:            {
                   1672:              z=cgetg(3,t_COMPLEX);
                   1673:              z[1]=ldiv((GEN)x[1],y);
                   1674:              z[2]=ldiv((GEN)x[2],y); return z;
                   1675:            }
                   1676:            av=avma; p1=cvtop(x,(GEN)y[2],precp(y)); tetpil=avma;
                   1677:            return gerepile(av,tetpil,gdiv(p1,y));
                   1678:
                   1679:          case t_QUAD:
                   1680:            lx=precision(x); if (!lx) err(gdiveri,tx,ty);
                   1681:            l=avma; p1=co8(y,lx); tetpil=avma;
                   1682:            return gerepile(l,tetpil,gdiv(x,p1));
                   1683:        }
                   1684:
                   1685:       case t_PADIC:
                   1686:        switch(ty)
                   1687:        {
                   1688:          case t_INT: case t_FRAC: case t_FRACN:
                   1689:            l=avma;
                   1690:            if (signe(x[4])) { p1=cgetp(x); gaffect(y,p1); }
                   1691:            else p1=cvtop(y,(GEN)x[2],(valp(x)>0)?valp(x):1);
                   1692:            tetpil=avma; return gerepile(l,tetpil,gdiv(x,p1));
                   1693:
                   1694:          case t_INTMOD:
                   1695:            l=avma; p1=cgetg(3,t_INTMOD);
                   1696:            p1[1]=y[1]; p1[2]=lgeti(lg(y[1]));
                   1697:            gaffect(x,p1); tetpil=avma;
                   1698:            return gerepile(l,tetpil,gdiv(p1,y));
                   1699:
                   1700:          case t_PADIC:
                   1701:            if (!egalii((GEN)x[2],(GEN)y[2])) err(gdiveri,tx,ty);
                   1702:            if (!signe(x[4]))
                   1703:            {
                   1704:              z=gcopy(x); setvalp(z,valp(x)-valp(y));
                   1705:              return z;
                   1706:            }
                   1707:
                   1708:            p1=(precp(x)>precp(y)) ? y : x;
                   1709:            z=cgetp(p1); l=avma;
                   1710:            setvalp(z,valp(x)-valp(y));
                   1711:            p2=mpinvmod((GEN)y[4],(GEN)p1[3]);
                   1712:            modiiz(mulii((GEN)x[4],p2),(GEN)p1[3],(GEN)z[4]);
                   1713:            avma=l; return z;
                   1714:
                   1715:          case t_COMPLEX: case t_QUAD:
                   1716:            l=avma; p1=gmul(x,gconj(y)); p2=gnorm(y); tetpil=avma;
                   1717:            return gerepile(l,tetpil,gdiv(p1,p2));
                   1718:
                   1719:          case t_REAL:
                   1720:            err(talker,"forbidden division p-adic/R");
                   1721:        }
                   1722:
                   1723:       case t_QUAD:
                   1724:        switch (ty)
                   1725:        {
                   1726:          case t_INT: case t_INTMOD: case t_FRAC: case t_FRACN:
                   1727:            z=cgetg(4,t_QUAD);
                   1728:            copyifstack(x[1], z[1]);
                   1729:            for (i=2; i<4; i++) z[i]=ldiv((GEN)x[i],y);
                   1730:            return z;
                   1731:
                   1732:          case t_REAL:
                   1733:            l=avma; p1=co8(x,lg(y)); tetpil=avma;
                   1734:            return gerepile(l,tetpil,gdiv(p1,y));
                   1735:
                   1736:          case t_PADIC:
                   1737:            l=avma; p1=cvtop(x,(GEN)y[2],precp(y));
                   1738:            tetpil=avma; return gerepile(l,tetpil,gdiv(p1,y));
                   1739:
                   1740:          case t_COMPLEX:
                   1741:            ly=precision(y); if (!ly) err(gdiveri,tx,ty);
                   1742:            l=avma; p1=co8(x,ly); tetpil=avma;
                   1743:            return gerepile(l,tetpil,gdiv(p1,y));
                   1744:
                   1745:          case t_QUAD:
                   1746:            k=x[1]; l=y[1];
                   1747:            if (!gegal((GEN)k,(GEN)l)) err(gdiveri,tx,ty);
                   1748:            l=avma; p1=gnorm(y); p2=gmul(x,gconj(y)); tetpil=avma;
                   1749:            return gerepile(l,tetpil,gdiv(p2,p1));
                   1750:        }
                   1751:     }
                   1752:     err(bugparier,"division");
                   1753:   }
                   1754:
                   1755:   vx=gvar(x); vy=gvar(y);
                   1756:   if (ty==t_POLMOD && (tx==t_POLMOD || vy<vx))
                   1757:   {
                   1758:     z=cgetg(3,t_POLMOD);
                   1759:     if (tx==t_POLMOD)
                   1760:     {
                   1761:       k=x[1]; l=y[1];
                   1762:       if (gegal((GEN)k,(GEN)l))
                   1763:       {
                   1764:         copyifstack(k, z[1]); av=avma;
                   1765:         p1 = ginvmod((GEN)y[2],(GEN)z[1]);
                   1766:         p2 = gmul((GEN)x[2],p1);
                   1767:       }
                   1768:       else
                   1769:       {
                   1770:         vx=varn(x[1]); vy=varn(y[1]);
                   1771:         if (vx==vy)
                   1772:         {
                   1773:           z[1]=lgcd((GEN)k,(GEN)l); av=avma;
                   1774:           p1=ginvmod((GEN)y[2],(GEN)z[1]);
                   1775:           p2=gmul((GEN)x[2],p1);
                   1776:         }
                   1777:         else
                   1778:         {
                   1779:           if (vx<vy)
                   1780:           { copyifstack(k,z[1]); av=avma; p2=gdiv((GEN)x[2],y); }
                   1781:           else
                   1782:           {
                   1783:             copyifstack(l,z[1]); av=avma;
                   1784:             p1 = ginvmod((GEN)y[2],(GEN)z[1]);
                   1785:             p2 = gmul(x, p1);
                   1786:           }
                   1787:         }
                   1788:       }
                   1789:       p2 = gmod(p2,(GEN)z[1]);
                   1790:     }
                   1791:     else
                   1792:     {
                   1793:       copyifstack(y[1],z[1]); av=avma;
                   1794:       p1 = ginvmod((GEN)y[2],(GEN)y[1]);
                   1795:       p2 = gmul(x,p1);
                   1796:     }
                   1797:     z[2]=lpileupto(av, p2); return z;
                   1798:   }
                   1799:   if (tx == t_POLMOD && vx<vy)
                   1800:   {
                   1801:     z=cgetg(3,t_POLMOD);
                   1802:     copyifstack(x[1],z[1]);
                   1803:     z[2]=ldiv((GEN)x[2],y); return z;
                   1804:   }
                   1805:   if (vx == vy)
                   1806:   {
                   1807:     av = avma;
                   1808:     if (tx == t_POLMOD)
                   1809:       return gerepileupto(av, gdiv(x, to_polmod(y,(GEN)x[1])));
                   1810:     if (ty == t_POLMOD)
                   1811:       return gerepileupto(av, gdiv(to_polmod(x,(GEN)y[1]), y));
                   1812:   }
                   1813:   /* now x and y are not both is_scalar_t */
                   1814:
                   1815:   lx = lg(x);
                   1816:   if ((vx<vy && (!is_matvec_t(tx) || !is_matvec_t(ty)))
                   1817:      || (vx==vy && is_scalar_t(ty)) || (is_matvec_t(tx) && !is_matvec_t(ty)))
                   1818:   {
                   1819:     if (tx == t_RFRAC) return divrfracscal(x,y);
                   1820:     z = cgetg(lx,tx);
                   1821:     if (tx == t_RFRACN)
                   1822:     {
                   1823:       z[2]=lmul((GEN)x[2],y);
                   1824:       z[1]=lcopy((GEN)x[1]); return z;
                   1825:     }
                   1826:     switch(tx)
                   1827:     {
                   1828:       case t_POL: lx = lgef(x);
                   1829:       case t_SER: z[1] = x[1];
                   1830:       case t_VEC: case t_COL: case t_MAT:
                   1831:         if (ty == t_POLMOD || ty == t_INTMOD)
                   1832:         {
                   1833:           if (!gcmp1(y)) y = ginv(y); /* garbage, left alone */
                   1834:           for (i=lontyp[tx]; i<lx; i++) z[i]=lmul((GEN)x[i],y);
                   1835:           return z;
                   1836:         }
                   1837:         else
                   1838:           for (i=lontyp[tx]; i<lx; i++) z[i]=ldiv((GEN)x[i],y);
                   1839:         return z;
                   1840:     }
                   1841:     err(typeer,"division");
                   1842:   }
                   1843:
                   1844:   ly=lg(y);
                   1845:   if (vy<vx || (vy==vx && is_scalar_t(tx)))
                   1846:   {
                   1847:     switch(ty)
                   1848:     {
                   1849:       case t_POL:
                   1850:        if (lgef(y)==3) return gdiv(x,(GEN)y[2]);
                   1851:         if (isexactzero(x)) return zeropol(vy);
                   1852:         av=avma; z=cgetg(3,t_RFRAC); z[1]=(long)x; z[2]=(long)y;
                   1853:         return gerepileupto(av,gred_rfrac(z));
                   1854:
                   1855:       case t_SER:
                   1856:        if (gcmp0(x))
                   1857:        {
                   1858:           l=avma; p1=ginv(y); tetpil=avma; /* a ameliorer !!!! */
                   1859:          return gerepile(l,tetpil,gmul(x,p1));
                   1860:        }
                   1861:         p1 = (GEN)gpmalloc(ly*sizeof(long));
                   1862:         p1[0] = evaltyp(t_SER) | evallg(ly);
                   1863:        p1[1] = evalsigne(1) | evalvalp(0) | evalvarn(vy);
                   1864:         p1[2] = (long)x; for (i=3; i<ly; i++) p1[i]=zero;
                   1865:         y = gdiv(p1,y); free(p1); return y;
                   1866:
                   1867:       case t_RFRAC: return divscalrfrac(x,y);
                   1868:       case t_RFRACN: z=cgetg(ly,t_RFRACN);
                   1869:         z[1]=lmul(x,(GEN)y[2]);
                   1870:         z[2]=lcopy((GEN)y[1]); return z;
                   1871:
                   1872:       case t_MAT:
                   1873:        if (ly==1 || lg(y[1])!=ly) err(gdiveri,tx,ty);
                   1874:        l=avma; p1=invmat(y); tetpil=avma;
                   1875:        return gerepile(l,tetpil,gmul(x,p1));
                   1876:
                   1877:       case t_VEC: case t_COL: err(gdiverf,tx,ty);
                   1878:     }
                   1879:     err(typeer,"division");
                   1880:   }
                   1881:
                   1882:   /* ici vx=vy et tx>=10 et ty>=10*/
                   1883:   switch(tx)
                   1884:   {
                   1885:     case t_POL:
                   1886:       switch(ty)
                   1887:       {
                   1888:        case t_POL:
                   1889:           if (lgef(y)==3) return gdiv(x,(GEN)y[2]);
                   1890:           if (isexactzero(x)) return zeropol(vy);
                   1891:           av=avma; z=cgetg(3,t_RFRAC); z[1]=(long)x; z[2]=(long)y;
                   1892:           return gerepileupto(av,gred_rfrac(z));
                   1893:
                   1894:        case t_SER:
                   1895:          if (gcmp0(x)) return zeropol(vx);
                   1896:          p1=greffe(x,ly,0); p2=gdiv(p1,y);
                   1897:           free(p1); return p2;
                   1898:
                   1899:         case t_RFRAC: return divscalrfrac(x,y);
                   1900:         case t_RFRACN: z=cgetg(ly,t_RFRACN);
                   1901:          z[1]=lmul(x,(GEN)y[2]);
                   1902:          z[2]=lcopy((GEN)y[1]); return z;
                   1903:
                   1904:        case t_VEC: case t_COL: case t_MAT: err(gdiverf,tx,ty);
                   1905:        default: err(typeer,"division");
                   1906:       }
                   1907:
                   1908:     case t_SER:
                   1909:       switch(ty)
                   1910:       {
                   1911:        case t_POL:
                   1912:          p1=greffe(y,lx,0); p2=gdiv(x,p1);
                   1913:           free(p1); return p2;
                   1914:
                   1915:        case t_SER:
                   1916:         {
                   1917:           GEN y_lead;
                   1918:
                   1919:           l = valp(x) - valp(y);
                   1920:          if (gcmp0(x)) return zeroser(vx,l);
                   1921:           y_lead = (GEN)y[2];
                   1922:           if (gcmp0(y_lead)) /* normalize denominator if leading term is 0 */
                   1923:           {
                   1924:             err(warner,"normalizing a series with 0 leading term");
                   1925:             for (i=3,y++; i<ly; i++,y++)
                   1926:             {
                   1927:               y_lead = (GEN)y[2]; ly--; l--;
                   1928:               if (!gcmp0(y_lead)) break;
                   1929:             }
                   1930:             if (i==ly) err(gdiver2);
                   1931:           }
                   1932:          if (ly < lx) lx = ly;
                   1933:          p2 = (GEN)gpmalloc(lx*sizeof(long));
                   1934:          for (i=3; i<lx; i++)
                   1935:           {
                   1936:             p1 = (GEN)y[i];
                   1937:             if (isexactzero(p1)) p2[i] = 0;
                   1938:             else
                   1939:             {
                   1940:               av = avma; p2[i] = lclone(gneg_i(p1));
                   1941:               avma = av;
                   1942:             }
                   1943:           }
                   1944:          z = cgetg(lx,t_SER);
                   1945:           z[1] = evalvalp(l) | evalvarn(vx) | evalsigne(1);
                   1946:          z[2] = ldiv((GEN)x[2], y_lead);
                   1947:          for (i=3; i<lx; i++)
                   1948:          {
                   1949:            av=avma; p1 = (GEN)x[i];
                   1950:            for (j=2; j<i; j++)
                   1951:             {
                   1952:               l = i-j+2;
                   1953:               if (p2[l])
                   1954:                 p1 = gadd(p1, gmul((GEN)z[j], (GEN)p2[l]));
                   1955:             }
                   1956:            tetpil=avma; z[i]=lpile(av,tetpil, gdiv(p1,y_lead));
                   1957:          }
                   1958:           for (i=3; i<lx; i++)
                   1959:             if (p2[i]) gunclone((GEN)p2[i]);
                   1960:           free(p2); return z;
                   1961:         }
                   1962:
                   1963:        case t_RFRAC: case t_RFRACN:
                   1964:          l=avma; p2=gmul(x,(GEN)y[2]); tetpil=avma;
                   1965:          return gerepile(l,tetpil,gdiv(p2,(GEN)y[1]));
                   1966:
                   1967:        case t_VEC: case t_COL: case t_MAT: err(gdiverf,tx,ty);
                   1968:        default: err(typeer,"division");
                   1969:       }
                   1970:
                   1971:     case t_RFRAC: case t_RFRACN:
                   1972:       switch(ty)
                   1973:       {
                   1974:        case t_POL:
                   1975:           if (tx==t_RFRAC) return  divrfracscal(x,y);
                   1976:           z=cgetg(3,t_RFRACN);
                   1977:           z[2]=lmul((GEN)x[2],y);
                   1978:          z[1]=lcopy((GEN)x[1]); return z;
                   1979:
                   1980:        case t_SER:
                   1981:          l=avma; p2=gmul((GEN)x[2],y); tetpil=avma;
                   1982:          return gerepile(l,tetpil, gdiv((GEN)x[1],p2));
                   1983:
                   1984:        case t_RFRAC: case t_RFRACN:
                   1985:          if (tx == t_RFRACN) ty=t_RFRACN;
                   1986:           if (ty != t_RFRACN) return divrfrac(x,y);
                   1987:          z=cgetg(3,t_RFRACN);
                   1988:          z[1]=lmul((GEN)x[1],(GEN)y[2]);
                   1989:           z[2]=lmul((GEN)x[2],(GEN)y[1]); return z;
                   1990:
                   1991:        case t_VEC: case t_COL: case t_MAT: err(gdiverf,tx,ty);
                   1992:        default: err(typeer,"division");
                   1993:       }
                   1994:
                   1995:     case t_VEC: case t_COL: case t_MAT:
                   1996:       if (!is_matvec_t(ty))
                   1997:       {
                   1998:        z=cgetg(lx,tx);
                   1999:        for (i=1; i<lx; i++) z[i]=ldiv((GEN)x[i],y);
                   2000:        return z;
                   2001:       }
                   2002:       if (ty!=t_MAT || ly==1 || lg(y[1])!=ly) err(gdiveri,tx,ty);
                   2003:       l=avma; p1=invmat(y); tetpil=avma;
                   2004:       return gerepile(l,tetpil,gmul(x,p1));
                   2005:   }
                   2006:   if (tx==ty)
                   2007:   {
                   2008:     l=signe(y[2]); setsigne(y[2],-l);
                   2009:     switch(tx)
                   2010:     {
                   2011:       case t_QFI: z = compimag(x,y);
                   2012:         setsigne(y[2],l); return z;
                   2013:       case t_QFR:
                   2014:         k=signe(y[4]); setsigne(y[4],-k); z=compreal(x,y);
                   2015:         setsigne(y[2],l); setsigne(y[4],k); return z;
                   2016:     }
                   2017:   }
                   2018:   err(typeer,"division");
                   2019:   return NULL; /* not reached */
                   2020: }

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