Skip to main content

Module polylog

Module polylog 

Source
Expand description

The polylogarithm $\mathrm{Li}_s(z) = \sum_{k \ge 1} z^k / k^s$ of a real argument, at a scalar real order.

Two things live here: the order plan (every order-dependent coefficient, computed once per call in the element type through the scalar math surface, and shared with thermite-complex’s kernel) and the real kernel, which returns the real part of the principal value for a real vector. Nothing in the real kernel is a complex number. Where the mathematics is complex (the negative axis, the cut $z > 1$, the far-field roots) the real part is taken analytically: the polynomial parts by a Goertzel recurrence, the transcendental parts in polar form.

§Regions

With $\mu = \ln z$ (principal: $\ln|z| + i\pi$ on the negative axis) and $t = |\mu| / 2\pi$, per lane:

  1. Defining series where $2\pi|z| < |\mu|$ (Roughan’s rule, which crosses the positive axis at z = 0.2323 and the negative axis at z = -0.5113), at a fixed term count set by the worst ratio 0.5113.
  2. Unity series where $t \le 0.512$ (Wood 9.3, Crandall 1.4, Roughan Series 2):
    \mathrm{Li}_s(z) = \Gamma(1-s)(-\mu)^{s-1} + \sum_{k \ge 0} \zeta(s-k)\,\frac{\mu^k}{k!}
    whose tail falls like $(|\mu|/2\pi)^k$. For $s = n + \varepsilon$ with $n \ge 1$ the $k = n-1$ term and the $\Gamma$ term each have a pole that the other cancels. They are fused algebraically into $\mu^{n-1} Q_{n-1}(L, \varepsilon)/(n-1)!$ with $L = \ln(-\mu)$ and
    Q_m(L, \varepsilon) = \Big[\zeta(1+\varepsilon) - \tfrac{1}{\varepsilon}\Big]
      + \Big[(-1)^m m!\,\Gamma(-m-\varepsilon) + \tfrac{1}{\varepsilon}\Big] e^{\varepsilon L}
      - \frac{e^{\varepsilon L} - 1}{\varepsilon}.
    Both brackets are scalars, finite and smooth for every $\varepsilon$ (the second is $-\mathrm{expm1}(u)/\varepsilon$ with $u = \ln\Gamma(1-\varepsilon) - \sum_{k \le m}\ln(1 + \varepsilon/k)$), so there is no near-integer threshold and no Taylor arm. Roughan’s Series 3 and its 1e-3 switch are what this replaces. At $\varepsilon = 0$ it collapses to Wood 9.5’s $H_m - L$ exactly, and every coefficient of the integer case is a table read.
  3. Far field, otherwise. Integer order takes the inversion formula (Crandall 1.3), $\mathrm{Li}_n(z) = -(-1)^n \mathrm{Li}_n(1/z) - \frac{(2\pi i)^n}{n!} B_n\!\big(\tfrac{\mu}{2\pi i}\big) - \sigma(z)\,\frac{2\pi i\,\mu^{n-1}}{(n-1)!}$, with $\mathrm{Li}_n(1/z)$ from the defining series. The step term is imaginary and drops out of a real part. Real order takes Wood’s m-th-root identity $\mathrm{Li}_s(z) = m^{s-1}\sum_{j} \mathrm{Li}_s(z^{1/m}\,e^{2\pi i j/m})$ (Roughan 2026 Section 4.6): m is chosen so every root’s $\mu_j$ satisfies $|\mu_j| \le 1.2\pi$, the coefficient sweep is shared across the roots, each root runs region 2 (the fused form included, so this arm serves near-integer orders too), and for a real argument the roots come in conjugate pairs with equal real parts, so only half of them are evaluated. Negative integer orders run regions 1 and 2 as they stand and reflect $\mathrm{Li}_{-p}(z) = -(-1)^p \mathrm{Li}_{-p}(1/z)$ (Wood 10.3) in the far field only.
  4. $\mathrm{Li}_1 = -\ln(1-z)$ and $\mathrm{Li}_0 = z/(1-z)$ are closed forms.

Every arm is fixed-length, so a packet pays the count once rather than its worst lane’s convergence. The counts scale with the policy’s precision tier.

§Real parts without complex numbers

A real polynomial at $x = a + ib$ divides by $(t-x)(t-\bar x) = t^2 - 2a\,t + |x|^2$. The Goertzel recurrence $B_k = c_k + 2a B_{k+1} - |x|^2 B_{k+2}$ leaves $\mathrm{Re}\,P(x) = B_0 - a B_1$ and $\mathrm{Im}\,P(x) = b B_1$, two real FMAs per term. The lead terms use $r = |\mu|$, $\theta = \arg(-\mu)$, $\varphi = \arg\mu$: $\mathrm{Re}\,\Gamma(1-s)(-\mu)^{s-1} = \Gamma(1-s)\,r^{s-1}\cos((s-1)\theta)$, and for the fused term $\mathrm{Re}[\mu^m Q] = r^m(\cos m\varphi\,\mathrm{Re}\,Q - \sin m\varphi\,\mathrm{Im}\,Q)$ with $e^{\varepsilon L} = r^\varepsilon e^{i\varepsilon\theta}$ and the difference quotient spelled $\ln r\,\varphi_1(\varepsilon \ln r)\cos\varepsilon\theta - \mathrm{versin}(\varepsilon\theta)/\varepsilon$ so that $\varepsilon \to 0$ is exact. Angles are carried as multiples of $\pi$ and go through the _pi trig, which is exact on the axes. On the cut near $z = 1$ the lead term’s imaginary part is enormous and a radian phase error leaks it into the real part. All verified against mpmath before being written (scratch goertzel.py, 2026-09-02).

Constants§

KMAX
Longest series any arm runs: binary64 at the root arm’s ratio 0.6 needs 74 terms. Also caps |n| for the inversion polynomial.
MMAX
Root-count cap. |z| = 1e308 asks for 341.

Traits§

PolylogElement
The element bounds the plan’s scalar precompute needs.

Functions§

polylog_impl
The real part of Li_s(z) for real z, every real order. See the module documentation.
root_count
The number of m-th roots the far field needs when the widest lane’s Re ln z is re_mu_max: the smallest m >= 2 with Re mu / m <= sqrt(alpha^2 - 1) pi = 2.0839 (alpha = 1.2), capped. The identity holds for any m, so the widest lane sets it for the packet. A comparison loop, so no count is converted out of a float.
t1
Unity-series boundary on |mu| / 2pi. Roughan’s 0.512 rather than 0.5: the extra sliver is what closes the gap the series-1 rule leaves near the negative axis.
unity_re
The real part of the unity series at mu = a + ib, including the fused or plain lead term. q = |mu|^2. See the module docs for the identities.
zeta_int
zeta(n) at an integer: the table for n >= 2 (exactly 1 past it), -1/2 at zero, -B_{j+1}/(j+1) at -j (zero for even j).
Last built: 2026-09-08 21:35:55 UTC