6
$\begingroup$

Is there a nice way to implement the dilogarithm function for real values, without actually performing the integration?

A series solution would have been nice, but the series around $0$ has a convergence radius of $1$, so it doesn't work for larger $x$. Ideally, I'm looking for an "elegant" method, rather than the "fastest" method.

For reference, the gsl library uses over 650 lines of code for the implementation, but I'm looking for somthing a bit more compact.

$\endgroup$
3
  • 2
    $\begingroup$ But you have identities like $$\mathrm{Li}_2(z) = -\mathrm{Li}_2\left(z^{-1}\right)-\frac12 \ln^2(-z)-\frac{\pi^2}{6}$$ (concerning series solution). $\endgroup$ Commented Aug 8, 2013 at 10:36
  • 2
    $\begingroup$ Or you could also use $$\text{Li}_{2}(z)= \frac{ \pi^{2}}{3}- \frac{ \ln^{2}(z)}{2}- \sum_{k=1}^{ \infty} \frac{1}{k^{2}z^{k}}-i \pi \ln(z),$$ and truncate the sum to however many terms you want. $\endgroup$ Commented Aug 8, 2013 at 10:38
  • $\begingroup$ What is your actual programming goal? "Nice" is rather vague, and "compact" is rarely something to strive for.... $\endgroup$
    – user14972
    Commented Aug 8, 2013 at 11:00

3 Answers 3

10
$\begingroup$

The cited Wikipedia page gives the expansion $$ \mathrm{Li}_2(x)=\frac{\pi^2}{3}-\frac12\log(x)^2-\sum_{k=1}^\infty\frac1{k^2x^k}-i\pi\log(x)\tag{1} $$ for $x\ge1$. Combined with $$ \mathrm{Li}_2(x)=\sum_{k=1}^\infty\frac{x^k}{k^2}\tag{2} $$ for $|x|\le1$, you should get what you need.


Equation $(1)$ also works for $x\le-1$ if we use $\log(x)=\log(-x)-\pi i$: $$ \mathrm{Li}_2(x)=-\frac{\pi^2}{6}-\frac12\log(-x)^2-\sum_{k=1}^\infty\frac1{k^2x^k}\tag{3} $$ for $x\le-1$.


Inversion Formula $$ \begin{align} \mathrm{Li}_2(x) &=-\int_0^x\log(1-t)\frac{\mathrm{d}t}{t}\\ &=\frac{\pi^2}{6}-\int_1^x\log(1-t)\frac{\mathrm{d}t}{t}\\ &=\frac{\pi^2}{6}-\pi i\log(x)-\int_1^x\log(t-1)\frac{\mathrm{d}t}{t}\\ &=\frac{\pi^2}{6}-\pi i\log(x)-\int_{1/x}^1\log(1/t-1)\frac{\mathrm{d}t}{t}\\ &=\frac{\pi^2}{6}-\pi i\log(x)-\int_{1/x}^1\Big(\log(1-t)-\log(t)\Big)\frac{\mathrm{d}t}{t}\\ &=\frac{\pi^2}{6}-\pi i\log(x)+\frac{\pi^2}{6}+\int_0^{1/x}\log(1-t)\frac{\mathrm{d}t}{t}+\int_{1/x}^1\log(t)\frac{\mathrm{d}t}{t}\\ &=\frac{\pi^2}{3}-\pi i\log(x)-\mathrm{Li}_2(1/x)-\frac12\log(x)^2\tag{4}\\ &=-\frac{\pi^2}{6}-\mathrm{Li}_2(1/x)-\frac12\log(-x)^2\tag{5} \end{align} $$ $(2)$ and $(4)$ prove expansion $(1)$. $(2)$ and $(5)$ prove expansion $(3)$.


Duplication Formula $$ \begin{align} \mathrm{Li}_2(x) &=-\int_0^x\log(1-t)\frac{\mathrm{d}t}{t}\\ &=-\int_0^1\log(1-t)\frac{\mathrm{d}t}{t}+\int_x^1\log(1-t)\frac{\mathrm{d}t}{t}\\ &=\frac{\pi^2}{6}+\int_0^{1-x}\log(t)\frac{\mathrm{d}t}{1-t}\\ &=\frac{\pi^2}{6}-\log(x)\log(1-x)+\int_0^{1-x}\log(1-t)\frac{\mathrm{d}t}{t}\\ &=\frac{\pi^2}{6}-\log(x)\log(1-x)-\mathrm{Li}_2(1-x)\tag{6}\\ \mathrm{Li}_2(x)+\mathrm{Li}_2(1-x) &=\frac{\pi^2}{6}-\log(x)\log(1-x)\tag{7} \end{align} $$

$\endgroup$
2
  • $\begingroup$ What about large negative $x$? the value will be real, and so the formula above (containing $i$) will not apply $\endgroup$ Commented Aug 8, 2013 at 11:07
  • 1
    $\begingroup$ @nbubis: I have converted $(1)$ for negative $x$. $\endgroup$
    – robjohn
    Commented Aug 8, 2013 at 11:24
2
$\begingroup$

I do not know how well this compares to other methods, but it is one I have devised for the purpose of computing the polylogarithm for values of z near the unit circle. In the case of the dilogarithm, the group of anharmonic ratios allows one to reduce the computation in the general case to a fundamental region for that group. However that still appears to involve computation for values near (or on) the unit circle, in particular the cube roots of -1 in the right half plane are fixed points for that group, so one needs to compute those. And nearby values.

A rational approximation to the polylogarithm can be had with poles in the branch cut (where they ought to be for any decent approximation). Runge's theorem guarantees there will be many.

We arrived at this one:

$$\text{Li}_{s}(z)\approx \frac{\pi z}{Γ(s)\sqrt{N}} \sum_{k=-N}^{N}\frac{e^{k\pi/\sqrt{N}}}{(e^{k\pi/\sqrt{N}}+1-z)(1+e^{k\pi/\sqrt{N}})} \log^{s-1}(1+e^{k\pi/\sqrt{N}})$$ $$= z\sum_{k=-N}^{N}\frac{w_{k}}{λ_{k}-z}$$

which is a Riemann sum for the integral representation

$$\text{Li}_{s}(z)=\frac{z}{Γ(s)}\int_{-\infty}^{\infty} \frac{e^{\tau}}{(e^{\tau}+1-z)(1+e^{\tau})} \log^{s-1}(1+e^{\tau})d\tau$$

which follows from a simple change of variables in the well known integral representation

$$\text{Li}_{s}(z)=\frac{1}{Γ(s)}\int_0^\infty \frac{ze^{-t}}{1-ze^{-t}}t^{s-1}dt$$

which can be obtained easily from the Laplace transform.

$\endgroup$
4
  • $\begingroup$ Thank you for your answer! I fixed up the LaTeX a bit, would you mind checking that this is still correct? $\endgroup$ Commented Nov 7, 2013 at 18:32
  • 1
    $\begingroup$ By the way I have not closely examined the selection of the distance 0≤h≤(π/(√N)) in the Riemann sum. I gave the formula for the largest possible, which seems to work well, but a smaller h could be better. As to the LaTex, it looks OK but this is what stackexchange made of what I constructed in Scientific Word, and on my screen the spacing and wraparound is a little off. The limits on the bottom integral should be 0 to infinity, which is what it sort-of looks like. $\endgroup$ Commented Nov 7, 2013 at 18:33
  • 1
    $\begingroup$ Transformations of the dilogarithm by anharmonic ratios (Cf. maths.dur.ac.uk/~dma0hg/dilog.pdf): Li₂((1/z)) = -Li₂(z)-((π²)/6)-(1/2)(log(1/z))² Li₂(1-z) = -Li₂(z)+((π²)/6)-(1/2)(log z)(log(1-z)) Li₂((z/(z-1))) = -Li₂(z)-(1/2)(log(1-z))² Li₂(((z-1)/z)) = Li₂(z)-((π²)/6)-(1/2)(log(z))²+(1/2)(log z)(log(1-z)) Li₂((1/(1-z))) = Li₂(z)+((π²)/6)+(log(1/z))(log(1-z))-(1/2)(log(1-z))² The problem is reduced to computing the dilogarithm for {|1-z|≤1}∩{Rez≤(1/2)} so the power series works well except for the points near the cube roots of unity. $\endgroup$ Commented Nov 9, 2013 at 15:47
  • $\begingroup$ More numerical experiments suggest that h = pi sqrt(2/N) is a good, but possibly not optimal choice. At z=1, the power series requires 1,000,000 terms to get relative error of about 6x10^-7, but the Riemann sum with 20 terms and h = pi sqrt(2/20) has relative error about 8x10^-9. So if this function is evaluated in an inner loop of another calculation, the Riemann sum should be used near the unit circle. $\endgroup$ Commented Apr 23, 2014 at 12:55
1
$\begingroup$

For further reference, based on @robjohn's answer, I came up with the following code for the calculation of the Spence function: $$\Phi(x)=-\int_0^x \frac{\ln|1-y|}{y}dy$$

double spenceFunction(double x, double precision = 1.0e-13) {
    if (x >= 0.5 && x < 1.0) {
        return  M_PI*M_PI/6.0 - spenceFunction(1.0 - x) - std::log( x)*std::log(1-x);
    }
    if (x >= 1.0) {
        return  M_PI*M_PI/3.0 - spenceFunction(1.0 / x) - std::log( x)*std::log(x) / 2.0;
    }
    if (x < -1.0) {
        return -M_PI*M_PI/6.0 - spenceFunction(1.0 / x) - std::log(-x)*std::log(-x) / 2.0;
    }

    double sum = 0.0, i = 1.0;
    for (; i < INT_MAX; i += 1.0) {
        double delta = std::pow(x,i) / (i*i);
        sum += delta;
        if (std::abs(delta/sum) < precision) break;
    }
    return sum;
}
$\endgroup$
3
  • $\begingroup$ You can avoid the ${\tt\mbox{std::}}$ "scope operator" whenever you add at the program beginning ( after the ${\tt\mbox{#include} < \cdots >}$ ) the line ${\tt\mbox{using namespace std;}}$ $\endgroup$ Commented Aug 13, 2014 at 3:17
  • 1
    $\begingroup$ @FelixMarin - I'm aware of that of course, It's just that "using namespace std" is considered bad form, for good reason. See here for instance: stackoverflow.com/questions/1452721/… $\endgroup$ Commented Aug 13, 2014 at 19:57
  • $\begingroup$ @nubis Thanks. I didn't know what you said about the 'bad form'. I'll check the link you gave about it. $\endgroup$ Commented Aug 16, 2014 at 21:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .