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

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

1.1     ! maekawa     1: /*******************************************************************/
        !             2: /*                                                                 */
        !             3: /*                ROOTS OF COMPLEX POLYNOMIALS                     */
        !             4: /*                (written by Xavier Gourdon)                      */
        !             5: /*                                                                 */
        !             6: /*******************************************************************/
        !             7: /* $Id: rootpol.c,v 1.2 1999/09/23 17:50:56 karim Exp $ */
        !             8: #include "pari.h"
        !             9:
        !            10: GEN polrecip_i(GEN x);
        !            11: #define pariINFINITY 100000
        !            12: #define NEWTON_MAX 10
        !            13:
        !            14: static GEN gunr, globalu;
        !            15: static long KARASQUARE_LIMIT, COOK_SQUARE_LIMIT, Lmax, step4;
        !            16: static double *radius;
        !            17:
        !            18: /********************************************************************/
        !            19: /**                                                                **/
        !            20: /**                      ARITHMETIQUE RAPIDE                       **/
        !            21: /**                                                                **/
        !            22: /********************************************************************/
        !            23:
        !            24: /* fast product of x,y which must be integer or complex of integer */
        !            25: static GEN
        !            26: quickmulcc(GEN x, GEN y)
        !            27: {
        !            28:   long tx=typ(x),ty=typ(y);
        !            29:   GEN z;
        !            30:
        !            31:   if (tx==t_INT)
        !            32:   {
        !            33:     if (ty==t_INT) return mulii(x,y);
        !            34:     if (ty==t_COMPLEX)
        !            35:     {
        !            36:       z=cgetg(3,t_COMPLEX);
        !            37:       z[1]=(long) mulii(x,(GEN) y[1]);
        !            38:       z[2]=(long) mulii(x,(GEN) y[2]);
        !            39:       return z;
        !            40:     }
        !            41:   }
        !            42:
        !            43:   if (tx==t_COMPLEX)
        !            44:   {
        !            45:     if (ty==t_INT)
        !            46:     {
        !            47:       z=cgetg(3,t_COMPLEX);
        !            48:       z[1]=(long) mulii((GEN)x[1],y);
        !            49:       z[2]=(long) mulii((GEN)x[2],y);
        !            50:       return z;
        !            51:     }
        !            52:     if (ty==t_COMPLEX)
        !            53:     {
        !            54:       long av,tetpil;
        !            55:       GEN p1,p2;
        !            56:
        !            57:       z=cgetg(3,t_COMPLEX); av=avma;
        !            58:       p1=mulii((GEN)x[1],(GEN)y[1]); p2=mulii((GEN)x[2],(GEN)y[2]);
        !            59:       x=addii((GEN)x[1],(GEN)x[2]); y=addii((GEN)y[1],(GEN)y[2]);
        !            60:       y=mulii(x,y); x=addii(p1,p2);
        !            61:       tetpil=avma; z[1]=lsubii(p1,p2); z[2]=lsubii(y,x);
        !            62:       gerepilemanyvec(av,tetpil,z+1,2);
        !            63:       return z;
        !            64:     }
        !            65:   }
        !            66:   err(talker,"bug in quickmulcc");
        !            67:   return NULL; /* not reached */
        !            68: }
        !            69:
        !            70: static void
        !            71: set_karasquare_limit(long bitprec)
        !            72: {
        !            73:   if (bitprec<600) { KARASQUARE_LIMIT=8; COOK_SQUARE_LIMIT=400; return; }
        !            74:   if (bitprec<2000) { KARASQUARE_LIMIT=4; COOK_SQUARE_LIMIT=200; return; }
        !            75:   if (bitprec<3000) { KARASQUARE_LIMIT=4; COOK_SQUARE_LIMIT=125; return; }
        !            76:   if (bitprec<5000) { KARASQUARE_LIMIT=2; COOK_SQUARE_LIMIT=75; return; }
        !            77:   KARASQUARE_LIMIT=1; COOK_SQUARE_LIMIT=50;
        !            78: }
        !            79:
        !            80: /* the pari library does not have specific procedure for the square of
        !            81: polynomials. This one is twice faster than gmul */
        !            82: static GEN
        !            83: mysquare(GEN p)
        !            84: {
        !            85:   GEN s,aux1,aux2;
        !            86:   long i,j,n=lgef(p)-3,nn,ltop,lbot;
        !            87:
        !            88:   if (n==-1) return gcopy(p);
        !            89:   nn=n<<1; s=cgetg(nn+3,t_POL);
        !            90:   s[1] = evalsigne(1) | evalvarn(varn(p)) | evallgef(nn+3);
        !            91:   for (i=0; i<=n; i++)
        !            92:   {
        !            93:     aux1=gzero; ltop=avma;
        !            94:     for (j=0; j<(i+1)>>1; j++)
        !            95:     {
        !            96:       aux2=quickmulcc((GEN) p[j+2],(GEN)p[i-j+2]);
        !            97:       aux1=gadd(aux1,aux2);
        !            98:     }
        !            99:     if (i%2==1) { lbot=avma; s[i+2]=lpile(ltop,lbot,gshift(aux1,1)); }
        !           100:     else
        !           101:     {
        !           102:       aux1=gshift(aux1,1);
        !           103:       aux2=quickmulcc((GEN)p[2+(i>>1)],(GEN)p[2+(i>>1)]);
        !           104:       lbot=avma; s[i+2]=lpile(ltop,lbot,gadd(aux1,aux2));
        !           105:     }
        !           106:   }
        !           107:   for (i=n+1; i<=nn; i++)
        !           108:   {
        !           109:     aux1=gzero; ltop=avma;
        !           110:     for (j=i-n; j<(i+1)>>1; j++)
        !           111:     {
        !           112:       aux2=quickmulcc((GEN)p[j+2],(GEN)p[i-j+2]);
        !           113:       aux1=gadd(aux1,aux2);
        !           114:     }
        !           115:     if (i%2==1) { lbot=avma; s[i+2]=lpile(ltop,lbot,gshift(aux1,1)); }
        !           116:     else
        !           117:     {
        !           118:       aux1=gshift(aux1,1);
        !           119:       aux2=quickmulcc((GEN)p[2+(i>>1)],(GEN)p[2+(i>>1)]);
        !           120:       lbot=avma; s[i+2]=lpile(ltop,lbot,gadd(aux1,aux2));
        !           121:     }
        !           122:   }
        !           123:   return s;
        !           124: }
        !           125:
        !           126: static GEN
        !           127: karasquare(GEN p)
        !           128: {
        !           129:   GEN p1,s0,s1,s2,aux;
        !           130:   long n=lgef(p)-3,n0,n1,i,var,nn0,ltop,lbot;
        !           131:
        !           132:   if (n<=KARASQUARE_LIMIT) return mysquare(p);
        !           133:   ltop=avma;
        !           134:   var=evalsigne(1)+evalvarn(varn(p)); n0=n>>1; n1=n-n0-1;
        !           135:   setlgef(p,n0+3); /* hack to have the first half of p */
        !           136:   s0=karasquare(p);
        !           137:   p1=cgetg(n1+3,t_POL); p1[1]=var+evallgef(n1+3);
        !           138:   for (i=2; i<=n1+2; i++) p1[i]=p[1+i+n0];
        !           139:   s2=karasquare(p1);
        !           140:   s1=karasquare(gadd(p,p1));
        !           141:   s1=gsub(s1,gadd(s0,s2));
        !           142:   nn0=n0<<1;
        !           143:   aux=cgetg((n<<1)+3,t_POL); aux[1]=var+evallgef(2*n+3);
        !           144:   var=lgef(s0);
        !           145:   for (i=2; i<var; i++) aux[i]=s0[i];
        !           146:   for (   ; i<=nn0+2; i++) aux[i]=zero;
        !           147:   var=lgef(s2);
        !           148:   for (i=2; i<var; i++) aux[2+i+nn0]=s2[i];
        !           149:   for (i=var-2; i<=(n1<<1); i++) aux[4+i+nn0]=zero;
        !           150:   aux[3+nn0]=zero;
        !           151:   for (i=3; i<=lgef(s1); i++)
        !           152:     aux[i+n0]=ladd((GEN) aux[i+n0],(GEN) s1[i-1]);
        !           153:   setlgef(p,n+3); /* recover all the polynomial p */
        !           154:   lbot=avma; return gerepile(ltop,lbot,gcopy(aux));
        !           155: }
        !           156:
        !           157: static GEN
        !           158: cook_square(GEN p)
        !           159: {
        !           160:   GEN p0,p1,p2,p3,q,aux0,aux1,r,aux,plus,moins;
        !           161:   long n=lgef(p)-3,n0,n3,i,j,ltop=avma,lbot,var;
        !           162:
        !           163:   if (n<=COOK_SQUARE_LIMIT) return karasquare(p);
        !           164:
        !           165:   n0=(n+1)/4; n3=n+1-3*n0;
        !           166:   p0=cgetg(n0+2,t_POL); p1=cgetg(n0+2,t_POL); p2=cgetg(n0+2,t_POL);
        !           167:   p3=cgetg(n3+2,t_POL);
        !           168:   var=evalsigne(1)|evalvarn(varn(p));
        !           169:   p0[1]=p1[1]=p2[1]=var|evallgef(n0+2); p3[1]=var|evallgef(n3+2);
        !           170:
        !           171:   for (i=0; i<n0; i++)
        !           172:   {
        !           173:     p0[i+2]=p[i+2]; p1[i+2]=p[i+n0+2]; p2[i+2]=p[i+2*n0+2];
        !           174:   }
        !           175:   for (i=0; i<n3; i++) p3[i+2]=p[i+3*n0+2];
        !           176:
        !           177:   q=cgetg(8,t_VEC); q=q+4;
        !           178:
        !           179:   q[0]=(long) p0;
        !           180:   aux0=gadd(p0,p2); aux1=gadd(p1,p3);
        !           181:   q[-1]=lsub(aux0,aux1); q[1]=ladd(aux0,aux1);
        !           182:   aux0=gadd(p0,gmulgs(p2,4)); aux1=gmulgs(gadd(p1,gmulgs(p3,4)),2);
        !           183:   q[-2]=lsub(aux0,aux1); q[2]=ladd(aux0,aux1);
        !           184:   aux0=gadd(p0,gmulgs(p2,9)); aux1=gmulgs(gadd(p1,gmulgs(p3,9)),3);
        !           185:   q[-3]=lsub(aux0,aux1); q[3]=ladd(aux0,aux1);
        !           186:   for (i=-3; i<=3; i++) q[i]=(long) cook_square((GEN)q[i]);
        !           187:   r=new_chunk(7);
        !           188:   plus=cgetg(4,t_VEC); moins=cgetg(4,t_VEC);
        !           189:   for (i=1; i<=3; i++)
        !           190:   {
        !           191:     plus[i]=ladd((GEN)q[-i],(GEN)q[i]);
        !           192:     moins[i]=lsub((GEN)q[-i],(GEN)q[i]);
        !           193:   }
        !           194:   r[0]=q[0];
        !           195:   r[1]=ldivgs(
        !           196:              gsub(
        !           197:                   gsub(gmulgs((GEN)moins[2],9),(GEN)moins[3]),
        !           198:                   gmulgs((GEN)moins[1],45)),
        !           199:              60);
        !           200:   r[2]=ldivgs(
        !           201:              gadd(
        !           202:                   gadd(gmulgs((GEN)plus[1],270),gmulgs((GEN)q[0],-490)),
        !           203:                   gadd(gmulgs((GEN)plus[2],-27),gmulgs((GEN)plus[3],2))),
        !           204:              360);
        !           205:   r[3]=ldivgs(
        !           206:              gadd(
        !           207:                   gadd(gmulgs((GEN)moins[1],13),gmulgs((GEN)moins[2],-8)),
        !           208:                   (GEN)moins[3]),
        !           209:              48);
        !           210:   r[4]=ldivgs(
        !           211:              gadd(
        !           212:                   gadd(gmulgs((GEN)q[0],56),gmulgs((GEN)plus[1],-39)),
        !           213:                   gsub(gmulgs((GEN)plus[2],12),(GEN)plus[3])),
        !           214:              144);
        !           215:   r[5]=ldivgs(
        !           216:              gsub(
        !           217:                   gadd(gmulgs((GEN)moins[1],-5),gmulgs((GEN)moins[2],4)),
        !           218:                   (GEN)moins[3]),
        !           219:              240);
        !           220:   r[6]=ldivgs(
        !           221:              gadd(
        !           222:                   gadd(gmulgs((GEN)q[0],-20),gmulgs((GEN)plus[1],15)),
        !           223:                   gadd(gmulgs((GEN)plus[2],-6),(GEN)plus[3])),
        !           224:              720);
        !           225:   q=cgetg(2*n+3,t_POL); q[1]=var|evallgef(2*n+3);
        !           226:   for (i=0; i<=2*n; i++) q[i+2]=zero;
        !           227:   for (i=0; i<=6; i++)
        !           228:   {
        !           229:     aux=(GEN) r[i];
        !           230:     for (j=0; j<=lgef(aux)-3; j++)
        !           231:       q[n0*i+j+2]=ladd((GEN)q[n0*i+j+2],(GEN)aux[j+2]);
        !           232:   }
        !           233:   lbot=avma; return gerepile(ltop,lbot,gcopy(q));
        !           234: }
        !           235:
        !           236: static GEN
        !           237: graeffe(GEN p)
        !           238: {
        !           239:   GEN p0,p1,s0,s1,ss1;
        !           240:   long n=lgef(p)-3,n0,n1,i,auxi,ns1;
        !           241:
        !           242:   if (n==0) return gcopy(p);
        !           243:   n0=n>>1; n1=(n-1)>>1;
        !           244:   auxi=evalsigne(1)|evalvarn(varn(p));
        !           245:   p0=cgetg(n0+3,t_POL); p0[1]=auxi|evallgef(n0+3);
        !           246:   p1=cgetg(n1+3,t_POL); p1[1]=auxi|evallgef(n1+3);
        !           247:   for (i=0; i<=n0; i++) p0[i+2]=p[2+(i<<1)];
        !           248:   for (i=0; i<=n1; i++) p1[i+2]=p[3+(i<<1)];
        !           249:
        !           250:   s0=cook_square(p0);
        !           251:   s1=cook_square(p1); ns1 = lgef(s1)-3;
        !           252:   ss1 = cgetg(ns1+4, t_POL);
        !           253:   ss1[1] = auxi | evallgef(ns1+4);
        !           254:   ss1[2]=zero;
        !           255:   for (i=0; i<=ns1; i++) ss1[3+i]=lneg((GEN)s1[2+i]);
        !           256:   /* now ss1 contains -x * s1 */
        !           257:   return gadd(s0,ss1);
        !           258: }
        !           259:
        !           260: /********************************************************************/
        !           261: /**                                                                **/
        !           262: /**        FACTORISATION SQUAREFREE AVEC LE GCD MODULAIRE          **/
        !           263: /**                                                                **/
        !           264: /********************************************************************/
        !           265:
        !           266: /* return a n x 2 matrix:
        !           267:  *   col 1 contains the i's such that A_i non constant
        !           268:  *   col 2 the A_i's, s.t. pol = A_i1^i1.A_i2^i2...A_in^in.
        !           269:  * if pol is constant return [;]
        !           270:  */
        !           271: GEN
        !           272: square_free_factorization(GEN pol)
        !           273: {
        !           274:   long deg,i,j,m;
        !           275:   GEN p1,x,t1,v1,t,v,A;
        !           276:
        !           277:   if (typ(pol)!=t_POL) err(typeer,"square_free_factorization");
        !           278:   deg=lgef(pol)-3; if (deg<1) return cgetg(1,t_MAT);
        !           279:   p1 = content(pol); if (!gcmp1(p1)) pol = gdiv(pol,p1);
        !           280:
        !           281:   x=cgetg(3,t_MAT);
        !           282:   if (deg > 1)
        !           283:   {
        !           284:     t1 = modulargcd(pol,derivpol(pol));
        !           285:     if (isscalar(t1)) deg = 1;
        !           286:   }
        !           287:   if (deg==1)
        !           288:   {
        !           289:     x[1]=lgetg(2,t_COL); p1=(GEN)x[1]; p1[1]=un;
        !           290:     x[2]=lgetg(2,t_COL); p1=(GEN)x[2]; p1[1]=(long)pol; return x;
        !           291:   }
        !           292:   A=new_chunk(deg+1); v1=gdivexact(pol,t1); v=v1; i=0;
        !           293:   while (lgef(v)>3)
        !           294:   {
        !           295:     v=modulargcd(t1,v1); i++;
        !           296:     A[i]=(long)gdivexact(v1,v);
        !           297:     t=gdivexact(t1,v); v1=v; t1=t;
        !           298:   }
        !           299:   m=1; x[1]=lgetg(deg+1,t_COL); x[2]=lgetg(deg+1,t_COL);
        !           300:   for (j=1; j<=i; j++)
        !           301:     if (isnonscalar(A[j]))
        !           302:     {
        !           303:       p1=(GEN)x[1]; p1[m] = lstoi(j);
        !           304:       p1=(GEN)x[2]; p1[m] = A[j];
        !           305:       m++;
        !           306:     }
        !           307:   setlg(x[1],m); setlg(x[2],m); return x;
        !           308: }
        !           309:
        !           310: /********************************************************************/
        !           311: /**                                                                **/
        !           312: /**                 CALCUL DU MODULE DES RACINES                   **/
        !           313: /**                                                                **/
        !           314: /********************************************************************/
        !           315:
        !           316: static double
        !           317: log2ir(GEN x)
        !           318: {
        !           319:   double l;
        !           320:
        !           321:   if (signe(x)==0) return (double) -pariINFINITY;
        !           322:   if (typ(x)==t_INT)
        !           323:   {
        !           324:     if (lgef(x)==3) return (double) log2( (double)(ulong) x[2]);
        !           325:     l=(double)(ulong) x[2]+
        !           326:        (double)(ulong) x[3] / exp2((double) BITS_IN_LONG);
        !           327:     return log2(l)+ (double) BITS_IN_LONG * (lgef(x)-3.);
        !           328:   }
        !           329:   /* else x is real */
        !           330:   return 1.+ (double) expo(x)+log2( (double)(ulong) x[2]) - (double) BITS_IN_LONG;
        !           331: }
        !           332:
        !           333: static double
        !           334: mylog2(GEN z)
        !           335: {
        !           336:   double x,y;
        !           337:
        !           338:   if (typ(z)!=t_COMPLEX) return log2ir(z);
        !           339:
        !           340:   x=log2ir((GEN) z[1]); y=log2ir((GEN) z[2]);
        !           341:   if (fabs(x-y)>10) return (x>y)? x: y;
        !           342:   return x+0.5*log2( 1 + exp2(2*(y-x)));
        !           343: }
        !           344:
        !           345: static long
        !           346: findpower(GEN p)
        !           347: {
        !           348:   double x, logbinomial,pente,pentemax=-pariINFINITY;
        !           349:   long n=lgef(p)-3,i;
        !           350:
        !           351:   logbinomial=mylog2((GEN) p[n+2]);
        !           352:   for (i=n-1; i>=0; i--)
        !           353:   {
        !           354:     logbinomial=logbinomial+log2((double) (i+1) / (double) (n-i));
        !           355:     x=mylog2((GEN) p[2+i])-logbinomial;
        !           356:     if (x>-pariINFINITY)
        !           357:     {
        !           358:       pente=x/ (double) (n-i);
        !           359:       if (pente>pentemax) pentemax=pente;
        !           360:     }
        !           361:   }
        !           362:   return (long) -floor(pentemax);
        !           363: }
        !           364:
        !           365: /* returns the exponent for the procedure modulus, from the newton diagram */
        !           366: static long
        !           367: polygone_newton(GEN p, long k)
        !           368: {
        !           369:   double *logcoef,pente;
        !           370:   long n=lgef(p)-3,i,j,h,l,*sommet,pentelong;
        !           371:
        !           372:   logcoef=(double*) gpmalloc((n+1)*sizeof(double));
        !           373:   sommet=(long*) gpmalloc((n+1)*sizeof(long));
        !           374:
        !           375:   /* sommet[i]=1 si i est un sommet, =0 sinon */
        !           376:   for (i=0; i<=n; i++) { logcoef[i]=mylog2((GEN)p[2+i]); sommet[i]=0; }
        !           377:   sommet[0]=1; i=0;
        !           378:   while (i<n)
        !           379:   {
        !           380:     pente=logcoef[i+1]-logcoef[i];
        !           381:     h=i+1;
        !           382:     for (j=i+1; j<=n; j++)
        !           383:     {
        !           384:       if (pente<(logcoef[j]-logcoef[i])/(double)(j-i))
        !           385:       {
        !           386:        h=j;
        !           387:        pente=(logcoef[j]-logcoef[i])/(double)(j-i);
        !           388:       }
        !           389:     }
        !           390:     i=h;
        !           391:     sommet[h]=1;
        !           392:   }
        !           393:   h=k; while (!sommet[h]) h++;
        !           394:   l=k-1; while (!sommet[l]) l--;
        !           395:   pentelong=(long) floor((logcoef[h]-logcoef[l])/(double)(h-l)+0.5);
        !           396:   free(logcoef); free(sommet); return pentelong;
        !           397: }
        !           398:
        !           399: /* change z into z*2^e, where z is real or complex of real */
        !           400: static void
        !           401: myshiftrc(GEN z, long e)
        !           402: {
        !           403:   if (typ(z)==t_COMPLEX)
        !           404:   {
        !           405:     if (signe(z[1])!=0) setexpo(z[1], expo(z[1])+e);
        !           406:     if (signe(z[2])!=0) setexpo(z[2], expo(z[2])+e);
        !           407:   }
        !           408:   else
        !           409:     if (signe(z)!=0) setexpo(z,expo(z)+e);
        !           410: }
        !           411:
        !           412: /* return z*2^e, where z is integer or complex of integer (destroy z) */
        !           413: static GEN
        !           414: myshiftic(GEN z, long e)
        !           415: {
        !           416:   if (typ(z)==t_COMPLEX)
        !           417:   {
        !           418:     z[1]=signe(z[1])? lmpshift((GEN) z[1],e): zero;
        !           419:     z[2]=lmpshift((GEN) z[2],e);
        !           420:     return z;
        !           421:   }
        !           422:   return signe(z)? mpshift(z,e): gzero;
        !           423: }
        !           424:
        !           425: static GEN
        !           426: mygprecrc(GEN x, long bitprec, long e)
        !           427: {
        !           428:   long tx=typ(x);
        !           429:   GEN y;
        !           430:
        !           431:   if (bitprec<0) bitprec=0; /* should rarely happen */
        !           432:   switch(tx)
        !           433:   {
        !           434:     case t_REAL:
        !           435:       y=cgetr(bitprec/BITS_IN_LONG+3); affrr(x,y);
        !           436:       if (!signe(x)) setexpo(y,-bitprec+e);
        !           437:       break;
        !           438:     case t_COMPLEX:
        !           439:       y=cgetg(3,t_COMPLEX);
        !           440:       y[1]=(long) mygprecrc((GEN)x[1],bitprec,e);
        !           441:       y[2]=(long) mygprecrc((GEN)x[2],bitprec,e);
        !           442:       break;
        !           443:     default: y=gcopy(x);
        !           444:   }
        !           445:   return y;
        !           446: }
        !           447:
        !           448: /* gprec behaves badly with the zero for polynomials.
        !           449: The second parameter in mygprec is the precision in base 2 */
        !           450: static GEN
        !           451: mygprec(GEN x, long bitprec)
        !           452: {
        !           453:   long tx=typ(x),lx,i,e;
        !           454:   GEN y;
        !           455:
        !           456:   switch(tx)
        !           457:   {
        !           458:     case t_POL:
        !           459:       lx=lgef(x); y=cgetg(lx,tx); y[1]=x[1]; e=gexpo(x);
        !           460:       for (i=2; i<lx; i++) y[i]=(long) mygprecrc((GEN)x[i],bitprec,e);
        !           461:       break;
        !           462:
        !           463:     default: y=mygprecrc(x,bitprec,0);
        !           464:   }
        !           465:   return y;
        !           466: }
        !           467:
        !           468: /* the round fonction has a bug in pari. Thus I create mygfloor, using gfloor
        !           469: which has no bug (destroy z)*/
        !           470: static GEN
        !           471: mygfloor(GEN z)
        !           472: {
        !           473:   if (typ(z)!=t_COMPLEX) return gfloor(z);
        !           474:   z[1]=lfloor((GEN)z[1]); z[2]=lfloor((GEN)z[2]); return z;
        !           475: }
        !           476:
        !           477: /* returns a polynomial q in (Z[i])[x] keeping bitprec bits of p */
        !           478: static GEN
        !           479: eval_rel_pol(GEN p,long bitprec)
        !           480: {
        !           481:   long e=gexpo(p),n=lgef(p),i,shift;
        !           482:   GEN q = gprec(p,(long) ((double) bitprec * L2SL10)+2);
        !           483:
        !           484:   shift=bitprec-e+1;
        !           485:   for (i=2; i<n; i++)
        !           486:     q[i]=(long) mygfloor(myshiftic((GEN)q[i],shift));
        !           487:   return q;
        !           488: }
        !           489:
        !           490: /* normalize a polynomial p, that is change it with coefficients in Z[i],
        !           491: after making product by 2^bitprec */
        !           492: static void
        !           493: pol_to_gaussint(GEN p, long bitprec)
        !           494: {
        !           495:   long i,n=lgef(p);
        !           496:   for (i=2; i<n; i++)
        !           497:   {
        !           498:     myshiftrc((GEN) p[i],bitprec);
        !           499:     p[i]=(long) mygfloor((GEN) p[i]);
        !           500:   }
        !           501: }
        !           502:
        !           503: /* returns p(R*x)/R^n (in R or R[i]), n=deg(p), bitprec bits of precision */
        !           504: static GEN
        !           505: homothetie(GEN p, double R, long bitprec)
        !           506: {
        !           507:   GEN q,r,gR,aux;
        !           508:   long n=lgef(p)-3,i;
        !           509:
        !           510:   gR=mygprec(dbltor(1/R),bitprec);
        !           511:   q=mygprec(p,bitprec);
        !           512:   r=cgetg(n+3,t_POL); r[1]=evalsigne(1)+evalvarn(varn(p))+evallgef(n+3);
        !           513:   aux=gR; r[n+2]=q[n+2];
        !           514:   for (i=n-1; i>=0; i--)
        !           515:   {
        !           516:     r[i+2]=lmul(aux,(GEN)q[i+2]);
        !           517:     aux=gmul(aux,gR);
        !           518:   }
        !           519:   return r;
        !           520: }
        !           521:
        !           522: /* change q in 2^(n*e) p(x*2^(-e)), n=deg(q) */
        !           523: static void
        !           524: homothetie2n(GEN p, long e)
        !           525: {
        !           526:   if (e)
        !           527:   {
        !           528:     long i,n=lgef(p)-1;
        !           529:     for (i=2; i<=n; i++) myshiftrc((GEN) p[i],(n-i)*e);
        !           530:   }
        !           531: }
        !           532:
        !           533: /* return 2^f * 2^(n*e) p(x*2^(-e)), n=deg(q) */
        !           534: static void
        !           535: homothetie_gauss(GEN p, long e,long f)
        !           536: {
        !           537:   if (e||f)
        !           538:   {
        !           539:     long i, n=lgef(p)-1;
        !           540:     for (i=2; i<=n; i++) p[i]=(long) myshiftic((GEN) p[i],f+(n-i)*e);
        !           541:   }
        !           542: }
        !           543:
        !           544: static long
        !           545: valuation(GEN p)
        !           546: {
        !           547:   long j=0,n=lgef(p)-3;
        !           548:
        !           549:   while ((j<=n) && isexactzero((GEN)p[j+2])) j++;
        !           550:   return j;
        !           551: }
        !           552:
        !           553: /* provides usually a good lower bound on the largest modulus of the roots,
        !           554: puts in k an upper bound of the number of roots near the largest root
        !           555: at a distance eps */
        !           556: static double
        !           557: lower_bound(GEN p, long *k, double eps)
        !           558: {
        !           559:   long n=lgef(p)-3,i,j,ltop=avma;
        !           560:   GEN a,s,icd;
        !           561:   double r,*rho;
        !           562:
        !           563:   if (n<4) { *k=n; return 0.; }
        !           564:   a=cgetg(6,t_POL); s=cgetg(6,t_POL);
        !           565:   rho=(double *) gpmalloc(4*sizeof(double));
        !           566:   icd=gdiv(gunr,(GEN) p[n+2]);
        !           567:   for (i=1; i<=4; i++) a[i+1]=lmul(icd,(GEN)p[n+2-i]);
        !           568:   for (i=1; i<=4; i++)
        !           569:   {
        !           570:     s[i+1]=lmulsg(i,(GEN)a[i+1]);
        !           571:     for (j=1; j<i; j++)
        !           572:       s[i+1]=ladd((GEN)s[i+1],gmul((GEN)s[j+1],(GEN)a[i+1-j]));
        !           573:     s[i+1]=lneg((GEN)s[i+1]);
        !           574:     r=gtodouble(gabs((GEN) s[i+1],3));
        !           575:     if (r<=0.)  /* should not be strictly negative */
        !           576:       rho[i-1]=0.;
        !           577:     else
        !           578:       rho[i-1]=exp(log(r/(double)n)/(double) i);
        !           579:   }
        !           580:   r=0.;
        !           581:   for (i=0; i<4; i++) if (r<rho[i]) r=rho[i];
        !           582:   if (r>0. && eps<1.2)
        !           583:     *k=(long) floor((n*rho[0]/r+n)/(1+exp(-eps)*cos(eps)));
        !           584:   else
        !           585:     *k=n;
        !           586:   free(rho); avma=ltop; return r;
        !           587: }
        !           588:
        !           589: /* returns the maximum of the modulus of p with a relative error tau */
        !           590: static GEN
        !           591: gmax_modulus(GEN p, double tau)
        !           592: {
        !           593:   GEN q,aux,new_gunr;
        !           594:   long i,j,k,valuat,n=lgef(p)-3,nn,ltop=avma,bitprec,imax,e;
        !           595:   double r=0.,rho,tau2,eps;
        !           596:
        !           597:   if (tau>3.0) tau=3.0; /* fix PZ 7.2.98: ensures eps is positive */
        !           598:   eps=1/log(4./tau); tau2=tau/6.;
        !           599:   bitprec=(long) ((double) n*log2(1./tau2)+3*log2((double) n))+1;
        !           600:   new_gunr=mygprec(gunr,bitprec+2*n);
        !           601:   aux=gdiv(new_gunr,(GEN) p[2+n]);
        !           602:   q=gmul(aux,p); q[2+n]=lcopy(new_gunr);
        !           603:   k=nn=n;
        !           604:   e=findpower(q); homothetie2n(q,e); r=-(double) e;
        !           605:   q=mygprec(q,bitprec+(n<<1));
        !           606:   pol_to_gaussint(q,bitprec);
        !           607:   imax=(long) ((log(log(4.*n))+log(3./tau))/log(2.))+2;
        !           608:   for (i=0,e=0;;)
        !           609:   {
        !           610:     rho=lower_bound(q,&k,eps);
        !           611:     if (rho>exp2(-(double) e)) e = (long) -floor(log2(rho));
        !           612:     r = r-(double) e/ exp2( (double) i);
        !           613:     if (++i == imax)
        !           614:     {
        !           615:       avma=ltop;
        !           616:       return gpui(dbltor(2.),dbltor(r),DEFAULTPREC);
        !           617:     }
        !           618:
        !           619:     if (k<nn)
        !           620:       bitprec=(long) ((double) k* log2(1./tau2)+
        !           621:                       (double) (nn-k)*log2(1./eps)+
        !           622:                       3*log2((double) nn))+1;
        !           623:     else
        !           624:       bitprec=(long) ((double) nn* log2(1./tau2)+
        !           625:                       3.*log2((double) nn))+1;
        !           626:     homothetie_gauss(q,e,bitprec-(long)floor(mylog2((GEN) q[2+nn])+0.5));
        !           627:     valuat=valuation(q);
        !           628:     if (valuat>0)
        !           629:     {
        !           630:       nn-=valuat; setlgef(q,nn+3);
        !           631:       for (j=0; j<=nn; j++) q[2+j]=q[2+valuat+j];
        !           632:     }
        !           633:     set_karasquare_limit(gexpo(q));
        !           634:     q = gerepileupto(ltop, graeffe(q));
        !           635:     tau2=1.5*tau2; eps=1/log(1./tau2);
        !           636:     e = findpower(q);
        !           637:   }
        !           638: }
        !           639:
        !           640: static double
        !           641: max_modulus(GEN p, double tau)
        !           642: {
        !           643:   return gtodouble(gmax_modulus(p,tau));
        !           644: }
        !           645:
        !           646: /* return the k-th modulus (in ascending order) of p, rel. error tau*/
        !           647: static double
        !           648: modulus(GEN p, long k, double tau)
        !           649: {
        !           650:   GEN q,new_gunr;
        !           651:   long i,j,kk=k,imax,n=lgef(p)-3,nn,nnn,valuat,av,ltop=avma,bitprec,decprec,e;
        !           652:   double tau2,r;
        !           653:
        !           654:   tau2=tau/6; nn=n;
        !           655:   bitprec= (long) ((double) n*(2.+log2(3.*(double) n)+log2(1./tau2)));
        !           656:   decprec=(long) ((double) bitprec * L2SL10)+1;
        !           657:   new_gunr=gprec(gunr,decprec);
        !           658:   av = avma;
        !           659:   q=gprec(p,decprec);
        !           660:   q=gmul(new_gunr,q);
        !           661:   e=polygone_newton(q,k);
        !           662:   homothetie2n(q,e);
        !           663:   r=(double) e;
        !           664:   imax=(long) ((log2(3./tau)+log2(log(4.*(double) n)) ))+1;
        !           665:   for (i=1; i<imax; i++)
        !           666:   {
        !           667:     q=eval_rel_pol(q,bitprec);
        !           668:
        !           669:     nnn=lgef(q)-3; valuat=valuation(q);
        !           670:     if (valuat>0)
        !           671:     {
        !           672:       kk-=valuat;
        !           673:       for (j=0; j<=nnn-valuat; j++) q[2+j]=q[2+valuat+j];
        !           674:       setlgef(q,nnn-valuat+3);
        !           675:     }
        !           676:     nn=nnn-valuat;
        !           677:
        !           678:     set_karasquare_limit(bitprec);
        !           679:     q = gerepileupto(av, graeffe(q));
        !           680:     e=polygone_newton(q,kk);
        !           681:     r=r+e/exp2((double)i);
        !           682:     q=gmul(new_gunr,q);
        !           683:     homothetie2n(q,e);
        !           684:
        !           685:     tau2=1.5*tau2; if (tau2>1.) tau2=1.;
        !           686:     bitprec= 1+(long) ((double) nn*(2.+log2(3.*(double) nn)+log2(1./tau2)));
        !           687:   }
        !           688:   avma=ltop; return exp2(-r);
        !           689: }
        !           690:
        !           691: /* return the k-th modulus r_k of p, rel. error tau, knowing that
        !           692: rmin < r_k < rmax. This helps because the information enable us to use
        !           693: less precision... quicker ! */
        !           694: static double
        !           695: pre_modulus(GEN p, long k, double tau, double rmin, double rmax)
        !           696: {
        !           697:   GEN q;
        !           698:   long n=lgef(p)-3,i,imax,imax2,bitprec,ltop=avma;
        !           699:   double aux,tau2,R;
        !           700:
        !           701:   tau2=tau/6.; aux=sqrt(rmax/rmin)*exp(4*tau2);
        !           702:   imax=(long) log2(log((double)n)/log(aux));
        !           703:   if (imax<=0) return modulus(p,k,tau);
        !           704:
        !           705:   R=sqrt(rmin*rmax);
        !           706:   bitprec=(long) ((double) n*(2.+log2(aux)+log2(1./tau2)));
        !           707:   q=homothetie(p,R,bitprec);
        !           708:   imax2=(long) ((log2(3./tau)+log2(log(4.*(double) n)) ))+1;
        !           709:   if (imax>imax2) imax=imax2;
        !           710:
        !           711:   for (i=0; i<imax; i++)
        !           712:   {
        !           713:     q=eval_rel_pol(q,bitprec);
        !           714:     set_karasquare_limit(bitprec);
        !           715:     q = gerepileupto(ltop, graeffe(q));
        !           716:     aux=aux*aux*exp(2*tau2);
        !           717:     tau2=1.5*tau2;
        !           718:     bitprec= (long) ((double) n*(2.+log2(aux)+log2(1./(1-exp(-tau2)))));
        !           719:     q=gmul(mygprec(gunr,bitprec),q);
        !           720:   }
        !           721:
        !           722:   aux=modulus(q,k,exp2((double)imax)*tau/3.);
        !           723:   R=R*exp(log(aux)*exp2(-(double)imax));
        !           724:   avma=ltop; return R;
        !           725: }
        !           726:
        !           727: /* returns the minimum of the modulus of p with a relative error tau */
        !           728: static double
        !           729: min_modulus(GEN p, double tau)
        !           730: {
        !           731:   long ltop=avma;
        !           732:   double r;
        !           733:
        !           734:   if (isexactzero((GEN)p[2])) return 0.;
        !           735:   r=1./max_modulus(polrecip_i(p),tau); avma=ltop; return r;
        !           736: }
        !           737:
        !           738: /* returns k such that r_k e^(-tau) < R < r_{ k+1 } e^tau.
        !           739: l is such that you know in advance that l<= k <= n-l */
        !           740: static long
        !           741: dual_modulus(GEN p, double R, double tau, long l)
        !           742: {
        !           743:   GEN q;
        !           744:   long i,j,imax,k,delta_k=0,n=lgef(p)-3,nn,nnn,valuat,ltop=avma,bitprec,ll=l;
        !           745:   double logmax,aux,tau2;
        !           746:
        !           747:   tau2=7.*tau/8.;
        !           748:   bitprec=6*n-5*l+(long) ((double) n*(log2(1/tau2)+8.*tau2/7.));
        !           749:   q=homothetie(p,R,bitprec);
        !           750:   nn=n;
        !           751:   imax=(long)(log(log(2.*(double)n)/tau2)/log(7./4.)+1);
        !           752:
        !           753:   for (i=0; i<imax; i++)
        !           754:   {
        !           755:     bitprec=6*nn-5*ll+(long) ((double) nn*(log2(1/tau2)+8.*tau2/7.));
        !           756:
        !           757:     q=eval_rel_pol(q,bitprec);
        !           758:     nnn=lgef(q)-3; valuat=valuation(q);
        !           759:     if (valuat>0)
        !           760:     {
        !           761:       delta_k+=valuat;
        !           762:       for (j=0; j<=nnn-valuat; j++) q[2+j]=q[2+valuat+j];
        !           763:       setlgef(q,nnn-valuat+3);
        !           764:     }
        !           765:     ll= (-valuat<nnn-n)? ll-valuat: ll+nnn-n; /* min(ll-valuat,ll+nnn-n) */
        !           766:     if (ll<0) ll=0;
        !           767:
        !           768:     nn=nnn-valuat;
        !           769:     if (nn==0) return delta_k;
        !           770:
        !           771:     set_karasquare_limit(bitprec);
        !           772:     q = gerepileupto(ltop, graeffe(q));
        !           773:     tau2=tau2*7./4.;
        !           774:   }
        !           775:   k=-1; logmax=- (double) pariINFINITY;
        !           776:   for (i=0; i<=lgef(q)-3; i++)
        !           777:   {
        !           778:     aux=mylog2((GEN)q[2+i]);
        !           779:     if (aux>logmax) { logmax=aux; k=i; }
        !           780:   }
        !           781:   avma=ltop; return delta_k+k;
        !           782: }
        !           783:
        !           784: /********************************************************************/
        !           785: /**                                                                **/
        !           786: /**       CALCUL D'UN FACTEUR PAR INTEGRATION SUR LE CERCLE        **/
        !           787: /**                                                                **/
        !           788: /********************************************************************/
        !           789:
        !           790: static GEN
        !           791: gmulbyi(GEN z)
        !           792: {
        !           793:   GEN aux = cgetg(3,t_COMPLEX);
        !           794:
        !           795:   if (typ(z)!=t_COMPLEX)
        !           796:   {
        !           797:     aux[1]=zero;
        !           798:     aux[2]=(long) z;
        !           799:   }
        !           800:   else
        !           801:   {
        !           802:     aux[1]=lneg((GEN)z[2]);
        !           803:     aux[2]=z[1];
        !           804:   }
        !           805:   return aux;
        !           806: }
        !           807:
        !           808: static void
        !           809: fft(GEN Omega, GEN p, GEN f, long step, long l)
        !           810: {
        !           811:   long i,l1,l2,l3,rap=Lmax/l,rapi,step4,ltop,lbot;
        !           812:   GEN f1,f2,f3,f02,f13,g02,g13,ff;
        !           813:
        !           814:   if (l==2)
        !           815:   {
        !           816:     f[0]=ladd((GEN)p[0],(GEN)p[step]);
        !           817:     f[1]=lsub((GEN)p[0],(GEN)p[step]); return;
        !           818:   }
        !           819:   if (l==4)
        !           820:   {
        !           821:     f1=gadd((GEN)p[0],(GEN)p[(step<<1)]);
        !           822:     f3=gadd((GEN)p[step],(GEN)p[3*step]);
        !           823:     f[0]=ladd(f1,f3);
        !           824:     f[2]=lsub(f1,f3);
        !           825:
        !           826:     f2=gsub((GEN)p[0],(GEN)p[(step<<1)]);
        !           827:     f02=gsub((GEN)p[step],(GEN)p[3*step]);
        !           828:     f02=gmulbyi(f02);
        !           829:     f[1]=ladd(f2,f02);
        !           830:     f[3]=lsub(f2,f02);
        !           831:     return;
        !           832:   }
        !           833:
        !           834:   l1=(l>>2); l2=(l1<<1); l3=l1+l2; step4=(step<<2);
        !           835:
        !           836:   ltop=avma;
        !           837:   fft(Omega,p,f,step4,l1);
        !           838:   fft(Omega,p+step,f+l1,step4,l1);
        !           839:   fft(Omega,p+(step<<1),f+l2,step4,l1);
        !           840:   fft(Omega,p+3*step,f+l3,step4,l1);
        !           841:
        !           842:   ff=cgetg(l+1,t_VEC);
        !           843:   for (i=0; i<l1; i++)
        !           844:   {
        !           845:     rapi=rap*i;
        !           846:     f1=gmul((GEN)Omega[rapi],(GEN) f[i+l1]);
        !           847:     f2=gmul((GEN)Omega[(rapi<<1)],(GEN) f[i+l2]);
        !           848:     f3=gmul((GEN)Omega[3*rapi],(GEN) f[i+l3]);
        !           849:
        !           850:     f02=gadd((GEN)f[i],f2);
        !           851:     g02=gsub((GEN)f[i],f2);
        !           852:     f13=gadd(f1,f3);
        !           853:     g13=gmulbyi(gsub(f1,f3));
        !           854:
        !           855:     ff[i+1]=ladd(f02,f13);
        !           856:     ff[i+l1+1]=ladd(g02,g13);
        !           857:     ff[i+l2+1]=lsub(f02,f13);
        !           858:     ff[i+l3+1]=lsub(g02,g13);
        !           859:   }
        !           860:   lbot=avma; ff=gerepile(ltop,lbot,gcopy(ff));
        !           861:   for (i=0; i<l; i++) f[i]=ff[i+1];
        !           862: }
        !           863:
        !           864: /* returns a vector RU which contains exp(2*i*k*Pi/NN), k=0..NN-1 */
        !           865: static GEN
        !           866: initRU(long NN, long bitprec)
        !           867: {
        !           868:   GEN prim,aux,RU,mygpi;
        !           869:   long i,N2=(NN>>1),N4=(NN>>2),N8=(NN>>3),decprec;
        !           870:
        !           871:   RU=cgetg(NN+1,t_VEC); RU++;
        !           872:   mygpi=mppi(bitprec/BITS_IN_LONG+3);
        !           873:   aux=gmul(gi,gdivgs(mygpi,NN/2)); /* 2i Pi/NN */
        !           874:   decprec=(long) ((double) bitprec * L2SL10)+1;
        !           875:   prim=gexp(aux,decprec);
        !           876:   RU[0]=lprec(gunr,decprec);
        !           877:
        !           878:   for (i=1; i<=N8; i++) RU[i]=lmul(prim,(GEN)RU[i-1]);
        !           879:   for (i=1; i<N8; i++)
        !           880:   {
        !           881:     aux=cgetg(3,t_COMPLEX);
        !           882:     aux[1]=((GEN)RU[i])[2]; aux[2]=((GEN)RU[i])[1];
        !           883:     RU[N4-i]=(long) aux;
        !           884:   }
        !           885:   for (i=0; i<N4; i++) RU[i+N4]=(long)gmulbyi((GEN)RU[i]);
        !           886:   for (i=0; i<N2; i++) RU[i+N2]=lneg((GEN)RU[i]);
        !           887:   return RU;
        !           888: }
        !           889:
        !           890: /* returns 1 if p has only real coefficients, 0 else */
        !           891: static long
        !           892: isreal(GEN p)
        !           893: {
        !           894:   long n=lgef(p)-3,i=0;
        !           895:
        !           896:   while (i<=n && typ(p[i+2])!=t_COMPLEX) i++;
        !           897:   return (i>n);
        !           898: }
        !           899:
        !           900: static void
        !           901: parameters(GEN p, double *mu, double *gamma,
        !           902:            long polreal, double param, double param2)
        !           903: {
        !           904:   GEN q,pc,Omega,coef,RU,prim,aux,ggamma,gx,mygpi;
        !           905:   long ltop=avma,limite=stack_lim(ltop,1),n=lgef(p)-3,bitprec,NN,K,i,j,ltop2;
        !           906:   double lx;
        !           907:
        !           908:   bitprec=gexpo(p)+(long)param2+8;
        !           909:   NN=(long) (param*3.14)+1; if (NN<Lmax) NN=Lmax;
        !           910:   K=NN/Lmax; if (K%2==1) K++; NN=Lmax*K;
        !           911:   mygpi=mppi(bitprec/BITS_IN_LONG+3);
        !           912:   aux=gmul(gi,gdivgs(mygpi,NN/2)); /* 2i Pi/NN */
        !           913:   prim=gexp(aux,(long) ((double) bitprec * L2SL10)+1);
        !           914:   RU=mygprec(gunr,bitprec);
        !           915:
        !           916:   Omega=initRU(Lmax,bitprec);
        !           917:
        !           918:   q=mygprec(p,bitprec);
        !           919:   pc=cgetg(Lmax+1,t_VEC); pc++;
        !           920:   for (i=n+1; i<Lmax; i++) pc[i]=zero;
        !           921:
        !           922:   coef=cgetg(Lmax+1,t_VEC); coef++;
        !           923:   *mu=(double)pariINFINITY; *gamma=0.;
        !           924:   ggamma=gmul(gzero,gunr);
        !           925:   if (polreal) K=K/2+1;
        !           926:   ltop2=avma;
        !           927:   for (i=0; i<K; i++)
        !           928:   {
        !           929:     aux=mygprec(gunr,bitprec);
        !           930:     for (j=0; j<=n; j++)
        !           931:     {
        !           932:       pc[j]=lmul((GEN)q[j+2],aux);
        !           933:       aux=gmul(aux,RU); /* RU = prim^i, aux=prim^(ij) */
        !           934:     }
        !           935:
        !           936:     fft(Omega,pc,coef,1,Lmax);
        !           937:     for (j=0; j<Lmax; j++)
        !           938:     {
        !           939:       aux=gprec((GEN)coef[j],DEFAULTPREC);
        !           940:       gx=gabs(aux,DEFAULTPREC);
        !           941:       lx=gtodouble(mplog(gx));
        !           942:       if (lx<*mu) *mu=lx;
        !           943:       if (polreal && (i>0 && i<K-1))
        !           944:       {
        !           945:        gx=gdiv(gdeux,gx);
        !           946:        ggamma=gadd(ggamma,gx);
        !           947:       }
        !           948:       else
        !           949:        ggamma=gadd(ggamma,ginv(gx));
        !           950:     }
        !           951:     RU=gmul(RU,prim);
        !           952:     if (low_stack(limite, stack_lim(ltop,1)))
        !           953:     {
        !           954:       GEN *gptr[2];
        !           955:       if(DEBUGMEM>1) err(warnmem,"parameters");
        !           956:       gptr[0]=&ggamma; gptr[1]=&RU; gerepilemany(ltop2,gptr,2);
        !           957:     }
        !           958:   }
        !           959:   ggamma=gdivgs(ggamma,NN);
        !           960:   *gamma=gtodouble(glog(ggamma,DEFAULTPREC))/log(2.);
        !           961:   avma=ltop;
        !           962: }
        !           963:
        !           964: /* NN is a multiple of Lmax */
        !           965: static void
        !           966: dft(GEN p, long k, long NN, long bitprec, GEN F, GEN H, long polreal)
        !           967: {
        !           968:   GEN Omega,q,qd,pc,pdc,alpha,beta,gamma,RU,aux,U,W,mygpi,prim,prim2;
        !           969:   long limite,n=lgef(p)-3,i,j,K,ltop;
        !           970:
        !           971:   mygpi=mppi(bitprec/BITS_IN_LONG+3);
        !           972:   aux=gmul(gi,gdivgs(mygpi,NN/2)); /* 2i Pi/NN */
        !           973:   prim=gexp(aux,(long) ((double) bitprec * L2SL10)+1);
        !           974:   prim2=mygprec(gunr,bitprec);
        !           975:   RU=cgetg(n+2,t_VEC); RU++;
        !           976:
        !           977:   Omega=initRU(Lmax,bitprec);
        !           978:   K=NN/Lmax; q=mygprec(p,bitprec);
        !           979:   qd=derivpol(q);
        !           980:
        !           981:   pc=cgetg(Lmax+1,t_VEC); pc++;
        !           982:   for (i=n+1; i<Lmax; i++) pc[i]=zero;
        !           983:   pdc=cgetg(Lmax+1,t_VEC); pdc++;
        !           984:   for (i=n; i<Lmax; i++) pdc[i]=zero;
        !           985:
        !           986:   alpha=cgetg(Lmax+1,t_VEC); alpha++;
        !           987:   beta=cgetg(Lmax+1,t_VEC); beta++;
        !           988:   gamma=cgetg(Lmax+1,t_VEC); gamma++;
        !           989:
        !           990:   if (polreal) K=K/2+1;
        !           991:
        !           992:   ltop=avma; limite = stack_lim(ltop,1);
        !           993:   W=cgetg(k+1,t_VEC); U=cgetg(k+1,t_VEC);
        !           994:   for (i=1; i<=k; i++) W[i]=U[i]=zero;
        !           995:
        !           996:   for (i=0; i<K; i++)
        !           997:   {
        !           998:     RU[0]=(long) gun;
        !           999:     for (j=1; j<=n; j++) RU[j]=lmul((GEN)RU[j-1],prim2);
        !          1000:     /* RU[j]=prim^{ ij }=prim2^j */
        !          1001:
        !          1002:     for (j=0; j<n; j++) pdc[j]=lmul((GEN)qd[j+2],(GEN)RU[j]);
        !          1003:     fft(Omega,pdc,alpha,1,Lmax);
        !          1004:     for (j=0; j<=n; j++) pc[j]=lmul((GEN)q[j+2],(GEN)RU[j]);
        !          1005:     fft(Omega,pc,beta,1,Lmax);
        !          1006:     for (j=0; j<Lmax; j++) gamma[j]=linv((GEN)beta[j]);
        !          1007:     for (j=0; j<Lmax; j++) beta[j]=lmul((GEN)alpha[j],(GEN)gamma[j]);
        !          1008:     fft(Omega,beta,alpha,1,Lmax);
        !          1009:     fft(Omega,gamma,beta,1,Lmax);
        !          1010:
        !          1011:     if (polreal) /* p has real coefficients */
        !          1012:     {
        !          1013:       if (i>0 && i<K-1)
        !          1014:       {
        !          1015:        for (j=1; j<=k; j++)
        !          1016:        {
        !          1017:          aux=gmul((GEN)alpha[j+1],(GEN)RU[j+1]);
        !          1018:          W[j]=ladd((GEN)W[j],gshift(greal(aux),1));
        !          1019:          aux=gmul((GEN)beta[j],(GEN)RU[j]);
        !          1020:          U[j]=ladd((GEN)U[j],gshift(greal(aux),1));
        !          1021:        }
        !          1022:       }
        !          1023:       else
        !          1024:       {
        !          1025:        for (j=1; j<=k; j++)
        !          1026:        {
        !          1027:          aux=gmul((GEN)alpha[j+1],(GEN)RU[j+1]);
        !          1028:          W[j]=ladd((GEN)W[j],greal(aux));
        !          1029:          aux=gmul((GEN)beta[j],(GEN)RU[j]);
        !          1030:          U[j]=ladd((GEN)U[j],greal(aux));
        !          1031:        }
        !          1032:       }
        !          1033:     }
        !          1034:     else
        !          1035:     {
        !          1036:       for (j=1; j<=k; j++)
        !          1037:       {
        !          1038:        W[j]=ladd((GEN)W[j],gmul((GEN)alpha[j+1],(GEN)RU[j+1]));
        !          1039:        U[j]=ladd((GEN)U[j],gmul((GEN)beta[j],(GEN)RU[j]));
        !          1040:       }
        !          1041:     }
        !          1042:     prim2=gmul(prim2,prim);
        !          1043:     if (low_stack(limite, stack_lim(ltop,1)))
        !          1044:     {
        !          1045:       GEN *gptr[3];
        !          1046:       if(DEBUGMEM>1) err(warnmem,"dft");
        !          1047:       gptr[0]=&W; gptr[1]=&U; gptr[2]=&prim2;
        !          1048:       gerepilemany(ltop,gptr,3);
        !          1049:     }
        !          1050:   }
        !          1051:
        !          1052:   for (i=1; i<=k; i++)
        !          1053:   {
        !          1054:     aux=(GEN)W[i];
        !          1055:     for (j=1; j<i; j++) aux=gadd(aux,gmul((GEN)W[i-j],(GEN)F[k+2-j]));
        !          1056:     F[k+2-i] = ldivgs(aux,-i*NN);
        !          1057:   }
        !          1058:   for (i=0; i<k; i++)
        !          1059:   {
        !          1060:     aux=(GEN)U[k-i];
        !          1061:     for (j=1+i; j<k; j++) aux=gadd(aux,gmul((GEN)F[2+j],(GEN)U[j-i]));
        !          1062:     H[i+2] = ldivgs(aux,NN);
        !          1063:   }
        !          1064: }
        !          1065:
        !          1066: static GEN
        !          1067: refine_H(GEN F, GEN G, GEN HH, long bitprec, long shiftbitprec)
        !          1068: {
        !          1069:   GEN H=HH,D,aux;
        !          1070:   long ltop=avma, limite=stack_lim(ltop,1),error=0,i,bitprec1,bitprec2,lbot;
        !          1071:
        !          1072:   D=gsub(gun,gres(gmul(HH,G),F)); error=gexpo(D);
        !          1073:   bitprec2=bitprec+shiftbitprec;
        !          1074:
        !          1075:   for (i=0; (error>-bitprec && i<NEWTON_MAX) && error<=0; i++)
        !          1076:   {
        !          1077:     if (low_stack(limite, stack_lim(ltop,1)))
        !          1078:     {
        !          1079:       GEN *gptr[2];
        !          1080:       if(DEBUGMEM>1) err(warnmem,"refine_H");
        !          1081:       gptr[0]=&D; gptr[1]=&H; gerepilemany(ltop,gptr,2);
        !          1082:     }
        !          1083:     bitprec1=-error+shiftbitprec;
        !          1084:     aux=gmul(mygprec(H,bitprec1),mygprec(D,bitprec1));
        !          1085:     aux=mygprec(aux,bitprec1);
        !          1086:     aux=gres(aux,mygprec(F,bitprec1));
        !          1087:
        !          1088:     bitprec1=-error*2+shiftbitprec;
        !          1089:     if (bitprec1>bitprec2) bitprec1=bitprec2;
        !          1090:     H=gadd(mygprec(H,bitprec1),aux);
        !          1091:     D=gsub(gun,gres(gmul(H,G),F));
        !          1092:     error=gexpo(D); if (error<-bitprec1) error=-bitprec1;
        !          1093:   }
        !          1094:   if (error<=-bitprec/2) { lbot=avma; return gerepile(ltop,lbot,gcopy(H)); }
        !          1095:   avma=ltop; return gzero; /* procedure failed */
        !          1096: }
        !          1097:
        !          1098: /* return 0 if fails, 1 else */
        !          1099: static long
        !          1100: refine_F(GEN p, GEN *F, GEN *G, GEN H, long bitprec, double gamma)
        !          1101: {
        !          1102:   GEN pp,FF,GG,r,HH,f0;
        !          1103:   long error,i,bitprec1=0,bitprec2,ltop=avma,shiftbitprec;
        !          1104:   long shiftbitprec2,n=lgef(p)-3,enh,normF,normG,limite=stack_lim(ltop,1);
        !          1105:
        !          1106:   FF=*F; HH=H;
        !          1107:   GG=poldivres(p,*F,&r);
        !          1108:   normF=gexpo(FF);
        !          1109:   normG=gexpo(GG);
        !          1110:   enh=gexpo(H); if (enh<0) enh=0;
        !          1111:   shiftbitprec=normF+2*normG+enh+(long) (4.*log2((double)n)+gamma) +1;
        !          1112:   shiftbitprec2=enh+2*(normF+normG)+(long) (2.*gamma+5.*log2((double)n))+1;
        !          1113:   bitprec2=bitprec+shiftbitprec;
        !          1114:   error=gexpo(r);
        !          1115:   if (error<-bitprec) error=1-bitprec;
        !          1116:   for (i=0; (error>-bitprec && i<NEWTON_MAX) && error<=0; i++)
        !          1117:   {
        !          1118:     if ((bitprec1==bitprec2) && (i>=2))
        !          1119:     {
        !          1120:       shiftbitprec+=n; shiftbitprec2+=n; bitprec2+=n;
        !          1121:     }
        !          1122:     if (low_stack(limite, stack_lim(ltop,1)))
        !          1123:     {
        !          1124:       GEN *gptr[4];
        !          1125:       if(DEBUGMEM>1) err(warnmem,"refine_F");
        !          1126:       gptr[0]=&FF; gptr[1]=&GG; gptr[2]=&r; gptr[3]=&HH;
        !          1127:       gerepilemany(ltop,gptr,4);
        !          1128:     }
        !          1129:
        !          1130:     bitprec1=-error+shiftbitprec2;
        !          1131:     HH=refine_H(mygprec(FF,bitprec1),mygprec(GG,bitprec1),
        !          1132:                mygprec(HH,bitprec1),1-error,shiftbitprec2);
        !          1133:     if (HH==gzero) return 0; /* procedure failed */
        !          1134:
        !          1135:     bitprec1=-error+shiftbitprec;
        !          1136:     r=gmul(mygprec(HH,bitprec1),mygprec(r,bitprec1));
        !          1137:     r=mygprec(r,bitprec1);
        !          1138:     f0=gres(r,mygprec(FF,bitprec1));
        !          1139:
        !          1140:     bitprec1=-2*error+shiftbitprec;
        !          1141:     if (bitprec1>bitprec2) bitprec1=bitprec2;
        !          1142:     FF=gadd(mygprec(FF,bitprec1),f0);
        !          1143:
        !          1144:     bitprec1=-3*error+shiftbitprec;
        !          1145:     if (bitprec1>bitprec2) bitprec1=bitprec2;
        !          1146:     pp=mygprec(p,bitprec1);
        !          1147:     GG=poldivres(pp,mygprec(FF,bitprec1),&r);
        !          1148:     error=gexpo(r); if (error<-bitprec1) error=-bitprec1;
        !          1149:   }
        !          1150:   if (error<=-bitprec)
        !          1151:   {
        !          1152:     *F=FF; *G=GG;
        !          1153:     return 1; /* procedure succeeds */
        !          1154:   }
        !          1155:   return 0; /* procedure failed */
        !          1156: }
        !          1157:
        !          1158: /* returns F and G from the unit circle U such that |p-FG|<2^(-bitprec) |cd|,
        !          1159: where cd is the leading coefficient of p */
        !          1160: static void
        !          1161: split_fromU(GEN p, long k, double delta, long bitprec,
        !          1162:             GEN *F, GEN *G, double param, double param2)
        !          1163: {
        !          1164:   GEN pp,FF,GG,H;
        !          1165:   long n=lgef(p)-3,NN,bitprec2,
        !          1166:   ltop=avma,polreal=isreal(p);
        !          1167:   double mu,gamma;
        !          1168:
        !          1169:   pp=gdiv(p,(GEN)p[2+n]);
        !          1170:   Lmax=4; while (Lmax<=n) Lmax=(Lmax<<1);
        !          1171:   parameters(pp,&mu,&gamma,polreal,param,param2);
        !          1172:
        !          1173:   H =cgetg(k+2,t_POL); H[1] =evalsigne(1) | evalvarn(varn(p)) | evallgef(k+2);
        !          1174:   FF=cgetg(k+3,t_POL); FF[1]=evalsigne(1) | evalvarn(varn(p)) | evallgef(k+3);
        !          1175:   FF[k+2]=un;
        !          1176:
        !          1177:   NN=(long) (0.5/delta); NN+=(NN%2); if (NN<2) NN=2;
        !          1178:   NN=NN*Lmax; ltop=avma;
        !          1179:   for(;;)
        !          1180:   {
        !          1181:     bitprec2=(long) (((double) NN*delta-mu)/log(2.))+gexpo(pp)+8;
        !          1182:     dft(pp,k,NN,bitprec2,FF,H,polreal);
        !          1183:     if (refine_F(pp,&FF,&GG,H,bitprec,gamma)) break;
        !          1184:     NN=(NN<<1); avma=ltop;
        !          1185:   }
        !          1186:   *G=gmul(GG,(GEN)p[2+n]); *F=FF;
        !          1187: }
        !          1188:
        !          1189: static void
        !          1190: optimize_split(GEN p, long k, double delta, long bitprec,
        !          1191:             GEN *F, GEN *G, double param, double param2)
        !          1192: {
        !          1193:   long n=lgef(p)-3;
        !          1194:   GEN FF,GG;
        !          1195:
        !          1196:   if (k<=n/2)
        !          1197:     split_fromU(p,k,delta,bitprec,F,G,param,param2);
        !          1198:   else
        !          1199:   { /* start from the reciprocal of p */
        !          1200:     split_fromU(polrecip_i(p),n-k,delta,bitprec,&FF,&GG,param,param2);
        !          1201:     *F=polrecip(GG); *G=polrecip(FF);
        !          1202:   }
        !          1203: }
        !          1204:
        !          1205: /********************************************************************/
        !          1206: /**                                                                **/
        !          1207: /**             RECHERCHE DU CERCLE DE SEPARATION                  **/
        !          1208: /**                                                                **/
        !          1209: /********************************************************************/
        !          1210:
        !          1211: /* return p(2^e*x) *2^(-n*e) */
        !          1212: static void
        !          1213: scalepol2n(GEN p, long e)
        !          1214: {
        !          1215:   long i,n=lgef(p)-1;
        !          1216:   for (i=2; i<=n; i++) p[i]=lmul2n((GEN)p[i],(i-n)*e);
        !          1217: }
        !          1218:
        !          1219: /* returns p(x/R)*R^n */
        !          1220: static GEN
        !          1221: scalepol(GEN p, GEN R, long bitprec)
        !          1222: {
        !          1223:   GEN q,aux,gR;
        !          1224:   long i;
        !          1225:
        !          1226:   aux = gR = mygprec(R,bitprec); q = mygprec(p,bitprec);
        !          1227:   for (i=lgef(p)-2; i>=2; i--)
        !          1228:   {
        !          1229:     q[i]=lmul(aux,(GEN)q[i]);
        !          1230:     aux = gmul(aux,gR);
        !          1231:   }
        !          1232:   return q;
        !          1233: }
        !          1234:
        !          1235: /* returns q(x)=p(b), where b is (usually) a polynomial  */
        !          1236: static GEN
        !          1237: shiftpol(GEN p, GEN b)
        !          1238: {
        !          1239:   long av = avma,i, limit = stack_lim(av,1);
        !          1240:   GEN q = gzero;
        !          1241:
        !          1242:   for (i=lgef(p)-1; i>=2; i--)
        !          1243:   {
        !          1244:     q = gadd((GEN)p[i], gmul(q,b));
        !          1245:     if (low_stack(limit, stack_lim(av,1))) q = gerepileupto(av,q);
        !          1246:   }
        !          1247:   return gerepileupto(av,q);
        !          1248: }
        !          1249:
        !          1250: /* return (aX-1)^n * p[ (X-a) / (aX-1) ] */
        !          1251: static GEN
        !          1252: conformal_pol(GEN p, GEN a, long bitprec)
        !          1253: {
        !          1254:   GEN r,pui,num,aux;
        !          1255:   long n=lgef(p)-3, i;
        !          1256:
        !          1257:   aux = pui = cgetg(4,t_POL);
        !          1258:   pui[1] = evalsigne(1) | evalvarn(varn(p)) | evallgef(4);
        !          1259:   pui[2] = (long) mygprec(gneg_i(gunr),bitprec);
        !          1260:   pui[3] = lconj(a);
        !          1261:   num = cgetg(4,t_POL);
        !          1262:   num[1] = pui[1];
        !          1263:   num[2] = lneg(a);
        !          1264:   num[3] = (long) mygprec(gunr,bitprec);
        !          1265:   r=(GEN)p[2+n];
        !          1266:   for (i=n-1; ; i--)
        !          1267:   {
        !          1268:     r=gadd(gmul(r,num),gmul(aux,(GEN) p[2+i]));
        !          1269:     if (i==0) return r;
        !          1270:     aux=gmul(pui,aux);
        !          1271:   }
        !          1272: }
        !          1273:
        !          1274: /* apply the conformal mapping then split from U */
        !          1275: static void
        !          1276: conformal_mapping(GEN p, long k, long bitprec, double aux,GEN *F,GEN *G)
        !          1277: {
        !          1278:   long bitprec2,bitprec3,n=lgef(p)-3,decprec,i,ltop = avma, av;
        !          1279:   GEN q,FF,GG,a,R, *gptr[2];
        !          1280:   double rmin,rmax,rho,delta,aux2,param,param2,r1,r2;
        !          1281:
        !          1282:   bitprec2=bitprec+(long) (n*(2.*log2(2.732)+log2(1.5)))+1;
        !          1283:   a=gsqrt(stoi(3),10);
        !          1284:   a=gmul(mygprec(a,bitprec2),mygprec(globalu,bitprec2));
        !          1285:   a=gdivgs(a,-6); /* a=-globalu/2/sqrt(3) */
        !          1286:
        !          1287:   av = avma; q=mygprec(p,bitprec2);
        !          1288:   q = conformal_pol(q,a,bitprec2);
        !          1289:   for (i=1; i<=n; i++)
        !          1290:     if (radius[i]!=0.) /* updating array radius */
        !          1291:     {
        !          1292:       aux2=radius[i]*radius[i];
        !          1293:       aux2=2.*(aux2-1)/(aux2-3.*radius[i]+3.);
        !          1294:       radius[i]=sqrt(1+aux2);
        !          1295:     }
        !          1296:   if (k>1)
        !          1297:   {
        !          1298:     i=k-1; while (i>0 && radius[i]==0.) i--;
        !          1299:     r1=radius[i]; r2=radius[k];
        !          1300:     rmin=pre_modulus(q,k,aux/10.,r1,r2);
        !          1301:   }
        !          1302:   else
        !          1303:     rmin=min_modulus(q,aux/10.);
        !          1304:   radius[k]=rmin;
        !          1305:
        !          1306:   if (k+1<n)
        !          1307:   {
        !          1308:     i=k+2; while (i<=n && radius[i]==0.) i++;
        !          1309:     r2=radius[i]; r1=radius[k+1];
        !          1310:     rmax=pre_modulus(q,k+1,aux/10.,r1,r2);
        !          1311:   }
        !          1312:   else /* k+1=n */
        !          1313:     rmax=max_modulus(q,aux/10.);
        !          1314:   radius[k+1]=rmax;
        !          1315:
        !          1316:   rho=sqrt(rmin*rmax); delta=0.5*log(rmax/rmin);
        !          1317:   if (delta>1.) delta=1.;
        !          1318:
        !          1319:   if (rho<1.) bitprec3=(long) ((double)n*log2(1./rho))+1;
        !          1320:   else bitprec3=(long) ((double)n*log2(rho))+1;
        !          1321:   bitprec2=bitprec2+bitprec3;
        !          1322:
        !          1323:   R=mygprec(dbltor(1/rho),bitprec2);
        !          1324:   q=scalepol(q,R,bitprec2);
        !          1325:   gptr[0]=&q; gptr[1]=&R; gerepilemany(av,gptr,2);
        !          1326:
        !          1327:   aux2=radius[k];
        !          1328:   for (i=k-1; i>=1; i--)
        !          1329:   {
        !          1330:     if (radius[i]==0.) radius[i]=aux2;
        !          1331:     else aux2=radius[i];
        !          1332:   }
        !          1333:   aux2=radius[k+1];
        !          1334:   for (i=k+1; i<=n; i++)
        !          1335:   {
        !          1336:     if (radius[i]==0.) radius[i]=aux2;
        !          1337:     else aux2=radius[i];
        !          1338:   }
        !          1339:   param=0.; param2=0.;
        !          1340:   for (i=1; i<=n; i++)
        !          1341:   {
        !          1342:     radius[i]=radius[i]/rho;
        !          1343:     aux2=fabs(1-radius[i]);
        !          1344:     param+=1./aux2;
        !          1345:     if (aux2<1.) param2-=log2(aux2);
        !          1346:   }
        !          1347:   optimize_split(q,k,delta,bitprec2,&FF,&GG,param,param2);
        !          1348:   bitprec2=bitprec2+n; R = ginv(R);
        !          1349:   FF=scalepol(FF,R,bitprec2);
        !          1350:   GG=scalepol(GG,R,bitprec2);
        !          1351:
        !          1352:   a=mygprec(a,bitprec2);
        !          1353:   FF=conformal_pol(FF,a,bitprec2);
        !          1354:   GG=conformal_pol(GG,a,bitprec2);
        !          1355:   a=ginv(gsub(gun,gmul(a,gconj(a))));
        !          1356:   a=glog(a,(long) (bitprec2 * L2SL10)+1);
        !          1357:
        !          1358:   decprec=(long) ((bitprec+n) * L2SL10)+1;
        !          1359:   FF=gmul(FF,gexp(gmulgs(a,k),decprec));
        !          1360:   GG=gmul(GG,gexp(gmulgs(a,n-k),decprec));
        !          1361:
        !          1362:   *F=mygprec(FF,bitprec+n); *G=mygprec(GG,bitprec+n);
        !          1363:   gptr[0]=F; gptr[1]=G; gerepilemany(ltop,gptr,2);
        !          1364: }
        !          1365:
        !          1366: /* split p, this time with no scaling. returns in F and G two polynomials
        !          1367: such that |p-FG|< 2^(-bitprec)|p| */
        !          1368: static void
        !          1369: split_2(GEN p, long bitprec, double thickness, GEN *F, GEN *G)
        !          1370: {
        !          1371:   double rmin,rmax,rho,kappa,aux,delta,param,param2,r1,r2;
        !          1372:   long n=lgef(p)-3,i,j,k,disti,diste,bitprec2;
        !          1373:   GEN q,FF,GG,R;
        !          1374:
        !          1375:   radius=(double *) gpmalloc((n+1)*sizeof(double));
        !          1376:   for (i=2; i<n; i++) radius[i]=0.;
        !          1377:   rmin=min_modulus(p,thickness/(double) n/4.);
        !          1378:   rmax=max_modulus(p,thickness/(double) n/4.);
        !          1379:   i=1; j=n; radius[1]=rmin; radius[n]=rmax;
        !          1380:   rho=sqrt(rmin*rmax);
        !          1381:   k=dual_modulus(p,rho,thickness/(double) n/4.,1);
        !          1382:   if (k<n/5. || (n/2.<k && k<(4*n)/5.)) { rmax=rho; j=k+1; radius[j]=rho; }
        !          1383:   else { rmin=rho; i=k; radius[i]=rho; }
        !          1384:   while (j>i+1)
        !          1385:   {
        !          1386:     disti= (i<n-j)? i: n-j; /* min(i,n-j) */
        !          1387:     diste= (j<n-i)? j: n-i;
        !          1388:     kappa=1.-log(1.+(double)disti)/log(1.+(double)diste);
        !          1389:     if (i+j<n+1)
        !          1390:       rho=exp( (log(rmin)+log(rmax)*(1+kappa))/(2+kappa));
        !          1391:     else if (i+j==n+1) rho=sqrt(rmin*rmax);
        !          1392:     else
        !          1393:       rho=exp( (log(rmin)*(1+kappa)+log(rmax))/(2+kappa));
        !          1394:     /* use log(rmax) - log(rmin) since rmax / rmin can overflow */
        !          1395:     aux=(log(rmax)-log(rmin))/(j-i)/4.;
        !          1396:
        !          1397:     k=(i<n+1-j)? i: n+1-j; /* min(i,n+1-j) */
        !          1398:     k=dual_modulus(p,rho,aux,k);
        !          1399:     if (k-i < j-k-1) { rmax=rho; j=k+1; radius[j]=rho*exp(-aux); }
        !          1400:     else
        !          1401:     {
        !          1402:       if (k-i > j-k-1) { rmin=rho; i=k; radius[i]=rho*exp(aux); }
        !          1403:       else
        !          1404:       {
        !          1405:        if (2*k>n) { rmax=rho; j=k+1; radius[j]=rho*exp(-aux); }
        !          1406:        else { rmin=rho; i=k; radius[i]=rho*exp(aux); }
        !          1407:       }
        !          1408:     }
        !          1409:   }
        !          1410:   aux=log(rmax)-log(rmin);
        !          1411:
        !          1412:   if (step4==0)
        !          1413:   {
        !          1414:     if (k>1)
        !          1415:     {
        !          1416:       i=k-1; while ((i>0) && (radius[i]==0.)) i--;
        !          1417:       r1=radius[i]; r2=radius[k];
        !          1418:       rmin=pre_modulus(p,k,aux/10.,r1,r2);
        !          1419:     }
        !          1420:     else /* k=1 */
        !          1421:       rmin=min_modulus(p,aux/10.);
        !          1422:     radius[k]=rmin;
        !          1423:
        !          1424:     if (k+1<n)
        !          1425:     {
        !          1426:       i=k+2; while ((i<=n) && (radius[i]==0.)) i++;
        !          1427:       r2=radius[i]; r1=radius[k+1];
        !          1428:       rmax=pre_modulus(p,k+1,aux/10.,r1,r2);
        !          1429:     }
        !          1430:     else /* k+1=n */
        !          1431:       rmax=max_modulus(p,aux/10.);
        !          1432:     radius[k+1]=rmax;
        !          1433:     rho=sqrt(rmin*rmax); delta=0.5*(log(rmax)-log(rmin));
        !          1434:
        !          1435:     aux=radius[k];
        !          1436:     for (i=k-1; i>=1; i--)
        !          1437:     {
        !          1438:       if (radius[i]==0.) radius[i]=aux;
        !          1439:       else aux=radius[i];
        !          1440:     }
        !          1441:     aux=radius[k+1];
        !          1442:     for (i=k+1; i<=n; i++)
        !          1443:     {
        !          1444:       if (radius[i]==0.) radius[i]=aux;
        !          1445:       else aux=radius[i];
        !          1446:     }
        !          1447:     param=0.; param2=0.;
        !          1448:     for (i=1; i<=n; i++)
        !          1449:     {
        !          1450:       radius[i]=radius[i]/rho;
        !          1451:       aux=fabs(1.-radius[i]);
        !          1452:       param+=1./aux;
        !          1453:       if (aux<1) param2-=log2(aux);
        !          1454:     }
        !          1455:     if (rho<1.) bitprec2=(long) ((double)n*log2(1./rho))+1;
        !          1456:     else bitprec2=(long) ((double)n*log2(rho))+1;
        !          1457:     bitprec2 += bitprec;
        !          1458:
        !          1459:     R=mygprec(dbltor(1./rho),bitprec2);
        !          1460:     q=scalepol(p,R,bitprec2);
        !          1461:     optimize_split(q,k,delta,bitprec2,&FF,&GG,param,param2);
        !          1462:     bitprec2 += n; R=ginv(R);
        !          1463:   }
        !          1464:   else
        !          1465:   {
        !          1466:     rho=sqrt(rmax*rmin);
        !          1467:     if (rho<1.) bitprec2=(long) ((double)n*log2(1./rho))+1;
        !          1468:     else bitprec2=(long) ((double)n*log2(rho))+1;
        !          1469:     bitprec2=bitprec+bitprec2;
        !          1470:
        !          1471:     R=mygprec(dbltor(1/rho),bitprec2);
        !          1472:     q=scalepol(p,R,bitprec2);
        !          1473:     for (i=1; i<=n; i++)
        !          1474:       if (radius[i]!=0.) radius[i]=radius[i]/rho;
        !          1475:
        !          1476:     conformal_mapping(q, k, bitprec2, aux, &FF, &GG);
        !          1477:     bitprec2 += n; R = ginv(mygprec(R,bitprec2));
        !          1478:   }
        !          1479:   free(radius);
        !          1480:   FF=scalepol(FF,R,bitprec2); GG=scalepol(GG,R,bitprec2);
        !          1481:   *F=mygprec(FF,bitprec+n); *G=mygprec(GG,bitprec+n);
        !          1482: }
        !          1483:
        !          1484: /* procedure corresponding to steps 5,6,.. page 44 in the RR n. 1852 */
        !          1485: /* put in F and G two polynomial such that |p-FG|<2^(-bitprec)|p|
        !          1486: where the maximum modulus of the roots of p is <=1 and the sum of roots
        !          1487: is zero */
        !          1488:
        !          1489: static void
        !          1490: split_1(GEN p, long bitprec, GEN *F, GEN *G)
        !          1491: {
        !          1492:   long bitprec2,bitprec3,i,imax,n=lgef(p)-3, polreal = isreal(p);
        !          1493:   double rmax,rmin,thickness,quo;
        !          1494:   GEN q,qq,newq,FF,GG,v,gr,r;
        !          1495:
        !          1496:   r=gmax_modulus(p,0.01);
        !          1497:   bitprec2=bitprec+n;
        !          1498:   gr=mygprec(ginv(r),bitprec2);
        !          1499:   q=scalepol(p,gr,bitprec2);
        !          1500:
        !          1501:   bitprec2=bitprec+gexpo(q)-gexpo(p);
        !          1502:
        !          1503:   bitprec3=bitprec2+(long)((double)n*2.*log2(3.)+1);
        !          1504:   v=cgetg(5,t_VEC); v++;
        !          1505:   v[0]=lmulgs(mygprec(gunr,bitprec3),2); v[1]=lneg((GEN)v[0]);
        !          1506:   v[2]=lmul((GEN)v[0],gi); v[3]=lneg((GEN)v[2]);
        !          1507:   imax = polreal? 3: 4;
        !          1508:   q=mygprec(q,bitprec3); thickness=1.;
        !          1509:   for (i=0; i<imax; i++)
        !          1510:   {
        !          1511:     qq=shiftpol(q,gadd(polx[varn(p)],(GEN)v[i]));
        !          1512:     rmin=min_modulus(qq,0.05);
        !          1513:     if (3./rmin > thickness)
        !          1514:     {
        !          1515:       rmax=max_modulus(qq,0.05); quo = rmax/rmin;
        !          1516:       if ((float)quo > (float)thickness)
        !          1517:       {
        !          1518:        thickness=quo; newq=qq; globalu=(GEN)v[i];
        !          1519:       }
        !          1520:     }
        !          1521:     if (thickness>2.) break;
        !          1522:     if (polreal && (i==1 && thickness>1.5)) break;
        !          1523:   }
        !          1524:   bitprec3=bitprec2+(long)((double) n*log2(3.)+1)+gexpo(newq)-gexpo(q);
        !          1525:   split_2(newq,bitprec3,log(thickness),&FF,&GG);
        !          1526:   globalu=gsub(polx[varn(p)],mygprec(globalu,bitprec3));
        !          1527:   FF=shiftpol(FF,globalu); GG=shiftpol(GG,globalu);
        !          1528:
        !          1529:   gr=ginv(gr);
        !          1530:   bitprec2=bitprec2+gexpo(FF)+gexpo(GG)-gexpo(q);
        !          1531:   *F=scalepol(FF,gr,bitprec2); *G=scalepol(GG,gr,bitprec2);
        !          1532: }
        !          1533:
        !          1534: /* put in F and G two polynomials such that |P-FG|<2^(-bitprec)|P|,
        !          1535: where the maximum modulus of the roots of p is <0.5 */
        !          1536: static void
        !          1537: split_0_2(GEN p, long bitprec, GEN *F, GEN *G)
        !          1538: {
        !          1539:   GEN q,b,FF,GG;
        !          1540:   long n=lgef(p)-3,k,bitprec2,i;
        !          1541:   double auxnorm;
        !          1542:
        !          1543:   step4=1;
        !          1544:   auxnorm=(double) n*log2(1+exp2(mylog2((GEN)p[n+1])
        !          1545:                                 -mylog2((GEN)p[n+2]))/(double)n);
        !          1546:   bitprec2=bitprec+1+(long) (log2((double)n)+auxnorm);
        !          1547:
        !          1548:   q=mygprec(p,bitprec2);
        !          1549:   b=gdivgs(gdiv((GEN)q[n+1],(GEN)q[n+2]),-n);
        !          1550:   q=shiftpol(q,gadd(polx[varn(p)],b));
        !          1551:
        !          1552:   k=0; while
        !          1553:       (gexpo((GEN)q[k+2])<-(bitprec2+2*(n-k)+gexpo(q))
        !          1554:        || gcmp0((GEN)q[k+2])) k++;
        !          1555:   if (k>0)
        !          1556:   {
        !          1557:     if (k>n/2) k=n/2;
        !          1558:     bitprec2+=(k<<1);
        !          1559:     FF=cgetg(k+3,t_POL); FF[1]=evalsigne(1)+evalvarn(varn(p))+evallgef(k+3);
        !          1560:     for (i=0; i<k; i++) FF[i+2]=zero;
        !          1561:     FF[k+2]=(long) mygprec(gunr,bitprec2);
        !          1562:     GG=cgetg(n-k+3,t_POL); GG[1]=evalsigne(1)+evalvarn(varn(p))+evallgef(n-k+3);
        !          1563:     for (i=0; i<=n-k; i++) GG[i+2]=q[i+k+2];
        !          1564:     b=gsub(polx[varn(p)],mygprec(b,bitprec2));
        !          1565:   }
        !          1566:   else
        !          1567:   {
        !          1568:     split_1(q,bitprec2,&FF,&GG);
        !          1569:     bitprec2=bitprec+gexpo(FF)+gexpo(GG)-gexpo(p)+(long)auxnorm+1;
        !          1570:     b=gsub(polx[varn(p)],mygprec(b,bitprec2));
        !          1571:     FF=mygprec(FF,bitprec2);
        !          1572:   }
        !          1573:   GG=mygprec(GG,bitprec2);
        !          1574:   *F=shiftpol(FF,b); *G=shiftpol(GG,b);
        !          1575: }
        !          1576:
        !          1577: /* put in F and G two polynomials such that |P-FG|<2^(-bitprec)|P|,
        !          1578: where the maximum modulus of the roots of p is <2 */
        !          1579: static void
        !          1580: split_0_1(GEN p, long bitprec, GEN *F, GEN *G)
        !          1581: {
        !          1582:   GEN q,FF,GG;
        !          1583:   long n=lgef(p)-3,bitprec2,normp,pow;
        !          1584:   double aux;
        !          1585:
        !          1586:   normp=gexpo(p);
        !          1587:   aux=exp2(mylog2((GEN)p[n+1])-mylog2((GEN)p[n+2]))/(double)n;
        !          1588:   pow=2;
        !          1589:   if (aux<=2.5){ split_0_2(p,bitprec,F,G); return; }
        !          1590:
        !          1591:   if (aux<=1.) pow=1;
        !          1592:   scalepol2n(p,pow); /* p <- 4^(-n) p(4*x) */
        !          1593:   bitprec2=bitprec+pow*n+gexpo(p)-normp;
        !          1594:   q=mygprec(p,bitprec2);
        !          1595:   split_1(q,bitprec2,&FF,&GG);
        !          1596:   scalepol2n(FF,-pow); scalepol2n(GG,-pow);
        !          1597:   bitprec2=bitprec+gexpo(FF)+gexpo(GG)-normp;
        !          1598:   *F=mygprec(FF,bitprec2); *G=mygprec(GG,bitprec2);
        !          1599: }
        !          1600:
        !          1601: /* put in F and G two polynomials such that |P-FG|<2^(-bitprec)|P| */
        !          1602: static void
        !          1603: split_0(GEN p, long bitprec, GEN *F, GEN *G)
        !          1604: {
        !          1605:   GEN FF,GG,q,R;
        !          1606:   long n=lgef(p)-3,k=0,i;
        !          1607:
        !          1608:   while (gexpo((GEN)p[k+2])<-bitprec) k++;
        !          1609:   if (k>0)
        !          1610:   {
        !          1611:     if (k>n/2) k=n/2;
        !          1612:     FF=cgetg(k+3,t_POL);
        !          1613:     FF[1]=evalsigne(1) | evalvarn(varn(p)) | evallgef(k+3);
        !          1614:     for (i=0; i<k; i++) FF[i+2]=lcopy(gzero);
        !          1615:     FF[k+2]=(long) mygprec(gunr,bitprec);
        !          1616:     GG=cgetg(n-k+3,t_POL);
        !          1617:     GG[1]=evalsigne(1) | evalvarn(varn(p)) | evallgef(n-k+3);
        !          1618:     for (i=0; i<=n-k; i++) GG[i+2]=p[i+k+2];
        !          1619:   }
        !          1620:   else
        !          1621:   {
        !          1622:     R = gmax_modulus(p,0.05);
        !          1623:     if (gexpo(R)<1 && gtodouble(R)<1.9) split_0_1(p,bitprec,&FF,&GG);
        !          1624:     else
        !          1625:     {
        !          1626:       q=cgetg(n+3,t_POL); q[1]=p[1];
        !          1627:       for (i=0; i<=n; i++) q[i+2]=p[n-i+2]; /* p^* with copy of ptr */
        !          1628:       R = gmax_modulus(q,0.05);
        !          1629:       if (gexpo(R)<1 && gtodouble(R)<1.9)
        !          1630:       {
        !          1631:        split_0_1(q,bitprec,&FF,&GG);
        !          1632:        FF=polrecip(FF); GG=polrecip(GG);
        !          1633:       }
        !          1634:       else
        !          1635:       {
        !          1636:        step4=0;
        !          1637:        split_2(p,bitprec,1.2837,&FF,&GG);
        !          1638:       }
        !          1639:     }
        !          1640:   }
        !          1641:   *F=FF; *G=GG;
        !          1642: }
        !          1643:
        !          1644: /********************************************************************/
        !          1645: /**                                                                **/
        !          1646: /**     CALCUL A POSTERIORI DE L'ERREUR ABSOLUE SUR LES RACINES    **/
        !          1647: /**                                                                **/
        !          1648: /********************************************************************/
        !          1649:
        !          1650: static GEN
        !          1651: root_error(long n, long k, GEN roots_pol, GEN sigma, GEN shatzle)
        !          1652: {
        !          1653:   GEN rho,d,eps,epsbis,eps2,prod,aux,rap=NULL;
        !          1654:   long i,j,m;
        !          1655:
        !          1656:   d=cgetg(n+1,t_VEC);
        !          1657:   for (i=1; i<=n; i++)
        !          1658:   {
        !          1659:     if (i!=k)
        !          1660:     {
        !          1661:       aux=gsub((GEN)roots_pol[i],(GEN)roots_pol[k]);
        !          1662:       d[i]=(long) gabs(mygprec(aux,31),4);
        !          1663:     }
        !          1664:   }
        !          1665:   rho=gabs(mygprec((GEN)roots_pol[k],31),4);
        !          1666:   if (gcmp(rho,dbltor(1.))==-1) rho=gun;
        !          1667:   eps=gmul(rho,shatzle);
        !          1668:   aux=gmul(gpui(rho,stoi(n),4),sigma);
        !          1669:
        !          1670:   for (j=1; j<=2 || (j<=5 && gcmp(rap,dbltor(1.2))==1); j++)
        !          1671:   {
        !          1672:     m=n; prod=gun;
        !          1673:     epsbis=gdivgs(gmulgs(eps,5),4);
        !          1674:     for (i=1; i<=n; i++)
        !          1675:     {
        !          1676:       if (i!=k && gcmp((GEN)d[i],epsbis)==1)
        !          1677:       {
        !          1678:        m--;
        !          1679:        prod=gmul(prod,gsub((GEN)d[i],eps));
        !          1680:       }
        !          1681:     }
        !          1682:     eps2=gdiv(gmul2n(aux,2*m-2),prod);
        !          1683:     eps2=gpui(eps2,dbltor(1./m),4);
        !          1684:     rap=gdiv(eps,eps2); eps=eps2;
        !          1685:   }
        !          1686:   return eps;
        !          1687: }
        !          1688:
        !          1689: /* round a complex or real number x to an absolute value of 2^(-e) */
        !          1690: static GEN
        !          1691: mygprec_absolute(GEN x, long bitprec)
        !          1692: {
        !          1693:   long tx=typ(x),e;
        !          1694:   GEN y;
        !          1695:
        !          1696:   switch(tx)
        !          1697:   {
        !          1698:     case t_REAL:
        !          1699:       e=gexpo(x);
        !          1700:       if (e<-bitprec || !signe(x)) { y=dbltor(0.); setexpo(y,-bitprec); }
        !          1701:       else y=mygprec(x,bitprec+e);
        !          1702:       break;
        !          1703:     case t_COMPLEX:
        !          1704:       if (gexpo((GEN)x[2])<-bitprec)
        !          1705:        y=mygprec_absolute((GEN)x[1],bitprec);
        !          1706:       else
        !          1707:       {
        !          1708:        y=cgetg(3,t_COMPLEX);
        !          1709:        y[1]=(long) mygprec_absolute((GEN)x[1],bitprec);
        !          1710:        y[2]=(long) mygprec_absolute((GEN)x[2],bitprec);
        !          1711:       }
        !          1712:       break;
        !          1713:
        !          1714:     default: y=mygprec(x,bitprec);
        !          1715:   }
        !          1716:   return y;
        !          1717: }
        !          1718:
        !          1719: static long
        !          1720: a_posteriori_errors(GEN p, GEN roots_pol, long err)
        !          1721: {
        !          1722:   GEN sigma,overn,shatzle,x;
        !          1723:   long i,n=lgef(p)-3,e,e_max;
        !          1724:
        !          1725:   sigma=mygprec(dbltor(1.),10);
        !          1726:   setexpo(sigma,err+(long) log2((double) n)+1);
        !          1727:   overn=dbltor(1./n);
        !          1728:   shatzle=gdiv(gpui(sigma,overn,0),
        !          1729:               gsub(gpui(gsub(gun,sigma),overn,0),
        !          1730:                    gpui(sigma,overn,0)));
        !          1731:   shatzle=gmul2n(shatzle,1); e_max=-pariINFINITY;
        !          1732:   for (i=1; i<=n; i++)
        !          1733:   {
        !          1734:     x=root_error(n,i,roots_pol,sigma,shatzle);
        !          1735:     e=gexpo(x); if (e>e_max) e_max=e;
        !          1736:     roots_pol[i]=(long) mygprec_absolute((GEN)roots_pol[i],-e);
        !          1737:   }
        !          1738:   return e_max;
        !          1739: }
        !          1740:
        !          1741: /********************************************************************/
        !          1742: /**                                                                **/
        !          1743: /**                           MAIN                                 **/
        !          1744: /**                                                                **/
        !          1745: /********************************************************************/
        !          1746:
        !          1747: /* compute roots in roots_pol so that |P-L_1...L_n|<2^(-bitprec)|P| , and
        !          1748: returns prod (x-roots_pol[i]) for i=1..degree(p) */
        !          1749: static GEN
        !          1750: split_complete(GEN p, long bitprec, GEN *roots_pol, long *iroots)
        !          1751: {
        !          1752:   long n=lgef(p)-3,decprec,ltop,lbot;
        !          1753:   GEN F,G,a,b,m1,m2,m;
        !          1754:   GEN *gptr[2];
        !          1755:
        !          1756:   if (n==1)
        !          1757:   {
        !          1758:     a=gneg_i(gdiv((GEN)p[2],(GEN)p[3]));
        !          1759:     (*iroots)++; (*roots_pol)[*iroots]=(long) a;
        !          1760:     return p;
        !          1761:   }
        !          1762:   ltop=avma;
        !          1763:   if (n==2)
        !          1764:   {
        !          1765:     F=gsub(gsqr((GEN)p[3]),gmul2n(gmul((GEN)p[2],(GEN)p[4]),2));
        !          1766:     decprec=(long) ((double) bitprec * L2SL10)+1;
        !          1767:     F=gsqrt(F,decprec);
        !          1768:     a=gneg_i(gdiv(gadd((GEN)p[3],F),gmul2n((GEN)p[4],1)));
        !          1769:     b=gdiv(gsub(F,(GEN)p[3]),gmul2n((GEN)p[4],1));
        !          1770:
        !          1771:     gptr[0]=&a; gptr[1]=&b;
        !          1772:     gerepilemany(ltop,gptr,2);
        !          1773:     (*iroots)++; (*roots_pol)[*iroots]=(long) a;
        !          1774:     (*iroots)++; (*roots_pol)[*iroots]=(long) b;
        !          1775:     m=gmul(gsub(polx[varn(p)],mygprec(a,3*bitprec)),
        !          1776:           gsub(polx[varn(p)],mygprec(b,3*bitprec)));
        !          1777:     return gmul(m,(GEN)p[4]);
        !          1778:   }
        !          1779:   split_0(p,bitprec,&F,&G);
        !          1780:   m1=split_complete(F,bitprec,roots_pol,iroots);
        !          1781:   m2=split_complete(G,bitprec,roots_pol,iroots);
        !          1782:   lbot=avma;
        !          1783:   m=gmul(m1,m2); *roots_pol=gcopy(*roots_pol);
        !          1784:   gptr[0]=roots_pol; gptr[1]=&m;
        !          1785:   gerepilemanysp(ltop,lbot,gptr,2); return m;
        !          1786: }
        !          1787:
        !          1788: /* compute a bound on the maximum modulus of roots of p */
        !          1789: static GEN
        !          1790: cauchy_bound(GEN p)
        !          1791: {
        !          1792:   long i,n=lgef(p)-3;
        !          1793:   GEN x=gzero,y,lc;
        !          1794:
        !          1795:   lc=gabs((GEN)p[n+2],DEFAULTPREC); /* leading coefficient */
        !          1796:   lc=gdiv(dbltor(1.),lc);
        !          1797:   for (i=0; i<n; i++)
        !          1798:   {
        !          1799:     y=gmul(gabs((GEN) p[i+2],DEFAULTPREC),lc);
        !          1800:     y=gpui(y,dbltor(1./(n-i)),DEFAULTPREC);
        !          1801:     if (gcmp(y,x) > 0) x=y;
        !          1802:   }
        !          1803:   return x;
        !          1804: }
        !          1805:
        !          1806: static GEN
        !          1807: mygprecrc_special(GEN x, long bitprec, long e)
        !          1808: {
        !          1809:   long tx=typ(x),lx,ex;
        !          1810:   GEN y;
        !          1811:
        !          1812:   if (bitprec<=0) bitprec=0; /* should not happen */
        !          1813:   switch(tx)
        !          1814:   {
        !          1815:     case t_REAL:
        !          1816:       lx=bitprec/BITS_IN_LONG+3;
        !          1817:       if (lx<lg(x)) lx=lg(x);
        !          1818:       y=cgetr(lx); affrr(x,y); ex=-bitprec+e;
        !          1819:       if (!signe(x) && expo(x)>ex) setexpo(y,ex);
        !          1820:       break;
        !          1821:     case t_COMPLEX:
        !          1822:       y=cgetg(3,t_COMPLEX);
        !          1823:       y[1]=(long) mygprecrc_special((GEN)x[1],bitprec,e);
        !          1824:       y[2]=(long) mygprecrc_special((GEN)x[2],bitprec,e);
        !          1825:       break;
        !          1826:     default: y=gcopy(x);
        !          1827:   }
        !          1828:   return y;
        !          1829: }
        !          1830:
        !          1831: /* like mygprec but keep at least the same precision as before */
        !          1832: static GEN
        !          1833: mygprec_special(GEN x, long bitprec)
        !          1834: {
        !          1835:   long tx=typ(x),lx,i,e;
        !          1836:   GEN y;
        !          1837:
        !          1838:   switch(tx)
        !          1839:   {
        !          1840:     case t_POL:
        !          1841:       lx=lgef(x); y=cgetg(lx,tx); y[1]=x[1]; e=gexpo(x);
        !          1842:       for (i=2; i<lx; i++) y[i]=(long) mygprecrc_special((GEN)x[i],bitprec,e);
        !          1843:       break;
        !          1844:
        !          1845:     default: y=mygprecrc_special(x,bitprec,0);
        !          1846:   }
        !          1847:   return y;
        !          1848: }
        !          1849:
        !          1850: static GEN
        !          1851: all_roots(GEN p, long bitprec)
        !          1852: {
        !          1853:   GEN q,roots_pol,m;
        !          1854:   long bitprec2,n=lgef(p)-3,iroots,i,j,e,av,tetpil;
        !          1855:
        !          1856:   roots_pol=cgetg(n+1,t_VEC); av=avma;
        !          1857:   for (i=1; i<=n; i++) roots_pol[i]=zero;
        !          1858:   for (j=1; j<=10; j++)
        !          1859:   {
        !          1860:     iroots=0; e = 2*gexpo(cauchy_bound(p)); if (e<0) e=0;
        !          1861:     bitprec2=bitprec+(1<<j)*n+gexpo(p)-gexpo((GEN)p[2+n])
        !          1862:       +(long) log2(n)+1+e;
        !          1863:     q=gmul(mygprec(gunr,bitprec2),mygprec(p,bitprec2));
        !          1864:     m=split_complete(q,bitprec2,&roots_pol,&iroots);
        !          1865:     e = gexpo(gsub(mygprec_special(p,bitprec2),m))
        !          1866:       - gexpo((GEN)q[2+n])+(long) log2((double)n)+1;
        !          1867:     if (e<-2*bitprec2) e=-2*bitprec2; /* to avoid e=-pariINFINITY */
        !          1868:     if (a_posteriori_errors(q,roots_pol,e) < -bitprec) return roots_pol;
        !          1869:
        !          1870:     tetpil=avma; roots_pol=gerepile(av,tetpil,gcopy(roots_pol));
        !          1871:   }
        !          1872:   err(bugparier,"all_roots");
        !          1873:   return NULL; /* not reached */
        !          1874: }
        !          1875:
        !          1876: /* true if x is an exact scalar, that is integer or rational */
        !          1877: static int
        !          1878: isexactscalar(GEN x)
        !          1879: {
        !          1880:   long tx=typ(x);
        !          1881:   return (tx==t_INT || is_frac_t(tx));
        !          1882: }
        !          1883:
        !          1884: static int
        !          1885: isexactpol(GEN p)
        !          1886: {
        !          1887:   long i,n=lgef(p)-3;
        !          1888:
        !          1889:   for (i=0; i<=n; i++)
        !          1890:     if (isexactscalar((GEN)p[i+2])==0) return 0;
        !          1891:   return 1;
        !          1892: }
        !          1893:
        !          1894: static long
        !          1895: isvalidcoeff(GEN x)
        !          1896: {
        !          1897:   long tx=typ(x);
        !          1898:
        !          1899:   switch(tx)
        !          1900:   {
        !          1901:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN: return 1;
        !          1902:     case t_COMPLEX:
        !          1903:       if (isvalidcoeff((GEN)x[1]) && isvalidcoeff((GEN)x[2])) return 1;
        !          1904:   }
        !          1905:   return 0;
        !          1906: }
        !          1907:
        !          1908: static long
        !          1909: isvalidpol(GEN p)
        !          1910: {
        !          1911:   long i,n = lgef(p);
        !          1912:   for (i=2; i<n; i++)
        !          1913:     if (!isvalidcoeff((GEN)p[i])) return 0;
        !          1914:   return 1;
        !          1915: }
        !          1916:
        !          1917: static GEN
        !          1918: solve_exact_pol(GEN p, long bitprec)
        !          1919: {
        !          1920:   GEN S,ex,factors,roots_pol,roots_fact;
        !          1921:   long i,j,k,m,n,iroots;
        !          1922:
        !          1923:   n=lgef(p)-3;
        !          1924:
        !          1925:   iroots=0;
        !          1926:   roots_pol=cgetg(n+1,t_VEC); for (i=1; i<=n; i++) roots_pol[i]=zero;
        !          1927:
        !          1928:   S=square_free_factorization(p);
        !          1929:   ex=(GEN) S[1]; factors=(GEN) S[2];
        !          1930:   for (i=1; i<lg(factors); i++)
        !          1931:   {
        !          1932:     roots_fact=all_roots((GEN)factors[i],bitprec);
        !          1933:     n=lgef(factors[i])-3; m=itos((GEN)ex[i]);
        !          1934:     for (j=1; j<=n; j++)
        !          1935:       for (k=1; k<=m; k++) roots_pol[++iroots] = roots_fact[j];
        !          1936:   }
        !          1937:   return roots_pol;
        !          1938: }
        !          1939:
        !          1940: /* return the roots of p with absolute error bitprec */
        !          1941: static GEN
        !          1942: roots_com(GEN p, long l)
        !          1943: {
        !          1944:   long bitprec;
        !          1945:
        !          1946:   if (gcmp0(p)) err(zeropoler,"roots");
        !          1947:   if (typ(p)!=t_POL)
        !          1948:   {
        !          1949:     if (!isvalidcoeff(p)) err(typeer,"roots");
        !          1950:     return cgetg(1,t_VEC); /* constant polynomial */
        !          1951:   }
        !          1952:   if (!isvalidpol(p)) err(talker,"invalid coefficients in roots");
        !          1953:   if (lgef(p) == 3) return cgetg(1,t_VEC); /* constant polynomial */
        !          1954:   if (l<3) l=3;
        !          1955:   bitprec=bit_accuracy(l); gunr=realun(l);
        !          1956:   return isexactpol(p)? solve_exact_pol(p,bitprec): all_roots(p,bitprec);
        !          1957: }
        !          1958:
        !          1959: static GEN
        !          1960: tocomplex(GEN x, long l)
        !          1961: {
        !          1962:   GEN y=cgetg(3,t_COMPLEX);
        !          1963:
        !          1964:   y[1]=lgetr(l);
        !          1965:   if (typ(x) == t_COMPLEX)
        !          1966:     { y[2]=lgetr(l); gaffect(x,y); }
        !          1967:   else
        !          1968:     { gaffect(x,(GEN)y[1]); y[2]=(long)realzero(l); }
        !          1969:  return y;
        !          1970: }
        !          1971:
        !          1972: /* Check if x is approximately real with precision e */
        !          1973: int
        !          1974: isrealappr(GEN x, long e)
        !          1975: {
        !          1976:   long tx=typ(x),lx,i;
        !          1977:   switch(tx)
        !          1978:   {
        !          1979:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
        !          1980:       return 1;
        !          1981:     case t_COMPLEX:
        !          1982:       return (gexpo((GEN)x[2]) < e);
        !          1983:     case t_QUAD:
        !          1984:       err(impl,"isrealappr for type t_QUAD");
        !          1985:     case t_POL: case t_SER: case t_RFRAC: case t_RFRACN:
        !          1986:     case t_VEC: case t_COL: case t_MAT:
        !          1987:       lx = (tx==t_POL)?lgef(x): lg(x);
        !          1988:       for (i=lontyp[tx]; i<lx; i++)
        !          1989:         if (! isrealappr((GEN)x[i],e)) return 0;
        !          1990:       return 1;
        !          1991:     default: err(typeer,"isrealappr"); return 0;
        !          1992:   }
        !          1993: }
        !          1994:
        !          1995: /* x,y sont de type t_COMPLEX */
        !          1996: static int
        !          1997: isconj(GEN x, GEN y, long e)
        !          1998: {
        !          1999:   return (gexpo( gsub((GEN)x[1],(GEN)y[1]) ) < e
        !          2000:        && gexpo( gadd((GEN)x[2],(GEN)y[2]) ) < e);
        !          2001: }
        !          2002:
        !          2003: /* returns the vector of roots of p, with guaranteed absolute error
        !          2004:  * BASE^(-(l-2)), where BASE=2^{ BITS_IN_LONG }.
        !          2005:  */
        !          2006: GEN
        !          2007: roots(GEN p, long l)
        !          2008: {
        !          2009:   long av,av1,tetpil,n,j,k,s, e = 5 - bit_accuracy(l);
        !          2010:   GEN p1,p2,p3,p22,res;
        !          2011:
        !          2012:   av=avma; p1=roots_com(p,l); n=lg(p1);
        !          2013:   if (isrealappr(p,e))
        !          2014:   {
        !          2015:     p3=cgetg(n,t_COL); s=0;
        !          2016:     for (j=1; j<n; j++)
        !          2017:     {
        !          2018:       p2=(GEN)p1[j];
        !          2019:       if (typ(p2) != t_COMPLEX) { p3[++s]=(long)p2; p1[j]=zero; }
        !          2020:       else if (isrealappr(p2,e)) { p3[++s]=p2[1]; p1[j]=zero; }
        !          2021:     }
        !          2022:     setlg(p3,s+1); p2=sort(p3); setlg(p3,n);
        !          2023:     tetpil=avma; res=cgetg(n,t_COL);
        !          2024:     for (j=1; j<=s; j++) res[j]=(long)tocomplex((GEN)p2[j],l);
        !          2025:     for (j=1; j<n; j++)
        !          2026:     {
        !          2027:       p2=(GEN)p1[j];
        !          2028:       if (typ(p2) == t_COMPLEX)
        !          2029:       {
        !          2030:        res[++s]=(long)tocomplex(p2,l);
        !          2031:         av1=avma;
        !          2032:        for (k=j+1; k<n; k++)
        !          2033:        {
        !          2034:          p22=(GEN)p1[k];
        !          2035:          if (typ(p22) == t_COMPLEX && isconj(p2,p22,e))
        !          2036:           {
        !          2037:             avma=av1; res[++s]=(long)tocomplex(p22,l);
        !          2038:             p1[k]=zero; break;
        !          2039:           }
        !          2040:        }
        !          2041:        if (k==n) err(bugparier,"roots (conjugates)");
        !          2042:       }
        !          2043:     }
        !          2044:     return gerepile(av,tetpil,res);
        !          2045:   }
        !          2046:   tetpil=avma; res=cgetg(n,t_COL);
        !          2047:   for (j=1; j<n; j++) res[j]=(long)tocomplex((GEN)p1[j],l);
        !          2048:   return gerepile(av,tetpil,res);
        !          2049: }
        !          2050:
        !          2051: GEN
        !          2052: roots0(GEN p, long flag,long l)
        !          2053: {
        !          2054:   switch(flag)
        !          2055:   {
        !          2056:     case 0: return roots(p,l);
        !          2057:     case 1: return rootsold(p,l);
        !          2058:     default: err(flagerr,"polroots");
        !          2059:   }
        !          2060:   return NULL; /* not reached */
        !          2061: }

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