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

Annotation of OpenXM_contrib/pari/src/basemath/polarit1.c, Revision 1.1

1.1     ! maekawa     1: /***********************************************************************/
        !             2: /**                                                                   **/
        !             3: /**               ARITHMETIC OPERATIONS ON POLYNOMIALS                **/
        !             4: /**                         (first part)                              **/
        !             5: /**                                                                   **/
        !             6: /***********************************************************************/
        !             7: /* $Id: polarit1.c,v 1.2 1999/09/23 17:50:56 karim Exp $ */
        !             8: #include "pari.h"
        !             9: GEN get_mul_table(GEN x,GEN bas,GEN *T);
        !            10: GEN pol_to_monic(GEN pol, GEN *lead);
        !            11: GEN sort_factor(GEN y, int (*cmp)(GEN,GEN));
        !            12: GEN bsrch(GEN p, GEN fa, long Ka, GEN eta, long Ma);
        !            13: GEN eleval(GEN f,GEN h,GEN a);
        !            14: GEN respm(GEN f1,GEN f2,GEN pm);
        !            15: GEN setup(GEN p,GEN f,GEN theta,GEN nut, long *La, long *Ma);
        !            16: GEN vstar(GEN p,GEN h);
        !            17:
        !            18: /* see splitgen() for how to use these two */
        !            19: GEN
        !            20: setloop(GEN a)
        !            21: {
        !            22:   a=icopy(a); new_chunk(2); /* dummy to get two cells of extra space */
        !            23:   return a;
        !            24: }
        !            25:
        !            26: /* assume a > 0 */
        !            27: GEN
        !            28: incpos(GEN a)
        !            29: {
        !            30:   long i,l=lgefint(a);
        !            31:
        !            32:   for (i=l-1; i>1; i--)
        !            33:     if (++a[i]) return a;
        !            34:   i=l+1; a--; /* use extra cell */
        !            35:   a[0]=evaltyp(1) | evallg(i);
        !            36:   a[1]=evalsigne(1) | evallgefint(i);
        !            37:   return a;
        !            38: }
        !            39:
        !            40: GEN
        !            41: incloop(GEN a)
        !            42: {
        !            43:   long i,l;
        !            44:
        !            45:   switch(signe(a))
        !            46:   {
        !            47:     case 0:
        !            48:       a--; /* use extra cell */
        !            49:       a[0]=evaltyp(t_INT) | evallg(3);
        !            50:       a[1]=evalsigne(1) | evallgefint(3);
        !            51:       a[2]=1; return a;
        !            52:
        !            53:     case -1:
        !            54:       l=lgefint(a);
        !            55:       for (i=l-1; i>1; i--)
        !            56:         if (a[i]--) break;
        !            57:       if (a[2] == 0)
        !            58:       {
        !            59:         a++; /* save one cell */
        !            60:         a[0] = evaltyp(t_INT) | evallg(2);
        !            61:         a[1] = evalsigne(0) | evallgefint(2);
        !            62:       }
        !            63:       return a;
        !            64:
        !            65:     default:
        !            66:       return incpos(a);
        !            67:   }
        !            68: }
        !            69:
        !            70: /*******************************************************************/
        !            71: /*                                                                 */
        !            72: /*                           DIVISIBILITE                          */
        !            73: /*                 Renvoie 1 si y divise x, 0 sinon .              */
        !            74: /*                                                                 */
        !            75: /*******************************************************************/
        !            76:
        !            77: int
        !            78: gdivise(GEN x, GEN y)
        !            79: {
        !            80:   long av=avma;
        !            81:   x=gmod(x,y); avma=av; return gcmp0(x);
        !            82: }
        !            83:
        !            84: int
        !            85: poldivis(GEN x, GEN y, GEN *z)
        !            86: {
        !            87:   long av = avma;
        !            88:   GEN p1 = poldivres(x,y,ONLY_DIVIDES);
        !            89:   if (p1) { *z = p1; return 1; }
        !            90:   avma=av; return 0;
        !            91: }
        !            92:
        !            93: /*******************************************************************/
        !            94: /*                                                                 */
        !            95: /*                          REDUCTION                              */
        !            96: /*    Do the transformation t_FRACN/t_RFRACN --> t_FRAC/t_RFRAC    */
        !            97: /*                                                                 */
        !            98: /*******************************************************************/
        !            99:
        !           100: /* x[1] is scalar, non-zero */
        !           101: static GEN
        !           102: gred_simple(GEN x)
        !           103: {
        !           104:   GEN p1,p2,x2,x3;
        !           105:
        !           106:   x2=content((GEN)x[2]); if (gcmp1(x2)) return gcopy(x);
        !           107:   x3=gdiv((GEN)x[1],x2); p2=denom(x3);
        !           108:   x2=gdiv((GEN)x[2],x2);
        !           109:
        !           110:   p1=cgetg(3,t_RFRAC);
        !           111:   p1[1]=(long)numer(x3);
        !           112:   p1[2]=lmul(x2,p2); return p1;
        !           113: }
        !           114:
        !           115: GEN
        !           116: gred_rfrac(GEN x)
        !           117: {
        !           118:   GEN y,p1,xx1,xx2,x3, x1 = (GEN)x[1], x2 = (GEN)x[2];
        !           119:   long tx,ty;
        !           120:
        !           121:   if (gcmp0(x1)) return gcopy(x1);
        !           122:
        !           123:   tx=typ(x1); ty=typ(x2);
        !           124:   if (ty!=t_POL)
        !           125:   {
        !           126:     if (tx!=t_POL) return gcopy(x);
        !           127:     if (gvar2(x2) > varn(x1)) return gdiv(x1,x2);
        !           128:     err(talker,"incompatible variables in gred");
        !           129:   }
        !           130:   if (tx!=t_POL)
        !           131:   {
        !           132:     if (varn(x2) < gvar2(x1)) return gred_simple(x);
        !           133:     err(talker,"incompatible variables in gred");
        !           134:   }
        !           135:   if (varn(x2) < varn(x1)) return gred_simple(x);
        !           136:   if (varn(x2) > varn(x1)) return gdiv(x1,x2);
        !           137:
        !           138:   /* now x1 and x2 are polynomials with the same variable */
        !           139:   xx1=content(x1); if (!gcmp1(xx1)) x1=gdiv(x1,xx1);
        !           140:   xx2=content(x2); if (!gcmp1(xx2)) x2=gdiv(x2,xx2);
        !           141:   x3=gdiv(xx1,xx2);
        !           142:   y = poldivres(x1,x2,&p1);
        !           143:   if (!signe(p1)) { cgiv(p1); return gmul(x3,y); }
        !           144:
        !           145:   p1 = ggcd(x2,p1);
        !           146:   if (!isscalar(p1)) { x1=gdeuc(x1,p1); x2=gdeuc(x2,p1); }
        !           147:   xx1=numer(x3); xx2=denom(x3);
        !           148:   p1=cgetg(3,t_RFRAC);
        !           149:   p1[1]=lmul(x1,xx1);
        !           150:   p1[2]=lmul(x2,xx2); return p1;
        !           151: }
        !           152:
        !           153: GEN
        !           154: gred(GEN x)
        !           155: {
        !           156:   long tx=typ(x),av=avma;
        !           157:   GEN y,p1,x1,x2;
        !           158:
        !           159:   if (is_frac_t(tx))
        !           160:   {
        !           161:     x1=(GEN)x[1]; x2=(GEN)x[2];
        !           162:     y = dvmdii(x1,x2,&p1);
        !           163:     if (p1 == gzero) return y; /* gzero volontaire */
        !           164:     (void)new_chunk((lgefint(x1)+lgefint(x2))<<1);
        !           165:     p1=mppgcd(x2,p1);
        !           166:     if (is_pm1(p1)) { avma=av; return gcopy(x); }
        !           167:     avma=av; y=cgetg(3,t_FRAC);
        !           168:     y[1]=ldivii(x1,p1);
        !           169:     y[2]=ldivii(x2,p1); return y;
        !           170:   }
        !           171:   if (is_rfrac_t(tx))
        !           172:     return gerepileupto(av, gred_rfrac(x));
        !           173:   return gcopy(x);
        !           174: }
        !           175:
        !           176: /*******************************************************************/
        !           177: /*                                                                 */
        !           178: /*                  POLYNOMIAL EUCLIDEAN DIVISION                  */
        !           179: /*                                                                 */
        !           180: /*******************************************************************/
        !           181: GEN gdivexact(GEN x, GEN y);
        !           182:
        !           183: /* Polynomial division x / y:
        !           184:  *   if z = ONLY_REM  return remainder, otherwise return quotient
        !           185:  *   if z != NULL set *z to remainder
        !           186:  *   *z is the last object on stack (and thus can be disposed of with cgiv
        !           187:  *   instead of gerepile)
        !           188:  */
        !           189: GEN
        !           190: poldivres(GEN x, GEN y, GEN *pr)
        !           191: {
        !           192:   long ty=typ(y),tx,vx,vy,dx,dy,dz,i,j,avy,av,av1,sx,lrem;
        !           193:   int remainder;
        !           194:   GEN z,p1,rem,y_lead,mod;
        !           195:   GEN (*f)(GEN,GEN);
        !           196:
        !           197:   if (pr == ONLY_DIVIDES_EXACT)
        !           198:     { f = gdivexact; pr = ONLY_DIVIDES; }
        !           199:   else
        !           200:     f = gdiv;
        !           201:   if (is_scalar_t(ty))
        !           202:   {
        !           203:     if (pr == ONLY_REM) return gzero;
        !           204:     if (pr && pr != ONLY_DIVIDES) *pr=gzero;
        !           205:     return f(x,y);
        !           206:   }
        !           207:   tx=typ(x); vy=gvar9(y);
        !           208:   if (is_scalar_t(tx) || gvar9(x)>vy)
        !           209:   {
        !           210:     if (pr == ONLY_REM) return gcopy(x);
        !           211:     if (pr == ONLY_DIVIDES) return gcmp0(x)? gzero: NULL;
        !           212:     if (pr) *pr=gcopy(x);
        !           213:     return gzero;
        !           214:   }
        !           215:   if (tx!=t_POL || ty!=t_POL) err(typeer,"euclidean division (poldivres)");
        !           216:
        !           217:   vx=varn(x);
        !           218:   if (vx<vy)
        !           219:   {
        !           220:     if (pr && pr != ONLY_DIVIDES)
        !           221:     {
        !           222:       p1 = zeropol(vx); if (pr == ONLY_REM) return p1;
        !           223:       *pr = p1;
        !           224:     }
        !           225:     return f(x,y);
        !           226:   }
        !           227:   if (!signe(y)) err(talker,"euclidean division by zero (poldivres)");
        !           228:
        !           229:   dy=lgef(y)-3; y_lead = (GEN)y[dy+2];
        !           230:   if (gcmp0(y_lead)) /* normalize denominator if leading term is 0 */
        !           231:   {
        !           232:     err(warner,"normalizing a polynomial with 0 leading term");
        !           233:     for (dy--; dy>=0; dy--)
        !           234:     {
        !           235:       y_lead = (GEN)y[dy+2];
        !           236:       if (!gcmp0(y_lead)) break;
        !           237:     }
        !           238:   }
        !           239:   if (!dy) /* y is constant */
        !           240:   {
        !           241:     if (pr && pr != ONLY_DIVIDES)
        !           242:     {
        !           243:       if (pr == ONLY_REM) return zeropol(vx);
        !           244:       *pr = zeropol(vx);
        !           245:     }
        !           246:     return f(x,(GEN)y[2]);
        !           247:   }
        !           248:   dx=lgef(x)-3;
        !           249:   if (vx>vy || dx<dy)
        !           250:   {
        !           251:     if (pr)
        !           252:     {
        !           253:       if (pr == ONLY_DIVIDES) return gcmp0(x)? gzero: NULL;
        !           254:       if (pr == ONLY_REM) return gcopy(x);
        !           255:       *pr = gcopy(x);
        !           256:     }
        !           257:     return zeropol(vy);
        !           258:   }
        !           259:   dz=dx-dy; av=avma; /* to avoid gsub's later on */
        !           260:   p1 = new_chunk(dy+3);
        !           261:   for (i=2; i<dy+3; i++)
        !           262:   {
        !           263:     GEN p2 = (GEN)y[i];
        !           264:     p1[i] = isexactzero(p2)? 0: (long)gneg_i(p2);
        !           265:   }
        !           266:   y = p1;
        !           267:   switch(typ(y_lead))
        !           268:   {
        !           269:     case t_INTMOD:
        !           270:     case t_POLMOD: y_lead = ginv(y_lead);
        !           271:       f = gmul; mod = (GEN)y_lead[1];
        !           272:       break;
        !           273:     default: if (gcmp1(y_lead)) y_lead = NULL;
        !           274:       mod = NULL;
        !           275:   }
        !           276:   avy=avma; z=cgetg(dz+3,t_POL);
        !           277:   z[1]=evalsigne(1) | evallgef(dz+3) | evalvarn(vx);
        !           278:   x += 2; y += 2; z += 2;
        !           279:
        !           280:   p1 = (GEN)x[dx]; remainder = (pr == ONLY_REM);
        !           281:   z[dz]=y_lead? (long)f(p1,y_lead): lcopy(p1);
        !           282:   for (i=dx-1; i>=dy; i--)
        !           283:   {
        !           284:     av1=avma; p1=(GEN)x[i];
        !           285:     for (j=i-dy+1; j<=i && j<=dz; j++)
        !           286:       if (y[i-j]) p1 = gadd(p1, gmul((GEN)z[j],(GEN)y[i-j]));
        !           287:     if (y_lead) p1 = f(p1,y_lead);
        !           288:     if (!remainder) p1 = avma==av1? gcopy(p1): gerepileupto(av1,p1);
        !           289:     z[i-dy] = (long)p1;
        !           290:   }
        !           291:   if (!pr) return gerepileupto(av,z-2);
        !           292:
        !           293:   rem = (GEN)avma; av1 = (long)new_chunk(dx+3);
        !           294:   for (sx=0; ; i--)
        !           295:   {
        !           296:     p1 = (GEN)x[i];
        !           297:     /* we always enter this loop at least once */
        !           298:     for (j=0; j<=i && j<=dz; j++)
        !           299:       if (y[i-j]) p1 = gadd(p1, gmul((GEN)z[j],(GEN)y[i-j]));
        !           300:     if (mod && avma==av1) p1 = gmod(p1,mod);
        !           301:     if (!gcmp0(p1)) { sx = 1; break; } /* remainder is non-zero */
        !           302:     if (!isinexactreal(p1) && !isexactzero(p1)) break;
        !           303:     if (!i) break;
        !           304:     avma=av1;
        !           305:   }
        !           306:   if (pr == ONLY_DIVIDES)
        !           307:   {
        !           308:     if (sx) { avma=av; return NULL; }
        !           309:     avma = (long)rem;
        !           310:     return gerepileupto(av,z-2);
        !           311:   }
        !           312:   lrem=i+3; rem -= lrem;
        !           313:   if (avma==av1) { avma = (long)rem; p1 = gcopy(p1); }
        !           314:   else p1 = gerepileupto((long)rem,p1);
        !           315:   rem[0]=evaltyp(t_POL) | evallg(lrem);
        !           316:   rem[1]=evalsigne(1) | evalvarn(vx) | evallgef(lrem);
        !           317:   rem += 2;
        !           318:   rem[i]=(long)p1;
        !           319:   for (i--; i>=0; i--)
        !           320:   {
        !           321:     av1=avma; p1 = (GEN)x[i];
        !           322:     for (j=0; j<=i && j<=dz; j++)
        !           323:       if (y[i-j]) p1 = gadd(p1, gmul((GEN)z[j],(GEN)y[i-j]));
        !           324:     if (mod && avma==av1) p1 = gmod(p1,mod);
        !           325:     rem[i]=avma==av1? lcopy(p1):lpileupto(av1,p1);
        !           326:   }
        !           327:   rem -= 2;
        !           328:   if (!sx) normalizepol_i(rem, lrem);
        !           329:   if (remainder) return gerepileupto(av,rem);
        !           330:   z -= 2;
        !           331:   {
        !           332:     GEN *gptr[2]; gptr[0]=&z; gptr[1]=&rem;
        !           333:     gerepilemanysp(av,avy,gptr,2); *pr = rem; return z;
        !           334:   }
        !           335: }
        !           336:
        !           337: /*******************************************************************/
        !           338: /*                                                                 */
        !           339: /*           ROOTS MODULO a prime p (no multiplicities)            */
        !           340: /*                                                                 */
        !           341: /*******************************************************************/
        !           342: static GEN
        !           343: mod(GEN x, GEN y)
        !           344: {
        !           345:   GEN z = cgetg(3,t_INTMOD);
        !           346:   z[1]=(long)y; z[2]=(long)x; return z;
        !           347: }
        !           348:
        !           349: static long
        !           350: factmod_init(GEN *F, GEN pp, long *p)
        !           351: {
        !           352:   GEN f = *F;
        !           353:   long i,d;
        !           354:   if (typ(f)!=t_POL || typ(pp)!=t_INT) err(typeer,"factmod");
        !           355:   if (expi(pp) > BITS_IN_LONG - 3) *p = 0;
        !           356:   else
        !           357:   {
        !           358:     *p = itos(pp);
        !           359:     if (*p < 2) err(talker,"not a prime in factmod");
        !           360:   }
        !           361:   f = gmul(f, mod(gun,pp));
        !           362:   if (!signe(f)) err(zeropoler,"factmod");
        !           363:   f = lift_intern(f); d = lgef(f);
        !           364:   for (i=2; i <d; i++)
        !           365:     if (typ(f[i])!=t_INT) err(impl,"factormod for general polynomials");
        !           366:   *F = f; return d-3;
        !           367: }
        !           368:
        !           369: #define mods(x,y) mod(stoi(x),y)
        !           370: static GEN
        !           371: root_mod_2(GEN f)
        !           372: {
        !           373:   int z1, z0 = !signe(f[2]);
        !           374:   long i,n;
        !           375:   GEN y;
        !           376:
        !           377:   for (i=2, n=1; i < lgef(f); i++)
        !           378:     if (signe(f[i])) n++;
        !           379:   z1 = n & 1;
        !           380:   y = cgetg(z0+z1+1, t_COL); i = 1;
        !           381:   if (z0) y[i++] = (long)mods(0,gdeux);
        !           382:   if (z1) y[i]   = (long)mods(1,gdeux);
        !           383:   return y;
        !           384: }
        !           385:
        !           386: #define i_mod4(x) (signe(x)? mod4((GEN)(x)): 0)
        !           387: static GEN
        !           388: root_mod_4(GEN f)
        !           389: {
        !           390:   long no,ne;
        !           391:   int z0 = !signe(f[2]);
        !           392:   int z2 = ((i_mod4(f[2]) + 2*i_mod4(f[3])) & 3) == 0;
        !           393:   int i,z1,z3;
        !           394:   GEN y,p;
        !           395:
        !           396:   for (ne=0,i=2; i<lgef(f); i+=2)
        !           397:     if (signe(f[i])) ne += mael(f,i,2);
        !           398:   for (no=0,i=3; i<lgef(f); i+=2)
        !           399:     if (signe(f[i])) no += mael(f,i,2);
        !           400:   no &= 3; ne &= 3;
        !           401:   z3 = (no == ne);
        !           402:   z1 = (no == ((4-ne)&3));
        !           403:   y=cgetg(1+z0+z1+z2+z3,t_COL); i = 1; p = stoi(4);
        !           404:   if (z0) y[i++] = (long)mods(0,p);
        !           405:   if (z1) y[i++] = (long)mods(1,p);
        !           406:   if (z2) y[i++] = (long)mods(2,p);
        !           407:   if (z3) y[i]   = (long)mods(3,p);
        !           408:   return y;
        !           409: }
        !           410: #undef i_mod4
        !           411:
        !           412: /* p even, accept p = 4 for p-adic stuff */
        !           413: static GEN
        !           414: root_mod_even(GEN f, long p)
        !           415: {
        !           416:   switch(p)
        !           417:   {
        !           418:     case 2: return root_mod_2(f);
        !           419:     case 4: return root_mod_4(f);
        !           420:   }
        !           421:   err(talker,"not a prime in rootmod");
        !           422:   return NULL; /* not reached */
        !           423: }
        !           424:
        !           425: /* by checking f(0..p-1) */
        !           426: GEN
        !           427: rootmod2(GEN f, GEN pp)
        !           428: {
        !           429:   GEN g,y,ss,q,r, x_minus_s;
        !           430:   long p,av = avma,av1,d,i,nbrac;
        !           431:
        !           432:   if (!(d = factmod_init(&f, pp, &p))) { avma=av; return cgetg(1,t_COL); }
        !           433:   if (!p) err(talker,"prime too big in rootmod2");
        !           434:   if ((p & 1) == 0) { avma = av; return root_mod_even(f,p); }
        !           435:   x_minus_s = gadd(polx[varn(f)], stoi(-1));
        !           436:
        !           437:   nbrac=1;
        !           438:   y=(GEN)gpmalloc((d+1)*sizeof(long));
        !           439:   if (gcmp0((GEN)f[2])) y[nbrac++] = 0;
        !           440:   ss = icopy(gun); av1 = avma;
        !           441:   do
        !           442:   {
        !           443:     mael(x_minus_s,2,2) = ss[2];
        !           444:     /* one might do a FFT-type evaluation */
        !           445:     q = Fp_poldivres(f, x_minus_s, pp, &r);
        !           446:     if (signe(r)) avma = av1;
        !           447:     else
        !           448:     {
        !           449:       y[nbrac++] = ss[2]; f = q; av1 = avma;
        !           450:     }
        !           451:     ss[2]++;
        !           452:   }
        !           453:   while (nbrac<d && p>ss[2]);
        !           454:   if (nbrac == 1) { avma=av; return cgetg(1,t_COL); }
        !           455:   if (nbrac == d && p != ss[2])
        !           456:   {
        !           457:     g = mpinvmod((GEN)f[3], pp); setsigne(g,-1);
        !           458:     ss = modis(mulii(g, (GEN)f[2]), p);
        !           459:     y[nbrac++]=ss[2];
        !           460:   }
        !           461:   avma=av; g=cgetg(nbrac,t_COL);
        !           462:   if (isonstack(pp)) pp = icopy(pp);
        !           463:   for (i=1; i<nbrac; i++) g[i]=(long)mods(y[i],pp);
        !           464:   free(y); return g;
        !           465: }
        !           466:
        !           467: /* by splitting */
        !           468: GEN
        !           469: rootmod(GEN f, GEN p)
        !           470: {
        !           471:   long av = avma,tetpil,n,i,j,la,lb;
        !           472:   GEN y,pol,a,b,q,pol0;
        !           473:
        !           474:   if (!factmod_init(&f, p, &i)) { avma=av; return cgetg(1,t_COL); }
        !           475:   i = p[lgefint(p)-1];
        !           476:   if ((i & 1) == 0) { avma = av; return root_mod_even(f,i); }
        !           477:   i=2; while (!signe(f[i])) i++;
        !           478:   if (i == 2) j = 1;
        !           479:   else
        !           480:   {
        !           481:     j = lgef(f) - (i-2);
        !           482:     if (j==3) /* f = x^n */
        !           483:     {
        !           484:       avma = av; y = cgetg(2,t_COL);
        !           485:       y[1] = (long)gmodulsg(0,p);
        !           486:       return y;
        !           487:     }
        !           488:     a = cgetg(j, t_POL); /* a = f / x^{v_x(f)} */
        !           489:     a[1] =  evalsigne(1) | evalvarn(varn(f)) | evallgef(j);
        !           490:     f += i-2; for (i=2; i<j; i++) a[i]=f[i];
        !           491:     j = 2; f = a;
        !           492:   }
        !           493:   q = shifti(p,-1);
        !           494:   /* take gcd(x^(p-1) - 1, f) by splitting (x^q-1) * (x^q+1) */
        !           495:   b = Fp_pow_mod_pol(polx[varn(f)],q, f,p);
        !           496:   if (lgef(b)<3) err(talker,"not a prime in rootmod");
        !           497:   b[2] = laddis((GEN)b[2],-1); /* b = x^((p-1)/2) - 1 mod f */
        !           498:   a = Fp_pol_gcd(f,b, p);
        !           499:   b[2] = laddis((GEN)b[2], 2); /* b = x^((p-1)/2) + 1 mod f */
        !           500:   b = Fp_pol_gcd(f,b, p);
        !           501:   la = lgef(a)-3;
        !           502:   lb = lgef(b)-3; n = la + lb;
        !           503:   if (!n)
        !           504:   {
        !           505:     avma = av; y = cgetg(n+j,t_COL);
        !           506:     if (j>1) y[1] = (long)gmodulsg(0,p);
        !           507:     return y;
        !           508:   }
        !           509:   y = cgetg(n+j,t_COL);
        !           510:   if (j>1) { y[1] = zero; n++; }
        !           511:   y[j] = (long)normalize_mod_p(b,p);
        !           512:   if (la) y[j+lb] = (long)normalize_mod_p(a,p);
        !           513:   pol = gadd(polx[varn(f)], gun); pol0 = (GEN)pol[2];
        !           514:   while (j<=n)
        !           515:   {
        !           516:     a=(GEN)y[j]; la=lgef(a)-3;
        !           517:     if (la==1)
        !           518:       y[j++] = lsubii(p, (GEN)a[2]);
        !           519:     else if (la==2)
        !           520:     {
        !           521:       GEN d = subii(sqri((GEN)a[3]), shifti((GEN)a[2],2));
        !           522:       GEN e = mpsqrtmod(d,p), u = addis(q, 1); /* u = 1/2 */
        !           523:       y[j++] = lmodii(mulii(u,subii(e,(GEN)a[3])), p);
        !           524:       y[j++] = lmodii(mulii(u,negi(addii(e,(GEN)a[3]))), p);
        !           525:     }
        !           526:     else for (pol0[2]=1; ; pol0[2]++)
        !           527:     {
        !           528:       b = Fp_pow_mod_pol(pol,q, a,p);
        !           529:       b[2] = laddis((GEN)b[2], -1);
        !           530:       b = Fp_pol_gcd(a,b, p); lb = lgef(b)-3;
        !           531:       if (lb && lb<la)
        !           532:       {
        !           533:         b = normalize_mod_p(b, p);
        !           534:         y[j+lb] = (long)Fp_deuc(a,b, p);
        !           535:         y[j]    = (long)b; break;
        !           536:       }
        !           537:     }
        !           538:   }
        !           539:   tetpil = avma; y = gerepile(av,tetpil,sort(y));
        !           540:   if (isonstack(p)) p = icopy(p);
        !           541:   for (i=1; i<=n; i++) y[i] = (long)mod((GEN)y[i], p);
        !           542:   return y;
        !           543: }
        !           544:
        !           545: GEN
        !           546: rootmod0(GEN f, GEN p, long flag)
        !           547: {
        !           548:   switch(flag)
        !           549:   {
        !           550:     case 0: return rootmod(f,p);
        !           551:     case 1: return rootmod2(f,p);
        !           552:     default: err(flagerr,"polrootsmod");
        !           553:   }
        !           554:   return NULL; /* not reached */
        !           555: }
        !           556:
        !           557: /*******************************************************************/
        !           558: /*                                                                 */
        !           559: /*                     FACTORISATION MODULO p                      */
        !           560: /*                                                                 */
        !           561: /*******************************************************************/
        !           562: static GEN
        !           563: trivfact(void)
        !           564: {
        !           565:   GEN y=cgetg(3,t_MAT);
        !           566:   y[1]=lgetg(1,t_COL);
        !           567:   y[2]=lgetg(1,t_COL); return y;
        !           568: }
        !           569:
        !           570: static void
        !           571: fqunclone(GEN x, GEN p)
        !           572: {
        !           573:   long i,lx = lgef(x);
        !           574:   for (i=2; i<lx; i++)
        !           575:   {
        !           576:     GEN p1 = (GEN)x[i];
        !           577:     if (typ(p1) == t_POLMOD) p1[1] = (long)p;
        !           578:   }
        !           579: }
        !           580:
        !           581: static GEN
        !           582: try_pow(GEN w0, GEN pol, GEN p, GEN q, long r)
        !           583: {
        !           584:   GEN w2, w = Fp_pow_mod_pol(w0,q, pol,p);
        !           585:   long s;
        !           586:   if (gcmp1(w)) return w0;
        !           587:   for (s=1; s<r; s++,w=w2)
        !           588:   {
        !           589:     w2 = gsqr(w);
        !           590:     w2 = Fp_res(w2, pol, p);
        !           591:     if (gcmp1(w2)) break;
        !           592:   }
        !           593:   return gcmp_1(w)? NULL: w;
        !           594: }
        !           595:
        !           596: /* INPUT:
        !           597:  *  m integer (converted to polynomial w in Z[X] by stopoly)
        !           598:  *  p prime; q = (p^d-1) / 2^r
        !           599:  *  t[0] polynomial of degree k*d product of k irreducible factors of degree d
        !           600:  *  t[0] is expected to be normalized (leading coeff = 1)
        !           601:  * OUTPUT:
        !           602:  *  t[0],t[1]...t[k-1] the k factors, normalized
        !           603:  */
        !           604: static void
        !           605: split(long m, GEN *t, long d, GEN pg, GEN q, long r)
        !           606: {
        !           607:   long p,l,v,dv,av0,av;
        !           608:   GEN w,w0;
        !           609:
        !           610:   dv=lgef(*t)-3; if (dv==d) return;
        !           611:   v=varn(*t); av0=avma; p = pg[2];
        !           612:   for(av=avma;;avma=av)
        !           613:   {
        !           614:     if (p==2)
        !           615:     {
        !           616:       w0=w=gpuigs(polx[v],m-1); m+=2;
        !           617:       for (l=1; l<d; l++)
        !           618:       {
        !           619:         w = gadd(w0, gsqr(w));
        !           620:         w = Fp_pol_red(w, pg);
        !           621:         w = Fp_res(w, *t, pg);
        !           622:       }
        !           623:     }
        !           624:     else
        !           625:     {
        !           626:       w = Fp_res(stopoly(m,p,v),*t, pg);
        !           627:       m++; w = try_pow(w,*t,pg,q,r);
        !           628:       if (!w) continue;
        !           629:       /* set w = w - 1 */
        !           630:       w[2] = laddis((GEN)w[2], -1); /* w != 1 or -1 */
        !           631:     }
        !           632:     w = Fp_pol_gcd(*t,w, pg);
        !           633:     l = lgef(w)-3; if (l && l!=dv) break;
        !           634:   }
        !           635:   w = normalize_mod_p(w, pg);
        !           636:   w = gerepileupto(av0, w);
        !           637:   l /= d; t[l]=Fp_deuc(*t,w,pg); *t=w;
        !           638:   split(m,t+l,d,pg,q,r);
        !           639:   split(m,t,  d,pg,q,r);
        !           640: }
        !           641:
        !           642: static void
        !           643: splitgen(GEN m, GEN *t, long d, GEN  p, GEN q, long r)
        !           644: {
        !           645:   long l,v,dv,av;
        !           646:   GEN w;
        !           647:
        !           648:   dv=lgef(*t)-3; if (dv==d) return;
        !           649:   v=varn(*t); m=setloop(m); m=incpos(m);
        !           650:   av=avma;
        !           651:   for(;; avma=av, m=incpos(m))
        !           652:   {
        !           653:     w = Fp_res(stopoly_gen(m,p,v),*t, p);
        !           654:     w = try_pow(w,*t,p,q,r);
        !           655:     if (!w) continue;
        !           656:     /* set w = w - 1 */
        !           657:     w[2] = laddis((GEN)w[2], -1); /* w != 1 or -1 */
        !           658:     w = Fp_pol_gcd(*t,w, p); l=lgef(w)-3;
        !           659:     if (l && l!=dv) break;
        !           660:
        !           661:   }
        !           662:   w = normalize_mod_p(w, p);
        !           663:   w = gerepileupto(av, w);
        !           664:   l /= d; t[l]=Fp_deuc(*t,w,p); *t=w;
        !           665:   splitgen(m,t+l,d,p,q,r);
        !           666:   splitgen(m,t,  d,p,q,r);
        !           667: }
        !           668:
        !           669: /* factor f mod pp. If (simple) ouput only the degrees, not the factors */
        !           670: static GEN
        !           671: factcantor0(GEN f, GEN pp, long simple)
        !           672: {
        !           673:   long i,j,k,d,e,vf,p,nbfact,tetpil,av = avma;
        !           674:   GEN ex,y,p1,f2,g,g1,u,v,pd,q;
        !           675:   GEN *t;
        !           676:
        !           677:   if (!(d = factmod_init(&f, pp, &p))) { avma=av; return trivfact(); }
        !           678:   /* to hold factors and exponents */
        !           679:   t = (GEN*)cgetg(d+1,t_VEC); ex = new_chunk(d+1);
        !           680:   vf=varn(f); e = nbfact = 1;
        !           681:   f = lift_intern(f);
        !           682:   for(;;)
        !           683:   {
        !           684:     f2 = Fp_pol_gcd(f,derivpol(f), pp);
        !           685:     g1 = Fp_deuc(f,f2,pp);
        !           686:     k = 0;
        !           687:     while (lgef(g1)>3)
        !           688:     {
        !           689:       k++; if (p && !(k%p)) { k++; f2 = Fp_deuc(f2,g1,pp); }
        !           690:       p1 = Fp_pol_gcd(f2,g1, pp); u = g1; g1 = p1;
        !           691:       if (!gcmp1(p1))
        !           692:       {
        !           693:         u = Fp_deuc( u,p1,pp);
        !           694:         f2= Fp_deuc(f2,p1,pp);
        !           695:       }
        !           696:       if (lgef(u)>3)
        !           697:       {
        !           698:         /* here u is square-free (product of irred. of multiplicity e * k) */
        !           699:         pd=gun; v=polx[vf];
        !           700:         for (d=1; d <= (lgef(u)-3)>>1; d++)
        !           701:         {
        !           702:           pd=mulii(pd,pp); v=Fp_pow_mod_pol(v,pp, u,pp);
        !           703:           g = Fp_pol_gcd(gadd(v, gneg(polx[vf])), u, pp);
        !           704:
        !           705:           if (lgef(g)>3)
        !           706:           {
        !           707:            /* Ici g est produit de pol irred ayant tous le meme degre d; */
        !           708:             j=nbfact+(lgef(g)-3)/d;
        !           709:
        !           710:             if (simple)
        !           711:               for ( ; nbfact<j; nbfact++)
        !           712:                 { t[nbfact]=(GEN)d; ex[nbfact]=e*k; }
        !           713:             else
        !           714:             {
        !           715:               long r;
        !           716:               g = normalize_mod_p(g, pp);
        !           717:               t[nbfact]=g; q = subis(pd,1); /* also ok for p=2: unused */
        !           718:               r = vali(q); q = shifti(q,-r);
        !           719:              /* le premier parametre est un entier variable m qui sera
        !           720:               * converti en un polynome w dont les coeff sont ses digits en
        !           721:               * base p (initialement m = p --> X) pour faire pgcd de g avec
        !           722:               * w^(p^d-1)/2 jusqu'a casser. p = 2 will be treated separately.
        !           723:               */
        !           724:               if (p)
        !           725:                 split(p,t+nbfact,d,pp,q,r);
        !           726:               else
        !           727:                 splitgen(pp,t+nbfact,d,pp,q,r);
        !           728:               for (; nbfact<j; nbfact++) ex[nbfact]=e*k;
        !           729:             }
        !           730:             u=Fp_deuc(u,g,pp);
        !           731:             v=Fp_res(v,u,pp);
        !           732:           }
        !           733:         }
        !           734:         if (lgef(u)>3)
        !           735:         {
        !           736:           t[nbfact] = simple? (GEN)(lgef(u)-3): u;
        !           737:           ex[nbfact++]=e*k;
        !           738:         }
        !           739:       }
        !           740:     }
        !           741:     j = lgef(f2); if (j==3) break;
        !           742:
        !           743:     e*=p; j=(j-3)/p+3; setlg(f,j); setlgef(f,j);
        !           744:     for (i=2; i<j; i++) f[i]=f2[p*(i-2)+2];
        !           745:   }
        !           746:   tetpil=avma; y=cgetg(3,t_MAT);
        !           747:   if (!simple)
        !           748:   {
        !           749:     y[1]=(long)t; setlg(t, nbfact);
        !           750:     y[2]=(long)ex; (void)sort_factor(y,cmpii);
        !           751:   }
        !           752:   u=cgetg(nbfact,t_COL); y[1]=(long)u;
        !           753:   v=cgetg(nbfact,t_COL); y[2]=(long)v;
        !           754:   if (simple)
        !           755:     for (j=1; j<nbfact; j++)
        !           756:     {
        !           757:       u[j] = lstoi((long)t[j]);
        !           758:       v[j] = lstoi(ex[j]);
        !           759:     }
        !           760:   else
        !           761:     for (j=1; j<nbfact; j++)
        !           762:     {
        !           763:       u[j] = (long)Fp_pol(t[j], pp);
        !           764:       v[j] = lstoi(ex[j]);
        !           765:     }
        !           766:   return gerepile(av,tetpil,y);
        !           767: }
        !           768:
        !           769: GEN
        !           770: factcantor(GEN f, GEN p)
        !           771: {
        !           772:   return factcantor0(f,p,0);
        !           773: }
        !           774:
        !           775: GEN
        !           776: simplefactmod(GEN f, GEN p)
        !           777: {
        !           778:   return factcantor0(f,p,1);
        !           779: }
        !           780:
        !           781: /* vector of polynomials (in v) whose coeffs are given by the columns of x */
        !           782: GEN
        !           783: mat_to_vecpol(GEN x, long v)
        !           784: {
        !           785:   long i,j, lx = lg(x), lcol = lg(x[1]);
        !           786:   GEN y = cgetg(lx, t_VEC);
        !           787:
        !           788:   for (j=1; j<lx; j++)
        !           789:   {
        !           790:     GEN p1, col = (GEN)x[j];
        !           791:     long k = lcol;
        !           792:
        !           793:     while (k-- && gcmp0((GEN)col[k]));
        !           794:     i=k+2; p1=cgetg(i,t_POL);
        !           795:     p1[1] = evalsigne(1) | evallgef(i) | evalvarn(v);
        !           796:     col--; for (k=2; k<i; k++) p1[k] = col[k];
        !           797:     y[j] = (long)p1;
        !           798:   }
        !           799:   return y;
        !           800: }
        !           801:
        !           802: /* matrix whose entries are given by the coeffs of the polynomials in
        !           803:  * vector v (considered as degree n polynomials) */
        !           804: GEN
        !           805: vecpol_to_mat(GEN v, long n)
        !           806: {
        !           807:   long i,j,d,N = lg(v);
        !           808:   GEN p1,w, y = cgetg(N, t_MAT);
        !           809:   n++;
        !           810:   for (j=1; j<N; j++)
        !           811:   {
        !           812:     p1 = cgetg(n,t_COL); y[j] = (long)p1;
        !           813:     w = (GEN)v[j];
        !           814:     if (typ(w) != t_POL) { p1[1] = (long)w; i=2; }
        !           815:     else
        !           816:     {
        !           817:       d=lgef(w)-1; w++;
        !           818:       for (i=1; i<d; i++) p1[i] = w[i];
        !           819:     }
        !           820:     for ( ; i<n; i++) p1[i] = zero;
        !           821:   }
        !           822:   return y;
        !           823: }
        !           824:
        !           825: /* set x <-- x + c*y mod p */
        !           826: static void
        !           827: Fp_pol_addmul(GEN x, GEN y, long c, long p)
        !           828: {
        !           829:   long i,lx = lgef(x), ly = lgef(y), l = min(lx,ly);
        !           830:   if (p & ~MAXHALFULONG)
        !           831:   {
        !           832:     for (i=2; i<l;  i++) x[i] = ((ulong)x[i]+ (ulong)mulssmod(c,y[i],p)) % p;
        !           833:     for (   ; i<ly; i++) x[i] = mulssmod(c,y[i],p);
        !           834:   }
        !           835:   else
        !           836:   {
        !           837:     for (i=2; i<l;  i++) x[i] = ((ulong)x[i] + (ulong)(c*y[i])) % p;
        !           838:     for (   ; i<ly; i++) x[i] = (c*y[i]) % p;
        !           839:   }
        !           840:   do i--; while (i>1 && !x[i]);
        !           841:   if (i==1) setsigne(x,0); else { setsigne(x,1); setlgef(x,i+1); }
        !           842: }
        !           843:
        !           844: long
        !           845: split_berlekamp(GEN Q, GEN *t, GEN pp, GEN pps2)
        !           846: {
        !           847:   GEN u = *t, p1, p2, vker,v,w,pol;
        !           848:   long av,N = lgef(u)-3, d,i,j,kk,l1,l2,p, vu = varn(u);
        !           849:
        !           850:   if (DEBUGLEVEL > 7) timer2();
        !           851:   p = is_bigint(pp)? 0: pp[2];
        !           852:   setlg(Q, N+1); setlg(Q[1], N+1);
        !           853:   w = v = Fp_pow_mod_pol(polx[vu],pp,u,pp);
        !           854:   for (j=2; j<=N; j++)
        !           855:   {
        !           856:     p1 = (GEN)Q[j]; setlg(p1, N+1);
        !           857:     d=lgef(w)-1; p2 = w+1;
        !           858:     for (i=1; i<d ; i++) p1[i] = p2[i];
        !           859:     for (   ; i<=N; i++) p1[i] = zero;
        !           860:     p1[j] = laddis((GEN)p1[j], -1);
        !           861:     if (j < N)
        !           862:     {
        !           863:       av = avma;
        !           864:       w = gerepileupto(av, Fp_res(gmul(w,v), u, pp));
        !           865:     }
        !           866:   }
        !           867:   if (DEBUGLEVEL > 7) msgtimer("frobenius");
        !           868:   vker = mat_to_vecpol(ker_mod_p(Q,pp), vu);
        !           869:   if (DEBUGLEVEL > 7) msgtimer("kernel");
        !           870:   d = lg(vker)-1;
        !           871:   if (p)
        !           872:     for (i=1; i<=d; i++)
        !           873:     {
        !           874:       p1 = (GEN)vker[i];
        !           875:       for (j=2; j<lg(p1); j++) p1[j] = itos((GEN)p1[j]);
        !           876:     }
        !           877:   pol = cgetg(N+3,t_POL);
        !           878:
        !           879:   for (kk=1; kk<d; )
        !           880:   {
        !           881:     GEN polt;
        !           882:     if (p)
        !           883:     {
        !           884:       if (p==2)
        !           885:       {
        !           886:         pol[2] = ((mymyrand() & 0x1000) == 0);
        !           887:         pol[1] = evallgef(pol[2]? 3: 2);
        !           888:         for (i=2; i<=d; i++)
        !           889:           Fp_pol_addmul(pol, (GEN)vker[i], ((mymyrand() & 0x1000) == 0), p);
        !           890:       }
        !           891:       else
        !           892:       {
        !           893:         pol[2] = mymyrand()%p; /* vker[1] = 1 */
        !           894:         pol[1] = evallgef(pol[2]? 3: 2);
        !           895:         for (i=2; i<=d; i++)
        !           896:           Fp_pol_addmul(pol, (GEN)vker[i], mymyrand()%p, p);
        !           897:       }
        !           898:       polt = small_to_pol(pol+2, lgef(pol), p);
        !           899:       setvarn(polt,vu);
        !           900:     }
        !           901:     else
        !           902:     {
        !           903:       pol[2] = (long)genrand(pp);
        !           904:       pol[1] = evallgef(signe(pol[2])? 3: 2) | evalvarn(vu);
        !           905:       for (i=2; i<=d; i++)
        !           906:         pol = gadd(pol, gmul((GEN)vker[i], genrand(pp)));
        !           907:       polt = Fp_pol_red(pol,pp);
        !           908:     }
        !           909:     for (i=1; i<=kk && kk<d; i++)
        !           910:     {
        !           911:       p1=t[i-1]; l1=lgef(p1)-3;
        !           912:       if (l1>1)
        !           913:       {
        !           914:         av = avma; p2 = Fp_res(polt, p1, pp);
        !           915:         if (lgef(p2) <= 3) { avma=av; continue; }
        !           916:         p2 = Fp_pow_mod_pol(p2,pps2, p1,pp);
        !           917:         /* set p2 = p2 - 1 */
        !           918:         p2[2] = laddis((GEN)p2[2], -1);
        !           919:         p2 = Fp_pol_gcd(p1,p2, pp); l2=lgef(p2)-3;
        !           920:         if (l2>0 && l2<l1)
        !           921:         {
        !           922:           p2 = normalize_mod_p(p2, pp);
        !           923:           t[i-1] = p2; kk++;
        !           924:           t[kk-1] = Fp_deuc(p1,p2,pp);
        !           925:           if (DEBUGLEVEL > 7) msgtimer("new factor");
        !           926:         }
        !           927:         else avma = av;
        !           928:       }
        !           929:     }
        !           930:   }
        !           931:   return d;
        !           932: }
        !           933:
        !           934: GEN
        !           935: factmod(GEN f, GEN pp)
        !           936: {
        !           937:   long i,j,k,e,p,N,nbfact,av = avma,tetpil,d;
        !           938:   GEN pps2,ex,y,f2,p1,g1,Q,u,v, *t;
        !           939:
        !           940:   if (!(d = factmod_init(&f, pp, &p))) { avma=av; return trivfact(); }
        !           941:   /* to hold factors and exponents */
        !           942:   t = (GEN*)cgetg(d+1,t_VEC); ex = new_chunk(d+1);
        !           943:   e = nbfact = 1;
        !           944:   pps2 = shifti(pp,-1);
        !           945:
        !           946:   Q = cgetg(d+1,t_MAT);
        !           947:   for (i=1; i<=d; i++) Q[i] = lgetg(d+1, t_COL);
        !           948:   p1 = (GEN)Q[1];
        !           949:   for (i=1; i<=d; i++) p1[i] = zero;
        !           950:   for(;;)
        !           951:   {
        !           952:     f2 = Fp_pol_gcd(f,derivpol(f), pp);
        !           953:     g1 = gcmp1(f2)? f: Fp_deuc(f,f2,pp);
        !           954:     k = 0;
        !           955:     while (lgef(g1)>3)
        !           956:     {
        !           957:       k++; if (p && !(k%p)) { k++; f2 = Fp_deuc(f2,g1,pp); }
        !           958:       p1 = Fp_pol_gcd(f2,g1, pp); u = g1; g1 = p1;
        !           959:       if (!gcmp1(p1))
        !           960:       {
        !           961:         u = Fp_deuc( u,p1,pp);
        !           962:         f2= Fp_deuc(f2,p1,pp);
        !           963:       }
        !           964:       N = lgef(u)-3;
        !           965:       if (N)
        !           966:       {
        !           967:         /* here u is square-free (product of irred. of multiplicity e * k) */
        !           968:         t[nbfact] = normalize_mod_p(u,pp);
        !           969:         d = (N==1)? 1: split_berlekamp(Q, t+nbfact, pp, pps2);
        !           970:         for (j=0; j<d; j++) ex[nbfact+j] = e*k;
        !           971:         nbfact += d;
        !           972:       }
        !           973:     }
        !           974:     if (!p) break;
        !           975:     j=(lgef(f2)-3)/p+3; if (j==3) break;
        !           976:
        !           977:     e*=p; setlg(f,j); setlgef(f,j);
        !           978:     for (i=2; i<j; i++) f[i] = f2[p*(i-2)+2];
        !           979:   }
        !           980:   tetpil=avma; y=cgetg(3,t_MAT);
        !           981:   y[1]=(long)t; setlg(t, nbfact);
        !           982:   y[2]=(long)ex; (void)sort_factor(y,cmpii);
        !           983:   u=cgetg(nbfact,t_COL); y[1]=(long)u;
        !           984:   v=cgetg(nbfact,t_COL); y[2]=(long)v;
        !           985:   for (j=1; j<nbfact; j++)
        !           986:   {
        !           987:     u[j] = (long)Fp_pol(t[j], pp);
        !           988:     v[j] = lstoi(ex[j]);
        !           989:   }
        !           990:   return gerepile(av,tetpil,y);
        !           991: }
        !           992:
        !           993: GEN
        !           994: factormod0(GEN f, GEN p, long flag)
        !           995: {
        !           996:   switch(flag)
        !           997:   {
        !           998:     case 0: return factmod(f,p);
        !           999:     case 1: return simplefactmod(f,p);
        !          1000:     default: err(flagerr,"factormod");
        !          1001:   }
        !          1002:   return NULL; /* not reached */
        !          1003: }
        !          1004:
        !          1005: /*******************************************************************/
        !          1006: /*                                                                 */
        !          1007: /*                Recherche de racines  p-adiques                  */
        !          1008: /*                                                                 */
        !          1009: /*******************************************************************/
        !          1010: /* make f suitable for [root|factor]padic */
        !          1011: static GEN
        !          1012: padic_pol_to_int(GEN f)
        !          1013: {
        !          1014:   long i, l = lgef(f);
        !          1015:   f = gdiv(f,content(f));
        !          1016:   for (i=2; i<l; i++)
        !          1017:     switch(typ(f[i]))
        !          1018:     {
        !          1019:       case t_INT: break;
        !          1020:       case t_PADIC: f[i] = ltrunc((GEN)f[i]); break;
        !          1021:       default: err(talker,"incorrect coeffs in padic_pol_to_int");
        !          1022:     }
        !          1023:   return f;
        !          1024: }
        !          1025:
        !          1026: /* return x + O(pr), x in Z, pr = p^r */
        !          1027: static GEN
        !          1028: int_to_padic(GEN x, GEN p, GEN pr, long r)
        !          1029: {
        !          1030:   GEN p1,y;
        !          1031:   long v;
        !          1032:   if (typ(x) == t_PADIC) return gcopy(x);
        !          1033:   y = cgetg(5,t_PADIC);
        !          1034:   if (signe(x) && (v = pvaluation(x,p,&p1)) < r)
        !          1035:   {
        !          1036:     y[4] = lmodii(p1,pr); r -= v;
        !          1037:   }
        !          1038:   else
        !          1039:   {
        !          1040:     y[4] = zero; v = r; r = 0;
        !          1041:   }
        !          1042:   y[3] = (long)pr;
        !          1043:   y[2] = (long)p;
        !          1044:   y[1] = evalprecp(r)|evalvalp(v); return y;
        !          1045: }
        !          1046:
        !          1047: /* return x + O(p^r), x in Z[X] */
        !          1048: static GEN
        !          1049: pol_to_padic(GEN x, GEN pr, GEN p, long r)
        !          1050: {
        !          1051:   long i,lx = lgef(x);
        !          1052:   GEN z = cgetg(lx,t_POL);
        !          1053:   for (i=2; i<lx; i++)
        !          1054:     z[i] = (long)int_to_padic((GEN)x[i],p,pr,r);
        !          1055:   z[1] = x[1]; return z;
        !          1056: }
        !          1057:
        !          1058: static GEN
        !          1059: padic_trivfact(GEN x, GEN p, long r)
        !          1060: {
        !          1061:   GEN p1, y = cgetg(3,t_MAT);
        !          1062:   p1=cgetg(2,t_COL); y[1]=(long)p1; p = icopy(p);
        !          1063:   p1[1]=(long)pol_to_padic(x,gpowgs(p,r),p,r);
        !          1064:   p1=cgetg(2,t_COL); y[2]=(long)p1;
        !          1065:   p1[1]=un; return y;
        !          1066: }
        !          1067:
        !          1068: /* a etant un p-adique, retourne le vecteur des racines p-adiques de f
        !          1069:  * congrues a a modulo p dans le cas ou on suppose f(a) congru a 0 modulo p
        !          1070:  * (ou a 4 si p=2).
        !          1071:  */
        !          1072: GEN
        !          1073: apprgen(GEN f, GEN a)
        !          1074: {
        !          1075:   GEN fp,p1,p,pro,x,x2,u,ip,quatre;
        !          1076:   long av=avma,tetpil,v,ps,i,j,k,lu,n,fl2;
        !          1077:
        !          1078:   if (typ(f)!=t_POL) err(notpoler,"apprgen");
        !          1079:   if (gcmp0(f)) err(zeropoler,"apprgen");
        !          1080:   if (typ(a) != t_PADIC) err(rootper1);
        !          1081:   f = padic_pol_to_int(f);
        !          1082:   fp=derivpol(f); p1=ggcd(f,fp);
        !          1083:   if (lgef(p1)>3) { f=gdeuc(f,p1); fp=derivpol(f); }
        !          1084:   p=(GEN)a[2]; p1=poleval(f,a);
        !          1085:   v=ggval(p1,p); if (v <= 0) err(rootper2);
        !          1086:   fl2=egalii(p,gdeux);
        !          1087:   if (fl2)
        !          1088:   {
        !          1089:     if (v==1) err(rootper2);
        !          1090:     quatre=stoi(4);
        !          1091:   }
        !          1092:   v=ggval(poleval(fp,a),p);
        !          1093:   if (!v) /* simple zero */
        !          1094:   {
        !          1095:     while (!gcmp0(p1))
        !          1096:     {
        !          1097:       a = gsub(a,gdiv(p1,poleval(fp,a)));
        !          1098:       p1 = poleval(f,a);
        !          1099:     }
        !          1100:     tetpil=avma; pro=cgetg(2,t_VEC); pro[1]=lcopy(a);
        !          1101:     return gerepile(av,tetpil,pro);
        !          1102:   }
        !          1103:   n=lgef(f)-3; pro=cgetg(n+1,t_VEC);
        !          1104:   p1=poleval(f,gadd(a,gmul(fl2?quatre:p,polx[varn(f)])));
        !          1105:   if (!gcmp0(p1)) p1=gdiv(p1,gpuigs(p,ggval(p1,p)));
        !          1106:
        !          1107:   if (is_bigint(p)) err(impl,"apprgen for p>=2^31");
        !          1108:   x = ggrandocp(p, valp(a) | precp(a));
        !          1109:   if (fl2)
        !          1110:   {
        !          1111:     ps=4; x2=ggrandocp(p,2); p=quatre;
        !          1112:   }
        !          1113:   else
        !          1114:   {
        !          1115:     ps=itos(p); x2=ggrandocp(p,1);
        !          1116:   }
        !          1117:   for (j=0,i=0; i<ps; i++)
        !          1118:   {
        !          1119:     ip=stoi(i);
        !          1120:     if (gcmp0(poleval(p1,gadd(ip,x2))))
        !          1121:     {
        !          1122:       u=apprgen(p1,gadd(x,ip)); lu=lg(u);
        !          1123:       for (k=1; k<lu; k++)
        !          1124:       {
        !          1125:         j++; pro[j]=ladd(a,gmul(p,(GEN)u[k]));
        !          1126:       }
        !          1127:     }
        !          1128:   }
        !          1129:   tetpil=avma; setlg(pro,j+1);
        !          1130:   return gerepile(av,tetpil,gcopy(pro));
        !          1131: }
        !          1132:
        !          1133: /* Retourne le vecteur des racines p-adiques de f en precision r */
        !          1134: GEN
        !          1135: rootpadic(GEN f, GEN p, long r)
        !          1136: {
        !          1137:   GEN fp,y,z,p1,pr,rac;
        !          1138:   long lx,i,j,k,n,av=avma,tetpil,fl2;
        !          1139:
        !          1140:   if (typ(f)!=t_POL) err(notpoler,"rootpadic");
        !          1141:   if (gcmp0(f)) err(zeropoler,"rootpadic");
        !          1142:   if (r<=0) err(rootper4);
        !          1143:   f = padic_pol_to_int(f);
        !          1144:   fp=derivpol(f); p1=ggcd(f,fp);
        !          1145:   if (lgef(p1)>3) { f=gdeuc(f,p1); fp=derivpol(f); }
        !          1146:   fl2=egalii(p,gdeux); rac=(fl2 && r>=2)? rootmod(f,stoi(4)): rootmod(f,p);
        !          1147:   lx=lg(rac); p=gclone(p);
        !          1148:   if (r==1)
        !          1149:   {
        !          1150:     tetpil=avma; y=cgetg(lx,t_COL);
        !          1151:     for (i=1; i<lx; i++)
        !          1152:     {
        !          1153:       z=cgetg(5,t_PADIC); y[i]=(long)z;
        !          1154:       z[1] = evalprecp(1)|evalvalp(0);
        !          1155:       z[2] = z[3] = (long)p;
        !          1156:       z[4] = lcopy(gmael(rac,i,2));
        !          1157:     }
        !          1158:     return gerepile(av,tetpil,y);
        !          1159:   }
        !          1160:   n=lgef(f)-3; y=cgetg(n+1,t_COL);
        !          1161:   j=0; pr = NULL;
        !          1162:   z = cgetg(5,t_PADIC);
        !          1163:   z[2] = (long)p;
        !          1164:   for (i=1; i<lx; i++)
        !          1165:   {
        !          1166:     p1 = gmael(rac,i,2);
        !          1167:     if (signe(p1))
        !          1168:     {
        !          1169:       if (!fl2 || mod2(p1))
        !          1170:       {
        !          1171:         z[1] = evalvalp(0)|evalprecp(r);
        !          1172:         z[4] = (long)p1;
        !          1173:       }
        !          1174:       else
        !          1175:       {
        !          1176:         z[1] = evalvalp(1)|evalprecp(r);
        !          1177:         z[4] = un;
        !          1178:       }
        !          1179:       if (!pr) pr=gpuigs(p,r);
        !          1180:       z[3] = (long)pr;
        !          1181:     }
        !          1182:     else
        !          1183:     {
        !          1184:       z[1] = evalvalp(r);
        !          1185:       z[3] = un;
        !          1186:       z[4] = (long)p1;
        !          1187:     }
        !          1188:     p1 = apprgen(f,z);
        !          1189:     for (k=1; k<lg(p1); k++) y[++j]=p1[k];
        !          1190:   }
        !          1191:   tetpil=avma; setlg(y,j+1);
        !          1192:   return gerepile(av,tetpil,gcopy(y));
        !          1193: }
        !          1194:
        !          1195: /* a usage interne. Pas de verifs ni de gestion de pile. On suppose que f est
        !          1196:  * un polynome a coeffs dans Z de degre n ayant n racines distinctes mod p, et
        !          1197:  * p>2, r>=2. On rend les n racines p-adiques en precision r si flall>0,
        !          1198:  * 1 seule si flall=0
        !          1199:  */
        !          1200: GEN
        !          1201: rootpadicfast(GEN f, GEN p, long r, long flall)
        !          1202: {
        !          1203:   GEN rac,fp,y,z,p1,p2;
        !          1204:   long i,e,n;
        !          1205:
        !          1206:   rac=rootmod(f,p); n=flall? lgef(f)-3: 1;
        !          1207:   fp=derivpol(f); y=cgetg(n+1,t_COL);
        !          1208:   p=gclone(p); p2=NULL;
        !          1209:   z=cgetg(5,t_PADIC); z[2]=(long)p;
        !          1210:   for (i=1; i<=n; i++)
        !          1211:   {
        !          1212:     p1=gmael(rac,i,2);
        !          1213:     if (signe(p1))
        !          1214:     {
        !          1215:       if (!p2) p2=sqri(p);
        !          1216:       z[1] = evalvalp(0)|evalprecp(2);
        !          1217:       z[3] = (long)p2;
        !          1218:     }
        !          1219:     else
        !          1220:     {
        !          1221:       z[1] = evalvalp(2);
        !          1222:       z[3] = un;
        !          1223:     }
        !          1224:     z[4] = (long)p1; p1 = z;
        !          1225:     for(e=2;;)
        !          1226:     {
        !          1227:       p1 = gsub(p1, gdiv(poleval(f,p1),poleval(fp,p1)));
        !          1228:       if (e==r) break;
        !          1229:       e<<=1; if (e>r) e=r;
        !          1230:       p1 = gprec(p1,e);
        !          1231:     }
        !          1232:     y[i] = (long)p1;
        !          1233:   }
        !          1234:   return y;
        !          1235: }
        !          1236:
        !          1237: static long
        !          1238: getprec(GEN x, long prec, GEN *p)
        !          1239: {
        !          1240:   long i,e;
        !          1241:   GEN p1;
        !          1242:
        !          1243:   for (i = lgef(x)-1; i>1; i--)
        !          1244:   {
        !          1245:     p1=(GEN)x[i];
        !          1246:     if (typ(p1)==t_PADIC)
        !          1247:     {
        !          1248:       e=valp(p1); if (signe(p1[4])) e += precp(p1);
        !          1249:       if (e<prec) prec = e; *p = (GEN)p1[2];
        !          1250:     }
        !          1251:   }
        !          1252:   return prec;
        !          1253: }
        !          1254:
        !          1255: /* a appartenant a une extension finie de Q_p, retourne le vecteur des
        !          1256:  * racines de f congrues a a modulo p dans le cas ou on suppose f(a) congru a
        !          1257:  * 0 modulo p (ou a 4 si p=2).
        !          1258:  */
        !          1259: GEN
        !          1260: apprgen9(GEN f, GEN a)
        !          1261: {
        !          1262:   GEN fp,p1,p,pro,x,x2,u,ip,t,vecg,quatre;
        !          1263:   long av=avma,tetpil,v,ps_1,i,j,k,lu,n,prec,d,va,fl2;
        !          1264:
        !          1265:   if (typ(f)!=t_POL) err(notpoler,"apprgen9");
        !          1266:   if (gcmp0(f)) err(zeropoler,"apprgen9");
        !          1267:   if (typ(a)==t_PADIC) return apprgen(f,a);
        !          1268:   if (typ(a)!=t_POLMOD || typ(a[2])!=t_POL) err(rootper1);
        !          1269:   fp=derivpol(f); p1=ggcd(f,fp);
        !          1270:   if (lgef(p1)>3) { f=gdeuc(f,p1); fp=derivpol(f); }
        !          1271:   t=(GEN)a[1];
        !          1272:   prec = getprec((GEN)a[2], BIGINT, &p);
        !          1273:   prec = getprec(t, prec, &p);
        !          1274:   if (prec==BIGINT) err(rootper1);
        !          1275:
        !          1276:   p1=poleval(f,a); v=ggval(lift_intern(p1),p); if (v<=0) err(rootper2);
        !          1277:   fl2=egalii(p,gdeux);
        !          1278:   if (fl2)
        !          1279:   {
        !          1280:     if (v==1) err(rootper2);
        !          1281:     quatre=stoi(4);
        !          1282:   }
        !          1283:   v=ggval(lift_intern(poleval(fp,a)), p);
        !          1284:   if (!v)
        !          1285:   {
        !          1286:     while (!gcmp0(p1))
        !          1287:     {
        !          1288:       a = gsub(a, gdiv(p1,poleval(fp,a)));
        !          1289:       p1 = poleval(f,a);
        !          1290:     }
        !          1291:     tetpil=avma; pro=cgetg(2,t_COL); pro[1]=lcopy(a);
        !          1292:     return gerepile(av,tetpil,pro);
        !          1293:   }
        !          1294:   n=lgef(f)-3; pro=cgetg(n+1,t_COL); j=0;
        !          1295:   p1=poleval(f,gadd(a,gmul(fl2?quatre:p,polx[varn(f)])));
        !          1296:   if (!gcmp0(p1)) p1=gdiv(p1,gpuigs(p,ggval(p1,p)));
        !          1297:
        !          1298:   if (is_bigint(p)) err(impl,"apprgen9 for p>=2^31");
        !          1299:   x=gmodulcp(ggrandocp(p,prec), t);
        !          1300:   if (fl2)
        !          1301:   {
        !          1302:     ps_1=3; x2=ggrandocp(p,2); p=quatre;
        !          1303:   }
        !          1304:   else
        !          1305:   {
        !          1306:     ps_1=itos(p)-1; x2=ggrandocp(p,1);
        !          1307:   }
        !          1308:   d=lgef(t)-3; vecg=cgetg(d+1,t_COL);
        !          1309:   for (i=1; i<=d; i++)
        !          1310:     vecg[i] = (long)setloop(gzero);
        !          1311:   va=varn(t);
        !          1312:   for(;;) /* loop through F_q */
        !          1313:   {
        !          1314:     ip=gmodulcp(gtopoly(vecg,va),t);
        !          1315:     if (gcmp0(poleval(p1,gadd(ip,x2))))
        !          1316:     {
        !          1317:       u=apprgen9(p1,gadd(ip,x)); lu=lg(u);
        !          1318:       for (k=1; k<lu; k++)
        !          1319:       {
        !          1320:         j++; pro[j]=ladd(a,gmul(p,(GEN)u[k]));
        !          1321:       }
        !          1322:     }
        !          1323:     for (i=d; i; i--)
        !          1324:     {
        !          1325:       p1 = (GEN)vecg[i];
        !          1326:       if (p1[2] != ps_1) { (void)incloop(p1); break; }
        !          1327:       affsi(0, p1);
        !          1328:     }
        !          1329:     if (!i) break;
        !          1330:   }
        !          1331:   tetpil=avma; setlg(pro,j+1);
        !          1332:   return gerepile(av,tetpil,gcopy(pro));
        !          1333: }
        !          1334:
        !          1335: /*****************************************/
        !          1336: /*  Factorisation p-adique d'un polynome */
        !          1337: /*****************************************/
        !          1338:
        !          1339: /* factorise le polynome T=nf[1] dans Zp avec la precision pr */
        !          1340: static GEN
        !          1341: padicff2(GEN nf,GEN p,long pr)
        !          1342: {
        !          1343:   long N=lgef(nf[1])-3,i,j,d,l;
        !          1344:   GEN mat,V,D,fa,p1,pk,dec_p,pke,a,theta;
        !          1345:
        !          1346:   pk=gpuigs(p,pr); dec_p=primedec(nf,p);
        !          1347:   l=lg(dec_p); fa=cgetg(l,t_COL);
        !          1348:   for (i=1; i<l; i++)
        !          1349:   {
        !          1350:     p1 = (GEN)dec_p[i];
        !          1351:     pke = idealpows(nf,p1, pr * itos((GEN)p1[3]));
        !          1352:     p1=smith2(pke); V=(GEN)p1[3]; D=(GEN)p1[1];
        !          1353:     for (d=1; d<=N; d++)
        !          1354:       if (! egalii(gcoeff(V,d,d),pk)) break;
        !          1355:     a=ginv(D); theta=gmael(nf,8,2); mat=cgetg(d,t_MAT);
        !          1356:     for (j=1; j<d; j++)
        !          1357:     {
        !          1358:       p1 = gmul(D, element_mul(nf,theta,(GEN)a[j]));
        !          1359:       setlg(p1,d); mat[j]=(long)p1;
        !          1360:     }
        !          1361:     fa[i]=(long)caradj(mat,0,NULL);
        !          1362:   }
        !          1363:   a = cgetg(l,t_COL); pk = icopy(pk);
        !          1364:   for (i=1; i<l; i++)
        !          1365:     a[i] = (long)pol_to_padic((GEN)fa[i],pk,p,pr);
        !          1366:   return a;
        !          1367: }
        !          1368:
        !          1369: static GEN
        !          1370: padicff(GEN x,GEN p,long pr)
        !          1371: {
        !          1372:   GEN q,bas,mul,dx,nf,mat;
        !          1373:   long n=lgef(x)-3,av=avma;
        !          1374:
        !          1375:   nf=cgetg(10,t_VEC); nf[1]=(long)x; dx=discsr(x);
        !          1376:   mat=cgetg(3,t_MAT); mat[1]=lgetg(3,t_COL); mat[2]=lgetg(3,t_COL);
        !          1377:   coeff(mat,1,1)=(long)p; coeff(mat,1,2)=lstoi(pvaluation(dx,p,&q));
        !          1378:   coeff(mat,2,1)=(long)q; coeff(mat,2,2)=un;
        !          1379:   bas=allbase4(x,(long)mat,(GEN*)(nf+3),NULL);
        !          1380:   if (!carrecomplet(divii(dx,(GEN)nf[3]),(GEN*)(nf+4)))
        !          1381:     err(bugparier,"factorpadic2 (incorrect discriminant)");
        !          1382:   mul = get_mul_table(x,bas,NULL);
        !          1383:   nf[7]=(long)bas;
        !          1384:   nf[8]=linv(vecpol_to_mat(bas,n));
        !          1385:   nf[9]=lmul((GEN)nf[8],mul); nf[2]=nf[5]=nf[6]=zero;
        !          1386:   return gerepileupto(av,padicff2(nf,p,pr));
        !          1387: }
        !          1388:
        !          1389: GEN
        !          1390: factorpadic2(GEN x, GEN p, long r)
        !          1391: {
        !          1392:   long av=avma,av2,k,i,j,i1,f,nbfac;
        !          1393:   GEN res,p1,p2,y,d,a,ap,t,v,w;
        !          1394:   GEN *fa;
        !          1395:
        !          1396:   if (typ(x)!=t_POL) err(notpoler,"factorpadic");
        !          1397:   if (gcmp0(x)) err(zeropoler,"factorpadic");
        !          1398:   if (r<=0) err(rootper4);
        !          1399:
        !          1400:   if (lgef(x)==3) return trivfact();
        !          1401:   if (lgef(x)==4) return padic_trivfact(x,p,r);
        !          1402:   y=cgetg(3,t_MAT);
        !          1403:   fa = (GEN*)new_chunk(lgef(x)-2);
        !          1404:   d=content(x); a=gdiv(x,d);
        !          1405:   ap=derivpol(a); t=ggcd(a,ap); v=gdeuc(a,t);
        !          1406:   w=gdeuc(ap,t); j=0; f=1; nbfac=0;
        !          1407:   while (f)
        !          1408:   {
        !          1409:     j++; w=gsub(w,derivpol(v)); f=signe(w);
        !          1410:     if (f) { res=ggcd(v,w); v=gdeuc(v,res); w=gdeuc(w,res); }
        !          1411:     else res=v;
        !          1412:     fa[j]=(lgef(res)>3) ? padicff(res,p,r) : cgetg(1,t_COL);
        !          1413:     nbfac += (lg(fa[j])-1);
        !          1414:   }
        !          1415:   av2=avma; y=cgetg(3,t_MAT);
        !          1416:   p1=cgetg(nbfac+1,t_COL); y[1]=(long)p1;
        !          1417:   p2=cgetg(nbfac+1,t_COL); y[2]=(long)p2;
        !          1418:   for (i=1,k=0; i<=j; i++)
        !          1419:     for (i1=1; i1<lg(fa[i]); i1++)
        !          1420:     {
        !          1421:       p1[++k]=lcopy((GEN)fa[i][i1]); p2[k]=lstoi(i);
        !          1422:     }
        !          1423:   return gerepile(av,av2,y);
        !          1424: }
        !          1425:
        !          1426: /*******************************************************************/
        !          1427: /*                                                                 */
        !          1428: /*                FACTORISATION P-adique avec ROUND 4              */
        !          1429: /*                                                                 */
        !          1430: /*******************************************************************/
        !          1431: GEN polmodi(GEN x, GEN y);
        !          1432: GEN polmodi_keep(GEN x, GEN y);
        !          1433:
        !          1434: static GEN
        !          1435: Decomppadic(GEN p,long r,GEN f,long mf,GEN theta,GEN chi,GEN nu)
        !          1436: {
        !          1437:   GEN pk,ph,pdr,unmodp;
        !          1438:   GEN pr,res,b1,b2,b3,a1,e,f1,f2;
        !          1439:   long valk;
        !          1440:
        !          1441:   if (DEBUGLEVEL>=3)
        !          1442:   {
        !          1443:     fprintferr("  entering Decomp_padic ");
        !          1444:     if (DEBUGLEVEL>=4)
        !          1445:     {
        !          1446:       fprintferr("with params: p=%Z, exponent=%ld, prec=%ld\n", p,mf,r);
        !          1447:       fprintferr("  f=%Z",f);
        !          1448:     }
        !          1449:     fprintferr("\n");
        !          1450:   }
        !          1451:   unmodp=gmodulsg(1,p);
        !          1452:
        !          1453:   pdr = respm(f, derivpol(f), gpuigs(p,mf));
        !          1454:
        !          1455:   b1=lift_intern(gmul(chi,unmodp)); a1=gun;
        !          1456:   b2=gun; b3=lift_intern(gmul(nu,unmodp));
        !          1457:   while (lgef(b3) > 3)
        !          1458:   {
        !          1459:     GEN p1;
        !          1460:     b1 = Fp_deuc(b1,b3, p);
        !          1461:     b2 = Fp_pol_red(gmul(b2,b3), p);
        !          1462:     b3 = Fp_pol_extgcd(b2,b1, p, &a1,&p1);
        !          1463:     p1 = leading_term(b3);
        !          1464:     if (!gcmp1(p1))
        !          1465:     {
        !          1466:       p1 = mpinvmod(p1,p);
        !          1467:       b3 = gmul(b3,p1);
        !          1468:       a1 = gmul(a1,p1);
        !          1469:     }
        !          1470:   }
        !          1471:   e=eleval(f,Fp_pol_red(gmul(a1,b2), p),theta);
        !          1472:   if (padicprec(e,p) > 0)
        !          1473:     e=gdiv(polmodi(gmul(pdr,e), mulii(pdr,p)),pdr);
        !          1474:
        !          1475:   pk=p; pr=gpuigs(p,r); ph=mulii(pdr,pr); valk = 1;
        !          1476:   /* E(t)-e(t) belongs to p^k Op, which is contained in p^(k-df)*Zp[xi] */
        !          1477:   while (cmpii(pk,ph) < 0)
        !          1478:   {
        !          1479:     e = gmul(e,gmul(e,gsubsg(3,gmul2n(e,1))));
        !          1480:     e = gres(e,f); pk=sqri(pk); valk <<= 1;
        !          1481:     if (valk<=padicprec(e,p))
        !          1482:       e = gdiv(polmodi(gmul(pdr,e), mulii(pk,pdr)), pdr);
        !          1483:   }
        !          1484:   f1=gcdpm(f,gmul(pdr,gsubsg(1,e)), ph);
        !          1485:   f1 = Fp_res(f1,f, pr);
        !          1486:   f2 = Fp_res(Fp_deuc(f,f1, pr), f, pr);
        !          1487:
        !          1488:   if (DEBUGLEVEL>=4)
        !          1489:   {
        !          1490:     fprintferr("  leaving Decomp_padic with parameters: ");
        !          1491:     fprintferr("f1=%Z, f2=%Z\n",f1,f2);
        !          1492:   }
        !          1493:   b1=factorpadic4(f1,p,r);
        !          1494:   b2=factorpadic4(f2,p,r); res=cgetg(3,t_MAT);
        !          1495:   res[1]=lconcat((GEN)b1[1],(GEN)b2[1]);
        !          1496:   res[2]=lconcat((GEN)b1[2],(GEN)b2[2]); return res;
        !          1497: }
        !          1498:
        !          1499: static GEN
        !          1500: nilordpadic(GEN p,long r,GEN fx,long mf,GEN gx)
        !          1501: {
        !          1502:   long Da,Na,La,Ma,first=1,n,v=varn(fx);
        !          1503:   GEN alpha,chi,nu,eta,w,phi,pmf,Dchi;
        !          1504:
        !          1505:   if (DEBUGLEVEL>=3)
        !          1506:   {
        !          1507:     fprintferr("  entering Nilord_padic ");
        !          1508:     if (DEBUGLEVEL>=4)
        !          1509:     {
        !          1510:       fprintferr("with parameters: p=%Z, expo=%ld\n",p,mf);
        !          1511:       fprintferr("  fx=%Z, gx=%Z",fx,gx);
        !          1512:     }
        !          1513:     fprintferr("\n");
        !          1514:   }
        !          1515:   pmf=gpuigs(p,mf+1); alpha=polx[v]; n=lgef(fx)-3;
        !          1516:   for(;;)
        !          1517:   {
        !          1518:     if (first) { chi=fx; nu=gx; first=0; }
        !          1519:     else
        !          1520:     {
        !          1521:       w=factcp(p,fx,alpha);
        !          1522:       chi=(GEN)w[1]; nu=(GEN)w[2];
        !          1523:       if (cmpis((GEN)w[3],1)==1)
        !          1524:         return Decomppadic(p,r,fx,mf,alpha,chi,nu);
        !          1525:     }
        !          1526:     Da=lgef(nu)-3; Na=n/Da;
        !          1527:
        !          1528:     if (mf+1<=padicprec(chi,p))
        !          1529:     {
        !          1530:       Dchi=modii(discsr(polmodi_keep(chi,pmf)), pmf);
        !          1531:       if (gcmp0(Dchi)) Dchi=discsr(chi);
        !          1532:     }
        !          1533:     else
        !          1534:       Dchi=discsr(chi);
        !          1535:
        !          1536:     if (gcmp0(Dchi))
        !          1537:       alpha=gadd(alpha,gmul(p,polx[v]));
        !          1538:     else
        !          1539:     {
        !          1540:       if (vstar(p,chi)[0] > 0)
        !          1541:         alpha=gadd(alpha,gun);
        !          1542:       else
        !          1543:       {
        !          1544:         eta=setup(p,chi,polx[v],nu, &La, &Ma);
        !          1545:         if (La>1)
        !          1546:           alpha=gadd(alpha,eleval(fx,eta,alpha));
        !          1547:         else
        !          1548:         {
        !          1549:           if (Ma==Na) return NULL; /* correspond to [fx; 1] */
        !          1550:           w=bsrch(p,chi,ggval(Dchi,p),eta,Ma);
        !          1551:           phi=eleval(fx,(GEN)w[2],alpha);
        !          1552:           if (gcmp1((GEN)w[1]))
        !          1553:             return Decomppadic(p,r,fx,mf,phi,(GEN)w[3],(GEN)w[4]);
        !          1554:           alpha=phi;
        !          1555:         }
        !          1556:       }
        !          1557:     }
        !          1558:   }
        !          1559: }
        !          1560:
        !          1561: static GEN
        !          1562: squarefree(GEN f, GEN *ex)
        !          1563: {
        !          1564:   GEN T,V,W,A,B;
        !          1565:   long n,i,k;
        !          1566:
        !          1567:   T=ggcd(derivpol(f),f); V=gdeuc(f,T);
        !          1568:   n=lgef(f)-2; A=cgetg(n,t_COL); B=cgetg(n,t_COL);
        !          1569:   k=1; i=1;
        !          1570:   do
        !          1571:   {
        !          1572:     W=ggcd(T,V); T=gdeuc(T,W);
        !          1573:     if (lgef(V) != lgef(W))
        !          1574:     {
        !          1575:       A[i]=ldeuc(V,W); B[i]=k; i++;
        !          1576:     }
        !          1577:     k++; V=W;
        !          1578:   }
        !          1579:   while (lgef(V)>3);
        !          1580:   setlg(A,i); *ex=B; return A;
        !          1581: }
        !          1582:
        !          1583: GEN
        !          1584: factorpadic4(GEN f,GEN p,long prec)
        !          1585: {
        !          1586:   GEN w,g,poly,fx,y,p1,p2,ex,pols,exps,ppow,lead;
        !          1587:   long v=varn(f),n=lgef(f)-3,av,tetpil,mfx,i,k,j,m,r,pr;
        !          1588:
        !          1589:   if (typ(f)!=t_POL) err(notpoler,"factorpadic");
        !          1590:   if (gcmp0(f)) err(zeropoler,"factorpadic");
        !          1591:   if (prec<=0) err(rootper4);
        !          1592:
        !          1593:   if (n==0) return trivfact();
        !          1594:   av=avma; f = padic_pol_to_int(f);
        !          1595:   if (n==1) return gerepileupto(av, padic_trivfact(f,p,prec));
        !          1596:   f = pol_to_monic(f, &lead);
        !          1597:   pr = lead? prec + (n-1) * ggval(lead,p): prec;
        !          1598:   poly=squarefree(f,&ex);
        !          1599:   pols=cgetg(n+1,t_COL);
        !          1600:   exps=cgetg(n+1,t_COL); n = lg(poly);
        !          1601:   for (j=1,i=1; i<n; i++)
        !          1602:   {
        !          1603:     long av1 = avma;
        !          1604:     fx=(GEN)poly[i]; mfx=ggval(discsr(fx),p);
        !          1605:     m = (pr<=mfx)?mfx+1:pr;
        !          1606:     w = (GEN)factmod(fx,p)[1]; r = lg(w)-1;
        !          1607:     g = lift_intern((GEN)w[r]);
        !          1608:     p2 = (r == 1)? nilordpadic(p,m,fx,mfx,g)
        !          1609:                  : Decomppadic(p,m,fx,mfx,polx[v],fx,g);
        !          1610:     if (p2)
        !          1611:     {
        !          1612:       p2 = gerepileupto(av1,p2);
        !          1613:       p1 = (GEN)p2[1];
        !          1614:       p2 = (GEN)p2[2];
        !          1615:       for (k=1; k<lg(p1); k++,j++)
        !          1616:       {
        !          1617:         pols[j]=p1[k];
        !          1618:         exps[j]=lmulis((GEN)p2[k],ex[i]);
        !          1619:       }
        !          1620:     }
        !          1621:     else
        !          1622:     {
        !          1623:       avma=av1;
        !          1624:       pols[j]=(long)fx;
        !          1625:       exps[j]=lstoi(ex[i]); j++;
        !          1626:     }
        !          1627:   }
        !          1628:   if (lead)
        !          1629:   {
        !          1630:     p1 = gmul(polx[v],lead);
        !          1631:     for (i=1; i<j; i++)
        !          1632:     {
        !          1633:       p2 = poleval((GEN)pols[i], p1);
        !          1634:       pols[i] = ldiv(p2, content(p2));
        !          1635:     }
        !          1636:   }
        !          1637:
        !          1638:   tetpil=avma; y=cgetg(3,t_MAT);
        !          1639:   p1 = cgetg(j,t_COL); ppow = gpowgs(p,prec); p = icopy(p);
        !          1640:   for (i=1; i<j; i++)
        !          1641:     p1[i] = (long)pol_to_padic((GEN)pols[i],ppow,p,prec);
        !          1642:   y[1]=(long)p1; setlg(exps,j);
        !          1643:   y[2]=lcopy(exps); return gerepile(av,tetpil,y);
        !          1644: }
        !          1645:
        !          1646: GEN
        !          1647: factorpadic0(GEN f,GEN p,long r,long flag)
        !          1648: {
        !          1649:   switch(flag)
        !          1650:   {
        !          1651:      case 0: return factorpadic4(f,p,r);
        !          1652:      case 1: return factorpadic2(f,p,r);
        !          1653:      default: err(flagerr,"factorpadic");
        !          1654:   }
        !          1655:   return NULL; /* not reached */
        !          1656: }
        !          1657:
        !          1658: /*******************************************************************/
        !          1659: /*                                                                 */
        !          1660: /*                     FACTORISATION DANS F_q                      */
        !          1661: /*                                                                 */
        !          1662: /*******************************************************************/
        !          1663: static GEN
        !          1664: to_fq(GEN x, GEN a, GEN p)
        !          1665: {
        !          1666:   long i,lx = lgef(x);
        !          1667:   GEN p1, z = cgetg(3,t_POLMOD), pol = cgetg(lx,t_POL);
        !          1668:   pol[1] = x[1];
        !          1669:   for (i=2; i<lx; i++)
        !          1670:   {
        !          1671:     p1 = cgetg(3,t_INTMOD);
        !          1672:     p1[1] = (long)p;
        !          1673:     p1[2] = x[i]; pol[i] = (long)p1;
        !          1674:   }
        !          1675:   /* assume deg(pol) < deg(a) */
        !          1676:   z[1] = (long)a;
        !          1677:   z[2] = (long)pol; return z;
        !          1678: }
        !          1679:
        !          1680: /* pol. in v whose coeff are the digits of m in base qq */
        !          1681: static GEN
        !          1682: stopoly9(GEN pg, GEN mm, GEN qq, long v, GEN a)
        !          1683: {
        !          1684:   long q,l,m,l1,i,va, smll = !is_bigint(mm), p = pg[2];
        !          1685:   GEN y,p1,r;
        !          1686:
        !          1687:   y = cgetg(bit_accuracy(lgefint(mm)) + 2, t_POL);
        !          1688:   va = varn(a);
        !          1689:   p1 = cgetg(bit_accuracy(lgefint(qq)) + 2,t_POL);
        !          1690:   p1[1] = evalsigne(1) | evalvarn(va);
        !          1691:   l = 2;
        !          1692:   if (smll)
        !          1693:   {
        !          1694:     q = itos(qq); m = itos(mm);
        !          1695:     do { y[l++] = m % q; m /= q; } while (m);
        !          1696:   }
        !          1697:   else
        !          1698:     do { mm=dvmdii(mm,qq,&r); y[l++]=(long)r; } while (signe(mm));
        !          1699:   if (smll)
        !          1700:     for (i=2; i<l; i++)
        !          1701:     {
        !          1702:       m=y[i]; l1=2;
        !          1703:       do { p1[l1++] = lstoi(m % p); m /= p; } while (m);
        !          1704:       setlgef(p1,l1); y[i]=(long)to_fq(p1,a,pg);
        !          1705:     }
        !          1706:   else
        !          1707:     for (i=2; i<l; i++)
        !          1708:     {
        !          1709:       mm=(GEN)y[i]; l1=2;
        !          1710:       do { mm=dvmdis(mm,p,&r); p1[l1++]=(long)r; } while (signe(mm));
        !          1711:       setlgef(p1,l1); y[i]=(long)to_fq(p1,a,pg);
        !          1712:     }
        !          1713:   y[1] = evalsigne(1) | evalvarn(v) | evallgef(l);
        !          1714:   return y;
        !          1715: }
        !          1716:
        !          1717: /* renvoie un polynome aleatoire de la variable v
        !          1718: de degre inferieur ou egal a 2*d1-1 */
        !          1719: static GEN
        !          1720: stopoly92(GEN pg, long d1, long v, GEN a, GEN *ptres)
        !          1721: {
        !          1722:   GEN y,p1;
        !          1723:   long m,l1,i,d2,l,va=varn(a),k=lgef(a)-3,nsh;
        !          1724:
        !          1725:   d2=2*d1+1; y=cgetg(d2+1,t_POL); y[1]=1;
        !          1726:   nsh=BITS_IN_RANDOM-1-k; if (nsh<=0) nsh=1;
        !          1727:   do
        !          1728:   {
        !          1729:     for (l=2; l<=d2; l++) y[l] = mymyrand() >> nsh;
        !          1730:     l=d2; while (!y[l]) l--;
        !          1731:   }
        !          1732:   while (l<=2);
        !          1733:   l++; y[1] = mymyrand() >> nsh;
        !          1734:   p1 = cgetg(BITS_IN_LONG+2,t_POL);
        !          1735:   p1[1] = evalsigne(1) | evalvarn(va);
        !          1736:   for (i=1; i<l; i++)
        !          1737:   {
        !          1738:     m=y[i]; l1=2;
        !          1739:     do { p1[l1++] = m&1? un: zero; m>>=1; } while (m);
        !          1740:     setlgef(p1,l1); y[i]=(long)to_fq(p1,a,pg);
        !          1741:   }
        !          1742:   *ptres = (GEN)y[1];
        !          1743:   y[1] = evalsigne(1) | evalvarn(v) | evallgef(l);
        !          1744:   return y;
        !          1745: }
        !          1746:
        !          1747: static void
        !          1748: split9(GEN m, GEN *t, long d, GEN pg, GEN q, GEN munfq, GEN qq, GEN a)
        !          1749: {
        !          1750:   long l,dv,v,av0,av,tetpil,p;
        !          1751:   GEN w,res,polmod;
        !          1752:
        !          1753:   dv=lgef(*t)-3; if (dv==d) return;
        !          1754:   v=varn(*t); m=setloop(m);
        !          1755:   av0=avma; p = pg[2];
        !          1756:   polmod=cgetg(3,t_POLMOD);
        !          1757:   polmod[1]=(long)dummyclone(*t);
        !          1758:   for(av=avma;;avma=av)
        !          1759:   {
        !          1760:     if (p==2)
        !          1761:     {
        !          1762:       polmod[2] = lres(stopoly92(pg,d,v,a,&res), *t);
        !          1763:       w = polmod; for (l=1; l<d; l++) w = gadd(polmod, powgi(w,qq));
        !          1764:       w = gadd((GEN)w[2], res); /* - res = res ! */
        !          1765:     }
        !          1766:     else
        !          1767:     {
        !          1768:       polmod[2] = lres(stopoly9(pg,m,qq,v,a), *t);
        !          1769:       m = incpos(m);
        !          1770:       w = powgi(polmod,q);
        !          1771:       w = gadd((GEN)w[2], munfq);
        !          1772:     }
        !          1773:     tetpil=avma; w=ggcd(*t,w); l=lgef(w)-3;
        !          1774:     if (l && l!=dv) break;
        !          1775:   }
        !          1776:   free((GEN)polmod[1]); w = gerepile(av0,tetpil,w);
        !          1777:   l /= d; t[l]=gdeuc(*t,w); *t=w;
        !          1778:   split9(m,t+l,d,pg,q,munfq,qq,a);
        !          1779:   split9(m,t  ,d,pg,q,munfq,qq,a);
        !          1780: }
        !          1781:
        !          1782: /* to "compare" (real) scalars and t_INTMODs */
        !          1783: static int
        !          1784: cmp_coeff(GEN x, GEN y)
        !          1785: {
        !          1786:   if (typ(x) == t_INTMOD) x = (GEN)x[2];
        !          1787:   if (typ(y) == t_INTMOD) y = (GEN)y[2];
        !          1788:   return gcmp(x,y);
        !          1789: }
        !          1790:
        !          1791: int
        !          1792: cmp_pol(GEN x, GEN y)
        !          1793: {
        !          1794:   long fx[3], fy[3];
        !          1795:   long i,lx,ly;
        !          1796:   int fl;
        !          1797:   if (typ(x) == t_POLMOD) x = (GEN)x[2];
        !          1798:   if (typ(y) == t_POLMOD) y = (GEN)y[2];
        !          1799:   if (typ(x) == t_POL) lx = lgef(x); else { lx = 3; fx[2] = (long)x; x = fx; }
        !          1800:   if (typ(y) == t_POL) ly = lgef(y); else { ly = 3; fy[2] = (long)y; y = fy; }
        !          1801:   if (lx > ly) return  1;
        !          1802:   if (lx < ly) return -1;
        !          1803:   for (i=lx-1; i>1; i--)
        !          1804:     if ((fl = cmp_coeff((GEN)x[i], (GEN)y[i]))) return fl;
        !          1805:   return 0;
        !          1806: }
        !          1807:
        !          1808: GEN
        !          1809: factmod9(GEN f, GEN pp, GEN a)
        !          1810: {
        !          1811:   long av = avma, tetpil,p,i,j,k,d,e,vf,va,nbfact,nbf,pk;
        !          1812:   GEN ex,y,f2,f3,df1,df2,g,g1,xmod,u,v,pd,q,qq,unfp,unfq,munfq,tokill, *t;
        !          1813:   GEN frobinv = gpowgs(pp, lgef(a)-4);
        !          1814:
        !          1815:   if (typ(a)!=t_POL || typ(f)!=t_POL || gcmp0(a)) err(typeer,"factmod9");
        !          1816:   vf=varn(f); va=varn(a);
        !          1817:   if (va<=vf) err(talker,"polynomial variable must be of higher priority than finite field\nvariable in factorff");
        !          1818:   p=itos(pp); unfp=gmodulss(1,p); a=gmul(unfp,a);
        !          1819:   unfq=gmodulo(gmul(unfp,polun[va]), a); tokill = (GEN)unfq[1];
        !          1820:   f = gmul(unfq,f); if (!signe(f)) err(zeropoler,"factmod9");
        !          1821:   d = lgef(f)-3; if (!d) { avma=av; gunclone(tokill); return trivfact(); }
        !          1822:
        !          1823:   pp = gmael(a,2,1); /* out of the stack */
        !          1824:   t = (GEN*)cgetg(d+1,t_VEC); ex = new_chunk(d+1);
        !          1825:
        !          1826:   xmod = cgetg(3,t_POLMOD);
        !          1827:   xmod[2] = lmul(polx[vf],unfq);
        !          1828:   munfq = gneg(unfq);
        !          1829:   qq=gpuigs(pp,lgef(a)-3);
        !          1830:   e = nbfact = 1;
        !          1831:   pk=1; df1=derivpol(f); f3=NULL;
        !          1832:   for(;;)
        !          1833:   {
        !          1834:     while (gcmp0(df1))
        !          1835:     {
        !          1836:       pk *= p; e=pk;
        !          1837:       j=(lgef(f)-3)/p+3; setlg(f,j); setlgef(f,j);
        !          1838:       for (i=2; i<j; i++) f[i] = (long)powgi((GEN)f[p*(i-2)+2], frobinv);
        !          1839:       df1=derivpol(f); f3=NULL;
        !          1840:     }
        !          1841:     f2 = f3? f3: ggcd(f,df1);
        !          1842:     if (lgef(f2)==3) u=f;
        !          1843:     else
        !          1844:     {
        !          1845:       g1=gdeuc(f,f2); df2=derivpol(f2);
        !          1846:       if (gcmp0(df2)) { u=g1; f3=f2; }
        !          1847:       else
        !          1848:       {
        !          1849:         f3=ggcd(f2,df2);
        !          1850:         if (lgef(f3)==3) u=gdeuc(g1,f2);
        !          1851:         else
        !          1852:           u=gdeuc(g1,gdeuc(f2,f3));
        !          1853:       }
        !          1854:     }
        !          1855:    /*  Ici u est square-free (produit des facteurs premiers de meme
        !          1856:     *  multiplicite e). On cherche le produit des facteurs de meme degre d
        !          1857:     */
        !          1858:     pd=gun; xmod[1]=(long)u; v=xmod;
        !          1859:     for (d=1; d <= (lgef(u)-3)>>1; d++)
        !          1860:     {
        !          1861:       pd=mulii(pd,qq); v=powgi(v,qq);
        !          1862:       g=ggcd((GEN)gsub(v,xmod)[2],u);
        !          1863:
        !          1864:       if (lgef(g) > 3)
        !          1865:       {
        !          1866:         /* Ici g est produit de pol irred ayant tous le meme degre d; */
        !          1867:         j = nbfact+(lgef(g)-3)/d;
        !          1868:
        !          1869:         t[nbfact]=g;
        !          1870:         q=shifti(subis(pd,1),-1);
        !          1871:        /* le premier parametre est un entier variable m qui sera
        !          1872:         * converti en un polynome w dont les coeff sont ses digits en
        !          1873:         * base p (initialement m = p --> X) pour faire pgcd de g avec
        !          1874:         * w^(p^d-1)/2 jusqu'a casser.
        !          1875:         */
        !          1876:         split9(addis(qq,1),t+nbfact,d,pp,q,munfq,qq,a);
        !          1877:         for (; nbfact<j; nbfact++) ex[nbfact]=e;
        !          1878:         u=gdeuc(u,g); v=gmodulcp((GEN)v[2],u);
        !          1879:       }
        !          1880:     }
        !          1881:     if (lgef(u)>3) { t[nbfact]=u; ex[nbfact++]=e; }
        !          1882:     if (lgef(f2) == 3) break;
        !          1883:
        !          1884:     f=f2; df1=df2; e += pk;
        !          1885:   }
        !          1886:
        !          1887:   nbf=nbfact; tetpil=avma; y=cgetg(3,t_MAT);
        !          1888:   for (j=1; j<nbfact; j++)
        !          1889:   {
        !          1890:     t[j]=gdiv((GEN)t[j],leading_term(t[j]));
        !          1891:     for (k=1; k<j; k++)
        !          1892:       if (ex[k] && gegal(t[j],t[k]))
        !          1893:       {
        !          1894:         ex[k] += ex[j]; ex[j]=0;
        !          1895:         nbf--; break;
        !          1896:       }
        !          1897:   }
        !          1898:   u=cgetg(nbf,t_COL); y[1]=(long)u;
        !          1899:   v=cgetg(nbf,t_COL); y[2]=(long)v;
        !          1900:   for (j=1,k=0; j<nbfact; j++)
        !          1901:     if (ex[j])
        !          1902:     {
        !          1903:       k++;
        !          1904:       u[k]=(long)t[j];
        !          1905:       v[k]=lstoi(ex[j]);
        !          1906:     }
        !          1907:   y = gerepile(av,tetpil,y);
        !          1908:   u=(GEN)y[1]; a = forcecopy(tokill);
        !          1909:   for (j=1; j<nbf; j++) fqunclone((GEN)u[j], a);
        !          1910:   (void)sort_factor(y, cmp_pol);
        !          1911:   gunclone(tokill); return y;
        !          1912: }
        !          1913:
        !          1914: /*******************************************************************/
        !          1915: /*                                                                 */
        !          1916: /*                         RACINES COMPLEXES                       */
        !          1917: /*        l represente la longueur voulue pour les parties         */
        !          1918: /*            reelles et imaginaires des racines de x              */
        !          1919: /*                                                                 */
        !          1920: /*******************************************************************/
        !          1921: GEN square_free_factorization(GEN pol);
        !          1922: static GEN gnorml1(GEN x, long PREC);
        !          1923: static GEN laguer(GEN pol,long N,GEN y0,GEN EPS,long PREC);
        !          1924: static GEN zrhqr(GEN a,long PREC);
        !          1925:
        !          1926: GEN
        !          1927: rootsold(GEN x, long l)
        !          1928: {
        !          1929:   long av1=avma,i,j,f,g,gg,fr,deg,l0,l1,l2,l3,l4,ln;
        !          1930:   long exc,expmin,m,deg0,k,ti,h,ii,e,e1,emax,v;
        !          1931:   GEN y,xc,xd0,xd,xdabs,p1,p2,p3,p4,p5,p6,p7,p8;
        !          1932:   GEN p9,p10,p11,p12,p14,p15,pa,pax,pb,pp,pq,ps;
        !          1933:
        !          1934:   if (typ(x)!=t_POL) err(typeer,"rootsold");
        !          1935:   v=varn(x); deg0=lgef(x)-3; expmin=12 - bit_accuracy(l);
        !          1936:   if (!signe(x)) err(zeropoler,"rootsold");
        !          1937:   y=cgetg(deg0+1,t_COL); if (!deg0) return y;
        !          1938:   for (i=1; i<=deg0; i++)
        !          1939:   {
        !          1940:     p1=cgetg(3,t_COMPLEX); p1[1]=lgetr(l); p1[2]=lgetr(l); y[i]=(long)p1;
        !          1941:     for (j=3; j<l; j++) ((GEN)p1[2])[j]=((GEN)p1[1])[j]=0;
        !          1942:   }
        !          1943:   g=1; gg=1; f=1;
        !          1944:   for (i=2; i<=deg0+2; i++)
        !          1945:   {
        !          1946:     ti=typ(x[i]);
        !          1947:     if (ti==t_REAL) gg=0;
        !          1948:     else if (ti==t_QUAD)
        !          1949:     {
        !          1950:       p2=gmael3(x,i,1,2);
        !          1951:       if (gsigne(p2)>0) g=0;
        !          1952:     } else if (ti != t_INT && ti != t_INTMOD && !is_frac_t(ti)) g=0;
        !          1953:   }
        !          1954:   l1=avma; p2=cgetg(3,t_COMPLEX);
        !          1955:   p2[1]=lmppi(DEFAULTPREC); p2[2]=ldivrs((GEN)p2[1],10);
        !          1956:   p11=cgetg(4,t_POL); p11[1]=evalsigne(1)+evallgef(4);
        !          1957:   setvarn(p11,v); p11[3]=un;
        !          1958:
        !          1959:   p12=cgetg(5,t_POL); p12[1]=evalsigne(1)+evallgef(5);
        !          1960:   setvarn(p12,v); p12[4]=un;
        !          1961:   for (i=2; i<=deg0+2 && gcmp0((GEN)x[i]); i++) gaffsg(0,(GEN)y[i-1]);
        !          1962:   k=i-2;
        !          1963:   if (k!=deg0)
        !          1964:   {
        !          1965:     if (k)
        !          1966:     {
        !          1967:       j=deg0+3-k; pax=cgetg(j,t_POL);
        !          1968:       pax[1]=evalsigne(1)+evallgef(j); setvarn(pax,v);
        !          1969:       for (i=2; i<j; i++) pax[i]=x[i+k];
        !          1970:     }
        !          1971:     else pax=x;
        !          1972:     xd0=deriv(pax,v); m=1; pa=pax;
        !          1973:     if (gg) { pp=ggcd(pax,xd0); h=isnonscalar(pp); if (h) pq=gdeuc(pax,pp); }
        !          1974:     else{ pp=gun; h=0; }
        !          1975:     do
        !          1976:     {
        !          1977:       if (h)
        !          1978:       {
        !          1979:         pa=pp; pb=pq; pp=ggcd(pa,deriv(pa,v)); h=isnonscalar(pp);
        !          1980:         if (h) pq=gdeuc(pa,pp); else pq=pa; ps=gdeuc(pb,pq);
        !          1981:       }
        !          1982:       else ps=pa;
        !          1983:           /* calcul des racines d'ordre exactement m */
        !          1984:       deg=lgef(ps)-3;
        !          1985:       if (deg)
        !          1986:       {
        !          1987:         l3=avma; e=gexpo((GEN)ps[deg+2]); emax=e;
        !          1988:         for (i=2; i<deg+2; i++)
        !          1989:         {
        !          1990:           p3=(GEN)(ps[i]);
        !          1991:           e1=gexpo(p3); if (e1>emax) emax=e1;
        !          1992:         }
        !          1993:         e=emax-e; if (e<0) e=0; avma=l3; if (ps!=pax) xd0=deriv(ps,v);
        !          1994:         xdabs=cgetg(deg+2,t_POL); xdabs[1]=xd0[1];
        !          1995:         for (i=2; i<deg+2; i++)
        !          1996:         {
        !          1997:           l3=avma; p3=(GEN)xd0[i];
        !          1998:           p4=gabs(greal(p3),l);
        !          1999:           p5=gabs(gimag(p3),l); l4=avma;
        !          2000:           xdabs[i]=lpile(l3,l4,gadd(p4,p5));
        !          2001:         }
        !          2002:         l0=avma; xc=gcopy(ps); xd=gcopy(xd0); l2=avma;
        !          2003:         for (i=1; i<=deg; i++)
        !          2004:         {
        !          2005:           if (i==deg)
        !          2006:           {
        !          2007:             p1=(GEN)y[k+m*i]; gdivz(gneg_i((GEN)xc[2]),(GEN)xc[3],p1);
        !          2008:             p14=(GEN)(p1[1]); p15=(GEN)(p1[2]);
        !          2009:           }
        !          2010:           else
        !          2011:           {
        !          2012:             p3=gshift(p2,e); p4=poleval(xc,p3); p5=gnorm(p4); exc=0;
        !          2013:             while (exc>= -20)
        !          2014:             {
        !          2015:               p6=poleval(xd,p3); p7=gneg_i(gdiv(p4,p6)); f=1;
        !          2016:               l3=avma;
        !          2017:               if (gcmp0(p5)) exc= -32;
        !          2018:               else exc=expo(gnorm(p7))-expo(gnorm(p3));
        !          2019:               avma=l3;
        !          2020:               for (j=1; j<=10 && f; j++)
        !          2021:               {
        !          2022:                 p8=gadd(p3,p7); p9=poleval(xc,p8); p10=gnorm(p9);
        !          2023:                 f=(cmprr(p10,p5)>=0)&&(exc>= -20);
        !          2024:                 if (f){ gshiftz(p7,-2,p7); avma=l3; }
        !          2025:               }
        !          2026:               if (f)
        !          2027:               {
        !          2028:                 avma=av1;
        !          2029:                 if (DEBUGLEVEL)
        !          2030:                 {
        !          2031:                   fprintferr("too many iterations in rootsold(): ");
        !          2032:                   fprintferr("using roots2()\n"); flusherr();
        !          2033:                 }
        !          2034:                 return roots2(x,l);
        !          2035:               }
        !          2036:               else
        !          2037:               {
        !          2038:                 GEN *gptr[3];
        !          2039:                 p3=p8; p4=p9; p5=p10;
        !          2040:                 gptr[0]=&p3; gptr[1]=&p4; gptr[2]=&p5;
        !          2041:                 gerepilemanysp(l2,l3,gptr,3);
        !          2042:               }
        !          2043:             }
        !          2044:             p1=(GEN)y[k+m*i]; setlg(p1[1],3); setlg(p1[2],3); gaffect(p3,p1);
        !          2045:             avma=l2; p14=(GEN)(p1[1]); p15=(GEN)(p1[2]);
        !          2046:             for (ln=4; ln<=l; ln=(ln<<1)-2)
        !          2047:             {
        !          2048:               setlg(p14,ln); setlg(p15,ln);
        !          2049:               if (gcmp0(p14)) { settyp(p14,t_INT); p14[1]=2; }
        !          2050:               if (gcmp0(p15)) { settyp(p15,t_INT); p15[1]=2; }
        !          2051:               p4=poleval(xc,p1);
        !          2052:               p5=poleval(xd,p1); p6=gneg_i(gdiv(p4,p5));
        !          2053:               settyp(p14,t_REAL); settyp(p15,t_REAL);
        !          2054:               gaffect(gadd(p1,p6),p1); avma=l2;
        !          2055:             }
        !          2056:           }
        !          2057:           setlg(p14,l); setlg(p15,l);
        !          2058:           p7=gcopy(p1); p14=(GEN)(p7[1]); p15=(GEN)(p7[2]);
        !          2059:           setlg(p14,l+1); setlg(p15,l+1);
        !          2060:           if (gcmp0(p14)) { settyp(p14,t_INT); p14[1]=2; }
        !          2061:           if (gcmp0(p15)) { settyp(p15,t_INT); p15[1]=2; }
        !          2062:           for (ii=1; ii<=5; ii++)
        !          2063:           {
        !          2064:             p4=poleval(ps,p7); p5=poleval(xd0,p7);
        !          2065:             p6=gneg_i(gdiv(p4,p5)); p7=gadd(p7,p6);
        !          2066:             p14=(GEN)(p7[1]); p15=(GEN)(p7[2]);
        !          2067:             if (gcmp0(p14)) { settyp(p14,t_INT); p14[1]=2; }
        !          2068:             if (gcmp0(p15)) { settyp(p15,t_INT); p15[1]=2; }
        !          2069:           }
        !          2070:           gaffect(p7,p1); p4=poleval(ps,p7);
        !          2071:           p6=gdiv(p4,poleval(xdabs,gabs(p7,l)));
        !          2072:           if (gexpo(p6)>=expmin)
        !          2073:           {
        !          2074:             avma=av1;
        !          2075:             if (DEBUGLEVEL)
        !          2076:             {
        !          2077:               fprintferr("internal error in rootsold(): using roots2()\n");
        !          2078:               flusherr();
        !          2079:             }
        !          2080:             return roots2(x,l);
        !          2081:           }
        !          2082:           avma=l2;
        !          2083:           if (expo(p1[2])<expmin && g)
        !          2084:           {
        !          2085:             gaffect(gzero,(GEN)p1[2]);
        !          2086:             for (j=1; j<m; j++) gaffect(p1,(GEN)y[k+(i-1)*m+j]);
        !          2087:             p11[2]=lneg((GEN)p1[1]);
        !          2088:             l4=avma; xc=gerepile(l0,l4,gdeuc(xc,p11));
        !          2089:           }
        !          2090:           else
        !          2091:           {
        !          2092:             for (j=1; j<m; j++) gaffect(p1,(GEN)y[k+(i-1)*m+j]);
        !          2093:             if (g)
        !          2094:             {
        !          2095:               p1=gconj(p1);
        !          2096:               for (j=1; j<=m; j++) gaffect(p1,(GEN)y[k+i*m+j]);
        !          2097:               i++;
        !          2098:               p12[2]=lnorm(p1); p12[3]=lmulsg(-2,(GEN)p1[1]); l4=avma;
        !          2099:               xc=gerepile(l0,l4,gdeuc(xc,p12));
        !          2100:             }
        !          2101:             else
        !          2102:             {
        !          2103:               p11[2]=lneg(p1); l4=avma;
        !          2104:               xc=gerepile(l0,l4,gdeuc(xc,p11));
        !          2105:             }
        !          2106:           }
        !          2107:           xd=deriv(xc,v); l2=avma;
        !          2108:         }
        !          2109:         k=k+deg*m;
        !          2110:       }
        !          2111:       m++;
        !          2112:     }
        !          2113:     while (k!=deg0);
        !          2114:   }
        !          2115:   avma=l1;
        !          2116:   if (deg0>1)
        !          2117:   {
        !          2118:     for (j=2; j<=deg0; j++)
        !          2119:     {
        !          2120:       p1=(GEN)y[j]; if (gcmp0((GEN)p1[2])) fr=0; else fr=1;
        !          2121:       for (k=j-1; k>=1; k--)
        !          2122:       {
        !          2123:         if (gcmp0((GEN)((GEN)y[k])[2])) f=0; else f=1;
        !          2124:         if (f<fr) break;
        !          2125:         if (f==fr && gcmp(gmael(y,k,1),(GEN)p1[1])<=0) break;
        !          2126:         y[k+1]=y[k];
        !          2127:       }
        !          2128:       y[k+1]=(long)p1;
        !          2129:     }
        !          2130:   }
        !          2131:   return y;
        !          2132: }
        !          2133:
        !          2134: #if 0
        !          2135: GEN
        !          2136: rootslong(GEN x, long l)
        !          2137: {
        !          2138:   long av1=avma,i,j,f,g,fr,deg,l0,l1,l2,l3,l4,ln;
        !          2139:   long exc,expmin,m,deg0,k,ti,h,ii,e,e1,emax,v;
        !          2140:   GEN y,xc,xd0,xd,xdabs,p1,p2,p3,p4,p5,p6,p7,p8;
        !          2141:   GEN p9,p10,p11,p12,p14,p15,pa,pax,pb,pp,pq,ps;
        !          2142:
        !          2143:   if (typ(x)!=t_POL) err(typeer,"rootslong");
        !          2144:   v=varn(x); deg0=lgef(x)-3; expmin = -bit_accuracy(l)+12;
        !          2145:   if (!signe(x)) err(zeropoler,"rootslong");
        !          2146:   y=cgetg(deg0+1,t_COL); if (!deg0) return y;
        !          2147:   for (i=1; i<=deg0; i++)
        !          2148:   {
        !          2149:     p1=cgetg(3,t_COMPLEX); y[i]=(long)p1;
        !          2150:     p1[1]=lgetr(l); p1[2]=lgetr(l);
        !          2151:     for (j=3; j<l; j++) mael(p1,2,j)=mael(p1,1,j)=0;
        !          2152:   }
        !          2153:   g=1; f=1;
        !          2154:   for (i=2; i<=deg0+2; i++)
        !          2155:   {
        !          2156:     ti=typ(x[i]);
        !          2157:     if (ti==t_QUAD)
        !          2158:     {
        !          2159:       p2=gmael3(x,i,1,2);
        !          2160:       if (gcmpgs(p2,0)>0) g=0;
        !          2161:     }
        !          2162:     else
        !          2163:       if (!is_const_t(ti) || ti==t_PADIC || ti==t_COMPLEX) g=0;
        !          2164:   }
        !          2165:   l1=avma; p2=cgetg(3,t_COMPLEX);
        !          2166:   p2[1]=lmppi(l);
        !          2167:   p2[2]=ldivrs((GEN)p2[1],10);
        !          2168:   p11=cgetg(4,t_POL); p11[1]=evalsigne(1)+evallgef(4); setvarn(p11,v); p11[3]=un;
        !          2169:   p12=cgetg(5,t_POL); p12[1]=evalsigne(1)+evallgef(5); setvarn(p12,v); p12[4]=un;
        !          2170:   for (i=2; (i<=deg0+2)&&(gcmp0((GEN)x[i])); i++)
        !          2171:     gaffsg(0,(GEN)y[i-1]); k=i-2;
        !          2172:   if (k!=deg0)
        !          2173:   {
        !          2174:     if (k)
        !          2175:     {
        !          2176:       j=deg0+3-k; pax=cgetg(j,t_POL); pax[1]=evalsigne(1)+evallgef(j);
        !          2177:       setvarn(pax,v);
        !          2178:       for (i=2; i<j; i++)
        !          2179:         pax[i]=x[i+k];
        !          2180:     }
        !          2181:     else pax=x;
        !          2182:     xd0=deriv(pax,v); pp=ggcd(pax,xd0); m=1; pa=pax;
        !          2183:     h=isnonscalar(pp); if (h) pq=gdeuc(pax,pp);
        !          2184:     do
        !          2185:     {
        !          2186:       if (h)
        !          2187:       {
        !          2188:         pa=pp; pb=pq;
        !          2189:         pp=ggcd(pa,deriv(pa,v)); h=isnonscalar(pp);
        !          2190:         if (h) pq=gdeuc(pa,pp); else pq=pa;
        !          2191:         ps=gdeuc(pb,pq);
        !          2192:       }
        !          2193:       else ps=pa;
        !          2194:           /* calcul des racines d'ordre exactement m */
        !          2195:       deg=lgef(ps)-3;
        !          2196:       if (deg)
        !          2197:       {
        !          2198:         l3=avma; e=gexpo((GEN)ps[deg+2]); emax=e;
        !          2199:         for (i=2; i<deg+2; i++)
        !          2200:         {
        !          2201:           p3=(GEN)(ps[i]);
        !          2202:           if (!gcmp0(p3))
        !          2203:           {
        !          2204:             e1=gexpo(p3);
        !          2205:             if (e1>emax) emax=e1;
        !          2206:           }
        !          2207:         }
        !          2208:         e=emax-e; if (e<0) e=0; avma=l3;
        !          2209:         if (ps!=pax) xd0=deriv(ps,v);
        !          2210:         xdabs=cgetg(deg+2,t_POL); xdabs[1]=xd0[1];
        !          2211:         for (i=2; i<deg+2; i++)
        !          2212:         {
        !          2213:           l3=avma; p3=(GEN)xd0[i]; p4=gabs(greal(p3),l);
        !          2214:           p5=gabs(gimag(p3),l); l4=avma;
        !          2215:           xdabs[i]=lpile(l3,l4,gadd(p4,p5));
        !          2216:         }
        !          2217:         l0=avma; xc=gcopy(ps); xd=gcopy(xd0); l2=avma;
        !          2218:         for (i=1; i<=deg; i++)
        !          2219:         {
        !          2220:           if (i==deg)
        !          2221:           {
        !          2222:             p1=(GEN)y[k+m*i];
        !          2223:             gdivz(gneg_i((GEN)xc[2]),(GEN)xc[3],p1);
        !          2224:             p14=(GEN)(p1[1]); p15=(GEN)(p1[2]);
        !          2225:           }
        !          2226:           else
        !          2227:           {
        !          2228:             p3=gshift(p2,e); p4=poleval(xc,p3);
        !          2229:             p5=gnorm(p4); exc=0;
        !          2230:             while (exc>= -20)
        !          2231:             {
        !          2232:               p6=poleval(xd,p3); p7=gneg_i(gdiv(p4,p6));
        !          2233:               f=1; l3=avma; if (gcmp0(p5)) exc= -32;
        !          2234:               else exc=expo(gnorm(p7))-expo(gnorm(p3));
        !          2235:               avma=l3;
        !          2236:               for (j=1; (j<=50)&&f; j++)
        !          2237:               {
        !          2238:                 p8=gadd(p3,p7); p9=poleval(xc,p8);
        !          2239:                 p10=gnorm(p9);
        !          2240:                 f=(cmprr(p10,p5)>=0)&&(exc>= -20);
        !          2241:                 if (f) { gshiftz(p7,-2,p7); avma=l3; }
        !          2242:               }
        !          2243:               if (f) err(poler9);
        !          2244:               else
        !          2245:               {
        !          2246:                 GEN *gptr[3];
        !          2247:                 p3=p8; p4=p9; p5=p10;
        !          2248:                 gptr[0]=&p3; gptr[1]=&p4; gptr[2]=&p5;
        !          2249:                 gerepilemanysp(l2,l3,gptr,3);
        !          2250:               }
        !          2251:             }
        !          2252:             p1=(GEN)y[k+m*i]; gaffect(p3,p1); avma=l2;
        !          2253:             p14=(GEN)(p1[1]); p15=(GEN)(p1[2]);
        !          2254:             for (ln=4; ln<=l; ln=(ln<<1)-2)
        !          2255:             {
        !          2256:               if (gcmp0(p14))
        !          2257:               { settyp(p14,t_INT); p14[1]=2; }
        !          2258:               if (gcmp0(p15))
        !          2259:               { settyp(p15,t_INT); p15[1]=2; }
        !          2260:               p4=poleval(xc,p1); p5=poleval(xd,p1);
        !          2261:               p6=gneg_i(gdiv(p4,p5));
        !          2262:               settyp(p14,t_REAL); settyp(p15,t_REAL);
        !          2263:               gaffect(gadd(p1,p6),p1); avma=l2;
        !          2264:             }
        !          2265:           }
        !          2266:           p7=gcopy(p1);
        !          2267:           p14=(GEN)(p7[1]); p15=(GEN)(p7[2]);
        !          2268:           setlg(p14,l+1); setlg(p15,l+1);
        !          2269:           if (gcmp0(p14))
        !          2270:           { settyp(p14,t_INT); p14[1]=2; }
        !          2271:           if (gcmp0(p15))
        !          2272:           { settyp(p15,t_INT); p15[1]=2; }
        !          2273:           for (ii=1; ii<=max(32,((e<<TWOPOTBITS_IN_LONG)+2)); ii<<=1)
        !          2274:           {
        !          2275:             p4=poleval(ps,p7); p5=poleval(xd0,p7);
        !          2276:             p6=gneg_i(gdiv(p4,p5)); p7=gadd(p7,p6);
        !          2277:             p14=(GEN)(p7[1]); p15=(GEN)(p7[2]);
        !          2278:             if (gcmp0(p14))
        !          2279:             { settyp(p14,t_INT); p14[1]=2; }
        !          2280:             if (gcmp0(p15))
        !          2281:             { settyp(p15,t_INT); p15[1]=2; }
        !          2282:           }
        !          2283:           gaffect(p7,p1); p4=poleval(ps,p7);
        !          2284:           p6=gdiv(p4,poleval(xdabs,gabs(p7,l)));
        !          2285:           if ((!gcmp0(p6))&&(gexpo(p6)>=expmin))
        !          2286:           {
        !          2287:             avma=av1;
        !          2288:             if (DEBUGLEVEL)
        !          2289:             {
        !          2290:               fprintferr("internal error in roots: using roots2\n"); flusherr();
        !          2291:             }
        !          2292:             return roots2(x,l);
        !          2293:           }
        !          2294:           avma=l2;
        !          2295:           if ((expo(p1[2])<expmin)&&g)
        !          2296:           {
        !          2297:             gaffect(gzero,(GEN)p1[2]);
        !          2298:             for (j=1; j<m; j++)
        !          2299:               gaffect(p1,(GEN)y[k+(i-1)*m+j]);
        !          2300:             p11[2]=lneg((GEN)p1[1]); l4=avma;
        !          2301:             xc=gerepile(l0,l4,gdeuc(xc,p11));
        !          2302:           }
        !          2303:           else
        !          2304:           {
        !          2305:             for (j=1; j<m; j++)
        !          2306:               gaffect(p1,(GEN)y[k+(i-1)*m+j]);
        !          2307:             if (g)
        !          2308:             {
        !          2309:               p1=gconj(p1);
        !          2310:               for (j=1; j<=m; j++)
        !          2311:                 gaffect(p1,(GEN)y[k+i*m+j]); i++;
        !          2312:               p12[2]=lnorm(p1);
        !          2313:               p12[3]=lmulsg(-2,(GEN)p1[1]);
        !          2314:               l4=avma;
        !          2315:               xc=gerepile(l0,l4,gdeuc(xc,p12));
        !          2316:             }
        !          2317:             else
        !          2318:             {
        !          2319:               p11[2]=lneg(p1); l4=avma;
        !          2320:               xc=gerepile(l0,l4,gdeuc(xc,p11));
        !          2321:             }
        !          2322:           }
        !          2323:           xd=deriv(xc,v); l2=avma;
        !          2324:         }
        !          2325:         k=k+deg*m;
        !          2326:       }
        !          2327:       m++;
        !          2328:     }
        !          2329:     while (k!=deg0);
        !          2330:   }
        !          2331:   avma=l1;
        !          2332:   if (deg0>1)
        !          2333:   {
        !          2334:     for (j=2; j<=deg0; j++)
        !          2335:     {
        !          2336:       p1=(GEN)y[j]; if (gcmp0((GEN)p1[2])) fr=0; else fr=1;
        !          2337:       for (k=j-1; k>=1; k--)
        !          2338:       {
        !          2339:         if (gcmp0((GEN)((GEN)y[k])[2])) f=0; else f=1;
        !          2340:         if (f<fr) break;
        !          2341:         if ((f==fr)&&(gcmp((GEN)((GEN)y[k])[1],(GEN)p1[1])<=0)) break;
        !          2342:         y[k+1]=y[k];
        !          2343:       }
        !          2344:       y[k+1]=(long)p1;
        !          2345:     }
        !          2346:   }
        !          2347:   return y;
        !          2348: }
        !          2349: #endif
        !          2350:
        !          2351: GEN
        !          2352: roots2(GEN pol,long PREC)
        !          2353: {
        !          2354:   long av = avma,tetpil,N,flagexactpol,flagrealpol,flagrealrac,ti,i,j;
        !          2355:   long nbpol,k,av1,multiqol,deg,nbroot,fr,f;
        !          2356:   GEN p1,p2,rr,EPS,qol,qolbis,x,b,c,*ad,v,tabqol;
        !          2357:
        !          2358:   if (typ(pol)!=t_POL) err(typeer,"roots2");
        !          2359:   if (!signe(pol)) err(zeropoler,"roots2");
        !          2360:   N=lgef(pol)-3;
        !          2361:   if (!N) return cgetg(1,t_COL);
        !          2362:   if (N==1)
        !          2363:   {
        !          2364:     p1=gmul(realun(PREC),(GEN)pol[3]);
        !          2365:     p2=gneg_i(gdiv((GEN)pol[2],p1));
        !          2366:     tetpil=avma; return gerepile(av,tetpil,gcopy(p2));
        !          2367:   }
        !          2368:   EPS=realun(3); setexpo(EPS, 12 - bit_accuracy(PREC));
        !          2369:   flagrealpol=1; flagexactpol=1;
        !          2370:   for (i=2; i<=N+2; i++)
        !          2371:   {
        !          2372:     ti=typ(pol[i]);
        !          2373:     if (ti!=t_INT && ti!=t_INTMOD && !is_frac_t(ti))
        !          2374:     {
        !          2375:       flagexactpol=0;
        !          2376:       if (ti!=t_REAL) flagrealpol=0;
        !          2377:     }
        !          2378:     if (ti==t_QUAD)
        !          2379:     {
        !          2380:       p1=gmael3(pol,i,1,2);
        !          2381:       flagrealpol = (gsigne(p1)>0)? 0 : 1;
        !          2382:     }
        !          2383:   }
        !          2384:   rr=cgetg(N+1,t_COL);
        !          2385:   for (i=1; i<=N; i++)
        !          2386:   {
        !          2387:     rr[i]=lgetg(3,t_COMPLEX); p1=(GEN)rr[i];
        !          2388:     mael(rr,i,1)=lgetr(PREC); mael(rr,i,2)=lgetr(PREC);
        !          2389:     for (j=3; j<PREC; j++) mael(p1,2,j)=mael(p1,1,j)=0;
        !          2390:   }
        !          2391:   if (flagexactpol) tabqol=square_free_factorization(pol);
        !          2392:   else
        !          2393:   {
        !          2394:     tabqol=cgetg(3,t_MAT);
        !          2395:     tabqol[1]=lgetg(2,t_COL); mael(tabqol,1,1)=un;
        !          2396:     tabqol[2]=lgetg(2,t_COL); mael(tabqol,2,1)=lcopy(pol);
        !          2397:   }
        !          2398:   nbpol=lg(tabqol[1])-1; nbroot=0;
        !          2399:   for (k=1; k<=nbpol; k++)
        !          2400:   {
        !          2401:     av1=avma; qol=gmael(tabqol,2,k); qolbis=gcopy(qol);
        !          2402:     multiqol=itos(gmael(tabqol,1,k)); deg=lgef(qol)-3;
        !          2403:     for (j=deg; j>=1; j--)
        !          2404:     {
        !          2405:       x=gzero; flagrealrac=0;
        !          2406:       if (j==1) x=gneg_i(gdiv((GEN)qolbis[2],(GEN)qolbis[3]));
        !          2407:       else
        !          2408:       {
        !          2409:         x=laguer(qolbis,j,x,EPS,PREC);
        !          2410:         if (x == NULL) goto RLAB;
        !          2411:       }
        !          2412:       if (flagexactpol)
        !          2413:       {
        !          2414:         x=gprec(x,(long)((PREC-1)*pariK));
        !          2415:         x=laguer(qol,deg,x,gmul2n(EPS,-32),PREC+1);
        !          2416:       }
        !          2417:       else x=laguer(qol,deg,x,EPS,PREC);
        !          2418:       if (x == NULL) goto RLAB;
        !          2419:
        !          2420:       if (typ(x)==t_COMPLEX &&
        !          2421:           gcmp(gabs(gimag(x),PREC),gmul2n(gmul(EPS,gabs(greal(x),PREC)),1))<=0)
        !          2422:         { x[2]=zero; flagrealrac=1; }
        !          2423:       else if (j==1 && flagrealpol)
        !          2424:         { x[2]=zero; flagrealrac=1; }
        !          2425:       else if (typ(x)!=t_COMPLEX) flagrealrac=1;
        !          2426:
        !          2427:       for (i=1; i<=multiqol; i++) gaffect(x,(GEN)rr[nbroot+i]);
        !          2428:       nbroot+=multiqol;
        !          2429:       if (!flagrealpol || flagrealrac)
        !          2430:       {
        !          2431:         ad = (GEN*) new_chunk(j+1);
        !          2432:         for (i=0; i<=j; i++) ad[i]=(GEN)qolbis[i+2];
        !          2433:         b=(GEN)ad[j];
        !          2434:         for (i=j-1; i>=0; i--)
        !          2435:         {
        !          2436:           c=(GEN)ad[i]; ad[i]=b;
        !          2437:           b=gadd(gmul((GEN)rr[nbroot],b),c);
        !          2438:         }
        !          2439:         v=cgetg(j+1,t_VEC); for (i=1; i<=j; i++) v[i]=(long)ad[j-i];
        !          2440:         qolbis=gtopoly(v,varn(qolbis));
        !          2441:         if (flagrealpol)
        !          2442:           for (i=2; i<=j+1; i++)
        !          2443:             if (typ(qolbis[i])==t_COMPLEX) mael(qolbis,i,2)=zero;
        !          2444:       }
        !          2445:       else
        !          2446:       {
        !          2447:         ad = (GEN*) new_chunk(j-1); ad[j-2]=(GEN)qolbis[j+2];
        !          2448:         p1=gmulsg(2,greal((GEN)rr[nbroot])); p2=gnorm((GEN)rr[nbroot]);
        !          2449:         ad[j-3]=gadd((GEN)qolbis[j+1],gmul(p1,ad[j-2]));
        !          2450:         for (i=j-2; i>=2; i--)
        !          2451:           ad[i-2] = gadd((GEN)qolbis[i+2],gsub(gmul(p1,ad[i-1]),gmul(p2,ad[i])));
        !          2452:         v=cgetg(j,t_VEC); for (i=1; i<=j-1; i++) v[i]=(long)ad[j-1-i];
        !          2453:         qolbis=gtopoly(v,varn(qolbis));
        !          2454:         for (i=2; i<=j; i++)
        !          2455:           if (typ(qolbis[i])==t_COMPLEX) mael(qolbis,i,2)=zero;
        !          2456:         for (i=1; i<=multiqol; i++)
        !          2457:           gaffect(gconj((GEN)rr[nbroot]), (GEN)rr[nbroot+i]);
        !          2458:         nbroot+=multiqol; j--;
        !          2459:       }
        !          2460:     }
        !          2461:     avma=av1;
        !          2462:   }
        !          2463:   for (j=2; j<=N; j++)
        !          2464:   {
        !          2465:     x=(GEN)rr[j]; if (gcmp0((GEN)x[2])) fr=0; else fr=1;
        !          2466:     for (i=j-1; i>=1; i--)
        !          2467:     {
        !          2468:       if (gcmp0(gmael(rr,i,2))) f=0; else f=1;
        !          2469:       if (f<fr) break;
        !          2470:       if (f==fr && gcmp(greal((GEN)rr[i]),greal(x)) <= 0) break;
        !          2471:       rr[i+1]=rr[i];
        !          2472:     }
        !          2473:     rr[i+1]=(long)x;
        !          2474:   }
        !          2475:   tetpil=avma; return gerepile(av,tetpil,gcopy(rr));
        !          2476:
        !          2477:  RLAB:
        !          2478:   avma=av;
        !          2479:   for(i=2;i<=N+2;i++)
        !          2480:   {
        !          2481:     ti=typ(pol[i]);
        !          2482:     if (is_intreal_t(ti) || ti==t_INTMOD) err(poler9);
        !          2483:   }
        !          2484:   if (DEBUGLEVEL)
        !          2485:   {
        !          2486:     fprintferr("too many iterations in roots2() ( laguer() ): \n");
        !          2487:     fprintferr("     real coefficients polynomial, using zrhqr()\n");
        !          2488:     flusherr();
        !          2489:   }
        !          2490:   return zrhqr(pol,PREC);
        !          2491: }
        !          2492:
        !          2493: #define MR 8
        !          2494: #define MT 10
        !          2495:
        !          2496: static GEN
        !          2497: laguer(GEN pol,long N,GEN y0,GEN EPS,long PREC)
        !          2498: {
        !          2499:   long av = avma, av1,MAXIT,iter,i,j;
        !          2500:   GEN rac,erre,I,x,abx,abp,abm,dx,x1,b,d,f,g,h,sq,gp,gm,g2,*ffrac;
        !          2501:
        !          2502:   MAXIT=MR*MT; rac=cgetg(3,t_COMPLEX);
        !          2503:   rac[1]=lgetr(PREC); rac[2]=lgetr(PREC);
        !          2504:   av1 = avma;
        !          2505:   I=cgetg(3,t_COMPLEX); I[1]=un; I[2]=un;
        !          2506:   ffrac=(GEN*)new_chunk(MR+1); for (i=0; i<=MR; i++) ffrac[i]=cgetr(PREC);
        !          2507:   affrr(dbltor(0.0), ffrac[0]); affrr(dbltor(0.5), ffrac[1]);
        !          2508:   affrr(dbltor(0.25),ffrac[2]); affrr(dbltor(0.75),ffrac[3]);
        !          2509:   affrr(dbltor(0.13),ffrac[4]); affrr(dbltor(0.38),ffrac[5]);
        !          2510:   affrr(dbltor(0.62),ffrac[6]); affrr(dbltor(0.88),ffrac[7]);
        !          2511:   affrr(dbltor(1.0),ffrac[8]);
        !          2512:   x=y0;
        !          2513:   for (iter=1; iter<=MAXIT; iter++)
        !          2514:   {
        !          2515:     b=(GEN)pol[N+2]; erre=gnorml1(b,PREC);
        !          2516:     d=gzero; f=gzero; abx=gnorml1(x,PREC);
        !          2517:     for (j=N-1; j>=0; j--)
        !          2518:     {
        !          2519:       f=gadd(gmul(x,f),d); d=gadd(gmul(x,d),b);
        !          2520:       b=gadd(gmul(x,b),(GEN)pol[j+2]);
        !          2521:       erre=gadd(gnorml1(b,PREC),gmul(abx,erre));
        !          2522:     }
        !          2523:     erre=gmul(erre,EPS);
        !          2524:     if (gcmp(gnorml1(b,PREC),erre)<=0)
        !          2525:     {
        !          2526:       gaffect(x,rac); avma = av1; return rac;
        !          2527:     }
        !          2528:     g=gdiv(d,b); g2=gsqr(g); h=gsub(g2, gmul2n(gdiv(f,b),1));
        !          2529:     sq=gsqrt(gmulsg(N-1,gsub(gmulsg(N,h),g2)),PREC);
        !          2530:     gp=gadd(g,sq); gm=gsub(g,sq); abp=gnorm(gp); abm=gnorm(gm);
        !          2531:     if (gcmp(abp,abm)<0) gp=gcopy(gm);
        !          2532:     if (gsigne(gmax(abp,abm))==1)
        !          2533:       dx = gdivsg(N,gp);
        !          2534:     else
        !          2535:       dx = gmul(gadd(gun,abx),gexp(gmulgs(I,iter),PREC));
        !          2536:     x1=gsub(x,dx);
        !          2537:     if (gcmp(gnorml1(gsub(x,x1),PREC),EPS)<0)
        !          2538:     {
        !          2539:       gaffect(x,rac); avma = av1; return rac;
        !          2540:     }
        !          2541:     if (iter%MT) x=gcopy(x1); else x=gsub(x,gmul(ffrac[iter/MT],dx));
        !          2542:   }
        !          2543:   avma=av; return NULL;
        !          2544: }
        !          2545:
        !          2546: #undef MR
        !          2547: #undef MT
        !          2548:
        !          2549: static GEN
        !          2550: gnorml1(GEN x,long PREC)
        !          2551: {
        !          2552:   long av,tetpil,lx,i;
        !          2553:   GEN p1,p2,s;
        !          2554:   av=avma;
        !          2555:   switch(typ(x))
        !          2556:   {
        !          2557:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
        !          2558:       return gabs(x,PREC);
        !          2559:
        !          2560:     case t_INTMOD: case t_PADIC: case t_POLMOD: case t_POL:
        !          2561:     case t_SER: case t_RFRAC: case t_RFRACN: case t_QFR: case t_QFI:
        !          2562:       return gcopy(x);
        !          2563:
        !          2564:     case t_COMPLEX:
        !          2565:       p1=gabs((GEN)x[1],PREC); p2=gabs((GEN)x[2],PREC); tetpil=avma;
        !          2566:       return gerepile(av,tetpil,gadd(p1,p2));
        !          2567:
        !          2568:     case t_QUAD:
        !          2569:       p1=gabs((GEN)x[2],PREC); p2=gabs((GEN)x[3],PREC); tetpil=avma;
        !          2570:       return gerepile(av,tetpil,gadd(p1,p2));
        !          2571:
        !          2572:     case t_VEC: case t_COL: case t_MAT:
        !          2573:       lx=lg(x); s=gzero;
        !          2574:       for (i=1; i<lx; i++) s=gadd(s,gnorml1((GEN)x[i],PREC)); tetpil=avma;
        !          2575:       return gerepile(av,tetpil,gcopy(s));
        !          2576:   }
        !          2577:   err(talker,"not a PARI object in gnorml1");
        !          2578:   return NULL; /* not reached */
        !          2579: }
        !          2580:
        !          2581: /***********************************************************************/
        !          2582: /**                                                                   **/
        !          2583: /**                     RACINES D'UN POLYNOME                         **/
        !          2584: /**                     A COEFFICIENTS REELS                          **/
        !          2585: /**                                                                   **/
        !          2586: /***********************************************************************/
        !          2587:
        !          2588: #define RADIX 1
        !          2589: #define COF 0.95
        !          2590:
        !          2591: /* ONLY FOR REAL COEFFICIENTS MATRIX : replace the matrix x with
        !          2592:    a symmetric matrix a with the same eigenvalues */
        !          2593: static GEN
        !          2594: balanc(GEN x)
        !          2595: {
        !          2596:   long av,tetpil,n,last,j,i,sqrdx;
        !          2597:   GEN s,r,g,f,c,cofgen,a;
        !          2598:
        !          2599:   av=avma; a=gcopy(x); n=lg(a)-1; sqrdx=RADIX+RADIX; last=0; cofgen=dbltor(COF);
        !          2600:   while (!last)
        !          2601:   {
        !          2602:     last=1;
        !          2603:     for (i=1; i<=n; i++)
        !          2604:     {
        !          2605:       r=c=gzero;
        !          2606:       for (j=1; j<=n; j++)
        !          2607:         if (j!=i){ c=gadd(gabs(gcoeff(a,j,i),0),c); r=gadd(gabs(gcoeff(a,i,j),0),r); }
        !          2608:         if ((!gcmp0(r))&&(!gcmp0(c)))
        !          2609:         {
        !          2610:           g=gmul2n(r,-RADIX); f=gun; s=gadd(c,r);
        !          2611:           while (gcmp(c,g)<0){ f=gmul2n(f,RADIX); c=gmul2n(c,sqrdx); }
        !          2612:           g=gmul2n(r,RADIX);
        !          2613:           while (gcmp(c,g)>0){ f=gmul2n(f,-RADIX); c=gmul2n(c,-sqrdx); }
        !          2614:           if (gcmp(gdiv(gadd(c,r),f),gmul(cofgen,s))<0)
        !          2615:           {
        !          2616:             last=0; g=ginv(f);
        !          2617:             for (j=1; j<=n; j++) coeff(a,i,j)=lmul(gcoeff(a,i,j),g);
        !          2618:             for (j=1; j<=n; j++) coeff(a,j,i)=lmul(gcoeff(a,j,i),f);
        !          2619:           }
        !          2620:         }
        !          2621:     }
        !          2622:   }
        !          2623:   tetpil=avma; return gerepile(av,tetpil,gcopy(a));
        !          2624: }
        !          2625:
        !          2626: #define SIGN(a,b) ((b)>=0.0 ? fabs(a) : -fabs(a))
        !          2627: static GEN
        !          2628: hqr(GEN mat) /* find all the eigenvalues of the matrix mat */
        !          2629: {
        !          2630:   long nn,n,m,l,k,j,its,i,mmin,flj,flk;
        !          2631:   double **a,p,q,r,s,t,u,v,w,x,y,z,anorm,*wr,*wi,eps;
        !          2632:   GEN eig;
        !          2633:
        !          2634:   eps=0.000001;
        !          2635:   n=lg(mat)-1; a=(double**)gpmalloc(sizeof(double*)*(n+1));
        !          2636:   for (i=1; i<=n; i++) a[i]=(double*)gpmalloc(sizeof(double)*(n+1));
        !          2637:   for (j=1; j<=n; j++)
        !          2638:     for (i=1; i<=n; i++) a[i][j]=gtodouble((GEN)((GEN)mat[j])[i]);
        !          2639:   wr=(double*)gpmalloc(sizeof(double)*(n+1));
        !          2640:   wi=(double*)gpmalloc(sizeof(double)*(n+1));
        !          2641:
        !          2642:   anorm=fabs(a[1][1]);
        !          2643:   for (i=2; i<=n; i++) for (j=(i-1); j<=n; j++) anorm+=fabs(a[i][j]);
        !          2644:   nn=n; t=0.0;
        !          2645:   if (DEBUGLEVEL>3)
        !          2646:   { fprintferr("* Finding eigenvalues\n"); flusherr(); }
        !          2647:   while (nn>=1)
        !          2648:   {
        !          2649:     its=0;
        !          2650:     do
        !          2651:     {
        !          2652:       for (l=nn; l>=2; l--)
        !          2653:       {
        !          2654:         s=fabs(a[l-1][l-1])+fabs(a[l][l]); if (s==0.0) s=anorm;
        !          2655:         if ((double)(fabs(a[l][l-1])+s)==s) break;
        !          2656:       }
        !          2657:       x=a[nn][nn];
        !          2658:       if (l==nn){ wr[nn]=x+t; wi[nn--]=0.0; }
        !          2659:       else
        !          2660:       {
        !          2661:         y=a[nn-1][nn-1]; w=a[nn][nn-1]*a[nn-1][nn];
        !          2662:         if (l==(nn-1))
        !          2663:         {
        !          2664:           p=0.5*(y-x); q=p*p+w; z=sqrt(fabs(q)); x+=t;
        !          2665:           if ((q>=0.0)||(fabs(q)<=eps))
        !          2666:           {
        !          2667:             z=p+SIGN(z,p); wr[nn-1]=wr[nn]=x+z;
        !          2668:             if (fabs(z)>eps) wr[nn]=x-w/z;
        !          2669:             wi[nn-1]=wi[nn]=0.0;
        !          2670:           }
        !          2671:           else{ wr[nn-1]=wr[nn]=x+p; wi[nn-1]=-(wi[nn]=z); }
        !          2672:           nn-=2;
        !          2673:         }
        !          2674:         else
        !          2675:         {
        !          2676:           if (its==30) err(talker,"too many iterations in hqr");
        !          2677:           if ((its==10)||(its==20))
        !          2678:           {
        !          2679:             t+=x; for (i=1; i<=nn; i++) a[i][i]-=x; s=fabs(a[nn][nn-1])+fabs(a[nn-1][nn-2]);
        !          2680:             y=x=0.75*s; w=-0.4375*s*s;
        !          2681:           }
        !          2682:           ++its;
        !          2683:           for (m=(nn-2); m>=l; m--)
        !          2684:           {
        !          2685:             z=a[m][m]; r=x-z; s=y-z; p=(r*s-w)/a[m+1][m]+a[m][m+1]; q=a[m+1][m+1]-z-r-s;
        !          2686:             r=a[m+2][m+1]; s=fabs(p)+fabs(q)+fabs(r); p/=s; q/=s; r/=s;
        !          2687:             if (m==l) break;
        !          2688:             u=fabs(a[m][m-1])*(fabs(q)+fabs(r));
        !          2689:             v=fabs(p)*(fabs(a[m-1][m-1])+fabs(z)+fabs(a[m+1][m+1]));
        !          2690:             if ((double)(u+v)==v) break;
        !          2691:           }
        !          2692:           for (i=m+2; i<=nn; i++){ a[i][i-2]=0.0; if (i!=(m+2)) a[i][i-3]=0.0; }
        !          2693:           for (k=m; k<=nn-1; k++)
        !          2694:           {
        !          2695:             if (k!=m)
        !          2696:             {
        !          2697:               p=a[k][k-1]; q=a[k+1][k-1]; r=0.0; if (k!=(nn-1)) r=a[k+2][k-1];
        !          2698:               if ((x=fabs(p)+fabs(q)+fabs(r))!=0.0){ p/=x; q/=x; r/=x; }
        !          2699:             }
        !          2700:             if ((s=SIGN(sqrt(p*p+q*q+r*r),p))!=0.0)
        !          2701:             {
        !          2702:               if (k==m){ if (l!=m) a[k][k-1]=-a[k][k-1]; }else a[k][k-1]=-s*x;
        !          2703:               p+=s; x=p/s; y=q/s; z=r/s; q/=p; r/=p;
        !          2704:               for (j=k; j<=nn; j++)
        !          2705:               {
        !          2706:                 p=a[k][j]+q*a[k+1][j]; if (k!=(nn-1)){ p+=r*a[k+2][j]; a[k+2][j]-=p*z; }
        !          2707:                 a[k+1][j]-=p*y; a[k][j]-=p*x;
        !          2708:               }
        !          2709:               mmin=(nn<k+3) ? nn : k+3;
        !          2710:               for (i=l; i<=mmin; i++)
        !          2711:               {
        !          2712:                 p=x*a[i][k]+y*a[i][k+1]; if (k!=(nn-1)){ p+=z*a[i][k+2]; a[i][k+2]-=p*r; }
        !          2713:                 a[i][k+1]-=p*q; a[i][k]-=p;
        !          2714:               }
        !          2715:             }
        !          2716:           }
        !          2717:         }
        !          2718:       }
        !          2719:     }
        !          2720:     while (l<nn-1);
        !          2721:   }
        !          2722:   for (j=2; j<=n; j++) /* ordering the roots */
        !          2723:   {
        !          2724:     x=wr[j]; y=wi[j]; if (y) flj=1; else flj=0;
        !          2725:     for (k=j-1; k>=1; k--)
        !          2726:     {
        !          2727:       if (wi[k]) flk=1; else flk=0;
        !          2728:       if (flk<flj) break;
        !          2729:       if ((!flk)&&(!flj)&&(wr[k]<=x)) break;
        !          2730:       if (flk&&flj&&(wr[k]<x)) break;
        !          2731:       if (flk&&flj&&(wr[k]==x)&&(wi[k]>0)) break;
        !          2732:       wr[k+1]=wr[k]; wi[k+1]=wi[k];
        !          2733:     }
        !          2734:     wr[k+1]=x; wi[k+1]=y;
        !          2735:   }
        !          2736:   if (DEBUGLEVEL>3)
        !          2737:   { fprintferr("* End of the computation of eigenvalues\n"); flusherr(); }
        !          2738:   for (i=1; i<=n; i++) free(a[i]); free(a); eig=cgetg(n+1,t_COL);
        !          2739:   for (i=1; i<=n; i++)
        !          2740:   {
        !          2741:     if (wi[i])
        !          2742:     {
        !          2743:       eig[i]=lgetg(3,t_COMPLEX);
        !          2744:       ((GEN)eig[i])[1]=(long)dbltor(wr[i]); ((GEN)eig[i])[2]=(long)dbltor(wi[i]);
        !          2745:     }
        !          2746:     else eig[i]=(long)dbltor(wr[i]);
        !          2747:   }
        !          2748:   free(wr); free(wi); return eig;
        !          2749: }
        !          2750:
        !          2751: static GEN
        !          2752: zrhqr(GEN a,long PREC)
        !          2753: /*    ONLY FOR POLYNOMIAL WITH REAL COEFFICIENTS : give the roots of
        !          2754:  *  the polynomial a (first, the real roots, then the
        !          2755:  *  non real roots) in increasing order of their real
        !          2756:  *  parts MULTIPLE ROOTS ARE FORBIDDEN.
        !          2757:  */
        !          2758: {
        !          2759:   long av,tetpil,n,i,j,k,ct,prec;
        !          2760:   GEN aa,b,p1,rt,rr,hess,x,dx,y,hessbis,eps,newval;
        !          2761:   GEN oldval = NULL; /* for lint */
        !          2762:
        !          2763:   av=avma; n=lgef(a)-3; prec=PREC;
        !          2764:   hess=cgetg(n+1,t_MAT); for (k=1; k<=n; k++) hess[k]=lgetg(n+1,t_COL);
        !          2765:   for (k=1; k<=n; k++)
        !          2766:   {
        !          2767:     p1=(GEN)hess[k]; p1[1]=lneg(gdiv((GEN)a[n-k+2],(GEN)a[n+2]));
        !          2768:     for (j=2; j<=n; j++){ if (j==(k+1)) p1[j]=un; else p1[j]=zero; }
        !          2769:   }
        !          2770:   rr=cgetg(n+1,t_COL);
        !          2771:   for (i=1; i<=n; i++)
        !          2772:   {
        !          2773:     rr[i]=lgetg(3,t_COMPLEX);
        !          2774:     mael(rr,i,1)=lgetr(PREC);
        !          2775:     mael(rr,i,2)=lgetr(PREC);
        !          2776:   }
        !          2777:   hessbis=balanc(hess); rt=hqr(hessbis);
        !          2778:   eps=cgetr(prec);
        !          2779:   p1=gpuigs(gdeux,-bit_accuracy(prec)); gaffect(p1,eps);
        !          2780:   prec=2*PREC; /* polishing the roots */
        !          2781:   aa=cgetg(n+3,t_POL); aa[1]=a[1];
        !          2782:   for (i=2; i<=n+2; i++){ aa[i]=lgetr(prec); gaffect((GEN)a[i],(GEN)aa[i]); }
        !          2783:   b=deriv(aa,varn(aa));
        !          2784:   for (i=1; i<=n; i++)
        !          2785:   {
        !          2786:     ct=0;
        !          2787:     if (typ(rt[i])==t_REAL) { x=cgetr(prec); affrr((GEN)rt[i],x); }
        !          2788:     else
        !          2789:     {
        !          2790:       x=cgetg(3,t_COMPLEX);
        !          2791:       x[1]=lgetr(prec); affrr(gmael(rt,i,1),(GEN)x[1]);
        !          2792:       x[2]=lgetr(prec); affrr(gmael(rt,i,2),(GEN)x[2]);
        !          2793:     }
        !          2794:   LAB1:
        !          2795:     dx=poleval(b,x);
        !          2796:     if (gcmp(gabs(dx,prec),eps) <= 0)
        !          2797:       err(talker,"the polynomial has probably multiple roots in zrhqr");
        !          2798:     y=gsub(x,gdiv(poleval(aa,x),dx));
        !          2799:     newval=gabs(poleval(aa,y),prec);
        !          2800:     if (gcmp(newval,eps) > 0 && (!ct || gcmp(newval,oldval) < 0))
        !          2801:     {
        !          2802:       ct++; oldval=newval; x=y;
        !          2803:       goto LAB1;
        !          2804:     }
        !          2805:     gaffect(y,(GEN)rr[i]);
        !          2806:   }
        !          2807:   if (DEBUGLEVEL>3){ fprintferr("polished roots = %Z",rr); flusherr(); }
        !          2808:   tetpil=avma; return gerepile(av,tetpil,gcopy(rr));
        !          2809: }

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