The Riemann Hypothesis (1859) states that all non-trivial zeros of the Riemann zeta function ζ(s) have real part ½. First proposed by Bernhard Riemann in his 1859 memoir, it is one of Hilbert's 23 problems (1900) and a Clay Millennium Prize problem ($1,000,000).
The function extends meromorphically to all of ℂ via the functional equation ζ(s) = 2sπs−1 sin(πs/2) Γ(1−s) ζ(1−s). Trivial zeros occur at s = −2, −4, −6, …. Non-trivial zeros lie in the critical strip 0 < Re(s) < 1. The RH asserts they all lie on the critical line Re(s) = ½.
The Prime Number Theorem acquires its sharpest error bound: π(x) = Li(x) + O(√x log x). Hundreds of results in analytic number theory currently depend on the assumption of RH. The distribution of prime numbers—and by extension, the security of RSA cryptography—is fundamentally constrained by the location of zeta zeros.
Current Status: Over 1013 zeros verified on the critical line (Platt & Trudgian, 2021). No counterexample found. The $1,000,000 Clay prize remains unclaimed.
On the critical line, the Hardy Z-function Z(t) = eiθ(t)ζ(½+it) is real-valued. Its zeros correspond to ζ zeros. The Riemann–Siegel formula computes Z(t) efficiently:
where N = ⌊√(t/(2π))⌋ and R(t) is the Gabcke remainder series with coefficients Ck(u). Our implementation uses M = 10 remainder terms, providing ~10−14 accuracy for t > 10.
from rh_numerical.zeta import riemann_siegel_Z
r = riemann_siegel_Z(100.0, M=10)
# r.Z = Z(100), r.theta = θ(100), r.N = 3 main-sum terms
| t | Z(t) | θ(t) | N |
|---|---|---|---|
| 10 | −1.570 | −3.067 | 1 |
| 100 | 2.690 | 87.972 | 3 |
| 1000 | 0.998 | 2034.546 | 12 |
| 10000 | 1.479 | — | 39 |
Zero Location: Evaluate Z(t) on a grid (spacing δ = 0.1), detect sign changes, refine via bisection. Gram Points gn satisfy θ(gn) = nπ and typically bracket one zero each. Turing's Method (1953): Verifies no zeros are missed by tracking discrepancy D(t) = Nexpected(t) − Nfound(t) against the Lehman bound |∫S(t)dt| ≤ 1.91 + 0.114 log(t/2π).
from rh_numerical.zeros import find_zeros_up_to, N_T_expected
zeros = find_zeros_up_to(100.0, step=0.1, M=10)
# Found 29 zeros; N(100) ≈ 29.00; discrepancy = 0.00
Riemann–von Mangoldt Formula: N(T) = (T/2π)log(T/2π) − T/2π + 7/8 + S(T) + O(1/T). Zeros become denser with height: mean density ~ (1/2π)log(T/2π).
RH admits 100+ equivalent forms. Four computationally checkable criteria:
| Criterion | Statement |
|---|---|
| Robin (1984) | σ(n) < eγ n log log n for n > 5040 |
| Lagarias (2002) | σ(n) ≤ Hn + eHn log Hn |
| Li (1997) | λn = ∑ρ[1−(1−1/ρ)n] > 0 ∀n |
| Mertens (weak) | M(x) = ∑μ(n) = O(x½+ε) |
from rh_numerical.equivalences import robin_check, li_criterion_check
holds, sigma, bound = robin_check(10080) # σ=39312, ratio=0.9858 ✓
li = li_criterion_check(10) # All λ_n > 0 ✓
Montgomery–Dyson (1972): Pair correlation of Riemann zeros matches GUE eigenvalue statistics: R2(x) = 1 − sinc2(πx). Wigner surmise: P(s) = (32/π2)s2e−4s2/π for GUE (β=2). Zeros exhibit quadratic level repulsion P(s) ∝ s2 as s → 0, in contrast to Poisson (no repulsion) or GOE (linear, β=1). Spectral rigidity: Number variance Σ2(L) ~ (1/π2)log L, far more rigid than Poisson Σ2(L) = L.
The imaginary parts γn of zeta zeros are eigenvalues of a self-adjoint (Hermitian) operator—describing a quantum chaotic system without time-reversal symmetry (unitary class, β = 2). The Berry–Keating Hamiltonian H = ½(xp+px) and Connes–Moscovici prolate operator are leading candidates.
Ensemble Simulators: generate_gue(N), generate_goe(N), generate_gse(N) produce eigenvalue distributions from the three classical Gaussian ensembles. Tracy–Widom: CDF/PDF for β=1,2,4 describing the fluctuations of the largest eigenvalue. Dyson β Estimation: Log-log regression on small spacings estimates the repulsion exponent; bootstrap provides 95% confidence intervals. Bayesian RH Test: Computes Bayes factor comparing H0 (β=2, RH true) vs. H1 (β≠2, RH false).
from rh_advanced.ensembles import generate_gue, estimate_dyson_beta, ks_test_gue
gue = generate_gue(500, seed=42)
beta = estimate_dyson_beta(spacings) # {beta: 2.03, ci_95: (1.92, 2.14)}
ks = ks_test_gue(spacings) # {D_statistic: 0.04, reject_gue: False}
SpacingVAE: Variational Autoencoder trained on zero spacings generates synthetic spacing distributions statistically indistinguishable from GUE. NeuralBetaEstimator: Feed-forward network predicts β directly from spacing histograms, trained on synthetic ensemble data. GaussianProcessZeta: GP regression with RBF kernel interpolates Z(t) with uncertainty estimates—useful for adaptive sampling and anomaly detection.
from rh_advanced.ml_layer import SpacingVAE, NeuralBetaEstimator
vae = SpacingVAE(latent_dim=4, hidden_dim=32)
vae.fit(spacing_windows, epochs=300)
synthetic = vae.generate(1000) # statistically ~ GUE
nn = NeuralBetaEstimator(); nn.fit(n_train=3000)
beta_nn = nn.predict(spacings) # neural β estimate
Parallel Z(t): parallel_evaluate_Z() distributes across CPU cores via ProcessPoolExecutor. Adaptive Zero Finding: Step-size adapts to Z(t) magnitude—fine near extrema, coarse near zeros. MemoizedZeta: LRU cache with 100K entries provides 90%+ hit rates for repeated evaluations. Benchmark: C++ achieves 10–100× speedup over Python for large-scale zero verification.
The Connes–Consani–Moscovici (2025) zeta spectral triple constructs a Galerkin matrix whose eigenvalues converge to Riemann zeros. Our implementation computes the finite-dimensional approximation and compares predicted zeros with known values. LMFDB Integration: Access to 103+ billion Platt-verified zeros. Dirichlet L-functions: L(s,χ) computation for GRH exploration.
from rh_advanced.connes_lmfdb import connes_galerkin_matrix, dirichlet_L
result = connes_galerkin_matrix(cutoff=19.0, N_max=60)
# Mean relative error vs actual zeros: ~0.05
Production FastAPI server with 26 endpoints at http://localhost:8420.
| Category | Endpoints |
|---|---|
| Zeta | /zeta/t/{t}, /zeta/s, /zeta/theta/{t}, /zeta/batch |
| Zeros | /zeros/search, /zeros/verify, /zeros/gram |
| Equivalences | /equivalence/robin, /lagarias, /li, /mertens |
| Statistics | /stats/gue |
| Primes | /primes/pi, /primes/psi, /primes/gaps |
| Advanced | /advanced/number-model, /dyson-analysis, /connes-operator, /ml-beta, /lmfdb-zeros, /dirichlet-L |
python -m rh_services.api
curl "http://localhost:8420/zeta/t/100.0"
curl "http://localhost:8420/advanced/number-model?t_max=300"
Header-optimized C++17 library in cpp/. CMake build with OpenMP, AVX2/FMA. The Riemann–Siegel main sum uses OpenMP #pragma omp parallel for. Gabcke coefficients via Haselgrove polynomial evaluation. Performance: Z(100) in 0.3 μs (30× Python), Z(104) in 30 μs (100× Python).
cd cpp && mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DRIEMANN_USE_OPENMP=ON
make -j$(nproc)
./test_riemann && ./bench_riemann
Seven interactive notebooks for browser-based exploration:
| # | Notebook | Content |
|---|---|---|
| 1 | Zeta Function | Z(t), θ(t), ζ spiral, Euler product |
| 2 | Zero Finding | Sign-change detection, Gram's law, Turing |
| 3 | GUE Statistics | Pair correlation, Wigner, β repulsion, KS |
| 4 | Equivalences | Robin, Lagarias, Li, Mertens criteria |
| 5 | Prime Analytics | π(x), ψ(x), prime gaps, crypto utility |
| 6 | Number Modelling | 5-layer framework, Dyson BM, Bayesian test |
| 7 | v2.0 Suite | VAE, Neural β, Connes operator, Dirichlet L |
Open any notebook: github.com/twomathematicians-code/riemann-hypothesis/tree/master/notebooks
git clone https://github.com/twomathematicians-code/riemann-hypothesis.git
cd riemann-hypothesis
pip install -r rh_services/requirements.txt
python -m rh_numerical.main --quick
python -m rh_services.api # → http://localhost:8420
Dependencies: Python 3.10+, NumPy, SciPy, FastAPI, uvicorn, Pydantic. Optional: mpmath (high-precision), matplotlib (plots), C++17 compiler + CMake (C++ library). Docker: docker build -t rh-services -f rh_services/Dockerfile . && docker run -p 8420:8420 rh-services
riemann-hypothesis/
├── rh_numerical/ Python numerical toolkit (6 modules)
│ ├── zeta.py Riemann–Siegel Z(t), θ(t), Euler product
│ ├── zeros.py Zero finding, Gram points, Gram's law
│ ├── turing.py Turing verification, S(T), Lehman bounds
│ ├── equivalences.py Robin, Lagarias, Li, Mertens
│ ├── correlations.py Pair correlation, GUE stats, Wigner
│ └── visualization.py 10+ plot types + dashboard
├── rh_advanced/ Advanced computing framework (7 modules)
│ ├── ensembles.py GUE/GOE/GSE, Tracy–Widom, Dyson β
│ ├── predictive.py Bayesian RH test, anomaly detection
│ ├── ml_layer.py VAE, Neural β, Gaussian Process
│ ├── dyson_brownian.py Dyson BM, Log-gas MC, TW MLE
│ ├── connes_lmfdb.py Connes operator, LMFDB, Dirichlet L
│ ├── hpc.py Parallel, adaptive, memoized
│ └── number_model.py 5-layer NumberModel synthesis
├── rh_services/ REST API service layer (8 files)
├── cpp/ C++17 high-performance library
├── notebooks/ 7 Colab/Kaggle notebooks
└── docs/ GitHub Pages + Handbook
| Metric | Result |
|---|---|
| Zeros at T = 100 | 29 (matches N(100)) |
| Turing verification (T = 500) | ✓ Passed |
| Robin's inequality (n ≤ 50,000) | No violations |
| Li coefficients λ1…λ10 | All > 0 |
| Dyson β (least squares) | ~2.0 (GUE predicts 2) |
| Dyson β (MLE) | ~2.0 (95% CI contains 2) |
| Bayesian P(RH true | data) | > 0.99 |
| KS test vs. GUE | Fail to reject (D < critical) |
| Anomalies (off-line zero screening) | None beyond GUE expectation |