Karim Belabas on Sun, 22 Mar 1998 04:15:16 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

patch, was Re: polroots algorithm


Hum, I wrote:
> (I might have overdone the garbage collecting simplification though, I'll
> have to recheck that on _huge_ examples, but that doesn't have high
> priority)

After a first check, I increased the priority of this...

If you are dealing with polynomials of huge degree (> 60, say), you should
apply this patch (if not, you don't need it). Otherwise, the stack overflows
much too easily...

Karim.

========================= patch 15 (2.0.7.alpha) ============================

*** src/basemath/rootpol.c.orig	Sat Mar 21 04:31:12 1998
--- src/basemath/rootpol.c	Sun Mar 22 03:55:40 1998
***************
*** 238,261 ****
  graeffe(GEN p)
  {
    GEN p0,p1,s0,s1,ss1;
!   long n=lgef(p)-3,n0,n1,ns1,i,ltop=avma,lbot,auxi;
  
!   if (n==0) return p;
    n0=(n>>1); n1=((n-1)>>1);
!   auxi=evalsigne(1)+evalvarn(varn(p));
!   p0=cgetg(n0+3,t_POL); p0[1]=auxi+evallgef(n0+3);
!   p1=cgetg(n1+3,t_POL); p1[1]=auxi+evallgef(n1+3);
    for (i=0; i<=n0; i++) p0[i+2]=p[2+(i<<1)];
    for (i=0; i<=n1; i++) p1[i+2]=p[3+(i<<1)];
  
    s0=cook_square(p0);
!   s1=cook_square(p1);
!   ns1=lgef(s1)-3;
!   ss1=cgetg(ns1+4,t_POL); /* will contain x*s1 */
!   ss1[1]=auxi+evallgef(ns1+4);
    ss1[2]=zero;
!   for (i=0; i<=ns1; i++) ss1[3+i]=s1[2+i];
!   lbot=avma; return gerepile(ltop,lbot,gsub(s0,ss1));
  }
  
  /********************************************************************/
--- 238,260 ----
  graeffe(GEN p)
  {
    GEN p0,p1,s0,s1,ss1;
!   long n=lgef(p)-3,n0,n1,i,auxi,ns1;
  
!   if (n==0) return gcopy(p);
    n0=(n>>1); n1=((n-1)>>1);
!   auxi=evalsigne(1)|evalvarn(varn(p));
!   p0=cgetg(n0+3,t_POL); p0[1]=auxi|evallgef(n0+3);
!   p1=cgetg(n1+3,t_POL); p1[1]=auxi|evallgef(n1+3);
    for (i=0; i<=n0; i++) p0[i+2]=p[2+(i<<1)];
    for (i=0; i<=n1; i++) p1[i+2]=p[3+(i<<1)];
  
    s0=cook_square(p0);
!   s1=cook_square(p1); ns1 = lgef(s1)-3;
!   ss1 = cgetg(ns1+4, t_POL);
!   ss1[1] = auxi | evallgef(ns1+4);
    ss1[2]=zero;
!   for (i=0; i<=ns1; i++) ss1[3+i]=s1[2+i]; /* now ss1 contains x * s1 */
!   ss1 = gneg(ss1); return gadd(s0,ss1);
  }
  
  /********************************************************************/
***************
*** 822,828 ****
  	for (j=0; j<=nn; j++) q[2+j]=q[2+valuat+j];
        }
        set_karasquare_limit(gexpo(q));
!       q=graeffe(q); tau2=1.5*tau2; eps=1/log(1./tau2);
      }
    }
    avma=ltop; return gpui(dbltor(2.),dbltor(r),DEFAULTPREC);
--- 821,828 ----
  	for (j=0; j<=nn; j++) q[2+j]=q[2+valuat+j];
        }
        set_karasquare_limit(gexpo(q));
!       q = gerepileupto(ltop, graeffe(q));
!       tau2=1.5*tau2; eps=1/log(1./tau2);
      }
    }
    avma=ltop; return gpui(dbltor(2.),dbltor(r),DEFAULTPREC);
***************
*** 839,851 ****
  modulus(GEN p, long k, double tau)
  {
    GEN q,new_gunr;
!   long i,j,kk=k,imax,n=lgef(p)-3,nn,nnn,valuat,ltop=avma,bitprec,decprec,e;
    double tau2,r;
  
    tau2=tau/6; nn=n;
    bitprec= (long) ((double) n*(2.+log2(3.*(double) n)+log2(1./tau2)));
    decprec=(long) ((double) bitprec * L2SL10)+1;
    new_gunr=gprec(gunr,decprec);
    q=gprec(p,decprec);
    q=gmul(new_gunr,q);
    e=polygone_newton(q,k);
--- 839,852 ----
  modulus(GEN p, long k, double tau)
  {
    GEN q,new_gunr;
!   long i,j,kk=k,imax,n=lgef(p)-3,nn,nnn,valuat,av,ltop=avma,bitprec,decprec,e;
    double tau2,r;
  
    tau2=tau/6; nn=n;
    bitprec= (long) ((double) n*(2.+log2(3.*(double) n)+log2(1./tau2)));
    decprec=(long) ((double) bitprec * L2SL10)+1;
    new_gunr=gprec(gunr,decprec);
+   av = avma;
    q=gprec(p,decprec);
    q=gmul(new_gunr,q);
    e=polygone_newton(q,k);
***************
*** 866,872 ****
      nn=nnn-valuat;
  
      set_karasquare_limit(bitprec);
!     q=graeffe(q);
      e=polygone_newton(q,kk);
      r=r+e/exp2((double)i);
      q=gmul(new_gunr,q);
--- 867,873 ----
      nn=nnn-valuat;
  
      set_karasquare_limit(bitprec);
!     q = gerepileupto(av, graeffe(q));
      e=polygone_newton(q,kk);
      r=r+e/exp2((double)i);
      q=gmul(new_gunr,q);
***************
*** 902,908 ****
    {
      q=eval_rel_pol(q,bitprec);
      set_karasquare_limit(bitprec);
!     q=graeffe(q);
      aux=aux*aux*exp(2*tau2);
      tau2=1.5*tau2;
      bitprec= (long) ((double) n*(2.+log2(aux)+log2(1./(1-exp(-tau2)))));
--- 903,909 ----
    {
      q=eval_rel_pol(q,bitprec);
      set_karasquare_limit(bitprec);
!     q = gerepileupto(ltop, graeffe(q));
      aux=aux*aux*exp(2*tau2);
      tau2=1.5*tau2;
      bitprec= (long) ((double) n*(2.+log2(aux)+log2(1./(1-exp(-tau2)))));
***************
*** 963,969 ****
      if (nn==0) return delta_k;
  
      set_karasquare_limit(bitprec);
!     q=graeffe(q); tau2=tau2*7./4.;
    }
    k=-1; logmax=- (double) pariINFINITY;
    for (i=0; i<=lgef(q)-3; i++)
--- 964,971 ----
      if (nn==0) return delta_k;
  
      set_karasquare_limit(bitprec);
!     q = gerepileupto(ltop, graeffe(q));
!     tau2=tau2*7./4.;
    }
    k=-1; logmax=- (double) pariINFINITY;
    for (i=0; i<=lgef(q)-3; i++)
***************
*** 1363,1375 ****
    Lmax=4; while (Lmax<=n) Lmax=(Lmax<<1);
    parameters(pp,&mu,&gamma,polreal,param,param2);
  
!   FF=cgetg(k+3,t_POL); FF[1]=evalsigne(1)+evalvarn(varn(p))+evallgef(k+3);
    FF[k+2]=un;
-   H=cgetg(k+2,t_POL); H[1]=evalsigne(1)+evalvarn(varn(p))+evallgef(k+2);
  
    NN=(long) (0.5/delta); NN+=(NN%2); if (NN<2) NN=2;
    NN=NN*Lmax; ltop=avma;
- 
    for(;;)
    {
      bitprec2=(long) (((double) NN*delta-mu)/log(2.))+gexpo(pp)+8;
--- 1365,1376 ----
    Lmax=4; while (Lmax<=n) Lmax=(Lmax<<1);
    parameters(pp,&mu,&gamma,polreal,param,param2);
  
!   H =cgetg(k+2,t_POL); H[1] =evalsigne(1) | evalvarn(varn(p)) | evallgef(k+2);
!   FF=cgetg(k+3,t_POL); FF[1]=evalsigne(1) | evalvarn(varn(p)) | evallgef(k+3);
    FF[k+2]=un;
  
    NN=(long) (0.5/delta); NN+=(NN%2); if (NN<2) NN=2;
    NN=NN*Lmax; ltop=avma;
    for(;;)
    {
      bitprec2=(long) (((double) NN*delta-mu)/log(2.))+gexpo(pp)+8;
***************
*** 1389,1395 ****
  
    if (k<=n/2) split_fromU(p,k,delta,bitprec,F,G,param,param2);
    else
!   {  /* we  start from the reciprocal of p */
      q=cgetg(n+3,t_POL); q[1]=p[1];
      for (i=0; i<=n; i++) q[i+2]=p[n-i+2];
      split_fromU(q,n-k,delta,bitprec,&FF,&GG,param,param2);
--- 1390,1396 ----
  
    if (k<=n/2) split_fromU(p,k,delta,bitprec,F,G,param,param2);
    else
!   { /* we start from the reciprocal of p */
      q=cgetg(n+3,t_POL); q[1]=p[1];
      for (i=0; i<=n; i++) q[i+2]=p[n-i+2];
      split_fromU(q,n-k,delta,bitprec,&FF,&GG,param,param2);
***************
*** 1431,1445 ****
  static GEN
  shiftpol(GEN p, GEN b)
  {
!   long ltop=avma,i,lbot=avma;
!   GEN r,q=gzero;
  
    for (i=lgef(p)-1; i>=2; i--)
    {
!     r=gmul(q,b);
!     lbot=avma; q=gadd((GEN)p[i],r);
    }
!   return gerepile(ltop,lbot,q);
  }
  
  /* return (aX-1)^n * p[ (X-a) / (aX-1) ] */
--- 1432,1446 ----
  static GEN
  shiftpol(GEN p, GEN b)
  {
!   long av = avma,i, limit = (av+bot)>>1;
!   GEN q = gzero;
  
    for (i=lgef(p)-1; i>=2; i--)
    {
!     q = gadd((GEN)p[i], gmul(q,b));
!     if (low_stack(limit, (av+bot)>>1)) q = gerepileupto(av,q);
    }
!   return gerepileupto(av,q);
  }
  
  /* return (aX-1)^n * p[ (X-a) / (aX-1) ] */
***************
*** 1449,1459 ****
    GEN r,pui,num,aux;
    long n=lgef(p)-3, i;
  
!   pui=cgetg(4,t_POL); pui[1]=evalsigne(1)+evalvarn(varn(p))+evallgef(4);
!   pui[2]=(long) mygprec(gneg(gunr),bitprec); pui[3]=lconj(a);
!   aux=pui;
!   num=cgetg(4,t_POL); num[1]=pui[1];
!   num[2]=lneg(a); num[3]=(long) mygprec(gunr,bitprec);
    r=(GEN)p[2+n];
    for (i=n-1; ; i--)
    {
--- 1450,1463 ----
    GEN r,pui,num,aux;
    long n=lgef(p)-3, i;
  
!   aux = pui = cgetg(4,t_POL);
!   pui[1] = evalsigne(1) | evalvarn(varn(p)) | evallgef(4);
!   pui[2] = (long) mygprec(gneg(gunr),bitprec);
!   pui[3] = lconj(a);
!   num = cgetg(4,t_POL);
!   num[1] = pui[1];
!   num[2] = lneg(a);
!   num[3] = (long) mygprec(gunr,bitprec);
    r=(GEN)p[2+n];
    for (i=n-1; ; i--)
    {
***************
*** 1467,1474 ****
  static void
  conformal_mapping(GEN p, long k, long bitprec, double aux,GEN *F,GEN *G)
  {
!   long bitprec2,bitprec3,n=lgef(p)-3,decprec,i;
!   GEN q,FF,GG,a,R;
    double rmin,rmax,rho,delta,aux2,param,param2,r1,r2;
  
    bitprec2=bitprec+(long) (n*(2.*log2(2.732)+log2(1.5)))+1;
--- 1471,1478 ----
  static void
  conformal_mapping(GEN p, long k, long bitprec, double aux,GEN *F,GEN *G)
  {
!   long bitprec2,bitprec3,n=lgef(p)-3,decprec,i,ltop = avma, av;
!   GEN q,FF,GG,a,R, *gptr[2];
    double rmin,rmax,rho,delta,aux2,param,param2,r1,r2;
  
    bitprec2=bitprec+(long) (n*(2.*log2(2.732)+log2(1.5)))+1;
***************
*** 1476,1483 ****
    a=gmul(mygprec(a,bitprec2),mygprec(globalu,bitprec2));
    a=gdivgs(a,-6); /* a=-globalu/2/sqrt(3) */
  
!   q=mygprec(p,bitprec2);
!   q=conformal_pol(q,a,bitprec2);
    for (i=1; i<=n; i++)
      if (radius[i]!=0.) /* updating array radius */
      {
--- 1480,1487 ----
    a=gmul(mygprec(a,bitprec2),mygprec(globalu,bitprec2));
    a=gdivgs(a,-6); /* a=-globalu/2/sqrt(3) */
  
!   av = avma; q=mygprec(p,bitprec2);
!   q = conformal_pol(q,a,bitprec2);
    for (i=1; i<=n; i++)
      if (radius[i]!=0.) /* updating array radius */
      {
***************
*** 1514,1519 ****
--- 1518,1524 ----
  
    R=mygprec(dbltor(1/rho),bitprec2);
    q=scalepol(q,R,bitprec2);
+   gptr[0]=&q; gptr[1]=&R; gerepilemany(av,gptr,2);
  
    aux2=radius[k];
    for (i=k-1; i>=1; i--)
***************
*** 1536,1546 ****
      if (aux2<1.) param2-=log2(aux2);
    }
    optimize_split(q,k,delta,bitprec2,&FF,&GG,param,param2);
!   bitprec2=bitprec2+n; R=ginv(R);
!   FF=scalepol(FF,R,bitprec2); GG=scalepol(GG,R,bitprec2);
  
    a=mygprec(a,bitprec2);
!   FF=conformal_pol(FF,a,bitprec2); GG=conformal_pol(GG,a,bitprec2);
    a=ginv(gsub(gun,gmul(a,gconj(a))));
    a=glog(a,(long) (bitprec2 * L2SL10)+1);
  
--- 1541,1553 ----
      if (aux2<1.) param2-=log2(aux2);
    }
    optimize_split(q,k,delta,bitprec2,&FF,&GG,param,param2);
!   bitprec2=bitprec2+n; R = ginv(R);
!   FF=scalepol(FF,R,bitprec2);
!   GG=scalepol(GG,R,bitprec2);
  
    a=mygprec(a,bitprec2);
!   FF=conformal_pol(FF,a,bitprec2);
!   GG=conformal_pol(GG,a,bitprec2);
    a=ginv(gsub(gun,gmul(a,gconj(a))));
    a=glog(a,(long) (bitprec2 * L2SL10)+1);
  
***************
*** 1549,1557 ****
    GG=gmul(GG,gexp(gmulgs(a,n-k),decprec));
  
    *F=mygprec(FF,bitprec+n); *G=mygprec(GG,bitprec+n);
  }
  
! /* split p, this time with no scaling . returns in F and G two polynomials
  such that |p-FG|< 2^(-bitprec)|p| */
  static void
  split_2(GEN p, long bitprec, double thickness, GEN *F, GEN *G)
--- 1556,1565 ----
    GG=gmul(GG,gexp(gmulgs(a,n-k),decprec));
  
    *F=mygprec(FF,bitprec+n); *G=mygprec(GG,bitprec+n);
+   gptr[0]=F; gptr[1]=G; gerepilemany(ltop,gptr,2);
  }
  
! /* split p, this time with no scaling. returns in F and G two polynomials
  such that |p-FG|< 2^(-bitprec)|p| */
  static void
  split_2(GEN p, long bitprec, double thickness, GEN *F, GEN *G)
***************
*** 1699,1706 ****
      rmin=min_modulus(qq,0.05);
      if (3./rmin > thickness)
      {
!       rmax=max_modulus(qq,0.05);
!       quo = rmax/rmin;
        if ((float)quo > (float)thickness)
        {
  	thickness=quo; newq=qq; globalu=(GEN)v[i];
--- 1707,1713 ----
      rmin=min_modulus(qq,0.05);
      if (3./rmin > thickness)
      {
!       rmax=max_modulus(qq,0.05); quo = rmax/rmin;
        if ((float)quo > (float)thickness)
        {
  	thickness=quo; newq=qq; globalu=(GEN)v[i];
***************
*** 1798,1808 ****
    if (k>0)
    {
      if (k>n/2) k=n/2;
!     FF=cgetg(k+3,t_POL); FF[1]=evalsigne(1)+evalvarn(varn(p))+evallgef(k+3);
      for (i=0; i<k; i++) FF[i+2]=lcopy(gzero);
      FF[k+2]=(long) mygprec(gunr,bitprec);
      GG=cgetg(n-k+3,t_POL);
!     GG[1]=evalsigne(1)+evalvarn(varn(p))+evallgef(n-k+3);
      for (i=0; i<=n-k; i++) GG[i+2]=p[i+k+2];
    }
    else
--- 1805,1816 ----
    if (k>0)
    {
      if (k>n/2) k=n/2;
!     FF=cgetg(k+3,t_POL); 
!     FF[1]=evalsigne(1) | evalvarn(varn(p)) | evallgef(k+3);
      for (i=0; i<k; i++) FF[i+2]=lcopy(gzero);
      FF[k+2]=(long) mygprec(gunr,bitprec);
      GG=cgetg(n-k+3,t_POL);
!     GG[1]=evalsigne(1) | evalvarn(varn(p)) | evallgef(n-k+3);
      for (i=0; i<=n-k; i++) GG[i+2]=p[i+k+2];
    }
    else
***************
*** 1939,1945 ****
  {
    long n=lgef(p)-3,decprec,ltop,lbot;
    GEN F,G,a,b,m1,m2,m;
!   GEN *gptr[3];
  
    if (n==1)
    {
--- 1947,1953 ----
  {
    long n=lgef(p)-3,decprec,ltop,lbot;
    GEN F,G,a,b,m1,m2,m;
!   GEN *gptr[2];
  
    if (n==1)
    {
--
Karim Belabas                          e-mail:
Max-Planck-Institut fuer Mathematik       karim@mpim-bonn.mpg.de
Gottfried-Claren-Str. 26               tel:
53225 Bonn (Germany)                      (00 49 228) 402-245