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

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

1.1       maekawa     1: /***********************************************************************/
                      2: /**                                                                   **/
                      3: /**               ARITHMETIC OPERATIONS ON POLYNOMIALS                **/
                      4: /**                         (second part)                             **/
                      5: /**                                                                   **/
                      6: /***********************************************************************/
                      7: /* $Id: polarit2.c,v 1.2 1999/09/20 13:30:05 karim Exp $ */
                      8: #include "pari.h"
                      9:
                     10: GEN
                     11: polsym(GEN x, long n)
                     12: {
                     13:   long av1,av2,dx=lgef(x)-3,i,k;
                     14:   GEN s,y,x_lead;
                     15:
                     16:   if (n<0) err(impl,"polsym of a negative n");
                     17:   if (typ(x) != t_POL) err(typeer,"polsym");
                     18:   if (!signe(x)) err(zeropoler,"polsym");
                     19:   y=cgetg(n+2,t_COL); y[1]=lstoi(dx);
                     20:   x_lead=(GEN)x[dx+2]; if (gcmp1(x_lead)) x_lead=NULL;
                     21:   for (k=1; k<=n; k++)
                     22:   {
                     23:     av1=avma; s = (dx>=k)? gmulsg(k,(GEN)x[dx+2-k]): gzero;
                     24:     for (i=1; i<k && i<=dx; i++)
                     25:       s = gadd(s,gmul((GEN)y[k-i+1],(GEN)x[dx+2-i]));
                     26:     if (x_lead) s = gdiv(s,x_lead);
                     27:     av2=avma; y[k+1]=lpile(av1,av2,gneg(s));
                     28:   }
                     29:   return y;
                     30: }
                     31:
                     32: static int (*polcmp_coeff_cmp)(GEN,GEN);
                     33:
                     34: /* assume x and y are polynomials in the same variable whose coeffs can be
                     35:  * compared (used to sort polynomial factorizations)
                     36:  */
                     37: static int
                     38: polcmp(GEN x, GEN y)
                     39: {
                     40:   long i, lx = lgef(x), ly = lgef(y);
                     41:   int fl;
                     42: #if 0 /* for efficiency */
                     43:   if (typ(x) != t_POL || typ(y) != t_POL)
                     44:     err(talker,"not a polynomial in polcmp");
                     45: #endif
                     46:   if (lx > ly) return  1;
                     47:   if (lx < ly) return -1;
                     48:   for (i=lx-1; i>1; i--)
                     49:     if ((fl = polcmp_coeff_cmp((GEN)x[i], (GEN)y[i]))) return fl;
                     50:   return 0;
                     51: }
                     52:
                     53: /* sort factorization so that factors appear by decreasing degree, in place */
                     54: GEN
                     55: sort_factor(GEN y, int (*cmp)(GEN,GEN))
                     56: {
                     57:   GEN w,c1,c2, p1 = (GEN)y[1], p2 = (GEN)y[2];
                     58:   long av=avma, n=lg(p1), i;
                     59:   int (*old)(GEN,GEN) = polcmp_coeff_cmp;
                     60:
                     61:   c1 = new_chunk(n); c2 = new_chunk(n);
                     62:   polcmp_coeff_cmp = cmp;
                     63:   w = gen_sort(p1, cmp_IND | cmp_C, polcmp);
                     64:   for (i=1; i<n; i++) { c1[i]=p1[w[i]]; c2[i]=p2[w[i]]; }
                     65:   for (i=1; i<n; i++) { p1[i]=c1[i]; p2[i]=c2[i]; }
                     66:   polcmp_coeff_cmp = old; avma = av; return y;
                     67: }
                     68:
                     69: /* for internal use */
                     70: GEN
                     71: centermod(GEN x, GEN p)
                     72: {
                     73:   long av,i,lx;
                     74:   GEN y,p1,ps2;
                     75:
                     76:   ps2=shifti(p,-1);
                     77:   switch(typ(x))
                     78:   {
                     79:     case t_INT:
                     80:       y=modii(x,p);
                     81:       if (cmpii(y,ps2)>0) return subii(y,p);
                     82:       return y;
                     83:
                     84:     case t_POL: lx=lgef(x);
                     85:       y=cgetg(lx,t_POL); y[1]=x[1];
                     86:       for (i=2; i<lx; i++)
                     87:       {
                     88:        av=avma; p1=modii((GEN)x[i],p);
                     89:        if (cmpii(p1,ps2)>0) p1=subii(p1,p);
                     90:        y[i]=lpileupto(av,p1);
                     91:       }
                     92:       return y;
                     93:
                     94:     case t_COL: lx=lg(x);
                     95:       y=cgetg(lx,t_COL);
                     96:       for (i=1; i<lx; i++)
                     97:       {
                     98:        p1=modii((GEN)x[i],p);
                     99:        if (cmpii(p1,ps2)>0) p1=subii(p1,p);
                    100:        y[i]=(long)p1;
                    101:       }
                    102:       return y;
                    103:   }
                    104:   return x;
                    105: }
                    106:
                    107: static GEN
                    108: decpol(GEN x, long klim)
                    109: {
                    110:   short int pos[200];
                    111:   long av=avma,av1,tete,k,kin,i,j,i1,i2,fl,d,nbfact;
                    112:   GEN res,p1,p2;
                    113:
                    114:   kin=1; res=cgetg(lgef(x)-2,t_VEC); nbfact=0;
                    115:   p1=roots(x,DEFAULTPREC); d=lg(p1)-1; if (!klim) klim=d;
                    116:   do
                    117:   {
                    118:     fl=1;
                    119:     for (k=kin; k+k <= d && k<=klim; k++)
                    120:     {
                    121:       for (i=0; i<=k; i++) pos[i]=i;
                    122:       do
                    123:       {
                    124:        av1=avma; p2=gzero; j=0;
                    125:        for (i1=1; i1<=k; i1++) p2=gadd(p2,(GEN)p1[pos[i1]]);
                    126:        if (gexpo(gimag(p2))<-20 && gexpo(gsub(p2,ground(p2)))<-20)
                    127:        {
                    128:          p2=gun;
                    129:          for (i1=1; i1<=k; i1++)
                    130:            p2=gmul(p2,gsub(polx[0],(GEN)p1[pos[i1]]));
                    131:           p2 = ground(p2);
                    132:          if (gcmp0(gimag(p2)) && gcmp0(gmod(x,p2)))
                    133:          {
                    134:            res[++nbfact]=(long)p2; x=gdiv(x,p2);
                    135:             kin=k; p2=cgetg(d-k+1,t_COL);
                    136:             for (i=i1=i2=1; i<=d; i++)
                    137:            {
                    138:              if (i1<=k && i==pos[i1]) i1++;
                    139:              else p2[i2++]=p1[i];
                    140:            }
                    141:            p1=p2; d-=k; fl=0; break;
                    142:          }
                    143:        }
                    144:        avma=av1; pos[k]++;
                    145:        while (pos[k-j] > d-j) { j++; pos[k-j]++; }
                    146:        for (i=k-j+1; i<=k; i++) pos[i]=i+pos[k-j]-k+j;
                    147:       }
                    148:       while (j<k);
                    149:       if (!fl) break;
                    150:     }
                    151:     if (lgef(x)<=3) break;
                    152:   }
                    153:   while (!fl || (k+k <= d && k<=klim));
                    154:   if (lgef(x)>3) res[++nbfact]=(long)x;
                    155:   setlg(res,nbfact+1); tete=avma;
                    156:   return gerepile(av,tete,greal(res));
                    157: }
                    158:
                    159: /* This code originally by Richard Schroeppel */
                    160:
                    161: /* Note that PARI's idea of the maximum possible coefficient involves the
                    162:  * limit on the degree (klim).  Consider revising this.  If I don't respect
                    163:  * the degree limit when testing potential factors, there's the possibility
                    164:  * that I might identify a high degree factor that isn't irreducible, because
                    165:  * it's lower degree divisors were missed because they had a coefficient
                    166:  * outside the Borne limit for klim, but the higher degree factor had it's
                    167:  * coefficients within Borne.  This would still have the property that any
                    168:  * factors of degree <= klim were guaranteed irr, but higher degrees
                    169:  * (> 2*klim) might not be irr.
                    170:  *
                    171:  * The subroutine:
                    172:  *  fxn points at the first unconsidered factor for the current combination
                    173:  *  psf is the product-so-far, or 0 for a null product
                    174:  *  dlim is the degree limit remaining for unconsidered divisors
                    175:  *  other arguments are "global" and must already be setup
                    176:  *  as factors are found, they are put in cmbf_fax; the count is kept in
                    177:  *  cmbf_faxn; and they are divided out of cmbf_target; the degree and
                    178:  *  leading coefficient are updated; and the constituent modular factors
                    179:  *  are deleted from cmbf_modfax.
                    180:  *  exit value is 1 if any factors are found.
                    181:  *  If psf is 0, all factors made up from pieces at or after fxn will be
                    182:  *  found & removed.  If psf is not 0, only the factor which is a
                    183:  *  continuation of psf will be found.
                    184:  */
                    185: /* setup for calling cmbf = combine_factors */
                    186: static GEN cmbf_target;      /* target poly. Assume content removed */
                    187: static GEN cmbf_lc;          /* leading coefficient */
                    188: static GEN cmbf_abslc;       /* |lc| */
                    189: static GEN cmbf_abslcxtarget;/* abslc * target */
                    190: static GEN cmbf_mod;         /* modulus */
                    191: static GEN cmbf_fax;         /* result array + one cell for leftover cst. */
                    192: static GEN cmbf_modfax; /* array of modular factors.  Each has LC 1.1 based
                    193:                            indexing. Product should be congruent to a/lc(a). */
                    194: static long cmbf_degree;     /* degree(target) */
                    195: static long cmbf_modfaxn;    /* number of modular factors */
                    196: static long cmbf_faxn;       /* last used cell in fax. # of factors found */
                    197: static GEN cmbf_modhalf;
                    198:
                    199: /* assume same variables, y normalized, non constant */
                    200: static GEN
                    201: polidivis(GEN x, GEN y, GEN bound)
                    202: {
                    203:   long dx,dy,dz,i,j,av, vx = varn(x);
                    204:   GEN z,p1,y_lead;
                    205:
                    206:   dy=lgef(y)-3;
                    207:   dx=lgef(x)-3;
                    208:   dz=dx-dy; if (dz<0) return NULL;
                    209:   z=cgetg(dz+3,t_POL);
                    210:   x += 2; y += 2; z += 2;
                    211:   y_lead = (GEN)y[dy];
                    212:   if (gcmp1(y_lead)) y_lead = NULL;
                    213:
                    214:   p1 = (GEN)x[dx];
                    215:   z[dz]=y_lead? ldivii(p1,y_lead): licopy(p1);
                    216:   for (i=dx-1; i>=dy; i--)
                    217:   {
                    218:     av=avma; p1=(GEN)x[i];
                    219:     for (j=i-dy+1; j<=i && j<=dz; j++)
                    220:       p1 = subii(p1, mulii((GEN)z[j],(GEN)y[i-j]));
                    221:     if (y_lead) { p1 = gdiv(p1,y_lead); if (typ(p1)!=t_INT) return NULL; }
                    222:     if (absi_cmp(p1, bound) > 0) return NULL;
                    223:     p1 = gerepileupto(av,p1);
                    224:     z[i-dy] = (long)p1;
                    225:   }
                    226:   av = avma;
                    227:   for (;; i--)
                    228:   {
                    229:     p1 = (GEN)x[i];
                    230:     /* we always enter this loop at least once */
                    231:     for (j=0; j<=i && j<=dz; j++)
                    232:       p1 = subii(p1, mulii((GEN)z[j],(GEN)y[i-j]));
                    233:     if (!gcmp0(p1)) return NULL;
                    234:     avma = av;
                    235:     if (!i) break;
                    236:   }
                    237:   z -= 2;
                    238:   z[1]=evalsigne(1) | evallgef(dz+3) | evalvarn(vx);
                    239:   return z;
                    240: }
                    241:
                    242: static int
                    243: try_div(GEN x, GEN y, GEN *q)
                    244: {
                    245:   if (resii((GEN)x[2], (GEN)y[2]) != gzero)
                    246:   {
                    247:     if (DEBUGLEVEL>6) fprintferr(".");
                    248:     return 0;
                    249:   }
                    250:   *q = polidivis(x,y,cmbf_modhalf);
                    251:   if (*q) return 1;
                    252:   if (DEBUGLEVEL>6) fprintferr("*");
                    253:   return 0;
                    254: }
                    255:
                    256: static int
                    257: cmbf(long fxn, GEN psf, long dlim, long hint)
                    258: {
                    259:   long newd,av,val2,val=0; /* assume failure */
                    260:   GEN newf,newpsf,quo,cont;
                    261:
                    262:   if (dlim <= 0 || fxn > cmbf_modfaxn) return 0;
                    263:
                    264:   /* first, try deeper factors without considering the current one */
                    265:   if (fxn < cmbf_modfaxn)
                    266:   {
                    267:     val = cmbf(fxn+1,psf,dlim,hint);
                    268:     if (val && psf) return val;
                    269:   }
                    270:
                    271:   /* second, try including the current modular factor in the product */
                    272:   newf = (GEN)cmbf_modfax[fxn];
                    273:   if (!newf) return val; /* modular factor already used */
                    274:
                    275:   newd = lgef(newf)-3; if (newd > dlim) return val;
                    276:   av = avma;
                    277:   if (!(newd%hint))
                    278:   {
                    279:     if (!psf) psf = cmbf_abslc;
                    280:     newpsf = centermod(gmul(psf,newf),cmbf_mod);
                    281:
                    282:     /* try out the new combination */
                    283:     if (try_div(cmbf_abslcxtarget, newpsf, &quo))
                    284:     {
                    285:       /* found a factor */
                    286:       cont = content(newpsf);
                    287:       if (signe(leading_term(newpsf)) < 0) cont = negi(cont);
                    288:       newpsf = gdiv(newpsf,cont);
                    289:       cmbf_fax[++cmbf_faxn] = (long)newpsf; /* store factor */
                    290:       cmbf_modfax[fxn] = 0; /* remove used modular factor */
                    291:       if (DEBUGLEVEL > 2)
                    292:       { fprintferr("\n"); msgtimer("to find factor %Z",newpsf); }
                    293:       /* fix up target */
                    294:       cmbf_target = gdiv(quo,leading_term(newpsf));
                    295:       cmbf_degree = lgef(cmbf_target)-3;
                    296:       cmbf_lc = (GEN)cmbf_target[cmbf_degree+2];
                    297:       cmbf_abslc = absi(cmbf_lc);
                    298:       cmbf_abslcxtarget = gmul(cmbf_abslc,cmbf_target);
                    299:       return 1;
                    300:     }
                    301:   }
                    302:   /* degree too large, or no more modular factors? */
                    303:   if (newd == dlim || fxn == cmbf_modfaxn) return val;
                    304:   /* include more factors */
                    305:   val2 = cmbf(fxn+1,newpsf,dlim-newd,hint);
                    306:   if (val2) cmbf_modfax[fxn] = 0; /* remove used modular factor */
                    307:   else avma = av;
                    308:   return val || val2;
                    309: }
                    310:
                    311: static long
                    312: min_deg(long jmax,ulong tabbit[])
                    313: {
                    314:   long j,k=1,j1=2;
                    315:
                    316:   for (j=jmax; j>=0; j--)
                    317:   {
                    318:     for (  ; k<=15; k++)
                    319:     {
                    320:       if (tabbit[j]&j1) return ((jmax-j)<<4)+k;
                    321:       j1<<=1;
                    322:     }
                    323:     k=0; j1=1;
                    324:   }
                    325:   return (jmax<<4)+15;
                    326: }
                    327:
                    328: static void
                    329: dotab(long d,long jmax,ulong *tabkbit,ulong *tmp)
                    330: {
                    331:   ulong rem,pro;
                    332:   long j,d1,d2;
                    333:
                    334:   d1=d>>4; d2=d&15; rem=0;
                    335:   for (j=jmax-d1; j>=0; j--)
                    336:   {
                    337:     pro = tabkbit[j+d1]<<d2;
                    338:     tmp[j] = (pro&0xffff)+rem; rem=pro>>16;
                    339:   }
                    340:   for (j=jmax-d1; j>=0; j--) tabkbit[j] |= tmp[j];
                    341: }
                    342:
                    343: /* lift factorisation mod p to mod p^e = pev */
                    344: GEN
                    345: hensel_lift_fact(GEN pol, GEN fact, GEN p, GEN pev, long e)
                    346: {
                    347:   long ev,i, nf = lg(fact);
                    348:   GEN aprov = pol, res = cgetg(nf, t_VEC);
                    349:
                    350:   for (i=nf-1; i; i--)
                    351:   {
                    352:     GEN ae,be,u,v,ae2,be2,s,t,pe,pe2,z,g;
                    353:     long ltop = avma;
                    354:
                    355:     ae = (GEN)fact[i]; /* lead coeff(ae) = 1 */
                    356:     be = Fp_poldivres(aprov,ae,p, NULL);
                    357:     g = (GEN)Fp_pol_extgcd(ae,be,p,&u,&v)[2]; /* deg g = 0 */
                    358:     if (!gcmp1(g))
                    359:     {
                    360:       g = mpinvmod(g, p);
                    361:       u = gmul(u, g);
                    362:       v = gmul(v, g);
                    363:     }
                    364:     for(pe=p,ev=1;;)
                    365:     {
                    366:       ev<<=1; pe2=(ev>=e)? pev: sqri(pe);
                    367:       g = gadd(aprov, gneg_i(gmul(ae,be)));
                    368:
                    369:       g = Fp_pol_red(g, pe2); g = gdivexact(g, pe);
                    370:       z = Fp_pol_red(gmul(v,g), pe);
                    371:       t = Fp_poldivres(z,ae,pe, &s);
                    372:       t = gadd(gmul(u,g), gmul(t,be));
                    373:       t = Fp_pol_red(t, pe);
                    374:       be2 = gadd(be, gmul(t,pe));
                    375:       ae2 = gadd(ae, gmul(s,pe)); /* already reduced mod pe2 */
                    376:       if (ev>=e) break;
                    377:
                    378:       g = gadd(gun, gneg_i(gadd(gmul(u,ae2),gmul(v,be2))));
                    379:
                    380:       g = Fp_pol_red(g, pe2); g = gdivexact(g, pe);
                    381:       z = Fp_pol_red(gmul(v,g), pe);
                    382:       t = Fp_poldivres(z,ae,pe, &s);
                    383:       t = gadd(gmul(u,g), gmul(t,be));
                    384:       t = Fp_pol_red(t, pe);
                    385:       u = gadd(u, gmul(t,pe));
                    386:       v = gadd(v, gmul(s,pe));
                    387:       pe=pe2; ae=ae2; be=be2;
                    388:     }
                    389:     ae = gerepileupto(ltop, ae2);
                    390:     aprov = Fp_poldivres(aprov,ae,pev, NULL);
                    391:     ltop = avma;
                    392:     res[i] = (long)ae;
                    393:     if (DEBUGLEVEL > 4)
                    394:       fprintferr("...lifting factor of degree %3ld. Time = %ld\n",
                    395:                  lgef(ae)-3,timer2());
                    396:   }
                    397:   return res;
                    398: }
                    399:
                    400: long split_berlekamp(GEN Q, GEN *t, GEN pp, GEN pps2);
                    401:
                    402: /* assume degree(a) > 0, a(0) != 0, and a squarefree */
                    403: static GEN
                    404: squff(GEN a, long klim, long hint)
                    405: {
                    406:   GEN Q,prime,primes2,factorsmodp,p1,p2,y,g,z,w,pe,*tabd,*tabdnew;
                    407:   long av=avma,tetpil,va=varn(a),da=lgef(a)-3;
                    408:   long chosenp,p,nfacp,lbit,i,j,d,e,np,nmax,lgg,nf,nft;
                    409:   ulong *tabbit, *tabkbit, *tmp;
                    410:   byteptr pt=diffptr;
                    411:   const int NOMBDEP = 5;
                    412:
                    413:   if (hint < 0) return decpol(a,klim);
                    414:   if (DEBUGLEVEL > 2) timer2();
                    415:   lbit=(da>>4)+1; nmax=da+1; i=da>>1;
                    416:   if (!klim || klim>i) klim=i;
                    417:   tabdnew = (GEN*)new_chunk(nmax);
                    418:   tabbit  = (ulong*)new_chunk(lbit);
                    419:   tabkbit = (ulong*)new_chunk(lbit);
                    420:   tmp     = (ulong*)new_chunk(lbit);
                    421:   p = np = 0; prime = icopy(gun);
                    422:   while (np < NOMBDEP)
                    423:   {
                    424:     GEN minuspolx;
                    425:     p += *pt++; if (!*pt) err(primer1);
                    426:     if (!smodis((GEN)a[da+2],p)) continue;
                    427:     prime[2] = p; z = Fp_pol(a, prime);
                    428:     if (gcmp0(discsr(z))) continue;
                    429:     z = lift_intern(z);
                    430:
                    431:     for (j=0; j<lbit-1; j++) tabkbit[j]=0;
                    432:     tabkbit[j]=1;
                    433:     d=0; e=da; nfacp=0;
                    434:     w = polx[va]; minuspolx = gneg(w);
                    435:     while (d < (e>>1))
                    436:     {
                    437:       d++; w = Fp_pow_mod_pol(w, prime, z, prime);
                    438:       g = Fp_pol_gcd(z, gadd(w, minuspolx), prime);
                    439:       tabdnew[d]=g; lgg=lgef(g)-3;
                    440:       if (lgg>0)
                    441:       {
                    442:        z = Fp_poldivres(z, g, prime, NULL);
                    443:         e = lgef(z)-3;
                    444:         w = Fp_poldivres(w, z, prime, ONLY_REM);
                    445:         lgg /= d; nfacp += lgg;
                    446:         if (DEBUGLEVEL>5)
                    447:           fprintferr("   %3ld %s of degree %3ld\n",
                    448:                      lgg, lgg==1?"factor": "factors",d);
                    449:        for (j=1; j<=lgg; j++) dotab(d,lbit-1,tabkbit,tmp);
                    450:       }
                    451:     }
                    452:     if (e>0)
                    453:     {
                    454:       if (DEBUGLEVEL>5)
                    455:         fprintferr("   %3ld factor of degree %3ld\n",1,e);
                    456:       tabdnew[e]=z; nfacp++;
                    457:       dotab(e,lbit-1,tabkbit,tmp);
                    458:     }
                    459:     if (np)
                    460:       for (j=0; j<lbit; j++) tabbit[j] &= tabkbit[j];
                    461:     else
                    462:       for (j=0; j<lbit; j++) tabbit[j] = tabkbit[j];
                    463:     if (DEBUGLEVEL > 4)
                    464:       fprintferr("...tried prime %3ld (%-3ld %s). Time = %ld\n",
                    465:                   p,nfacp,nfacp==1?"factor": "factors",timer2());
                    466:     if (min_deg(lbit-1,tabbit) > klim)
                    467:     {
                    468:       avma=av; y=cgetg(2,t_COL); y[1]=lcopy(a); return y;
                    469:     }
                    470:     if (nfacp<nmax)
                    471:     {
                    472:       nmax=nfacp; tabd=tabdnew; chosenp=p;
                    473:       for (j=d+1; j<e; j++) tabd[j]=polun[va];
                    474:       tabdnew = (GEN*)new_chunk(da);
                    475:     }
                    476:     np++;
                    477:   }
                    478:   prime[2]=chosenp; primes2 = shifti(prime, -1);
                    479:   nf=nmax; nft=1;
                    480:   y=cgetg(nf+1,t_COL); factorsmodp=cgetg(nf+1,t_COL);
                    481:   Q = cgetg(da+1,t_MAT);
                    482:   for (i=1; i<=da; i++) Q[i] = lgetg(da+1, t_COL);
                    483:   p1 = (GEN)Q[1]; for (i=1; i<=da; i++) p1[i] = zero;
                    484:   for (d=1; nft<=nf; d++)
                    485:   {
                    486:     g=tabd[d]; lgg=lgef(g)-3;
                    487:     if (lgg)
                    488:     {
                    489:       long n = lgg/d;
                    490:       factorsmodp[nft] = (long)normalize_mod_p(g, prime);
                    491:       if (n==1) nft++;
                    492:       else
                    493:       {
                    494:         (void)split_berlekamp(Q, (GEN*)(factorsmodp+nft),prime,primes2);
                    495:         nft += n;
                    496:       }
                    497:     }
                    498:   }
                    499:   if (DEBUGLEVEL > 4) msgtimer("splitting mod p = %ld",chosenp);
                    500:
                    501:   p1=gzero; for (i=2; i<=da+2; i++) p1=addii(p1,sqri((GEN)a[i]));
                    502:   p2=absi((GEN)a[da+2]);
                    503:   p1=addii(p2,addsi(1,racine(p1)));
                    504:   p1=mulii(p1,binome(stoi(da-1),klim));
                    505:   p1=shifti(mulii(p2,p1),1);
                    506:   for (e=1,pe=gun; ; e++)
                    507:   {
                    508:     pe = mulis(pe,chosenp);
                    509:     if (cmpii(pe,p1) >= 0) break;
                    510:   }
                    511:   if (DEBUGLEVEL > 4) fprintferr("coeff bound: %Z\n",p1);
                    512:
                    513:   cmbf_target = a;
                    514:   cmbf_degree = lgef(a)-3;
                    515:   cmbf_lc = (GEN)a[lgef(a)-1];
                    516:   cmbf_abslc = absi(cmbf_lc);
                    517:   cmbf_abslcxtarget = gmul(cmbf_abslc,a);
                    518:   cmbf_mod = pe;
                    519:   cmbf_modhalf = shifti(pe,-1);
                    520:   cmbf_modfax = hensel_lift_fact(a,factorsmodp,prime,pe,e);
                    521:   cmbf_modfaxn = nf;
                    522:   cmbf_fax = cgetg(nf+2,t_COL);
                    523:   cmbf_faxn = 0;
                    524:   /* sorting factors decreasing by degree helps if klim is used
                    525:    * If not, can start with first arg of 2 instead of 1, saving some time.
                    526:    * Should be sending tabbit through for more efficiency ???
                    527:    */
                    528:   cmbf(1,NULL,klim,hint); /* The Call */
                    529:   if (cmbf_degree)
                    530:   {
                    531:     if (signe(cmbf_lc)<0) cmbf_target = gneg_i(cmbf_target);
                    532:     cmbf_fax[++cmbf_faxn] = (long)cmbf_target; /* leftover factor */
                    533:   }
                    534:   if (DEBUGLEVEL>6) fprintferr("\n");
                    535:   tetpil=avma; y=cgetg(cmbf_faxn+1,t_COL);
                    536:   for (i=1; i<=cmbf_faxn; i++) y[i]=lcopy((GEN)cmbf_fax[i]);
                    537:   return gerepile(av,tetpil,y);
                    538: }
                    539:
                    540: /* klim=0 habituellement, sauf si l'on ne veut chercher que les facteurs
                    541:  * de degre <= klim
                    542:  */
                    543: GEN
                    544: factpol(GEN x, long klim, long hint)
                    545: {
                    546:   GEN fa,p1,d,t,v,w, y = cgetg(3,t_MAT);
                    547:   long av=avma,av2,lx,vx,i,j,k,ex,nbfac,zval;
                    548:
                    549:   if (typ(x)!=t_POL) err(notpoler,"factpol");
                    550:   if (!signe(x)) err(zeropoler,"factpol");
                    551:
                    552:   ex = nbfac = 0;
                    553:   p1 = x+2; while (gcmp0((GEN)*p1)) p1++;
                    554:   zval = p1 - (x + 2);
                    555:   lx = lgef(x) - zval;
                    556:   vx = varn(x);
                    557:   if (zval)
                    558:   {
                    559:     x = cgetg(lx, t_POL); p1 -= 2;
                    560:     for (i=2; i<lx; i++) x[i] = p1[i];
                    561:     x[1] = evalsigne(1)|evalvarn(vx)|evallgef(lx);
                    562:     nbfac++;
                    563:   }
                    564:   /* now x(0) != 0 */
                    565:   if (lx==3) goto END;
                    566:   p1 = cgetg(1,t_VEC); fa=cgetg(lx,t_VEC);
                    567:   for (i=1; i<lx; i++) fa[i] = (long)p1;
                    568:   d=content(x); if (gsigne(leading_term(x)) < 0) d = gneg_i(d);
                    569:   if (!gcmp1(d)) x=gdiv(x,d);
                    570:   if (lx==4) { nbfac++; ex++; fa[1] = (long)concatsp(p1,x); goto END; }
                    571:
                    572:   w=derivpol(x); t=modulargcd(x,w);
                    573:   if (!gcmp1(t)) { x=gdeuc(x,t); w=gdeuc(w,t); }
                    574:   k=1;
                    575:   while (k)
                    576:   {
                    577:     ex++; w=gadd(w, gneg_i(derivpol(x))); k=signe(w);
                    578:     if (k) { t=modulargcd(x,w); x=gdeuc(x,t); w=gdeuc(w,t); } else t=x;
                    579:     if (lgef(t) > 3)
                    580:     {
                    581:       fa[ex] = (long)squff(t,klim,hint);
                    582:       nbfac += lg(fa[ex])-1;
                    583:     }
                    584:   }
                    585: END: av2=avma;
                    586:   v=cgetg(nbfac+1,t_COL); y[1]=(long)v;
                    587:   w=cgetg(nbfac+1,t_COL); y[2]=(long)w;
                    588:   if (zval) { v[1]=lpolx[vx]; w[1]=lstoi(zval); k=1; } else k=0;
                    589:   for (i=1; i<=ex; i++)
                    590:     for (j=1; j<lg(fa[i]); j++)
                    591:     {
                    592:       k++; v[k]=lcopy(gmael(fa,i,j)); w[k]=lstoi(i);
                    593:     }
                    594:   gerepilemanyvec(av,av2,y+1,2);
                    595:   return sort_factor(y, cmpii);
                    596: }
                    597:
                    598: GEN
                    599: factpol2(GEN x, long klim)
                    600: {
                    601:   return factpol(x,klim,-1);
                    602: }
                    603:
                    604: /***********************************************************************/
                    605: /**                                                                   **/
                    606: /**                          FACTORISATION                            **/
                    607: /**                                                                   **/
                    608: /***********************************************************************/
                    609: #define LT 17
                    610: #define assign_or_fail(x,y) {\
                    611:   if (y==NULL) y=x; else if (!gegal(x,y)) return 0;\
                    612: }
                    613: #define tsh 6
                    614: #define typs(x,y) ((x << tsh) | y)
                    615: #define typ1(x) (x >> tsh)
                    616: #define typ2(x) (x & ((1<<tsh)-1))
                    617:
                    618: static long
                    619: poltype(GEN x, GEN *ptp, GEN *ptpol, long *ptpa)
                    620: {
                    621:   long t[LT]; /* code pour 0,1,2,3,61,62,63,67,7,81,82,83,86,87,91,93,97 */
                    622:   long tx = typ(x),lx,i,j,s,pa=BIGINT;
                    623:   GEN pcx=NULL, p=NULL,pol=NULL,p1,p2;
                    624:
                    625:   if (is_scalar_t(tx))
                    626:   {
                    627:     if (tx == t_POLMOD) return 0;
                    628:     x = scalarpol(x,0);
                    629:   }
                    630:   for (i=2; i<LT; i++) t[i]=0; /* t[0..1] unused */
                    631:   lx = lgef(x);
                    632:   for (i=2; i<lx; i++)
                    633:   {
                    634:     p1=(GEN)x[i];
                    635:     switch(typ(p1))
                    636:     {
                    637:       case t_INT: case t_FRAC: case t_FRACN:
                    638:         break;
                    639:       case t_REAL:
                    640:         s = precision(p1); if (s < pa) pa = s;
                    641:         t[2]=1; break;
                    642:       case t_INTMOD:
                    643:        assign_or_fail((GEN)p1[1],p);
                    644:         t[3]=1; break;
                    645:       case t_COMPLEX:
                    646:         if (!pcx)
                    647:         {
                    648:           pcx = cgetg(5,t_POL); /* x^2 + 1 */
                    649:           pcx[1] = evalsigne(1)|evalvarn(0)|m_evallgef(5),
                    650:           pcx[2]=pcx[4]=un; pcx[3]=zero;
                    651:         }
                    652:        for (j=1; j<=2; j++)
                    653:        {
                    654:          p2 = (GEN)p1[j];
                    655:          switch(typ(p2))
                    656:          {
                    657:            case t_INT: case t_FRAC: case t_FRACN:
                    658:              assign_or_fail(pcx,pol);
                    659:              t[4]=1; break;
                    660:            case t_REAL:
                    661:               s = precision(p2); if (s < pa) pa = s;
                    662:              t[5]=1; break;
                    663:            case t_INTMOD:
                    664:              assign_or_fail((GEN)p2[1],p);
                    665:              assign_or_fail(pcx,pol);
                    666:              t[6]=1; break;
                    667:            case t_PADIC:
                    668:              s = precp(p2) + valp(p2); if (s < pa) pa = s;
                    669:              assign_or_fail((GEN)p2[2],p);
                    670:              assign_or_fail(pcx,pol);
                    671:              t[7]=1; break;
                    672:            default: return 0;
                    673:          }
                    674:        }
                    675:        break;
                    676:       case t_PADIC:
                    677:         s = precp(p1) + valp(p1); if (s < pa) pa = s;
                    678:        assign_or_fail((GEN)p1[2],p);
                    679:         t[8]=1; break;
                    680:       case t_QUAD:
                    681:        for (j=2; j<=3; j++)
                    682:        {
                    683:          p2 = (GEN)p1[j];
                    684:          switch(typ(p2))
                    685:          {
                    686:            case t_INT: case t_FRAC: case t_FRACN:
                    687:              assign_or_fail((GEN)p1[1],pol);
                    688:              t[9]=1; break;
                    689:            case t_REAL:
                    690:              s = precision(p2); if (s < pa) pa = s;
                    691:              if (gsigne(discsr((GEN)p1[1]))>0) t[10]=1; else t[12]=1;
                    692:              break;
                    693:            case t_INTMOD:
                    694:              assign_or_fail((GEN)p2[1],p);
                    695:              assign_or_fail((GEN)p1[1],pol);
                    696:              t[11]=1; break;
                    697:            case t_PADIC:
                    698:              s = precp(p2) + valp(p2); if (s < pa) pa = s;
                    699:              assign_or_fail((GEN)p2[2],p);
                    700:              assign_or_fail((GEN)p1[1],pol);
                    701:              t[13]=1; break;
                    702:            default: return 0;
                    703:          }
                    704:        }
                    705:        break;
                    706:       case t_POLMOD:
                    707:        assign_or_fail((GEN)p1[1],pol);
                    708:        for (j=1; j<=2; j++)
                    709:        {
                    710:          GEN pbis = NULL, polbis = NULL;
                    711:          long pabis;
                    712:          switch(poltype((GEN)p1[j],&pbis,&polbis,&pabis))
                    713:          {
                    714:            case t_INT: t[14]=1; break;
                    715:            case t_INTMOD: t[15]=1; break;
                    716:            case t_PADIC: t[16]=1; if (pabis<pa) pa=pabis; break;
                    717:            default: return 0;
                    718:          }
                    719:          if (pbis) assign_or_fail(pbis,p);
                    720:          if (polbis) assign_or_fail(polbis,pol);
                    721:        }
                    722:        break;
                    723:       default: return 0;
                    724:     }
                    725:   }
                    726:   if (t[5]||t[12])
                    727:   {
                    728:     if (t[3]||t[6]||t[7]||t[8]||t[11]||t[13]||t[14]||t[15]||t[16]) return 0;
                    729:     *ptpa=pa; return t_COMPLEX;
                    730:   }
                    731:   if (t[2]||t[10])
                    732:   {
                    733:     if (t[3]||t[6]||t[7]||t[8]||t[11]||t[13]||t[14]||t[15]||t[16]) return 0;
                    734:     *ptpa=pa; return t[4]?t_COMPLEX:t_REAL;
                    735:   }
                    736:   if (t[6]||t[11]||t[15])
                    737:   {
                    738:     *ptpol=pol; *ptp=p;
                    739:     i = t[15]? t_POLMOD: (t[11]? t_QUAD: t_COMPLEX);
                    740:     return typs(i, t_INTMOD);
                    741:   }
                    742:   if (t[7]||t[13]||t[16])
                    743:   {
                    744:     *ptpol=pol; *ptp=p; *ptpa=pa;
                    745:     i = t[16]? t_POLMOD: (t[13]? t_QUAD: t_COMPLEX);
                    746:     return typs(i, t_PADIC);
                    747:   }
                    748:   if (t[4]||t[9]||t[14])
                    749:   {
                    750:     *ptpol=pol;
                    751:     i = t[14]? t_POLMOD: (t[9]? t_QUAD: t_COMPLEX);
                    752:     return typs(i, t_INT);
                    753:   }
                    754:   if (t[3]) { *ptp=p; return t_INTMOD; }
                    755:   if (t[8]) { *ptp=p; *ptpa=pa; return t_PADIC; }
                    756:   return t_INT;
                    757: }
                    758: #undef LT
                    759:
                    760: GEN
                    761: factor0(GEN x,long flag)
                    762: {
                    763:   long tx=typ(x);
                    764:
                    765:   if (flag<0) return factor(x);
                    766:   if (is_matvec_t(tx)) return gboundfact(x,flag);
                    767:   if (tx==t_INT || tx==t_FRAC || tx==t_FRACN) return boundfact(x,flag);
                    768:   err(talker,"partial factorization is not meaningful here");
                    769:   return NULL; /* not reached */
                    770: }
                    771:
                    772: static GEN
                    773: poldeg1(long v, GEN x0, GEN x1)
                    774: {
                    775:   GEN x = cgetg(4,t_POL);
                    776:   x[1] = evalsigne(1) | evalvarn(v) | evallgef(4);
                    777:   x[2] = (long)x0; x[3] = (long)x1; return normalizepol(x);
                    778: }
                    779:
                    780: GEN
                    781: factor(GEN x)
                    782: {
                    783:   long tx=typ(x),lx,av,tetpil,i,j,pa,v,r1;
                    784:   GEN  y,p,p1,p2,p3,p4,p5,pol;
                    785:
                    786:   if (is_matvec_t(tx))
                    787:   {
                    788:     lx=lg(x); y=cgetg(lx,tx);
                    789:     for (i=1; i<lx; i++) y[i]=(long)factor((GEN)x[i]);
                    790:     return y;
                    791:   }
                    792:   if (gcmp0(x))
                    793:   {
                    794:     y=cgetg(3,t_MAT);
                    795:     p1=cgetg(2,t_COL); y[1]=(long)p1; p1[1]=zero;
                    796:     p2=cgetg(2,t_COL); y[2]=(long)p2; p2[1]=un;
                    797:     return y;
                    798:   }
                    799:   switch(tx)
                    800:   {
                    801:     case t_INT: return decomp(x);
                    802:
                    803:     case t_FRACN:
                    804:       av=avma; x=gred(x); /* fall through */
                    805:     case t_FRAC:
                    806:       if (tx==t_FRAC) av=avma;
                    807:       p1 = decomp((GEN)x[1]);
                    808:       p2 = decomp((GEN)x[2]);
                    809:       p4 = concatsp((GEN)p1[1], (GEN)p2[1]);
                    810:       p5 = concatsp((GEN)p1[2], gneg_i((GEN)p2[2]));
                    811:       p3 = sindexsort(p4); lx = lg(p3);
                    812:       tetpil=avma; y=cgetg(3,t_MAT);
                    813:       p1 = cgetg(lx,t_COL); y[1]=(long)p1;
                    814:       p2 = cgetg(lx,t_COL); y[2]=(long)p2;
                    815:       for (i=1; i<lx; i++)
                    816:       {
                    817:        p1[i] = licopy((GEN)p4[p3[i]]);
                    818:        p2[i] = licopy((GEN)p5[p3[i]]);
                    819:       }
                    820:       return gerepile(av,tetpil,y);
                    821:
                    822:     case t_POL:
                    823:       tx=poltype(x,&p,&pol,&pa);
                    824:       switch(tx)
                    825:       {
                    826:         case 0: err(impl,"factor for general polynomials");
                    827:        case t_INT: return factpol(x,0,1);
                    828:        case t_INTMOD: return factmod(x,p);
                    829:
                    830:        case t_COMPLEX: y=cgetg(3,t_MAT); lx=lgef(x)-2; v=varn(x);
                    831:          av=avma; p1=roots(x,pa); tetpil=avma;
                    832:           p2=cgetg(lx,t_COL);
                    833:          for (i=1; i<lx; i++)
                    834:             p2[i] = (long)poldeg1(v, gneg((GEN)p1[i]), gun);
                    835:          y[1]=lpile(av,tetpil,p2);
                    836:          p3=cgetg(lx,t_COL); for (i=1; i<lx; i++) p3[i] = un;
                    837:           y[2]=(long)p3; return y;
                    838:
                    839:        case t_REAL: y=cgetg(3,t_MAT); lx=lgef(x)-2; v=varn(x);
                    840:          av=avma; p1=roots(x,pa); tetpil=avma;
                    841:          for(r1=1; r1<lx; r1++)
                    842:             if (signe(gmael(p1,r1,2))) break;
                    843:          lx=(r1+lx)>>1; p2=cgetg(lx,t_COL);
                    844:          for(i=1; i<r1; i++)
                    845:             p2[i] = (long)poldeg1(v, negr(gmael(p1,i,1)), gun);
                    846:          for(   ; i<lx; i++)
                    847:          {
                    848:            GEN a = (GEN) p1[2*i-r1];
                    849:            p = cgetg(5, t_POL); p2[i] = (long)p;
                    850:            p[1] = evalsigne(1) | evalvarn(v) | evallgef(5);
                    851:            p[2] = lnorm(a);
                    852:            p[3] = lmul2n((GEN)a[1],1); setsigne(p[3],-signe(p[3]));
                    853:            p[4] = un;
                    854:          }
                    855:          y[1]=lpile(av,tetpil,p2);
                    856:          p3=cgetg(lx,t_COL); for (i=1; i<lx; i++) p3[i] = un;
                    857:           y[2]=(long)p3; return y;
                    858:
                    859:        case t_PADIC: return factorpadic4(x,p,pa);
                    860:
                    861:         default:
                    862:         {
                    863:           long killv;
                    864:          av=avma; x = dummycopy(x); lx=lgef(x);
                    865:           pol = dummycopy(pol);
                    866:           v = manage_var(4,NULL);
                    867:           for(i=2; i<lx; i++)
                    868:           {
                    869:             p1=(GEN)x[i];
                    870:             switch(typ(p1))
                    871:             {
                    872:               case t_QUAD: p1++;
                    873:               case t_COMPLEX:
                    874:                 p2 = cgetg(3, t_POLMOD); x[i] = (long) p2;
                    875:                 p2[1] = (long)pol;
                    876:                 p2[2] = (long)poldeg1(v, (GEN)p1[1],(GEN)p1[2]);
                    877:             }
                    878:           }
                    879:           killv = (avma != (long)pol);
                    880:           if (killv) setvarn(pol, fetch_var());
                    881:           switch (typ2(tx))
                    882:           {
                    883:             case t_INT: p1 = polfnf(x,pol); break;
                    884:             case t_INTMOD: p1 = factmod9(x,p,pol); break;
                    885:            default: err(impl,"factor of general polynomial");
                    886:           }
                    887:           switch (typ1(tx))
                    888:           {
                    889:             case t_POLMOD:
                    890:               if (killv) delete_var();
                    891:               return gerepileupto(av,p1);
                    892:             case t_COMPLEX: p5 = gi; break;
                    893:             case t_QUAD: p5=cgetg(4,t_QUAD);
                    894:               p5[1]=(long)pol; p5[2]=zero; p5[3]=un;
                    895:               break;
                    896:            default: err(impl,"factor of general polynomial");
                    897:           }
                    898:           p2=(GEN)p1[1];
                    899:           for(i=1; i<lg(p2); i++)
                    900:           {
                    901:             p3=(GEN)p2[i];
                    902:             for(j=2; j<lgef(p3); j++)
                    903:             {
                    904:               p4=(GEN)p3[j];
                    905:               if(typ(p4)==t_POLMOD) p3[j]=lsubst((GEN)p4[2],v,p5);
                    906:             }
                    907:           }
                    908:           if (killv) delete_var();
                    909:           tetpil=avma; y=cgetg(3,t_MAT);
                    910:           y[1]=lcopy(p2);y[2]=lcopy((GEN)p1[2]);
                    911:           return gerepile(av,tetpil,y);
                    912:         }
                    913:       }
                    914:
                    915:     case t_RFRACN:
                    916:       av=avma; x=gred_rfrac(x); /* fall through */
                    917:     case t_RFRAC:
                    918:       if (tx==t_RFRAC) av=avma;
                    919:       p1=factor((GEN)x[1]);
                    920:       p2=factor((GEN)x[2]); p3=gneg_i((GEN)p2[2]);
                    921:       tetpil=avma; y=cgetg(3,t_MAT);
                    922:       y[1]=lconcat((GEN)p1[1],(GEN)p2[1]);
                    923:       y[2]=lconcat((GEN)p1[2],p3);
                    924:       return gerepile(av,tetpil,y);
                    925:   }
                    926:   err(impl,"general factorization");
                    927:   return NULL; /* not reached */
                    928: }
                    929: #undef typ1
                    930: #undef typ2
                    931: #undef typs
                    932: #undef tsh
                    933:
                    934: GEN
                    935: divide_conquer_prod(GEN x, GEN (*mul)(GEN,GEN))
                    936: {
                    937:   long i,k,lx = lg(x);
                    938:
                    939:   if (lx == 1) return gun;
                    940:   if (lx == 2) return gcopy((GEN)x[1]);
                    941:   x = dummycopy(x); k = lx;
                    942:   while (k > 2)
                    943:   {
                    944:     if (DEBUGLEVEL>7)
                    945:       fprintferr("prod: remaining objects %ld\n",k-1);
                    946:     lx = k; k = 1;
                    947:     for (i=1; i<lx-1; i+=2)
                    948:       x[k++] = (long)mul((GEN)x[i],(GEN)x[i+1]);
                    949:     if (i < lx) x[k++] = x[i];
                    950:   }
                    951:   return (GEN)x[1];
                    952: }
                    953:
                    954: static GEN static_nf;
                    955:
                    956: static GEN
                    957: myidealmul(GEN x, GEN y) { return idealmul(static_nf, x, y); }
                    958:
                    959: static GEN
                    960: myidealpow(GEN x, GEN n) { return idealpow(static_nf, x, n); }
                    961:
                    962: GEN
                    963: factorback(GEN fa, GEN nf)
                    964: {
                    965:   long av=avma,k,l,lx;
                    966:   GEN ex, x;
                    967:   GEN (*_mul)(GEN,GEN);
                    968:   GEN (*_pow)(GEN,GEN);
                    969:
                    970:   if (typ(fa)!=t_MAT || lg(fa)!=3)
                    971:     err(talker,"incorrect factorisation in factorback");
                    972:   ex=(GEN)fa[2]; fa=(GEN)fa[1];
                    973:   lx = lg(fa); if (lx == 1) return gun;
                    974:   x = cgetg(lx,t_VEC);
                    975:   if (nf)
                    976:   {
                    977:     static_nf = nf;
                    978:     _mul = &myidealmul;
                    979:     _pow = &myidealpow;
                    980:   }
                    981:   else
                    982:   {
                    983:     _mul = &gmul;
                    984:     _pow = &powgi;
                    985:   }
                    986:   for (l=1,k=1; k<lx; k++)
                    987:     if (signe(ex[k]))
                    988:       x[l++] = (long)_pow((GEN)fa[k],(GEN)ex[k]);
                    989:   setlg(x,l);
                    990:   return gerepileupto(av, divide_conquer_prod(x, _mul));
                    991: }
                    992:
                    993: GEN
                    994: gisirreducible(GEN x)
                    995: {
                    996:   long av=avma, tx = typ(x),l,i;
                    997:   GEN y;
                    998:
                    999:   if (is_matvec_t(tx))
                   1000:   {
                   1001:     l=lg(x); y=cgetg(l,tx);
                   1002:     for (i=1; i<l; i++) y[i]=(long)gisirreducible((GEN)x[i]);
                   1003:     return y;
                   1004:   }
                   1005:   if (is_intreal_t(tx) || is_frac_t(tx)) return gzero;
                   1006:   if (tx!=t_POL) err(notpoler,"gisirreducible");
                   1007:   l=lgef(x); if (l<=3) return gzero;
                   1008:   y=factor(x); avma=av;
                   1009:   return (lgef(gcoeff(y,1,1))==l)?gun:gzero;
                   1010: }
                   1011:
                   1012: /*******************************************************************/
                   1013: /*                                                                 */
                   1014: /*                         PGCD GENERAL                            */
                   1015: /*                                                                 */
                   1016: /*******************************************************************/
                   1017:
                   1018: GEN
                   1019: gcd0(GEN x, GEN y, long flag)
                   1020: {
                   1021:   switch(flag)
                   1022:   {
                   1023:     case 0: return ggcd(x,y);
                   1024:     case 1: return modulargcd(x,y);
                   1025:     case 2: return srgcd(x,y);
                   1026:     default: err(flagerr,"gcd");
                   1027:   }
                   1028:   return NULL; /* not reached */
                   1029: }
                   1030:
                   1031: /* x is a COMPLEX or a QUAD */
                   1032: static GEN
                   1033: triv_cont_gcd(GEN x, GEN y)
                   1034: {
                   1035:   long av = avma, tetpil;
                   1036:   GEN p1 = (typ(x)==t_COMPLEX)? ggcd((GEN)x[1],(GEN)x[2])
                   1037:                               : ggcd((GEN)x[2],(GEN)x[3]);
                   1038:   tetpil=avma; return gerepile(av,tetpil,ggcd(p1,y));
                   1039: }
                   1040:
                   1041: static GEN
                   1042: cont_gcd(GEN x, GEN y)
                   1043: {
                   1044:   long av = avma, tetpil;
                   1045:   GEN p1 = content(x);
                   1046:
                   1047:   tetpil=avma; return gerepile(av,tetpil,ggcd(p1,y));
                   1048: }
                   1049:
                   1050: /* y is a PADIC, x a rational number or an INTMOD */
                   1051: static GEN
                   1052: padic_gcd(GEN x, GEN y)
                   1053: {
                   1054:   long v = ggval(x,(GEN)y[2]), w = valp(y);
                   1055:   if (w < v) v = w;
                   1056:   return gpuigs((GEN)y[2], v);
                   1057: }
                   1058:
                   1059: #define fix_frac(z) if (signe(z[2])<0)\
                   1060: {\
                   1061:   setsigne(z[1],-signe(z[1]));\
                   1062:   setsigne(z[2],1);\
                   1063: }
                   1064:
                   1065: GEN
                   1066: ggcd(GEN x, GEN y)
                   1067: {
                   1068:   long l,av,tetpil,i,vx,vy, tx = typ(x), ty = typ(y);
                   1069:   GEN p1,z;
                   1070:
                   1071:   if (tx>ty) { p1=x; x=y; y=p1; l=tx; tx=ty; ty=l; }
                   1072:   if (is_matvec_t(ty))
                   1073:   {
                   1074:     l=lg(y); z=cgetg(l,ty);
                   1075:     for (i=1; i<l; i++) z[i]=lgcd(x,(GEN)y[i]);
                   1076:     return z;
                   1077:   }
                   1078:   if (gcmp0(x)) return gcopy(y);
                   1079:   if (gcmp0(y)) return gcopy(x);
                   1080:   if (is_const_t(tx))
                   1081:   {
                   1082:     if (ty == t_FRACN)
                   1083:     {
                   1084:       if (tx==t_INTMOD)
                   1085:       {
                   1086:         av=avma; y = gred(y); tetpil=avma;
                   1087:         return gerepile(av,tetpil,ggcd(x,y));
                   1088:       }
                   1089:       ty = t_FRAC;
                   1090:     }
                   1091:     if (tx == t_FRACN) tx = t_FRAC;
                   1092:     if (ty == tx) switch(tx)
                   1093:     {
                   1094:       case t_INT:
                   1095:         return mppgcd(x,y);
                   1096:
                   1097:       case t_INTMOD: z=cgetg(3,t_INTMOD);
                   1098:         if (egalii((GEN)x[1],(GEN)y[1]))
                   1099:           { copyifstack(x[1],z[1]); }
                   1100:         else
                   1101:           z[1]=lmppgcd((GEN)x[1],(GEN)y[1]);
                   1102:         if (gcmp1((GEN)z[1])) z[2]=zero;
                   1103:         else
                   1104:         {
                   1105:           av=avma; p1=mppgcd((GEN)z[1],(GEN)x[2]);
                   1106:           if (!gcmp1(p1))
                   1107:           {
                   1108:             tetpil=avma;
                   1109:             p1=gerepile(av,tetpil,mppgcd(p1,(GEN)y[2]));
                   1110:           }
                   1111:           z[2]=(long)p1;
                   1112:         }
                   1113:         return z;
                   1114:
                   1115:       case t_FRAC: z=cgetg(3,t_FRAC);
                   1116:         (void)new_chunk(lgefint(x[2])+lgefint(y[2]));
                   1117:         p1 = divii((GEN)y[2], mppgcd((GEN)x[2], (GEN)y[2]));
                   1118:         avma = (long)z;
                   1119:         z[2] = lmulii(p1, (GEN)x[2]);
                   1120:         z[1] = (long)mppgcd((GEN)x[1], (GEN)y[1]);
                   1121:         fix_frac(z); return z;
                   1122:
                   1123:       case t_COMPLEX:
                   1124:         av=avma; p1=gdiv(x,y);
                   1125:         if (gcmp0((GEN)p1[2]))
                   1126:         {
                   1127:           p1=(GEN)p1[1];
                   1128:           switch(typ(p1))
                   1129:           {
                   1130:             case t_INT:
                   1131:               avma=av; return gcopy(y);
                   1132:             case t_FRAC: case t_FRACN:
                   1133:               tetpil=avma; return gerepile(av,tetpil,gdiv(y,(GEN)p1[2]));
                   1134:             default: avma=av; return gun;
                   1135:           }
                   1136:         }
                   1137:         avma=av;
                   1138:         if (typ(p1[1])==t_INT && typ(p1[2])==t_INT) return gcopy(y);
                   1139:         p1=gdiv(y,x); avma=av;
                   1140:         if (typ(p1[1])==t_INT && typ(p1[2])==t_INT) return gcopy(x);
                   1141:         return triv_cont_gcd(y,x);
                   1142:
                   1143:       case t_PADIC:
                   1144:         if (!egalii((GEN)x[2],(GEN)y[2])) return gun;
                   1145:         return gpuigs((GEN)y[2],min(valp(y),valp(x)));
                   1146:
                   1147:       case t_QUAD:
                   1148:         av=avma; p1=gdiv(x,y);
                   1149:         if (gcmp0((GEN)p1[3]))
                   1150:         {
                   1151:           p1=(GEN)p1[2];
                   1152:           if (typ(p1)==t_INT) { avma=av; return gcopy(y); }
                   1153:           tetpil=avma; return gerepile(av,tetpil, gdiv(y,(GEN)p1[2]));
                   1154:         }
                   1155:         avma=av;
                   1156:         if (typ(p1[2])==t_INT && typ(p1[3])==t_INT) return gcopy(y);
                   1157:         p1=gdiv(y,x); avma=av;
                   1158:         if (typ(p1[2])==t_INT && typ(p1[3])==t_INT) return gcopy(x);
                   1159:         return triv_cont_gcd(y,x);
                   1160:
                   1161:       default: return gun; /* t_REAL */
                   1162:     }
                   1163:     if (is_const_t(ty)) switch(tx)
                   1164:     {
                   1165:       case t_INT:
                   1166:         switch(ty)
                   1167:         {
                   1168:           case t_INTMOD: z=cgetg(3,t_INTMOD);
                   1169:             copyifstack(y[1],z[1]); av=avma;
                   1170:             p1=mppgcd((GEN)y[1],(GEN)y[2]);
                   1171:             if (!gcmp1(p1))
                   1172:               { tetpil=avma; p1=gerepile(av,tetpil,mppgcd(x,p1)); }
                   1173:             z[2]=(long)p1; return z;
                   1174:
                   1175:           case t_FRAC: z=cgetg(3,t_FRAC);
                   1176:             z[1]=lmppgcd(x,(GEN)y[1]);
                   1177:             z[2]=licopy((GEN)y[2]); return z;
                   1178:
                   1179:           case t_COMPLEX: case t_QUAD:
                   1180:             return triv_cont_gcd(y,x);
                   1181:
                   1182:           case t_PADIC:
                   1183:             return padic_gcd(x,y);
                   1184:
                   1185:           default: /* t_REAL */
                   1186:             return gun;
                   1187:         }
                   1188:
                   1189:       case t_INTMOD:
                   1190:         switch(ty)
                   1191:         {
                   1192:           case t_FRAC:
                   1193:             av=avma; p1=mppgcd((GEN)x[1],(GEN)y[2]); tetpil=avma;
                   1194:             if (!gcmp1(p1))
                   1195:               err(talker,"non invertible fraction in a gcd with INTMOD");
                   1196:             return gerepile(av,tetpil, ggcd((GEN)y[1],x));
                   1197:
                   1198:           case t_COMPLEX: case t_QUAD:
                   1199:             return triv_cont_gcd(y,x);
                   1200:
                   1201:           case t_PADIC:
                   1202:             return padic_gcd(x,y);
                   1203:         }
                   1204:
                   1205:       case t_FRAC:
                   1206:         switch(ty)
                   1207:         {
                   1208:           case t_COMPLEX: case t_QUAD:
                   1209:             return triv_cont_gcd(y,x);
                   1210:
                   1211:           case t_PADIC:
                   1212:             return padic_gcd(x,y);
                   1213:         }
                   1214:
                   1215:       case t_COMPLEX: /* ty = PADIC or QUAD */
                   1216:         return triv_cont_gcd(x,y);
                   1217:
                   1218:       case t_PADIC: /* ty = QUAD */
                   1219:         return triv_cont_gcd(y,x);
                   1220:
                   1221:       default: /* tx = t_REAL */
                   1222:         return gun;
                   1223:     }
                   1224:     return cont_gcd(y,x);
                   1225:   }
                   1226:
                   1227:   vx=gvar9(x); vy=gvar9(y);
                   1228:   if (vy<vx) return cont_gcd(y,x);
                   1229:   if (vx<vy) return cont_gcd(x,y);
                   1230:   switch(tx)
                   1231:   {
                   1232:     case t_POLMOD:
                   1233:       switch(ty)
                   1234:       {
                   1235:        case t_POLMOD: z=cgetg(3,t_POLMOD);
                   1236:           if (gegal((GEN)x[1],(GEN)y[1]))
                   1237:            { copyifstack(x[1],z[1]); }
                   1238:           else
                   1239:             z[1] = lgcd((GEN)x[1],(GEN)y[1]);
                   1240:          if (lgef(z[1])<=3) z[2]=zero;
                   1241:          else
                   1242:          {
                   1243:            av=avma; p1=ggcd((GEN)z[1],(GEN)x[2]);
                   1244:            if (lgef(p1)>3)
                   1245:            {
                   1246:              tetpil=avma;
                   1247:               p1=gerepile(av,tetpil,ggcd(p1,(GEN)y[2]));
                   1248:            }
                   1249:            z[2]=(long)p1;
                   1250:          }
                   1251:          return z;
                   1252:
                   1253:        case t_POL: z=cgetg(3,t_POLMOD);
                   1254:           copyifstack(x[1],z[1]); av=avma;
                   1255:           p1=ggcd((GEN)x[1],(GEN)x[2]);
                   1256:          if (lgef(p1)>3)
                   1257:             { tetpil=avma; p1=gerepile(av,tetpil,ggcd(y,p1)); }
                   1258:          z[2]=(long)p1; return z;
                   1259:
                   1260:        case t_RFRAC:
                   1261:          av=avma; p1=ggcd((GEN)x[1],(GEN)y[2]); tetpil=avma;
                   1262:           if (!gcmp1(p1))
                   1263:             err(talker,"non invertible fraction in a gcd with POLMOD");
                   1264:          return gerepile(av,tetpil,ggcd((GEN)y[1],x));
                   1265:
                   1266:        case t_RFRACN:
                   1267:          av=avma; p1=gred_rfrac(y); tetpil=avma;
                   1268:          return gerepile(av,tetpil,ggcd(p1,x));
                   1269:       }
                   1270:       break;
                   1271:
                   1272:     case t_POL:
                   1273:       switch(ty)
                   1274:       {
                   1275:        case t_POL:
                   1276:          return srgcd(x,y);
                   1277:
                   1278:        case t_SER:
                   1279:          return gpuigs(polx[vx],min(valp(y),gval(x,vx)));
                   1280:
                   1281:        case t_RFRAC: case t_RFRACN: av=avma; z=cgetg(3,ty);
                   1282:           z[1]=lgcd(x,(GEN)y[1]);
                   1283:           z[2]=lcopy((GEN)y[2]); return z;
                   1284:       }
                   1285:       break;
                   1286:
                   1287:     case t_SER:
                   1288:       switch(ty)
                   1289:       {
                   1290:        case t_SER:
                   1291:          return gpuigs(polx[vx],min(valp(x),valp(y)));
                   1292:
                   1293:        case t_RFRAC: case t_RFRACN:
                   1294:          return gpuigs(polx[vx],min(valp(x),gval(y,vx)));
                   1295:       }
                   1296:       break;
                   1297:
                   1298:     case t_RFRAC: case t_RFRACN: z=cgetg(3,ty);
                   1299:       if (!is_rfrac_t(ty))
                   1300:         err(talker,"forbidden gcd rational function with vector/matrix");
                   1301:       p1 = gdiv((GEN)y[2], ggcd((GEN)x[2], (GEN)y[2]));
                   1302:       tetpil = avma;
                   1303:       z[2] = lpile((long)z,tetpil,gmul(p1, (GEN)x[2]));
                   1304:       z[1] = lgcd((GEN)x[1], (GEN)y[1]); return z;
                   1305:   }
                   1306:   err(talker,"gcd vector/matrix with a forbidden type");
                   1307:   return NULL; /* not reached */
                   1308: }
                   1309:
                   1310: GEN
                   1311: glcm(GEN x, GEN y)
                   1312: {
                   1313:   long av=avma,tx,ty=typ(y),i,l;
                   1314:   GEN p1,p2,z;
                   1315:
                   1316:   if (is_matvec_t(ty))
                   1317:   {
                   1318:     l=lg(y); z=cgetg(l,ty);
                   1319:     for (i=1; i<l; i++) z[i]=(long)glcm(x,(GEN)y[i]);
                   1320:     return z;
                   1321:   }
                   1322:   tx=typ(x);
                   1323:   if (is_matvec_t(tx))
                   1324:   {
                   1325:     l=lg(x); z=cgetg(l,tx);
                   1326:     for (i=1; i<l; i++) z[i]=(long)glcm((GEN)x[i],y);
                   1327:     return z;
                   1328:   }
                   1329:   if (gcmp0(x)) return gzero;
                   1330:   if (tx==t_INT && ty==t_INT)
                   1331:   {
                   1332:     p1 = mppgcd(x,y); if (is_pm1(p1)) { avma = av; return mulii(x,y); }
                   1333:     p2 = mulii(divii(y,p1), x);
                   1334:     if (signe(p2)<0) setsigne(p2,1);
                   1335:     return gerepileupto(av, p2);
                   1336:   }
                   1337:   p1 = ggcd(x,y); if (gcmp1(p1)) {avma = av; return gmul(x,y); }
                   1338:   p2 = gmul(gdiv(y,p1), x);
                   1339:   if (typ(p2)==t_INT && signe(p2)<0) setsigne(p2,1);
                   1340:   if (typ(p2)==t_POL)
                   1341:   {
                   1342:     p1=leading_term(p2);
                   1343:     if (typ(p1)==t_INT && signe(p1)<0) p2=gneg(p2);
                   1344:   }
                   1345:   return gerepileupto(av,p2);
                   1346: }
                   1347:
                   1348: static GEN
                   1349: polgcdnun(GEN x, GEN y)
                   1350: {
                   1351:   long av1, av = avma, lim = stack_lim(av,1);
                   1352:   GEN p1, yorig = y;
                   1353:
                   1354:   for(;;)
                   1355:   {
                   1356:     av1 = avma; p1 = gres(x,y);
                   1357:     if (gcmp0(p1))
                   1358:     {
                   1359:       avma = av1;
                   1360:       return (y==yorig)? gcopy(y): gerepileupto(av,y);
                   1361:     }
                   1362:     x = y; y = p1;
                   1363:     if (low_stack(lim,stack_lim(av,1)))
                   1364:     {
                   1365:       GEN *gptr[2]; x = gcopy(x); gptr[0]=&x; gptr[1]=&y;
                   1366:       if(DEBUGMEM>1) err(warnmem,"polgcdnun");
                   1367:       gerepilemanysp(av,av1,gptr,2);
                   1368:     }
                   1369:   }
                   1370: }
                   1371:
                   1372: /* return 1 if coeff explosion is not possible */
                   1373: static int
                   1374: issimplefield(GEN x)
                   1375: {
                   1376:   long lx,i;
                   1377:   switch(typ(x))
                   1378:   {
                   1379:     case t_REAL: case t_INTMOD: case t_PADIC: case t_SER:
                   1380:       return 1;
                   1381:     case t_POL:
                   1382:       lx=lgef(x);
                   1383:       for (i=2; i<lx; i++)
                   1384:        if (!issimplefield((GEN)x[i])) return 0;
                   1385:       return 1;
                   1386:     case t_COMPLEX: case t_POLMOD:
                   1387:       return issimplefield((GEN)x[1]) || issimplefield((GEN)x[2]);
                   1388:   }
                   1389:   return 0;
                   1390: }
                   1391:
                   1392: static int
                   1393: isrational(GEN x)
                   1394: {
                   1395:   long i;
                   1396:   for (i=lgef(x)-1; i>1; i--)
                   1397:     switch(typ(x[i]))
                   1398:     {
                   1399:       case t_INT:
                   1400:       case t_FRAC: break;
                   1401:       default: return 0;
                   1402:     }
                   1403:   return 1;
                   1404: }
                   1405:
                   1406: static int
                   1407: isinexactfield(GEN x)
                   1408: {
                   1409:   long lx,i;
                   1410:   switch(typ(x))
                   1411:   {
                   1412:     case t_REAL: case t_PADIC: case t_SER:
                   1413:       return 1;
                   1414:     case t_POL:
                   1415:       lx=lgef(x);
                   1416:       for (i=2; i<lx; i++)
                   1417:        if (!isinexactfield((GEN)x[i])) return 0;
                   1418:       return 1;
                   1419:     case t_COMPLEX: case t_POLMOD:
                   1420:       return isinexactfield((GEN)x[1]) || isinexactfield((GEN)x[2]);
                   1421:   }
                   1422:   return 0;
                   1423: }
                   1424:
                   1425: static GEN
                   1426: gcdmonome(GEN x, GEN y)
                   1427: {
                   1428:   long tetpil,av=avma, lx=lgef(x), v=varn(x), e=gval(y,v);
                   1429:   GEN p1,p2;
                   1430:
                   1431:   if (lx-3<e) e=lx-3;
                   1432:   p1=ggcd(leading_term(x),content(y)); p2=gpuigs(polx[v],e);
                   1433:   tetpil=avma; return gerepile(av,tetpil,gmul(p1,p2));
                   1434: }
                   1435:
                   1436: /***********************************************************************/
                   1437: /**                                                                   **/
                   1438: /**                         BEZOUT GENERAL                            **/
                   1439: /**                                                                   **/
                   1440: /***********************************************************************/
                   1441:
                   1442: static GEN
                   1443: polinvinexact(GEN x, GEN y)
                   1444: {
                   1445:   long i,dx=lgef(x)-3,dy=lgef(y)-3,lz=dx+dy, av=avma, tetpil;
                   1446:   GEN v,z;
                   1447:
                   1448:   z=cgetg(dy+2,t_POL); z[1]=y[1];
                   1449:   v=cgetg(lz+1,t_COL);
                   1450:   for (i=1; i<lz; i++) v[i]=zero;
                   1451:   v[lz]=un; v=gauss(sylvestermatrix(y,x),v);
                   1452:   for (i=2; i<dy+2; i++) z[i]=v[lz-i+2];
                   1453:   z = normalizepol_i(z, dy+2); tetpil = avma;
                   1454:   return gerepile(av,tetpil,gcopy(z));
                   1455: }
                   1456:
                   1457: static GEN
                   1458: polinvmod(GEN x, GEN y)
                   1459: {
                   1460:   long av,av1,tx,vx=varn(x),vy=varn(y);
                   1461:   GEN u,v,d,p1;
                   1462:
                   1463:   while (vx!=vy)
                   1464:   {
                   1465:     if (vx > vy)
                   1466:     {
                   1467:       d=cgetg(3,t_RFRAC);
                   1468:       d[1]=(long)polun[vx];
                   1469:       d[2]=lcopy(x); return d;
                   1470:     }
                   1471:     if (lgef(x)!=3) err(talker,"non-invertible polynomial in polinvmod");
                   1472:     x=(GEN)x[2]; vx=gvar(x);
                   1473:   }
                   1474:   tx=typ(x);
                   1475:   if (tx==t_POL)
                   1476:   {
                   1477:     if (isinexactfield(x) || isinexactfield(y))
                   1478:       return polinvinexact(x,y);
                   1479:
                   1480:     av=avma; d=subresext(x,y,&u,&v);
                   1481:     if (gcmp0(d)) err(talker,"non-invertible polynomial in polinvmod");
                   1482:     if (typ(d)==t_POL && varn(d)==vx)
                   1483:     {
                   1484:       if (lgef(d)>3) err(talker,"non-invertible polynomial in polinvmod");
                   1485:       d=(GEN)d[2];
                   1486:     }
                   1487:     av1=avma; return gerepile(av,av1,gdiv(u,d));
                   1488:   }
                   1489:   if (!is_rfrac_t(tx)) err(typeer,"polinvmod");
                   1490:   av=avma; p1=gmul((GEN)x[1],polinvmod((GEN)x[2],y));
                   1491:   av1=avma; return gerepile(av,av1,gmod(p1,y));
                   1492: }
                   1493:
                   1494: GEN
                   1495: gbezout(GEN x, GEN y, GEN *u, GEN *v)
                   1496: {
                   1497:   long tx=typ(x),ty=typ(y);
                   1498:
                   1499:   if (tx==t_INT && ty==t_INT) return bezout(x,y,u,v);
                   1500:   if (!is_extscalar_t(tx) || !is_extscalar_t(ty)) err(typeer,"gbezout");
                   1501:   return bezoutpol(x,y,u,v);
                   1502: }
                   1503:
                   1504: GEN
                   1505: vecbezout(GEN x, GEN y)
                   1506: {
                   1507:   GEN z=cgetg(4,t_VEC);
                   1508:   z[3]=(long)gbezout(x,y,(GEN*)(z+1),(GEN*)(z+2));
                   1509:   return z;
                   1510: }
                   1511:
                   1512: GEN
                   1513: vecbezoutres(GEN x, GEN y)
                   1514: {
                   1515:   GEN z=cgetg(4,t_VEC);
                   1516:   z[3]=(long)subresext(x,y,(GEN*)(z+1),(GEN*)(z+2));
                   1517:   return z;
                   1518: }
                   1519:
                   1520: /*******************************************************************/
                   1521: /*                                                                 */
                   1522: /*                    CONTENU ET PARTIE PRIMITIVE                  */
                   1523: /*                                                                 */
                   1524: /*******************************************************************/
                   1525:
                   1526: GEN
                   1527: content(GEN x)
                   1528: {
                   1529:   long av,tetpil,lx,i,tx=typ(x);
                   1530:   GEN p1,p2;
                   1531:
                   1532:   if (is_scalar_t(tx))
                   1533:     return tx==t_POLMOD? content((GEN)x[2]): gcopy(x);
                   1534:   av = avma;
                   1535:   switch(tx)
                   1536:   {
                   1537:     case t_RFRAC: case t_RFRACN:
                   1538:       p1=content((GEN)x[1]);
                   1539:       p2=content((GEN)x[2]); tetpil=avma;
                   1540:       return gerepile(av,tetpil,gdiv(p1,p2));
                   1541:
                   1542:     case t_VEC: case t_COL: case t_MAT:
                   1543:       lx = lg(x); if (lx==1) return gun;
                   1544:       p1=content((GEN)x[1]);
                   1545:       for (i=2; i<lx; i++) p1 = ggcd(p1,content((GEN)x[i]));
                   1546:       return gerepileupto(av,p1);
                   1547:
                   1548:     case t_POL:
                   1549:       if (!signe(x)) return gzero;
                   1550:       lx = lgef(x); break;
                   1551:     case t_SER:
                   1552:       if (!signe(x)) return gzero;
                   1553:       lx = lg(x); break;
                   1554:     case t_QFR: case t_QFI:
                   1555:       lx = 4; break;
                   1556:
                   1557:     default: err(typeer,"content");
                   1558:   }
                   1559:   for (i=lontyp[tx]; i<lx; i++)
                   1560:     if (typ(x[i]) != t_INT) break;
                   1561:   lx--; p1=(GEN)x[lx];
                   1562:   if (i > lx)
                   1563:   { /* integer coeffs */
                   1564:     while (lx>lontyp[tx])
                   1565:     {
                   1566:       lx--; p1=mppgcd(p1,(GEN)x[lx]);
                   1567:       if (is_pm1(p1)) { avma=av; return gun; }
                   1568:     }
                   1569:   }
                   1570:   else
                   1571:   {
                   1572:     while (lx>lontyp[tx])
                   1573:     {
                   1574:       lx--; p1=ggcd(p1,(GEN)x[lx]);
                   1575:     }
                   1576:     if (isinexactreal(p1)) { avma=av; return gun; }
                   1577:   }
                   1578:   return av==avma? gcopy(p1): gerepileupto(av,p1);
                   1579: }
                   1580:
                   1581: /*******************************************************************/
                   1582: /*                                                                 */
                   1583: /*                         SOUS RESULTANT                          */
                   1584: /*                                                                 */
                   1585: /*******************************************************************/
                   1586: GEN
                   1587: gdivexact(GEN x, GEN y)
                   1588: {
                   1589:   long i,lx;
                   1590:   GEN z;
                   1591:   if (gcmp1(y)) return x;
                   1592:   switch(typ(x))
                   1593:   {
                   1594:     case t_INT:
                   1595:       if (typ(y)==t_INT) return divii(x,y);
                   1596:       if (!signe(x)) return gzero;
                   1597:       break;
                   1598:     case t_INTMOD:
                   1599:     case t_POLMOD: return gmul(x,ginv(y));
                   1600:     case t_POL:
                   1601:       switch(typ(y))
                   1602:       {
                   1603:         case t_INTMOD:
                   1604:         case t_POLMOD: return gmul(x,ginv(y));
                   1605:         case t_POL:
                   1606:           if (varn(x)==varn(y)) return poldivres(x,y, ONLY_DIVIDES_EXACT);
                   1607:       }
                   1608:       lx = lgef(x); z = cgetg(lx,t_POL);
                   1609:       for (i=2; i<lx; i++) z[i]=(long)gdivexact((GEN)x[i],y);
                   1610:       z[1]=x[1]; return z;
                   1611:   }
                   1612:   if (DEBUGLEVEL) err(warner,"missing case in gdivexact");
                   1613:   return gdiv(x,y);
                   1614: }
                   1615:
                   1616: static GEN
                   1617: init_resultant(GEN x, GEN y)
                   1618: {
                   1619:   long tx,ty;
                   1620:   if (gcmp0(x) || gcmp0(y)) return gzero;
                   1621:   tx = typ(x); ty = typ(y);
                   1622:   if (is_scalar_t(tx) || is_scalar_t(ty))
                   1623:   {
                   1624:     if (tx==t_POL) return gpuigs(y,lgef(x)-3);
                   1625:     if (ty==t_POL) return gpuigs(x,lgef(y)-3);
                   1626:     return gun;
                   1627:   }
                   1628:   if (tx!=t_POL || ty!=t_POL) err(typeer,"subresall");
                   1629:   if (varn(x)==varn(y)) return NULL;
                   1630:   return (varn(x)<varn(y))? gpuigs(y,lgef(x)-3): gpuigs(x,lgef(y)-3);
                   1631: }
                   1632:
                   1633: /* return coefficients s.t x = x_0 X^n + ... + x_n */
                   1634: static GEN
                   1635: revpol(GEN x)
                   1636: {
                   1637:   long i,n = lgef(x)-3;
                   1638:   GEN y = cgetg(n+3,t_POL);
                   1639:   y[1] = x[1]; x += 2; y += 2;
                   1640:   for (i=0; i<=n; i++) y[i] = x[n-i];
                   1641:   return y;
                   1642: }
                   1643:
                   1644: /* assume dx >= dy, y non constant */
                   1645: GEN
                   1646: pseudorem(GEN x, GEN y)
                   1647: {
                   1648:   long av = avma, av2,lim, vx = varn(x),dx,dy,dz,i,lx, p;
                   1649:
                   1650:   if (!signe(y)) err(talker,"euclidean division by zero (pseudorem)");
                   1651:   (void)new_chunk(2);
                   1652:   dx=lgef(x)-3; x = revpol(x);
                   1653:   dy=lgef(y)-3; y = revpol(y); dz=dx-dy; p = dz+1;
                   1654:   av2 = avma; lim = stack_lim(av2,1);
                   1655:   for (;;)
                   1656:   {
                   1657:     x[0] = lneg((GEN)x[0]); p--;
                   1658:     for (i=1; i<=dy; i++)
                   1659:       x[i] = ladd(gmul((GEN)y[0], (GEN)x[i]), gmul((GEN)x[0],(GEN)y[i]));
                   1660:     for (   ; i<=dx; i++)
                   1661:       x[i] = lmul((GEN)y[0], (GEN)x[i]);
                   1662:     do { x++; dx--; } while (dx >= 0 && gcmp0((GEN)x[0]));
                   1663:     if (dx < dy) break;
                   1664:     if (low_stack(lim,stack_lim(av2,1)))
                   1665:     {
                   1666:       if(DEBUGMEM>1) err(warnmem,"pseudorem dx = %ld >= %ld",dx,dy);
                   1667:       gerepilemanycoeffs(av2,x,dx+1);
                   1668:     }
                   1669:   }
                   1670:   if (dx < 0) return zeropol(vx);
                   1671:   lx = dx+3; x -= 2;
                   1672:   x[0]=evaltyp(t_POL) | evallg(lx);
                   1673:   x[1]=evalsigne(1) | evalvarn(vx) | evallgef(lx);
                   1674:   x = revpol(x) - 2;
                   1675:   return gerepileupto(av, gmul(x, gpowgs((GEN)y[0], p)));
                   1676: }
                   1677:
                   1678: /* Si sol != NULL:
                   1679:  *   met dans *sol le dernier polynome non nul de la polynomial remainder
                   1680:  *   sequence si elle a ete effectuee, 0 sinon
                   1681:  */
                   1682: GEN
                   1683: subresall(GEN u, GEN v, GEN *sol)
                   1684: {
                   1685:   long degq,av,av2,lim,tetpil,dx,dy,du,dv,dr,signh;
                   1686:   GEN g,h,r,p1,p2,p3,p4;
                   1687:
                   1688:   if (sol) *sol=gzero;
                   1689:   if ((r = init_resultant(u,v))) return r;
                   1690:
                   1691:   if (isinexactfield(u) || isinexactfield(v)) return resultant2(u,v);
                   1692:   dx=lgef(u); dy=lgef(v); signh=1;
                   1693:   if (dx<dy)
                   1694:   {
                   1695:     p1=u; u=v; v=p1; du=dx; dx=dy; dy=du;
                   1696:     if ((dx&1) == 0 && (dy&1) == 0) signh = -signh;
                   1697:   }
                   1698:   if (dy==3) return gpowgs((GEN)v[2],dx-3);
                   1699:   av=avma;
                   1700:   p3=content(u); if (gcmp1(p3)) p3=NULL; else u=gdiv(u,p3);
                   1701:   p4=content(v); if (gcmp1(p4)) p4=NULL; else v=gdiv(v,p4);
                   1702:   g=gun; h=gun; av2 = avma; lim = stack_lim(av2,1);
                   1703:   for(;;)
                   1704:   {
                   1705:     r = pseudorem(u,v); dr = lgef(r);
                   1706:     if (dr==2)
                   1707:     {
                   1708:       if (sol) {avma = (long)(r+2); *sol=gerepileupto(av,v);} else avma = av;
                   1709:       return gzero;
                   1710:     }
                   1711:     du=lgef(u); dv=lgef(v);
                   1712:     degq=du-dv; u=v;
                   1713:     p1 = g; g = leading_term(u);
                   1714:     switch(degq)
                   1715:     {
                   1716:       case 0: break;
                   1717:       case 1:
                   1718:         p1 = gmul(h,p1); h = g; break;
                   1719:       default:
                   1720:         p1 = gmul(gpuigs(h,degq),p1);
                   1721:         h = gdivexact(gpuigs(g,degq), gpuigs(h,degq-1));
                   1722:     }
                   1723:     if ((du&1) == 0 && (dv&1) == 0) signh = -signh;
                   1724:     v = gdivexact(r,p1);
                   1725:     if (dr==3) break;
                   1726:     if (low_stack(lim,stack_lim(av2,1)))
                   1727:     {
                   1728:       GEN *gptr[4]; gptr[0]=&u; gptr[1]=&v; gptr[2]=&g; gptr[3]=&h;
                   1729:       if(DEBUGMEM>1) err(warnmem,"subresall, dr = %ld",dr);
                   1730:       gerepilemany(av2,gptr,4);
                   1731:     }
                   1732:   }
                   1733:   if (dv==4) { tetpil=avma; p2=gcopy((GEN)v[2]); }
                   1734:   else
                   1735:   {
                   1736:     if (dv == 3) err(bugparier,"subres");
                   1737:     p1=gpuigs((GEN)v[2],dv-3); p2=gpuigs(h,dv-4);
                   1738:     tetpil=avma; p2=gdiv(p1,p2);
                   1739:   }
                   1740:   if (p3) { p1=gpuigs(p3,dy-3); tetpil=avma; p2=gmul(p2,p1); }
                   1741:   if (p4) { p1=gpuigs(p4,dx-3); tetpil=avma; p2=gmul(p2,p1); }
                   1742:   if (signh<0) { tetpil=avma; p2=gneg(p2); }
                   1743:   {
                   1744:     GEN *gptr[2]; gptr[0]=&p2; if (sol) { *sol=gcopy(u); gptr[1]=sol; }
                   1745:     gerepilemanysp(av,tetpil,gptr,sol?2:1);
                   1746:     return p2;
                   1747:   }
                   1748: }
                   1749:
                   1750: static GEN
                   1751: scalar_res(GEN x, GEN y, GEN *U, GEN *V)
                   1752: {
                   1753:   long dx=lgef(x)-4;
                   1754:   *V=gpuigs(y,dx); *U=gzero; return gmul(y,*V);
                   1755: }
                   1756:
                   1757: /* calcule U et V tel que Ux+By=resultant(x,y) */
                   1758: GEN
                   1759: subresext(GEN x, GEN y, GEN *U, GEN *V)
                   1760: {
                   1761:   long degq,av,tetpil,tx,ty,dx,dy,du,dv,dr,signh;
                   1762:   GEN z,g,h,r,p1,p2,p3,p4,u,v,lpu,um1,uze, *gptr[2];
                   1763:
                   1764:   if (gcmp0(x) || gcmp0(y)) { *U = *V = gzero; return gzero; }
                   1765:   tx=typ(x); ty=typ(y);
                   1766:   if (is_scalar_t(tx) || is_scalar_t(ty))
                   1767:   {
                   1768:     if (tx==t_POL) return scalar_res(x,y,U,V);
                   1769:     if (ty==t_POL) return scalar_res(y,x,V,U);
                   1770:     *U=ginv(x); *V=gzero; return gun;
                   1771:   }
                   1772:   if (tx!=t_POL || ty!=t_POL) err(typeer,"subresext");
                   1773:   if (varn(x)!=varn(y))
                   1774:     return (varn(x)<varn(y))? scalar_res(x,y,U,V)
                   1775:                             : scalar_res(y,x,V,U);
                   1776:   dx=lgef(x); dy=lgef(y); signh=1;
                   1777:   if (dx<dy)
                   1778:   {
                   1779:     GEN *W = U; U=V; V=W;
                   1780:     du=dx; dx=dy; dy=du; p1=x; x=y; y=p1;
                   1781:     if ((dx&1) == 0 && (dy&1) == 0) signh = -signh;
                   1782:   }
                   1783:   if (dy==3)
                   1784:   {
                   1785:     *V=gpuigs((GEN)y[2],dx-4);
                   1786:     *U=gzero; return gmul(*V,(GEN)y[2]);
                   1787:   }
                   1788:   av=avma;
                   1789:   p3=content(x); if (gcmp1(p3)) {p3 = NULL; u=x; } else u=gdiv(x,p3);
                   1790:   p4=content(y); if (gcmp1(p4)) {p4 = NULL; v=y; } else v=gdiv(y,p4);
                   1791:   g=gun; h=gun; um1=gun; uze=gzero;
                   1792:   for(;;)
                   1793:   {
                   1794:     du=lgef(u); dv=lgef(v); degq=du-dv;
                   1795:     lpu=gpuigs((GEN)v[dv-1],degq+1);
                   1796:     p1=gmul(lpu,u); p2=poldivres(p1,v,&r);
                   1797:     dr=lgef(r); if (dr==2) { *U=gzero; *V=gzero; avma=av; return gzero; }
                   1798:
                   1799:     p1=gsub(gmul(lpu,um1),gmul(p2,uze));
                   1800:     um1=uze; uze=p1; u=v;
                   1801:     p1 = g; g = leading_term(u);
                   1802:     switch(degq)
                   1803:     {
                   1804:       case 0: break;
                   1805:       case 1: p1 = gmul(h,p1); h = g; break;
                   1806:       default:
                   1807:         p1 = gmul(gpuigs(h,degq),p1);
                   1808:         h = gdivexact(gpuigs(g,degq), gpuigs(h,degq-1));
                   1809:     }
                   1810:     if ((du & 1) == 0 && (dv & 1) == 0) signh= -signh;
                   1811:     v=gdivexact(r,p1); uze=gdivexact(uze,p1);
                   1812:     if (dr==3) break;
                   1813:   }
                   1814:
                   1815:   p2=(dv==4)?gun:gpuigs(gdiv((GEN)v[2],h),dv-4);
                   1816:   if (p3) p2 = gmul(p2,gpuigs(p3,dy-3));
                   1817:   if (p4) p2 = gmul(p2,gpuigs(p4,dx-3));
                   1818:   if (signh<0) p2=gneg_i(p2);
                   1819:   p3 = p3? gdiv(p2,p3): p2;
                   1820:
                   1821:   tetpil=avma; z=gmul((GEN)v[2],p2); uze=gmul(uze,p3);
                   1822:   gptr[0]=&z; gptr[1]=&uze; gerepilemanysp(av,tetpil,gptr,2);
                   1823:
                   1824:   av=avma; p1 = gadd(z, gneg(gmul(uze,x))); tetpil = avma;
                   1825:   if (!poldivis(p1,y,&p1)) err(bugparier,"subresext");
                   1826:   *U=uze; *V=gerepile(av,tetpil,p1); return z;
                   1827: }
                   1828:
                   1829: static GEN
                   1830: scalar_bezout(GEN x, GEN y, GEN *U, GEN *V)
                   1831: {
                   1832:   long v = varn(x);
                   1833:   *U=gzero; *V=gdiv(polun[v],y); return polun[v];
                   1834: }
                   1835:
                   1836: static GEN
                   1837: zero_bezout(GEN y, GEN *U, GEN *V)
                   1838: {
                   1839:   GEN x=content(y);
                   1840:   *U=gzero; *V = gdiv(polun[varn(y)],x); return gmul(y,*V);
                   1841: }
                   1842:
                   1843: /* calcule U et V tel que Ux+Vy=GCD(x,y) par le sous-resultant */
                   1844: GEN
                   1845: bezoutpol(GEN x, GEN y, GEN *U, GEN *V)
                   1846: {
                   1847:   long degq,av,tetpil,tx,ty,dx,dy,du,dv,dr;
                   1848:   GEN g,h,r,p1,p2,p3,p4,u,v,lpu,um1,uze,vze,xprim,yprim;
                   1849:   GEN *gptr[3];
                   1850:
                   1851:   if (gcmp0(x)) return zero_bezout(y,U,V);
                   1852:   if (gcmp0(y)) return zero_bezout(x,V,U);
                   1853:   tx=typ(x); ty=typ(y); av=avma;
                   1854:   if (is_scalar_t(tx) || is_scalar_t(ty))
                   1855:   {
                   1856:     if (tx==t_POL) return scalar_bezout(x,y,U,V);
                   1857:     if (ty==t_POL) return scalar_bezout(y,x,V,U);
                   1858:     *U=ginv(x); *V=gzero; return polun[0];
                   1859:   }
                   1860:   if (tx!=t_POL || ty!=t_POL) err(typeer,"bezoutpol");
                   1861:   if (varn(x)!=varn(y))
                   1862:     return (varn(x)<varn(y))? scalar_bezout(x,y,U,V)
                   1863:                             : scalar_bezout(y,x,V,U);
                   1864:   dx=lgef(x); dy=lgef(y);
                   1865:   if (dx<dy)
                   1866:   {
                   1867:     GEN *W=U; U=V; V=W;
                   1868:     p1=x; x=y; y=p1; du=dx; dx=dy; dy=du;
                   1869:   }
                   1870:   if (dy==3) return scalar_bezout(x,y,U,V);
                   1871:
                   1872:   p3=content(x); u=gdiv(x,p3);
                   1873:   p4=content(y); v=gdiv(y,p4);
                   1874:   xprim=u; yprim=v; g=gun; h=gun; um1=gun; uze=gzero;
                   1875:   for(;;)
                   1876:   {
                   1877:     du=lgef(u); dv=lgef(v); degq=du-dv;
                   1878:     lpu=gpuigs((GEN)v[dv-1],degq+1);
                   1879:     p1=gmul(lpu,u); p2=poldivres(p1,v,&r);
                   1880:     dr=lgef(r); if (dr<=2) break;
                   1881:     p1=gsub(gmul(lpu,um1),gmul(p2,uze)); um1=uze; uze=p1;
                   1882:
                   1883:     u=v; p1 = g; g  = leading_term(u);
                   1884:     switch(degq)
                   1885:     {
                   1886:       case 0: break;
                   1887:       case 1:
                   1888:         p1 = gmul(h,p1); h = g; break;
                   1889:       default:
                   1890:         p1 = gmul(gpuigs(h,degq), p1);
                   1891:         h = gdiv(gpuigs(g,degq), gpuigs(h,degq-1));
                   1892:     }
                   1893:     v=gdiv(r,p1); uze=gdiv(uze,p1);
                   1894:     if (dr==3) break;
                   1895:   }
                   1896:   if (!poldivis(gsub(v,gmul(uze,xprim)),yprim, &vze))
                   1897:     err(warner,"non-exact computation in bezoutpol");
                   1898:   uze=gdiv(uze,p3); vze=gdiv(vze,p4); p1=ginv(content(v));
                   1899:
                   1900:   tetpil=avma; uze=gmul(uze,p1); vze=gmul(vze,p1); p1=gmul(v,p1);
                   1901:   gptr[0]=&uze; gptr[1]=&vze; gptr[2]=&p1;
                   1902:   gerepilemanysp(av,tetpil,gptr,3);
                   1903:   *U=uze; *V=vze; return p1;
                   1904: }
                   1905:
                   1906:
                   1907:
                   1908: /*******************************************************************/
                   1909: /*                                                                 */
                   1910: /*               RESULTANT PAR L'ALGORITHME DE DUCOS               */
                   1911: /*                                                                 */
                   1912: /*******************************************************************/
                   1913: GEN addshiftw(GEN x, GEN y, long d);
                   1914:
                   1915: static GEN
                   1916: reductum(GEN P)
                   1917: {
                   1918:   if (signe(P)==0) return P;
                   1919:   return normalizepol_i(dummycopy(P),lgef(P)-1);
                   1920: }
                   1921:
                   1922: static GEN
                   1923: Lazard(GEN x, GEN y, long n)
                   1924: {
                   1925:   long a, b;
                   1926:   GEN c;
                   1927:
                   1928:   if (n==1) return x;
                   1929:   a=1; while (n >= (b=a+a)) a=b;
                   1930:   c=x; n-=a;
                   1931:   while (a>1)
                   1932:   {
                   1933:     a>>=1; c=gdivexact(gsqr(c),y);
                   1934:     if (n>=a) { c=gdivexact(gmul(c,x),y); n -= a; }
                   1935:   }
                   1936:   return c;
                   1937: }
                   1938:
                   1939: static GEN
                   1940: Lazard2(GEN F, GEN x, GEN y, long n)
                   1941: {
                   1942:   if (n<=1) return F;
                   1943:   x = Lazard(x,y,n-1); return gdivexact(gmul(x,F),y);
                   1944: }
                   1945:
                   1946: static GEN
                   1947: addshift(GEN x, GEN y)
                   1948: {
                   1949:   long v = varn(x);
                   1950:   if (!signe(x)) return y;
                   1951:   x = addshiftw(x,y,1);
                   1952:   setvarn(x,v); return x;
                   1953: }
                   1954:
                   1955: static GEN
                   1956: nextSousResultant(GEN P, GEN Q, GEN Z, GEN s)
                   1957: {
                   1958:   GEN p0, q0, z0, H, A;
                   1959:   long p, q, j, av, lim, v = varn(P);
                   1960:
                   1961:   z0 = leading_term(Z);
                   1962:   p = degree(P); p0 = leading_term(P); P = reductum(P);
                   1963:   q = degree(Q); q0 = leading_term(Q); Q = reductum(Q);
                   1964:
                   1965:   av = avma; lim = stack_lim(av,1);
                   1966:   H = gneg(reductum(Z));
                   1967:   A = gmul((GEN)P[q+2],H);
                   1968:   for (j = q+1; j < p; j++)
                   1969:   {
                   1970:     H = (degree(H) == q-1) ?
                   1971:       addshift(reductum(H), gdivexact(gmul(gneg((GEN)H[q+1]),Q), q0)) :
                   1972:       addshift(H, zeropol(v));
                   1973:     A = gadd(A,gmul((GEN)P[j+2],H));
                   1974:     if (low_stack(lim,stack_lim(av,1)))
                   1975:     {
                   1976:       GEN *gptr[2]; gptr[0]=&A; gptr[1]=&H;
                   1977:       if(DEBUGMEM>1) err(warnmem,"nextSousResultant j = %ld/%ld",j,p);
                   1978:       gerepilemany(av,gptr,2);
                   1979:     }
                   1980:   }
                   1981:   P = normalizepol_i(P, q+2);
                   1982:   A = gdivexact(gadd(A,gmul(z0,P)), p0);
                   1983:   A = (degree(H) == q-1) ?
                   1984:     gadd(gmul(q0,addshift(reductum(H),A)), gmul(gneg((GEN)H[q+1]),Q)) :
                   1985:     gmul(q0, addshift(H,A));
                   1986:   return gdivexact(A, ((p-q)&1)? s: gneg(s));
                   1987: }
                   1988:
                   1989: GEN
                   1990: resultantducos(GEN P, GEN Q)
                   1991: {
                   1992:   long delta, av=avma, tetpil, lim = stack_lim(av,1);
                   1993:   GEN Z, s;
                   1994:
                   1995:   if ((Z = init_resultant(P,Q))) return Z;
                   1996:   delta = degree(P) - degree(Q);
                   1997:   if (delta < 0)
                   1998:   {
                   1999:     Z = ((degree(P)&1) && (degree(Q)&1)) ? gneg(Q) : Q;
                   2000:     Q = P; P = Z; delta = -delta;
                   2001:   }
                   2002:   s = gun;
                   2003:   if (degree(Q) > 0)
                   2004:   {
                   2005:     s = gpuigs(leading_term(Q),delta);
                   2006:     Z = Q;
                   2007:     Q = pseudorem(P, gneg(Q));
                   2008:     P = Z;
                   2009:     while(degree(Q) > 0)
                   2010:     {
                   2011:       if (low_stack(lim,stack_lim(av,1)))
                   2012:       {
                   2013:         GEN *gptr[2]; gptr[0]=&P; gptr[1]=&Q;
                   2014:         if(DEBUGMEM>1) err(warnmem,"resultantducos, deg Q = %ld",degree(Q));
                   2015:         gerepilemany(av,gptr,2); s = leading_term(P);
                   2016:       }
                   2017:       delta = degree(P) - degree(Q);
                   2018:       Z = Lazard2(Q, leading_term(Q), s, delta);
                   2019:       Q = nextSousResultant(P, Q, Z, s);
                   2020:       P = Z;
                   2021:       s = leading_term(P);
                   2022:     }
                   2023:   }
                   2024:   if (!signe(Q)) { avma = av; return gzero; }
                   2025:   s = Lazard(leading_term(Q), s, degree(P));
                   2026:   tetpil = avma; return gerepile(av,tetpil,gcopy(s));
                   2027: }
                   2028:
                   2029: /*******************************************************************/
                   2030: /*                                                                 */
                   2031: /*               RESULTANT PAR MATRICE DE SYLVESTER                */
                   2032: /*                                                                 */
                   2033: /*******************************************************************/
                   2034: GEN
                   2035: sylvestermatrix_i(GEN x, GEN y)
                   2036: {
                   2037:   long d,dx,dy,i,j;
                   2038:   GEN p1,p2;
                   2039:
                   2040:   dx=lgef(x)-3; dy=lgef(y)-3; d=dx+dy;
                   2041:   p1=cgetg(d+1,t_MAT);
                   2042:   for (j=1; j<=dy; j++)
                   2043:   {
                   2044:     p2=cgetg(d+1,t_COL); p1[j]=(long)p2;
                   2045:     for (i=1; i<j; i++) p2[i]=zero;
                   2046:     for (   ; i<=j+dx; i++) p2[i]=x[dx-i+j+2];
                   2047:     for (   ; i<=d; i++) p2[i]=zero;
                   2048:   }
                   2049:   for (j=1; j<=dx; j++)
                   2050:   {
                   2051:     p2=cgetg(d+1,t_COL); p1[j+dy]=(long)p2;
                   2052:     for (i=1; i<j; i++) p2[i]=zero;
                   2053:     for (   ; i<=j+dy; i++) p2[i]=y[dy-i+j+2];
                   2054:     for (   ; i<=d; i++) p2[i]=zero;
                   2055:   }
                   2056:   return p1;
                   2057: }
                   2058:
                   2059: GEN
                   2060: sylvestermatrix(GEN x, GEN y)
                   2061: {
                   2062:   long i,j,lx;
                   2063:   if (typ(x)!=t_POL || typ(y)!=t_POL) err(typeer,"sylvestermatrix");
                   2064:   if (varn(x) != varn(y))
                   2065:     err(talker,"not the same variables in sylvestermatrix");
                   2066:   x = sylvestermatrix_i(x,y); lx = lg(x);
                   2067:   for (i=1; i<lx; i++)
                   2068:     for (j=1; j<lx; j++) coeff(x,i,j) = lcopy(gcoeff(x,i,j));
                   2069:   return x;
                   2070: }
                   2071:
                   2072: GEN
                   2073: resultant2(GEN x, GEN y)
                   2074: {
                   2075:   long av;
                   2076:   GEN r;
                   2077:   if ((r = init_resultant(x,y))) return r;
                   2078:   av = avma; return gerepileupto(av,det(sylvestermatrix_i(x,y)));
                   2079: }
                   2080:
                   2081: static GEN
                   2082: fix_pol(GEN x, long v, long *mx)
                   2083: {
                   2084:   long vx;
                   2085:   GEN p1;
                   2086:
                   2087:   if (typ(x) == t_POL)
                   2088:   {
                   2089:     vx = varn(x);
                   2090:     if (vx)
                   2091:     {
                   2092:       if (v>=vx) return gsubst(x,v,polx[0]);
                   2093:       p1 = cgetg(3,t_POL);
                   2094:       p1[1] = evalvarn(0)|evalsigne(signe(x))|evallgef(3);
                   2095:       p1[2] = (long)x; return p1;
                   2096:     }
                   2097:     if (v)
                   2098:     {
                   2099:       *mx = 1;
                   2100:       return gsubst(gsubst(x,0,polx[MAXVARN]),v,polx[0]);
                   2101:     }
                   2102:   }
                   2103:   return x;
                   2104: }
                   2105:
                   2106: /* resultant of x and y with respect to variable v, or with respect to their
                   2107:  * main variable if v < 0.
                   2108:  */
                   2109: GEN
                   2110: polresultant0(GEN x, GEN y, long v, long flag)
                   2111: {
                   2112:   long av = avma, m = 0;
                   2113:
                   2114:   if (v >= 0)
                   2115:   {
                   2116:     x = fix_pol(x,v, &m);
                   2117:     y = fix_pol(y,v, &m);
                   2118:   }
                   2119:   switch(flag)
                   2120:   {
                   2121:     case 0: x=subresall(x,y,NULL); break;
                   2122:     case 1: x=resultant2(x,y); break;
                   2123:     case 2: x=resultantducos(x,y); break;
                   2124:     default: err(flagerr,"polresultant");
                   2125:   }
                   2126:   if (m) x = gsubst(x,MAXVARN,polx[0]);
                   2127:   return gerepileupto(av,x);
                   2128: }
                   2129:
                   2130: /*******************************************************************/
                   2131: /*                                                                 */
                   2132: /*           P.G.C.D PAR L'ALGORITHME DU SOUS RESULTANT            */
                   2133: /*                                                                 */
                   2134: /*******************************************************************/
                   2135:
                   2136: GEN
                   2137: srgcd(GEN x, GEN y)
                   2138: {
                   2139:   long av,av1,tetpil,tx=typ(x),ty=typ(y),dx,dy,vx,lim;
                   2140:   GEN d,g,h,p1,p2,u,v;
                   2141:
                   2142:   if (!signe(y)) return gcopy(x);
                   2143:   if (!signe(x)) return gcopy(y);
                   2144:   if (is_scalar_t(tx) || is_scalar_t(ty)) return gun;
                   2145:   if (tx!=t_POL || ty!=t_POL) err(typeer,"srgcd");
                   2146:   vx=varn(x); if (vx!=varn(y)) return gun;
                   2147:   if (ismonome(x)) return gcdmonome(x,y);
                   2148:   if (ismonome(y)) return gcdmonome(y,x);
                   2149:   if (isrational(x) && isrational(y)) return modulargcd(x,y);
                   2150:
                   2151:   av=avma;
                   2152:   if (issimplefield(x) || issimplefield(y)) x = polgcdnun(x,y);
                   2153:   else
                   2154:   {
                   2155:     dx=lgef(x); dy=lgef(y);
                   2156:     if (dx<dy) { p1=x; x=y; y=p1; tx=dx; dx=dy; dy=tx; }
                   2157:     p1=content(x); p2=content(y); d=ggcd(p1,p2);
                   2158:
                   2159:     tetpil=avma; d=gmul(d,polun[vx]);
                   2160:     if (dy==3) return gerepile(av,tetpil,d);
                   2161:
                   2162:     av1=avma; lim=stack_lim(av1,1);
                   2163:     u=gdiv(x,p1); v=gdiv(y,p2); g=h=gun;
                   2164:     for(;;)
                   2165:     {
                   2166:       GEN r = pseudorem(u,v);
                   2167:       long degq, du, dv, dr=lgef(r);
                   2168:
                   2169:       if (dr<=3)
                   2170:       {
                   2171:         if (gcmp0(r)) break;
                   2172:         avma=av1; return gerepile(av,tetpil,d);
                   2173:       }
                   2174:       if (DEBUGLEVEL > 9) fprintferr("srgcd: dr = %ld\n", dr);
                   2175:       du=lgef(u); dv=lgef(v); degq=du-dv; u=v;
                   2176:       switch(degq)
                   2177:       {
                   2178:         case 0:
                   2179:           v = gdiv(r,g);
                   2180:           g = leading_term(u);
                   2181:           break;
                   2182:         case 1:
                   2183:           v = gdiv(r,gmul(h,g));
                   2184:           h = g = leading_term(u);
                   2185:           break;
                   2186:         default:
                   2187:           v = gdiv(r,gmul(gpuigs(h,degq),g));
                   2188:           g = leading_term(u);
                   2189:           h = gdiv(gpuigs(g,degq), gpuigs(h,degq-1));
                   2190:       }
                   2191:       if (low_stack(lim, stack_lim(av1,1)))
                   2192:       {
                   2193:         GEN *gptr[4]; gptr[0]=&u; gptr[1]=&v; gptr[2]=&g; gptr[3]=&h;
                   2194:         if(DEBUGMEM>1) err(warnmem,"srgcd");
                   2195:         gerepilemany(av1,gptr,4);
                   2196:       }
                   2197:     }
                   2198:     p1 = content(v); if (!gcmp1(p1)) v = gdiv(v,p1);
                   2199:     x = gmul(d,v);
                   2200:   }
                   2201:
                   2202:   if (typ(x)!=t_POL) x = gmul(polun[vx],x);
                   2203:   else
                   2204:   {
                   2205:     p1=leading_term(x); ty=typ(p1);
                   2206:     if ((is_frac_t(ty) || is_intreal_t(ty)) && gsigne(p1)<0) x = gneg(x);
                   2207:   }
                   2208:   return gerepileupto(av,x);
                   2209: }
                   2210:
                   2211: GEN qf_disc(GEN x, GEN y, GEN z);
                   2212:
                   2213: GEN
                   2214: poldisc0(GEN x, long v)
                   2215: {
                   2216:   long av,tx=typ(x),i;
                   2217:   GEN z,p1,p2;
                   2218:
                   2219:   switch(tx)
                   2220:   {
                   2221:     case t_POL:
                   2222:       if (gcmp0(x)) return gzero;
                   2223:       av = avma; i = 0;
                   2224:       if (v >= 0 && v != varn(x)) x = fix_pol(x,v, &i);
                   2225:       p1 = subres(x, derivpol(x));
                   2226:       p2 = leading_term(x); if (!gcmp1(p2)) p1 = gdiv(p1,p2);
                   2227:       if ((lgef(x)-3) & 2) p1 = gneg(p1);
                   2228:       if (i) p1 = gsubst(p1, MAXVARN, polx[0]);
                   2229:       return gerepileupto(av,p1);
                   2230:
                   2231:     case t_COMPLEX:
                   2232:       return stoi(-4);
                   2233:
                   2234:     case t_QUAD: case t_POLMOD:
                   2235:       return poldisc0((GEN)x[1], v);
                   2236:
                   2237:     case t_QFR: case t_QFI:
                   2238:       av = avma; return gerepileuptoint(av, qf_disc(x,NULL,NULL));
                   2239:
                   2240:     case t_VEC: case t_COL: case t_MAT:
                   2241:       i=lg(x); z=cgetg(i,tx);
                   2242:       for (i--; i; i--) z[i]=(long)poldisc0((GEN)x[i], v);
                   2243:       return z;
                   2244:   }
                   2245:   err(typeer,"discsr");
                   2246:   return NULL; /* not reached */
                   2247: }
                   2248:
                   2249: GEN
                   2250: discsr(GEN x)
                   2251: {
                   2252:   return poldisc0(x, -1);
                   2253: }
                   2254:
                   2255: GEN
                   2256: reduceddiscsmith(GEN pol)
                   2257: {
                   2258:   long av=avma,tetpil,i,j,n;
                   2259:   GEN polp,alpha,p1,m;
                   2260:
                   2261:   if (typ(pol)!=t_POL) err(typeer,"reduceddiscsmith");
                   2262:   n=lgef(pol)-3;
                   2263:   if (n<=0) err(constpoler,"reduceddiscsmith");
                   2264:   check_pol_int(pol);
                   2265:   if (!gcmp1((GEN)pol[n+2]))
                   2266:     err(talker,"non-monic polynomial in poldiscreduced");
                   2267:   polp = derivpol(pol); alpha = polx[varn(pol)];
                   2268:   m=cgetg(n+1,t_MAT);
                   2269:   for (j=1; j<=n; j++)
                   2270:   {
                   2271:     p1=cgetg(n+1,t_COL); m[j]=(long)p1;
                   2272:     for (i=1; i<=n; i++) p1[i]=(long)truecoeff(polp,i-1);
                   2273:     if (j<n) polp = gres(gmul(alpha,polp), pol);
                   2274:   }
                   2275:   tetpil=avma; return gerepile(av,tetpil,smith(m));
                   2276: }
                   2277:
                   2278: /***********************************************************************/
                   2279: /**                                                                  **/
                   2280: /**                     ALGORITHME DE STURM                          **/
                   2281: /**             (number of real roots of x in ]a,b])                 **/
                   2282: /**                                                                  **/
                   2283: /***********************************************************************/
                   2284:
                   2285: /* if a (resp. b) is NULL, set it to -oo (resp. +oo) */
                   2286: long
                   2287: sturmpart(GEN x, GEN a, GEN b)
                   2288: {
                   2289:   long av = avma,sl,sr,s,t,r1;
                   2290:   GEN g,h,u,v;
                   2291:
                   2292:   if (typ(x) != t_POL) err(typeer,"sturm");
                   2293:   if (gcmp0(x)) err(zeropoler,"sturm");
                   2294:   s=lgef(x); if (s==3) return 0;
                   2295:
                   2296:   sl = gsigne(leading_term(x));
                   2297:   if (s==4)
                   2298:   {
                   2299:     s = b? gsigne(poleval(x,b)):  sl;
                   2300:     t = a? gsigne(poleval(x,a)): -sl;
                   2301:     avma = av; return (s == t)? 0: 1;
                   2302:   }
                   2303:   u=gdiv(x,content(x)); v=derivpol(x);
                   2304:   v=gdiv(v,content(v));
                   2305:   g=gun; h=gun;
                   2306:   s = b? gsigne(poleval(u,b)): sl;
                   2307:   t = a? gsigne(poleval(u,a)): ((lgef(u)&1)? sl: -sl);
                   2308:   r1=0;
                   2309:   sr = b? gsigne(poleval(v,b)): s;
                   2310:   if (sr)
                   2311:   {
                   2312:     if (!s) s=sr;
                   2313:     else if (sr!=s) { s= -s; r1--; }
                   2314:   }
                   2315:   sr = a? gsigne(poleval(v,a)): -t;
                   2316:   if (sr)
                   2317:   {
                   2318:     if (!t) t=sr;
                   2319:     else if (sr!=t) { t= -t; r1++; }
                   2320:   }
                   2321:   for(;;)
                   2322:   {
                   2323:     GEN p1, r = pseudorem(u,v);
                   2324:     long du=lgef(u), dv=lgef(v), dr=lgef(r), degq=du-dv;
                   2325:
                   2326:     if (dr<=2) err(talker,"not a squarefree polynomial in sturm");
                   2327:     if (gsigne(leading_term(v)) > 0 || degq&1) r=gneg_i(r);
                   2328:     sl = gsigne((GEN) r[dr-1]);
                   2329:     sr = b? gsigne(poleval(r,b)): sl;
                   2330:     if (sr)
                   2331:     {
                   2332:       if (!s) s=sr;
                   2333:       else if (sr!=s) { s= -s; r1--; }
                   2334:     }
                   2335:     sr = a? gsigne(poleval(r,a)): ((dr&1)? sl: -sl);
                   2336:     if (sr)
                   2337:     {
                   2338:       if (!t) t=sr;
                   2339:       else if (sr!=t) { t= -t; r1++; }
                   2340:     }
                   2341:     if (dr==3) { avma=av; return r1; }
                   2342:
                   2343:     u=v; p1 = g; g = gabs(leading_term(u),DEFAULTPREC);
                   2344:     switch(degq)
                   2345:     {
                   2346:       case 0: break;
                   2347:       case 1:
                   2348:         p1 = gmul(h,p1); h = g; break;
                   2349:       default:
                   2350:         p1 = gmul(gpuigs(h,degq),p1);
                   2351:         h = gdiv(gpuigs(g,degq), gpuigs(h,degq-1));
                   2352:     }
                   2353:     v = gdiv(r,p1);
                   2354:   }
                   2355: }
                   2356:
                   2357: /*******************************************************************/
                   2358: /*                                                                 */
                   2359: /*         POLYNOME QUADRATIQUE ASSOCIE A UN DISCRIMINANT          */
                   2360: /*                                                                 */
                   2361: /*******************************************************************/
                   2362:
                   2363: GEN
                   2364: quadpoly0(GEN x, long v)
                   2365: {
                   2366:   long res,l,tetpil,i,sx, tx = typ(x);
                   2367:   GEN y,p1;
                   2368:
                   2369:   if (is_matvec_t(tx))
                   2370:   {
                   2371:     l=lg(x); y=cgetg(l,tx);
                   2372:     for (i=1; i<l; i++) y[i]=(long)quadpoly0((GEN)x[i],v);
                   2373:     return y;
                   2374:   }
                   2375:   if (tx!=t_INT) err(arither1);
                   2376:   if (v < 0) v = 0;
                   2377:   sx=signe(x);
                   2378:   if (!sx) err(talker,"zero discriminant in quadpoly");
                   2379:   y=cgetg(5,t_POL);
                   2380:   y[1]=evalsigne(1) | evalvarn(v) | evallgef(5); y[4]=un;
                   2381:   res=mod4(x); if (sx<0 && res) res=4-res;
                   2382:   if (res>1) err(funder2,"quadpoly");
                   2383:
                   2384:   l=avma; p1=shifti(x,-2); setsigne(p1,-signe(p1));
                   2385:   y[2] = (long) p1;
                   2386:   if (!res) y[3] = zero;
                   2387:   else
                   2388:   {
                   2389:     if (sx<0) { tetpil=avma; y[2] = lpile(l,tetpil,addsi(1,p1)); }
                   2390:     y[3] = lnegi(gun);
                   2391:   }
                   2392:   return y;
                   2393: }
                   2394:
                   2395: GEN
                   2396: quadpoly(GEN x)
                   2397: {
                   2398:   return quadpoly0(x,-1);
                   2399: }
                   2400:
                   2401: GEN
                   2402: quadgen(GEN x)
                   2403: {
                   2404:   GEN y=cgetg(4,t_QUAD);
                   2405:   y[1]=lquadpoly(x); y[2]=zero; y[3]=un; return y;
                   2406: }
                   2407:
                   2408: /*******************************************************************/
                   2409: /*                                                                 */
                   2410: /*                    INVERSE MODULO GENERAL                       */
                   2411: /*                                                                 */
                   2412: /*******************************************************************/
                   2413:
                   2414: GEN
                   2415: ginvmod(GEN x, GEN y)
                   2416: {
                   2417:   long tx=typ(x);
                   2418:
                   2419:   switch(typ(y))
                   2420:   {
                   2421:     case t_POL:
                   2422:       if (tx==t_POL) return polinvmod(x,y);
                   2423:       if (is_scalar_t(tx)) return ginv(x);
                   2424:       break;
                   2425:     case t_INT:
                   2426:       if (tx==t_INT) return mpinvmod(x,y);
                   2427:       if (tx==t_POL) return gzero;
                   2428:   }
                   2429:   err(typeer,"ginvmod");
                   2430:   return NULL; /* not reached */
                   2431: }
                   2432:
                   2433: /***********************************************************************/
                   2434: /**                                                                  **/
                   2435: /**                        NEWTON POLYGON                            **/
                   2436: /**                                                                  **/
                   2437: /***********************************************************************/
                   2438:
                   2439: /* assume leading coeff of x is non-zero */
                   2440: GEN
                   2441: newtonpoly(GEN x, GEN p)
                   2442: {
                   2443:   GEN y;
                   2444:   long n,ind,a,b,c,u1,u2,r1,r2;
                   2445:   long *vval, num[] = {evaltyp(t_INT) | m_evallg(3), 0, 0};
                   2446:
                   2447:   if (typ(x)!=t_POL) err(typeer,"newtonpoly");
                   2448:   n=lgef(x)-3; if (n<=0) { y=cgetg(1,t_VEC); return y; }
                   2449:   y = cgetg(n+1,t_VEC); x += 2; /* now x[i] = term of degree i */
                   2450:   vval = (long *) gpmalloc(sizeof(long)*(n+1));
                   2451:   for (a=0; a<=n; a++) vval[a] = ggval((GEN)x[a],p);
                   2452:   for (a=0, ind=1; a<n; a++)
                   2453:   {
                   2454:     if (vval[a] != VERYBIGINT) break;
                   2455:     y[ind++] = lstoi(VERYBIGINT);
                   2456:   }
                   2457:   for (b=a+1; b<=n; a=b, b=a+1)
                   2458:   {
                   2459:     while (vval[b] == VERYBIGINT) b++;
                   2460:     u1=vval[a]-vval[b]; u2=b-a;
                   2461:     for (c=b+1; c<=n; c++)
                   2462:     {
                   2463:       if (vval[c] == VERYBIGINT) continue;
                   2464:       r1=vval[a]-vval[c]; r2=c-a;
                   2465:       if (u1*r2<=u2*r1) { u1=r1; u2=r2; b=c; }
                   2466:     }
                   2467:     while (ind<=b) { affsi(u1,num); y[ind++] = ldivgs(num,u2); }
                   2468:   }
                   2469:   free(vval); return y;
                   2470: }
                   2471:
                   2472: int cmp_pol(GEN x, GEN y);
                   2473:
                   2474: /* Factor polynomial a on the number field defined by polynomial t */
                   2475: GEN
                   2476: polfnf(GEN a, GEN t)
                   2477: {
                   2478:   GEN x0, y,p1,p2,u,g,fa,n,unt;
                   2479:   long av=avma,tetpil,lx,v,i,k,vt;
                   2480:
                   2481:   if (typ(a)!=t_POL || typ(t)!=t_POL) err(typeer,"polfnf");
                   2482:   if (gcmp0(a)) return gcopy(a);
                   2483:   vt=varn(t); v=varn(a);
                   2484:   if (vt<=v)
                   2485:     err(talker,"polynomial variable must be of higher priority than number field variable\nin factornf");
                   2486:   u = gdiv(a, ggcd(a,derivpol(a)));
                   2487:   unt = gmodulsg(1,t); u = gmul(unt,u);
                   2488:   g = lift(u);
                   2489:   for (k=-1; ; k++)
                   2490:   {
                   2491:     n = gsub(polx[MAXVARN], gmulsg(k,polx[vt]));
                   2492:     n = subres(t, poleval(g,n));
                   2493:     if (lgef(ggcd(n,derivpol(n))) == 3) break;
                   2494:   }
                   2495:   fa=factor(n); fa=(GEN)fa[1]; lx=lg(fa);
                   2496:   y=cgetg(3,t_MAT);
                   2497:   p1=cgetg(lx,t_COL); y[1]=(long)p1;
                   2498:   p2=cgetg(lx,t_COL); y[2]=(long)p2;
                   2499:   x0 = gadd(polx[v],gmulsg(k,gmodulcp(polx[vt],t)));
                   2500:   for (i=1; i<lx; i++)
                   2501:   {
                   2502:     GEN b, pro = ggcd(u, gmul(unt, poleval((GEN)fa[i], x0)));
                   2503:     long e;
                   2504:
                   2505:     p1[i] = (typ(pro)==t_POL)? ldiv(pro,leading_term(pro)): (long)pro;
                   2506:     if (gcmp1((GEN)p1[i])) err(talker,"reducible modulus in factornf");
                   2507:     e=0; while (poldivis(a,(GEN)p1[i], &b)) { a = b; e++; }
                   2508:     p2[i] = lstoi(e);
                   2509:   }
                   2510:   (void)sort_factor(y, cmp_pol);
                   2511:   tetpil=avma; return gerepile(av,tetpil,gcopy(y));
                   2512: }

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