HurwitzZeta¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
HurwitzZeta[s, a]
is the Hurwitz zeta function zeta(s, a) = Sum_{k>=0} (k + a)^-s.
Notes
Identical to Zeta\[s, a\] for Re(a) \> 0, but built on the principal-branch power (k + a)^-s, so it differs from Zeta for non-positive real a and has poles at a = 0, -1, -2, ... . HurwitzZeta\[s, 1\] is Zeta\[s\], HurwitzZeta\[s, 1/2\] is (2^s - 1) Zeta\[s\], and a positive integer a reduces to Zeta\[s\] minus a finite power sum. A non-positive integer a gives ComplexInfinity for positive integer s and the Bernoulli-polynomial value for non-positive integer s. Real, complex, machine and arbitrary-precision (MPFR) arguments evaluate numerically via an Euler-Maclaurin kernel. Listable.Examples (12)¶
Every input below was run against the current Mathilda build and its output recorded.
Basic examples (3)¶
In[1]:= HurwitzZeta[s, 1/2]
Out[1]= (-1 + 2^s) Zeta[s]
In[2]:= HurwitzZeta[3, -3.5]
Out[2]= 0.0307784
In[3]:= HurwitzZeta[-3, -2]
Out[3]= -1079/120
Applications (9)¶
Reduces to Zeta[2] when the second argument is 1
The half-integer shift: (2^s - 1) Zeta[s]
Positive integer second argument: Zeta[4] minus a finite power sum
At a non-positive integer a, -BernoulliB[4, -2]/4
Principal powers keep the pole at a = -1
Machine reals, threaded over a list
Complex s and a on the machine kernel
Arbitrary precision via arb
Principal versus symmetric powers for negative a
Algorithm¶
Mathilda -- the Hurwitz zeta function.
defined elsewhere by analytic continuation. HurwitzZeta agrees with the two-argument Zeta for Re(a) > 0, but unlike Zeta it sums the principal branch powers (k+a)^-s rather than ((k+a)^2)^(-s/2). The consequences:
- the two functions disagree for non-positive real a, and
- HurwitzZeta retains the singular summands that Zeta discards, so it has
poles at a = 0, -1, -2, ... .
The evaluator routes each kind of argument to the cheapest exact or fastest numeric path:
s == 1 (exact) -> ComplexInfinity (pole, for any a)
a == 1 -> Zeta[s] (Riemann closed forms)
a == 1/2 -> (2^s - 1) Zeta[s]
a positive integer m >= 2 -> Zeta[s] - Sum_{k=1}^{m-1} k^-s
a non-positive integer:
s positive integer -> ComplexInfinity (pole)
s non-positive integer -> -BernoulliB[1-s, a]/(1-s) (polynomial)
any inexact operand -> Euler-Maclaurin complex-MPFR kernel
everything else -> stays symbolic (return NULL)
MPFR has no Hurwitz zeta, so the numeric kernel is implemented here from the Euler-Maclaurin summation formula (DLMF 25.11.5):
zeta(s,a) = Sum_{k=0}^{N-1} (a+k)^-s
+ (a+N)^(1-s)/(s-1)
+ 1/2 (a+N)^-s
+ Sum_{j>=1} B_{2j}/(2j)! (s)_{2j-1} (a+N)^(-s-2j+1)
with (s)_{2j-1} the rising factorial. N grows with the working precision and
kernel uses the principal branch for every (a+k)^-s, which is exactly the HurwitzZeta convention. (The structure mirrors src/special_functions/zeta.c; the self-contained Bernoulli cache and complex-MPFR toolkit are replicated here so the two files stay independent.)
Attributes: Listable, NumericFunction, Protected.
Implementation notes¶
Algorithm. builtin_hurwitzzeta handles HurwitzZeta[s, a] = Sum_{k>=0} (k+a)^{-s}, summing principal-branch powers (so, unlike two-argument Zeta, it keeps poles at a = 0, -1, -2, …). Dispatch order: (1) the machine-scalar gate sf_machine_scalar_args — for a machine-precision call, sf_hurwitz_r (real) or sf_hurwitz_c (complex s and/or a) from sf_machine_zeta.c answers when s ≠ 1, Re s ≥ 1/2 and Re a > 0: Euler–Maclaurin with each k + a formed by an exact TwoSum and its power corrected to first order, declining a complex sum whose terms exceed 16× its value; a = 1 is delegated to the Riemann kernel. (2) Exact reductions when neither operand is inexact: s == 1 → ComplexInfinity; a == 1 → Zeta[s]; a == 1/2 → (2^s − 1) Zeta[s]; positive integer a = m → Zeta[s] − Σ_{k=1}^{m−1} k^{−s} (cap HZ_HURWITZ_A_CAP = 100000); a non-positive integer a gives ComplexInfinity for positive integer s and the entire value −BernoulliB[1−s, a]/(1−s) for non-positive integer s. (3) Numeric (hz_numeric): above machine precision arb's acb_dirichlet_hurwitz via flint_num_hurwitz_zeta; otherwise (and on an arb decline) the complex-MPFR Euler–Maclaurin kernel hz_hurwitz_cx (head sum, (a+N)^{1−s}/(s−1) and ½(a+N)^{−s} corrections, Bernoulli tail truncated at its optimal term). A head term k + a = 0 with Re s > 0 signals the pole and returns ComplexInfinity.
Data structures. Expr; a self-contained mpq_t Bernoulli cache and the alias-safe complex-MPFR toolkit hcx; the shared double kernels and ZM_B2K_FACT table in sf_machine_zeta.c. ND: binary kernel NDKB_HurwitzZeta (REG_B) whose real and complex arms both call sf_hurwitz_c, so packed and visible-NDArray arguments are evaluated on the buffer, bit-identical to the scalar path. Compile[] lowers HurwitzZeta[s, a] at scalar and rank-1 array shapes, real and complex (Compiled -> True).
Complexity / limits. Machine values ≈ 0.3 µs real, ≈ 1 µs complex. The Euler–Maclaurin head-term count and correction depth grow with precision and |s|; arbitrary-precision cost is arb's. Re s < 1/2 at machine precision is computed on the MPFR path. Known gap: for real s and negative non-integer real a with non-integer s (where the principal value is complex) the MPFR path returns only the real part. Precision follows the minimum over inexact leaves, floored at machine. Attributes: Listable, NumericFunction, Protected.
Attributes: Listable, NumericFunction, Protected.
References¶
- DLMF §25.11 — the Hurwitz zeta function ζ(s,a) = Sum_{k>=0} (k+a)^{-s} and the Euler–Maclaurin summation formula 25.11.5.
- Source:
src/special_functions/hurwitzzeta.c - Specification:
docs/spec/builtins/special-functions.md - Tests:
tests/test_compile.c - Tests:
tests/test_flint_bridge.c - Tests:
tests/test_hurwitzzeta.c - Tests:
tests/test_integrate_intrep.c
Notes & additional examples¶
Notes¶
HurwitzZeta[s, a] = Σ_{k≥0} (k+a)^(−s), continued to alls ≠ 1. Unlike two-argumentZeta, it uses principal-branch powers. It therefore keeps poles ata = 0, -1, -2, …and differs fromZeta[s, a]for negative reala.- Exact reductions:
s == 1givesComplexInfinity,a == 1givesZeta[s],a == 1/2gives(2^s - 1) Zeta[s], and a positive integeragivesZeta[s]minus a finite power sum. At a non-positive integera, the result isComplexInfinityfor positive integersand the Bernoulli-polynomial value for non-positive integers. - Numeric surfaces: machine-precision real and complex arguments with
Re s ≥ 1/2andRe a > 0use one Euler–Maclaurindoublekernel, shared by the scalar, packed/NDArrayandCompile[]paths (scalar and array, real and complex). Higher precision goes to arb'sacb_dirichlet_hurwitz, and other inputs go to a complex-MPFR Euler–Maclaurin kernel. - Known gap: for a negative non-integer real
awith non-integer reals(e.g.HurwitzZeta[-2.5, -0.5]), the principal value is complex, but only its real part is returned. - Attributes:
Listable,NumericFunction,Protected. - See also:
Zeta,LerchPhi,PolyGamma,BernoulliB.