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

Annotation of OpenXM_contrib/pari-2.2/src/basemath/gen1.c, Revision 1.1

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

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