| Karim BELABAS on Fri, 12 Nov 1999 20:09:40 +0100 (MET) |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| Re: dilog() bug |
[Michael Somos:]
> gp> polylog(2,10)
> %1 = 0.5363012873578627365501597698 - 7.233784412415464812490046550*I
> gp> dilog(10)
> %2 = 0.5363012873578627365501597699 - 7.233784412415464812490046550*I
> gp> \ps3
> seriesprecision = 3 significant terms
> gp> polylog(2,x)
> %3 = x + 1/4*x^2 + O(x^3)
> gp> dilog(x)
> *** incorrect type in comparison.
>
> It seems to me that polylog(2,x) and dilog(x) shuould give essentially
> the same answer for any value of x. In fact, I would define it as follows:
>
> dilog(x)=polylog(2,x)
>
> Any reason why this is not the case?
The functional equation (relating values at x and 1/x) can be written in a
(slightly) more efficient way when m = 2. But in fact, the way it was
written, it became (slightly) _less_ efficient (to save 3 multiplications,
one ordinary logarithm had to be recomputed...).
I trivialized dilog() the way you suggested and special cased m = 2 in
polylog(), rewriting the optimization so that it works as intended (skipping
the log computation). The patch is big, since I cleaned up the neighbouring
code.
Karim.
Index: src/basemath/trans3.c
===================================================================
RCS file: /home/megrez/cvsroot/pari/src/basemath/trans3.c,v
retrieving revision 1.2
diff -c -r1.2 trans3.c
*** src/basemath/trans3.c 1999/09/23 17:50:57 1.2
--- src/basemath/trans3.c 1999/11/12 19:05:00
***************
*** 809,885 ****
GEN
polylog(long m, GEN x, long prec)
{
! long av,av1,limpile,tetpil,l,e,sx,i;
! GEN p1,p2,n,y,logx,logx2;
! GEN *gptr[4];
if (m<0) err(talker,"negative index in polylog");
if (!m) return gneg(ghalf);
if (gcmp0(x)) return gcopy(x);
! av=avma;
if (m==1)
! {
! p1=glog(gsub(gun,x),prec); tetpil=avma;
! return gerepile(av,tetpil,gneg(p1));
! }
! l=precision(x);
if (!l) { l=prec; x=gmul(x, realun(l)); }
! e=gexpo(gnorm(x)); if (!e || e== -1) return cxpolylog(m,x,prec);
! if (e>0)
{
! logx=glog(x,l); sx=gsigne(gimag(x));
if (!sx)
{
! if (m&1)
! sx = gsigne(greal(gsub(gun,x)));
! else
! sx = -gsigne(greal(x));
}
! x=ginv(x);
}
av1=avma; limpile=stack_lim(av1,1);
! y=x; n=gun; p1=x;
! do
{
! n=addsi(1,n); p1=gmul(x,p1); p2=gdiv(p1,gpuigs(n,m));
! y=gadd(y,p2);
if (low_stack(limpile, stack_lim(av1,1)))
! {
if(DEBUGMEM>1) err(warnmem,"polylog");
! gptr[0]=&y; gptr[1]=&n; gptr[2]=&p1; gptr[3]=&p2;
! gerepilemany(av1,gptr,4);
}
}
! while (gexpo(p2) > -bit_accuracy(l));
! tetpil=avma;
! if (e<=0) return gerepile(av,tetpil,gcopy(y));
! logx2=gsqr(logx); p1=gneg_i(ghalf);
! for (i=m-2; i>=0; i-=2)
{
! p1 = gadd(izeta(m-i,l), gmul(p1,gdivgs(logx2,(i+1)*(i+2))));
}
! if (m&1) p1 = gmul(logx,p1);
! p2=cgetg(3,t_COMPLEX); p2[1]=zero;
! p2[2]=ldiv(gmulsg(sx,mppi(l)),mpfact(m-1));
! p1=gadd(gmul2n(p1,1), gmul(p2,gpuigs(logx,m-1)));
! if ((m&1) == 0) y = gneg_i(y);
! tetpil=avma; return gerepile(av,tetpil,gadd(p1,y));
}
GEN
dilog(GEN x, long prec)
{
! GEN p1,p2,p3,y;
! long av=avma,tetpil;
!
! if (gcmpgs(gnorm(x),1)<1)
! {
! tetpil=avma; return gerepile(av,tetpil,polylog(2,x,prec));
! }
! y=gneg_i(polylog(2,ginv(x),prec)); p3=mppi(prec); p2=gdivgs(gsqr(p3),6);
! p1=glog(gneg_i(x),prec); p1=gadd(p2,gmul2n(gsqr(p1),-1));
! p1 = gneg_i(p1); tetpil=avma;
! return gerepile(av,tetpil,gadd(y,p1));
}
GEN
--- 809,883 ----
GEN
polylog(long m, GEN x, long prec)
{
! long av,av1,limpile,l,e,i,G;
! GEN z,p1,p2,n,y,logx;
if (m<0) err(talker,"negative index in polylog");
if (!m) return gneg(ghalf);
if (gcmp0(x)) return gcopy(x);
! av = avma;
if (m==1)
! return gerepileupto(av, gneg(glog(gsub(gun,x), prec)));
!
! l = precision(x);
if (!l) { l=prec; x=gmul(x, realun(l)); }
! e = gexpo(gnorm(x)); if (!e || e== -1) return cxpolylog(m,x,prec);
! if (e > 0)
{
! long sx = gsigne(gimag(x));
! logx = glog(x,l);
if (!sx)
{
! if (m&1) sx = gsigne(gsub(gun,greal(x)));
! else sx = - gsigne(greal(x));
}
! z = cgetg(3,t_COMPLEX);
! z[1] = zero;
! z[2] = ldivri(mppi(l), mpfact(m-1));
! if (sx < 0) z[2] = lnegr((GEN)z[2]);
! x = ginv(x);
}
+ G = -bit_accuracy(l);
+ n = icopy(gun);
av1=avma; limpile=stack_lim(av1,1);
! y=x; p1=x;
! for (i=2; ; i++)
{
! n[2] = i; p1 = gmul(x,p1); p2 = gdiv(p1,gpuigs(n,m));
! y = gadd(y,p2);
! if (gexpo(p2) <= G) break;
!
if (low_stack(limpile, stack_lim(av1,1)))
! { GEN *gptr[2]; gptr[0]=&y; gptr[1]=&p1;
if(DEBUGMEM>1) err(warnmem,"polylog");
! gerepilemany(av1,gptr,2);
}
}
! if (e < 0) return gerepileupto(av, y);
!
! if (m == 2)
! { /* same formula as below, written more efficiently */
! y = gneg_i(y);
! p1 = gmul2n(gsqr(gsub(logx, z)), -1); /* = (log(-x))^2 / 2 */
! p1 = gadd(divrs(gsqr(mppi(l)), 6), p1);
! p1 = gneg_i(p1);
! }
! else
{
! GEN logx2 = gsqr(logx); p1 = gneg_i(ghalf);
! for (i=m-2; i>=0; i-=2)
! p1 = gadd(izeta(m-i,l), gmul(p1,gdivgs(logx2,(i+1)*(i+2))));
! if (m&1) p1 = gmul(logx,p1); else y = gneg_i(y);
! p1 = gadd(gmul2n(p1,1), gmul(z,gpuigs(logx,m-1)));
}
!
! return gerepileupto(av, gadd(y,p1));
}
GEN
dilog(GEN x, long prec)
{
! return gpolylog(2, x, prec);
}
GEN
__
Karim Belabas email: Karim.Belabas@math.u-psud.fr
Dep. de Mathematiques, Bat. 425
Universite Paris-Sud Tel: (00 33) 1 69 15 57 48
F-91405 Orsay (France) Fax: (00 33) 1 69 15 60 19
--
PARI/GP Home Page: http://hasse.mathematik.tu-muenchen.de/ntsw/pari/