FLINT3.7.0-dev
Algorithm

Zeros of the Riemann zeta function

Cost
O(t)O(\sqrt{t}) operations per evaluation of Z(t)Z(t) by the Riemann–Siegel formula; Platt's method costs O(t+Nlog⁡N)O(\sqrt{t} + N \log N) for NN grid points, amortised over thousands of zeros.

The nontrivial zeros of ζ(s)\zeta(s) with positive imaginary part are numbered ρn=βn+iγn\rho_n = \beta_n + i\gamma_n by increasing γn\gamma_n (with multiplicity). FLINT computes them with proof: it finds sign changes of the real function Z(t)Z(t), and uses Turing's method to prove that the number of zeros up to a given height equals the number of sign changes found, so that every zero in the range is simple, lies on the critical line, and has a known index. The approach follows the implementation in mpmath by Arias de Reyna [Ari2012], with Platt's method [Pla2017] for many zeros at large height.

The Hardy Z-function#

The Riemann–Siegel theta function θ(t)=arg⁡(π−it/2Γ(14+it2))\theta(t) = \arg\bigl(\pi^{-it/2}\Gamma(\tfrac14 + \tfrac{it}{2})\bigr), defined by continuity with θ(0)=0\theta(0) = 0, makes

Z(t)=eiθ(t)ζ(12+it)Z(t) = e^{i\theta(t)} \zeta(\tfrac12 + it)

real for real tt, with ∣Z(t)∣=∣ζ(12+it)∣|Z(t)| = |\zeta(\frac12 + it)|. Every sign change of ZZ is a zero of ζ\zeta on the critical line. The number of zeros with 0<γ≤t0 < \gamma \le t is

N(t)=θ(t)π+1+S(t),S(t)=1πarg⁡ζ(12+it),N(t) = \frac{\theta(t)}{\pi} + 1 + S(t), \qquad S(t) = \frac{1}{\pi} \arg \zeta(\tfrac12 + it),

where the argument is defined by continuous variation from 22 to 2+it2 + it to 12+it\frac12 + it, and S(t)=O(log⁡t)S(t) = O(\log t) with explicit bounds [Tru2014]. acb_dirichlet_hardy_theta evaluates θ(t)\theta(t) with the log-gamma function, and acb_dirichlet_hardy_z evaluates Z(t)Z(t); for Dirichlet L-functions the same definitions apply with the root number in θ\theta.

Gram points and Gram blocks#

The nn-th Gram point gng_n is the solution of θ(gn)=nπ\theta(g_n) = n\pi (g−1≈9.67g_{-1} \approx 9.67, g0≈17.85g_0 \approx 17.85), computed by acb_dirichlet_gram_point from an asymptotic formula in terms of the Lambert W function, refined by Newton's method. Since θ(t)≈t2log⁡t2π−t2−π8\theta(t) \approx \frac{t}{2}\log\frac{t}{2\pi} - \frac{t}{2} - \frac{\pi}{8}, the Gram points are spaced about 2π/log⁡(t/2π)2\pi/\log(t/2\pi) apart, like the zeros. A Gram point is good if (−1)nZ(gn)>0(-1)^n Z(g_n) > 0.

Gram's law is the observation that ZZ usually changes sign exactly once between consecutive Gram points; it locates correctly the first 126 zeros. A Gram block is an interval [gn,gn+k)[g_n, g_{n+k}) between good Gram points with no good Gram points inside; Rosser's rule says that a Gram block of length kk contains kk zeros, and it holds for all Gram blocks containing the first 13999526 zeros. Both fail infinitely often, but they are true often enough to guide the search: acb_dirichlet_isolate_hardy_z_zero uses Gram's law up to n=126n = 126, Rosser's rule up to n=13999526n = 13999526 (where it is known to hold), and Turing's method beyond.

Turing's method#

Counting sign changes gives lower bounds for N(t)N(t); Turing's method gives the matching upper bound from the average of S(t)S(t) [Tur1953].

Theorem 1 (Turing, Lehman, Trudgian). For t2>t1≥168πt_2 > t_1 \ge 168\pi,

∣∫t1t2S(t) dt∣≤2.067+0.059log⁡t2.\left| \int_{t_1}^{t_2} S(t)\,dt \right| \le 2.067 + 0.059 \log t_2.

This is the bound of [Tru2011], which improves those of [Leh1970] and [Bre1979]. If ZZ has at least the expected number of sign changes in a run of consecutive Gram blocks after gng_n (each block satisfying Rosser's rule), then SS cannot be much larger than 00 at gng_n without violating the integral bound, which gives N(gn)≤n+1N(g_n) \le n + 1; a run of blocks before gpg_p gives N(gp)≥p+1N(g_p) \ge p + 1 symmetrically [Bre1979]. Together with the sign changes counted in [gn,gp)[g_n, g_p), this proves that N(gp)−N(gn)=p−nN(g_p) - N(g_n) = p - n and that all zeros in the range are simple and on the line.

acb_dirichlet_turing_method_bound returns the number of good Gram blocks needed at height gpg_p: the ceiling of the smaller of 0.0061log⁡2gp+0.08log⁡gp0.0061 \log^2 g_p + 0.08 \log g_p and 0.0031log⁡2gp+0.11log⁡gp0.0031 \log^2 g_p + 0.11 \log g_p, derived from the two integral bounds. The isolation routines scan Gram blocks outward from the target until enough consecutive blocks satisfying Rosser's rule are found on each side, subdividing blocks with missing sign changes until all expected zeros are separated. acb_dirichlet_zeta_nzeros computes N(t)N(t) exactly in the same way, and acb_dirichlet_backlund_s derives S(t)S(t) from it.

The Riemann–Siegel formula#

Euler–Maclaurin summation costs O(t)O(t) operations at height tt (see Euler–Maclaurin summation); the Riemann–Siegel formula needs O(t)O(\sqrt{t}). With a=t/2πa = \sqrt{t/2\pi}, N=⌊a⌋N = \lfloor a \rfloor and p=1−2(a−N)p = 1 - 2(a - N), for s=σ+its = \sigma + it,

ζ(s)=R(s)+X(s)R‾(1−sˉ),X(s)=πs−1/2Γ((1−s)/2)Γ(s/2),\zeta(s) = \mathcal{R}(s) + X(s) \overline{\mathcal{R}}(1-\bar s), \qquad X(s) = \pi^{s-1/2} \frac{\Gamma((1-s)/2)}{\Gamma(s/2)},
R(s)=∑k=1N1ks+(−1)N−1Ua−σ[∑k=0KCk(p)ak+RSK],\mathcal{R}(s) = \sum_{k=1}^N \frac{1}{k^s} + (-1)^{N-1} U a^{-\sigma} \left[ \sum_{k=0}^K \frac{C_k(p)}{a^k} + RS_K \right],

where UU is a unimodular factor and the coefficients Ck(p)C_k(p) are combinations of derivatives of F(p)=cos⁡(π(p2/2+3/8))/cos⁡(πp)F(p) = \cos(\pi(p^2/2 + 3/8))/\cos(\pi p) with coefficients dj(k)d_j^{(k)} depending on σ\sigma. Arias de Reyna [Ari2011] gives recurrences for the dj(k)d_j^{(k)} (acb_dirichlet_zeta_rs_d_coeffs), the derivatives F(j)(p)F^{(j)}(p) by power series division (acb_dirichlet_zeta_rs_f_coeffs), and a rigorous bound for RSKRS_K (Theorem 4.2 of [Ari2011], acb_dirichlet_zeta_rs_bound) valid for tt large enough relative to KK. The asymptotic series converges only up to K=O(t)K = O(t) terms, which limits the attainable precision at a given height; acb_dirichlet_zeta uses the formula from ∣t∣≥24p3/2|t| \ge 24 p^{3/2}, where it always suffices.

The main cost is the sum of N≈t/2πN \approx \sqrt{t/2\pi} powers k−sk^{-s}. It is computed with the sieve of acb_dirichlet_powsum_sieved, or, when the required absolute accuracy (about p+10−log⁡2tp + 10 - \log_2 t bits after the point) fits, with dfloat_powsum_sieved in double-word floating-point arithmetic with rigorous error bounds, which is several times faster. Derivatives for acb_dirichlet_zeta_jet_rs are obtained by a finite difference.

Isolating and refining zeros#

Given an interval (a,b)(a, b) in which ZZ changes sign exactly once, _acb_dirichlet_refine_hardy_z_zero locates the zero. The value of ZZ near a zero only needs to be known to about p−log⁡2tp - \log_2 t bits after the binary point to determine its sign, so ZZ is evaluated at p+12p + 12 bits while the iterates carry p+log⁡2t+8p + \log_2 t + 8 bits.

  • Below 4log⁡2t+404\log_2 t + 40 bits, the Illinois variant of the secant method is used, which converges superlinearly while always keeping a bracket. When an iterate falls so close to the zero that the sign of ZZ cannot be determined, the zero is bracketed by evaluating at a quarter of the tolerance on either side. Within this range, from log⁡2t+96\log_2 t + 96 bits on, the zero is first refined in the same way to about half the precision, where ZZ is much cheaper, and then finished by one secant step and sign checks at the target precision, four evaluations in total.
  • From 4log⁡2t+404 \log_2 t + 40 bits, Newton's method with acb_dirichlet_hardy_z of length 2 is used.

The zeros of a range are refined in parallel with flint_parallel_do.

Platt's method#

At large height, each evaluation of ZZ by the Riemann–Siegel formula costs O(t)O(\sqrt{t}), and isolating nn zeros needs several evaluations per zero. Platt's method [Pla2011], [Pla2017], building on the FFT-based approach of Odlyzko and Schönhage [OS1988] and its rigorous version by Booker [Boo2006], evaluates at once the real function

F(t)=Λ(t)eπt/4,Λ(t)=π−it/2Γ(1/2+it2)ζ(12+it),F(t) = \Lambda(t) e^{\pi t / 4}, \qquad \Lambda(t) = \pi^{-it/2} \Gamma\left(\tfrac{1/2+it}{2}\right) \zeta\left(\tfrac12 + it\right),

which has the same zeros as Z(t)Z(t), on a grid of N=ABN = AB points T−B/2+k/AT - B/2 + k/A around a height TT:

  1. The product of F(T+t)F(T + t) with a Gaussian e−t2/(2h2)e^{-t^2/(2h^2)} has a Fourier transform that is a sum over j≤Jj \le J of terms j−1/2j^{-1/2} times smooth functions of x−log⁡(jπ)/(2π)x - \log(j\sqrt\pi)/(2\pi). The terms are grouped by the grid point m/Bm/B nearest to log⁡(jπ)/(2π)\log(j\sqrt\pi)/(2\pi) and expanded in Taylor series of length KK around it, which turns the transform into KK convolutions of the sums Sm,k=∑jj−1/2(log⁡(jπ)/(2π)−m/B)kS_{m,k} = \sum_j j^{-1/2} (\log(j\sqrt\pi)/(2\pi) - m/B)^k with tables of Gaussian-gamma factors.
  2. The convolutions are computed with fast Fourier transforms of length NN (acb_dft and gr_dft), summed in the frequency domain, and transformed back, which gives FF on the whole grid.
  3. Every truncation is bounded rigorously: the Dirichlet series at JJ (Lemma B.1 of [Pla2017]), the Taylor expansion at KK (Lemma B.2), the aliasing of the discrete transform (Lemmas A.5–A.11), and the Gaussian window (Lemma 3.2), with the bounds acb_dirichlet_platt_lemma_*.
  4. Between grid points, FF is evaluated by Gaussian-windowed Whittaker–Shannon interpolation of the grid values, with rigorous bounds for the truncation of the interpolation sum and for the window (acb_dirichlet_platt_ws_interpolation); this is used to find sign changes between grid points and to refine zeros.

The sums Sm,kS_{m,k} over j≤J≈Tj \le J \approx \sqrt{T} dominate the cost; acb_dirichlet_platt_multieval computes them in double-word arithmetic when the precision allows (acb_dirichlet_platt_use_dfloat), and distributes the work over threads. The parameters AA, BB, hh, JJ, KK, the interpolation parameters and the odd integers σ\sigma of the error bounds are chosen by fitted formulas in terms of log⁡T\log T for 104≤n<103710^4 \le n < 10^{37}. One multi-evaluation isolates thousands of zeros, and the per-zero cost after it is about 10 ms at n=1015n = 10^{15}; _acb_dirichlet_hardy_z_zeros_use_platt compares measured costs of both methods to decide which one acb_dirichlet_hardy_z_zeros uses (Platt's method from n=1011n = 10^{11} when enough zeros are requested). The accuracy of the grid is limited by the parameters, which depend only on the height, to about 150–250 bits; higher precision is obtained by refining each zero with the Riemann–Siegel formula.

The secondary zeta function#

Z(s)=∑n≥1γn−s\mathcal{Z}(s) = \sum_{n \ge 1} \gamma_n^{-s} converges for Re⁡(s)>1\operatorname{Re}(s) > 1 and extends meromorphically to C\mathbb{C}. Arias de Reyna [Ari2020] writes it as A(s)−P(s)+E(s)−S(s)A(s) - P(s) + E(s) - S(s), where the terms are given by convergent series and integrals involving the gamma function and the prime powers, depending on a free parameter a>0a > 0. acb_dirichlet_secondary_zeta implements this decomposition with rigorous bounds for the tails of AA, PP and SS (replacing the heuristic bounds of [Ari2020]), without assuming the Riemann hypothesis.

Use in FLINT#

Referenced from#

References#

Cite this page

The FLINT team, “Zeros of the Riemann zeta function,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/special-functions/zeta-zeros.html (generated 2026-11-02).