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);
}
!   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);

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
```