Skip to content

The Two-Argument Zeta ​

The Riemann zeta ζ(s)=∑n≥1n−s\zeta(s) = \sum_{n\ge 1} n^{-s} has a two-argument cousin, the Hurwitz zeta,

ζ(s,a)  =  ∑n=0∞(n+a)−s,\zeta(s, a) \;=\; \sum_{n=0}^{\infty} (n + a)^{-s},

convergent for Re⁡(s)>1\operatorname{Re}(s) > 1 and continued analytically everywhere else. It recovers the ordinary case at a=1a = 1 (ζ(s,1)=ζ(s)\zeta(s, 1) = \zeta(s)) and shifts the sum otherwise, so ζ(s,2)=ζ(s)−1\zeta(s, 2) = \zeta(s) - 1, and in general ζ(s,m)=ζ(s)−∑k=1m−1k−s\zeta(s, m) = \zeta(s) - \sum_{k=1}^{m-1} k^{-s} for a positive integer mm.

@enumeratio/analytic adds HurwitzZeta (and a two-argument Zeta) to compute-engine by Euler–Maclaurin summation, aligned with Wolfram. Because the head is declared on the playground engine, you can evaluate it in any cell:

ζ(s, a) at a few values

InHurwitzZeta(2,1)\mathrm{HurwitzZeta}(2, 1)Outπ26\frac{π^2}{6}InHurwitzZeta(2,2)\mathrm{HurwitzZeta}(2, 2)Outπ26−1\frac{π^2}{6}-1InHurwitzZeta(0,a)\mathrm{HurwitzZeta}(0, a)Out12−a\frac{1}{2}-a
source · editable

The first two reduce to closed forms — π2/6\pi^2/6 and π2/6−1\pi^2/6 - 1. At nonpositive integer ss the values are Bernoulli polynomials in aa, so ζ(0,a)=12−a\zeta(0, a) = \tfrac12 - a (and ζ(−1,a)=−112(6a2−6a+1)\zeta(-1, a) = -\tfrac{1}{12}(6a^2 - 6a + 1)). Write the head as \operatorname{HurwitzZeta} — the bare \zeta(s, a) LaTeX still parses as the one-argument Riemann zeta.

The surface ​

As a bivariate function it is a smooth sheet for Re⁡(s)>1\operatorname{Re}(s) > 1, a>0a > 0, climbing steeply as a→0+a \to 0^+ toward the pole at a=0a = 0. Drag to rotate; the surface is sampled by compiling the expression to a native function (no per-point symbolic evaluation), so it stays responsive.

ζ(s, a) over s ∈ [2,5], a ∈ (0,3]

source · editable

Here xx is ss and yy is aa. Push aa toward 00 and the sheet lifts off — the n=0n = 0 term (a)−s(a)^{-s} blows up. The generalized Zeta drops exactly that term, so Zeta(s, 0) is finite and equals ζ(s)\zeta(s) — the one place the two functions genuinely disagree.

On the GPU ​

The same surface with gpu set evaluates its grid in a WebGPU compute shader instead of on the CPU — HurwitzZeta compiles to the zetaWGSL kernel via compute-engine's WGSL target. It falls back to the CPU path automatically where WebGPU is unavailable, so the two look identical; the difference is a denser grid stays interactive. (Look for the GPU badge under the figure.)

The third argument, as a dial ​

A surface fixes one slice; a Manipulate hands you the rest. LerchPhi(z, s, a) has three arguments, and a surface can only show two — so sweep the one it cannot, and the sheet deforms as zz walks across its disk. The same works for the order of the polylogarithm, which is the exponent every term is raised to.

At z=0z = 0 only the n=0n = 0 term survives and the sheet is just a−sa^{-s}; push zz toward 11 and the higher terms pile on until it becomes the Hurwitz zeta itself. Push it the other way and the alternating series pulls the sheet down instead.

Turn the same surface ninety degrees — plot it over zz and aa, and put the order ss on the dial:

Raising ss flattens it: every term carries (n+a)−s(n+a)^{-s}, so a larger exponent crushes the tail and leaves the n=0n = 0 term standing alone.

ζ(s, a) evaluated on the GPU (denser grid)

source · editable

The parent: LerchPhi ​

Both of these sit inside the Lerch transcendent

Φ(z,s,a)  =  ∑n=0∞zn(n+a)s,\Phi(z, s, a) \;=\; \sum_{n=0}^{\infty} \frac{z^n}{(n+a)^s},

which is ζ(s,a)\zeta(s, a) at z=1z = 1 and the polylogarithm Li⁡s(z)=z Φ(z,s,1)\operatorname{Li}_s(z) = z\,\Phi(z, s, 1) along a=1a = 1. @enumeratio/analytic provides LerchPhi; the znz^n factor gives geometric convergence for ∣z∣<1|z| < 1, so the series is summed directly.

LerchPhi reductions

InLerchPhi(1,2,1)\mathrm{LerchPhi}(1, 2, 1)Outπ26\frac{π^2}{6}InLerchPhi(z,0,a)\mathrm{LerchPhi}(z, 0, a)Out11−z\frac{1}{1-z}
source · editable

The first is Φ(1,2,1)=ζ(2)=π2/6\Phi(1, 2, 1) = \zeta(2) = \pi^2/6; the second is Φ(z,0,a)=1/(1−z)\Phi(z, 0, a) = 1/(1-z).

Its surface Φ(z, 2, a) — sweeping zz (as xx) and aa (as yy) — is a heavier per-point cost than zeta (a full series each), which makes it a good stress test for the GPU: a 256×256 grid takes ~4 ms on the GPU versus ~270 ms on the CPU here (~65×), because every pixel runs its own series in parallel.

Φ(z, 2, a) on the GPU

source · editable

Where it gets beautiful ​

Fix ss instead and let aa range over the whole complex plane, and ζ(s,a)\zeta(s, a) becomes a phase portrait full of pinwheels, zeros, and poles.

→ ζ on the GPU: a phase portrait — the whole Euler–Maclaurin kernel running per pixel, in real time.