teal-sea / zeta-labstate of record · compiled 14 Aug 2026 · revision 9ebdea0 · source

Library · docs/00-orientation.md

Orientation

4,576 words · 406 lines · source

The short version. The Riemann zeta function starts life as the sum 1 + 1/2^s + 1/3^s + ..., which converges only when Re(s) > 1, but extends uniquely to a function defined on the whole complex plane except for a single pole at s = 1. That extended function has zeros. Some are boring and fully understood (s = -2, -4, -6, ...); the rest all lie in the strip 0 ≤ Re(s) ≤ 1, and the Riemann Hypothesis (RH) asserts that every one of them has real part exactly 1/2. This is not a curiosity about a special function: the zeros are, via an exact formula, the complete correction term for the count of prime numbers, and RH is precisely equivalent to the statement that the count of primes below x deviates from its smooth approximation Li(x) by no more than about √x log x. RH has been open since 1859. This repository is an instrument for seeing all of this happen numerically — not an attempt to prove it.


1. The object

For Re(s) > 1 the series and the product below both converge, and Euler's identity says they are equal:

             ∞
   ζ(s)  =   Σ  n^(-s)   =   Π  ( 1 - p^(-s) )^(-1)        (Re(s) > 1)
            n=1              p prime

That identity is the whole reason zeta matters. The left side knows about all integers; the right side knows only about primes. Unique factorization is what glues them together — expand each factor as a geometric series 1 + p^-s + p^-2s + ..., multiply out, and every n^-s appears exactly once, because every n has exactly one prime factorization. So any analytic fact about ζ is, in disguise, an arithmetic fact about primes.

The series diverges at s = 1 (it's the harmonic series) and everywhere left of it. But ζ has a unique analytic continuation to C \ {1}, with a simple pole of residue 1 at s = 1 (docs/01-sums-integrals-and-continuation.md builds this by hand). The continuation satisfies a functional equation, cleanest in terms of the completed zeta function

   ξ(s) = (1/2) · s · (s-1) · π^(-s/2) · Γ(s/2) · ζ(s),        ξ(s) = ξ(1-s)

ξ is entire, and the reflection s ↦ 1-s is a symmetry of it about the vertical line Re(s) = 1/2. (You can check this numerically right now: zeta.core.functional_equation_defect returns |ξ(s) - ξ(1-s)|; at s = 0.3 + 7.1i I get about 10^-31 at 30-digit precision. The derivation is docs/03-functional-equation.md.)

The Γ(s/2) factor has poles at s = 0, -2, -4, ..., which forces ζ to vanish at s = -2, -4, -6, ... to keep ξ entire (s = 0 is absorbed by the s factor). Those are the trivial zeros. Everything else — the non-trivial zeros — must lie in the critical strip 0 ≤ Re(s) ≤ 1, since the Euler product shows ζ ≠ 0 for Re(s) > 1, and the functional equation reflects that into Re(s) < 0.

The first few non-trivial zeros sit at 1/2 ± 14.134725...i, 1/2 ± 21.022040...i, 1/2 ± 25.010858...i. There are 29 with imaginary part in (0, 100) and 649 in (0, 1000) (both checked against mpmath while writing this).

2. The statement

CONJECTURE (Riemann, 1859) — the Riemann Hypothesis. Every zero of ζ(s) with 0 ≤ Re(s) ≤ 1 satisfies Re(s) = 1/2.

Equivalently: after the substitution s = 1/2 + iz, the entire function Ξ(z) := ξ(1/2 + iz) has only real zeros. Equivalently again: ζ(s) ≠ 0 for Re(s) > 1/2.

Two things to be clear about. First, Riemann did not present this as a central goal; he remarked in passing that it was "very probable" and that after some fleeting attempts he had set the search for a proof aside. Second, RH says nothing about simplicity or spacing of the zeros — those are separate open questions (§5).

3. Why anyone cares

Let π(x) be the number of primes ≤ x, and Li(x) = ∫₂^x dt/log t the logarithmic integral.

THEOREM (Hadamard; de la Vallée Poussin, independently, 1896) — the Prime Number Theorem. π(x) ~ x / log x, equivalently π(x) ~ Li(x).

The proof turns on showing ζ(1 + it) ≠ 0 for all real t ≠ 0: the PNT is exactly the statement that zeta has no zeros on the edge of the critical strip.

That is the template for everything that follows. Where the zeros are controls how well the primes are distributed. The mechanism is von Mangoldt's explicit formula (1895): writing ψ(x) = Σ_{p^k ≤ x} log p for the weighted prime count,

   ψ(x)  =  x  -  Σ  x^ρ / ρ  -  log(2π)  -  (1/2)·log(1 - x^(-2))
                  ρ

summed over non-trivial zeros ρ in conjugate pairs. This is an identity, not an approximation (with the standard proviso that at a prime-power x the left side means the midpoint of the jump; docs/04-explicit-formula.md and zeta/explicit.py spell this out). Read it: the smooth main term is x; every zero ρ = β + iγ contributes an oscillating term of magnitude x^β / |ρ| and frequency γ in log x. A zero far to the right is a loud, slowly-decaying wave of error in the primes. So the size of the error term is governed by sup β over all zeros — and RH is exactly the statement sup β = 1/2, giving errors of size √x.

THEOREM (von Koch, 1901). RH holds if and only if π(x) = Li(x) + O(√x · log x). (Equivalently ψ(x) = x + O(√x (log x)²), or π(x) = Li(x) + O(x^(1/2+ε)) for every ε > 0.)

This is a genuine equivalence in both directions — RH is not merely sufficient for square-root error, it is necessary. So RH is a precise assertion about the regularity of the primes: they are as evenly distributed as a random-looking sequence could plausibly be, no worse than the square-root cancellation of a coin-flip model.

Concretely, at x = 10^10: π(x) = 455,052,511 and Li(x) ≈ 455,055,613.5. The discrepancy is about 3103 — under seven parts per million, and far inside √x log x / (8π) ≈ 91,617. (I recomputed all four numbers with mpmath/sympy while writing this. The √x log x/(8π) bound is Schoenfeld's 1976 refinement, valid under RH for x ≥ 2657 — commonly cited as such; check the source before leaning on the constants.)

A caution against over-reading numerics: Li(x) > π(x) for every x anyone has ever computed, which looks like a law. It isn't.

THEOREM (Littlewood, 1914). π(x) - Li(x) changes sign infinitely often.

No explicit crossing is known; the smallest known upper bound for one is astronomically large (the Skewes-number literature; figures around 10^316 are commonly cited, and I would verify the current record before quoting one). This is the single most useful cautionary tale in the subject: the first 10^10 cases can be unanimous and still wrong about the truth.

4. What is rigorously known

A ledger, all THEOREM unless marked otherwise.

Counting. (Riemann asserted, von Mangoldt proved, 1905.) The number N(T) of zeros with 0 < Im(ρ) < T satisfies

   N(T)  =  (T/2π)·log(T/2π)  -  T/2π  +  7/8  +  O(log T)

so the zeros get denser as you go up: mean spacing near height T is 2π / log(T/2π) (≈ 2.27 at T = 100, ≈ 1.24 at T = 1000). I checked the smooth part of the formula against exact zero counts at several heights up to T = 400; it was never off by more than 0.6 at the heights I sampled. (zeta/zeros.py implements the exact form of this identity, with the S(T) argument term, in N_of_T.)

Zeros on the line.

Note what this does not say. Even "99% of zeros on the line" would leave infinitely many possibly off it, and by §3 a single zero at β = 0.51 would already break RH.

Numerical verification.

Zero-free regions — the "how far right can a zero be?" question.

Look hard at that list, because it is the honest measure of the gap. Every known zero-free region touches the line Re(s) = 1 asymptotically, pulling away from it more and more slowly as |t| grows. No known theorem excludes a zero with real part 0.99 at some large height. RH asks us to exclude everything past 0.5. Why that gap is structural and not a matter of effort is the subject of docs/08-why-it-is-hard.md.

Zero density — "how many zeros can be far right?" — is the complementary, more tractable attack. N(σ,T) counts zeros with Re(ρ) ≥ σ up to height T; RH says N(σ,T) = 0 for σ > 1/2, and density theorems say off-line zeros are at least rare. Ingham's 1940 bound N(σ,T) ≪ T^(3(1-σ)/(2-σ)+ε) stood essentially unimproved near σ = 3/4 for over eighty years.

THEOREM (Guth–Maynard, 2024), "New large value estimates for Dirichlet polynomials." A new bound on how often a Dirichlet polynomial can be large, yielding the first improvement on Ingham's density estimate around σ = 3/4. The commonly quoted form is N(σ,T) ≪ T^(30(1-σ)/13 + o(1)) for 3/4 ≤ σ ≤ 1I am confident in the qualitative claim and the attribution, less so reciting the exponent from memory; check the paper. A headline consequence: intervals [x, x + x^(17/30 + o(1))] contain a prime for large x, improving Huxley's long-standing x^(7/12).

Two precision points, since this result is often loosely described. It is a large-values / zero-density theorem, not a zero-free-region theorem — a different axis of progress. And it does not approach RH: it improves how rare far-right zeros are, while RH needs them absent.

The heat-flow frontier. Deform Ξ by a heat flow, producing a family H_t of entire functions with H_0 ∝ Ξ (up to scaling — docs/05-de-bruijn-newman.md pins the normalisation down empirically). De Bruijn showed that zeros, once all real, stay real as t increases, so there is a threshold — the de Bruijn–Newman constant Λ — with H_t having only real zeros exactly when t ≥ Λ. Then:

So RH is equivalent to the single equality Λ = 0, pinned into [0, 0.2] from both sides. This is the subject of zeta/heatflow.py and docs/05-de-bruijn-newman.md, and it is the most vivid thing in the repo: you can watch zeros of H_t collide and go complex as you run the flow backwards.

5. What is conjectural or heuristic

Clearly separated from §4.

6. Scope of this repository — an honest statement

This is a laboratory instrument. It exists to make the objects above concrete: to compute ζ where the defining series diverges, to find zeros and count them with certificates, to rebuild the primes from the zeros and watch the error shrink as you add more, to test the GUE statistics against real data, and to run the heat flow.

Zeta Lab is a computational and formal workbench that reconstructs, tests, connects, and falsifies ideas around RH, without claiming to advance RH. That is not a disclaimer of ambition; it is Littlewood's theorem (see §8). If RH is settled by this route, it will come from constructing that framework, not from measuring zeta harder. §4 records 1.24 × 10^13 verified zeros, and §3 records Littlewood's theorem, which guarantees that a pattern holding for every computed case can still be false. Numerics in this subject are for building intuition, checking that formulas mean what you think they mean, and generating questions — never for evidence of truth. If a computation here appears to settle something, the correct inference is that there is a bug.

Where a result is conditional on RH, the code and docs are meant to say so at the point of use.

Since 2026-08 the laboratory also carries a second certainty regime alongside the numerics: lean/, a Lean 4 + Mathlib project whose theorems are checked by a proof kernel rather than measured. It formalizes known mathematics — the ground-truth values above, and (the current target) the Davenport–Heilbronn counterexample — which strengthens the instrument without touching the scope rule: a kernel-checked theorem about known facts is certification of the reference points, not progress on RH. Its house rule mirrors zeta/rigor.py's: nothing counts until it compiles with zero sorrys.

That rule extends to the one part of the repository that looks like it might break it. ontology/ (§7) generates candidate observations and records the small number nothing killed as survivors. A survivor is a lead to be examined by hand — not a result, not a theorem, not evidence for RH — and the funnel writes that sentence into every such record's own proof_gap field. Because there is no network here, nothing is looked up in OEIS or arXiv either: "not recognised offline" is the absence of a lookup, and the layer has no code path that renders it as novelty. If a run of it appears to settle something open, the inference is the same as everywhere else in this repository — there is a bug.

7. Map of the repository

The package is zeta/, twelve analysis modules (plus plots.py, which draws the figures):

A second package, ontology/, sits on top of that one and studies the laboratory rather than the subject. It is a discovery funnel: generators mine the computed objects above for candidate observations, a catalogue and a battery of screens try to kill them, and every step is logged — so the conversion rate per generator can be measured. The premise is unflattering and load-bearing: most numerical "discoveries" are already known or trivial, and a system that does not measure its own hit rate is measuring its operator's enthusiasm. On a fresh ledger the seven generators produce 32 candidates and the funnel's verdict is 26 already known (81.2 %), 1 trivial, 5 inconclusive, 0 survivors — and that table, not the survivor list, is the output.

It is split along one seam. schema.py, registry.py, ledger.py, funnel.py, metrics.py and historical_cases.py are domain-agnostic: they name no quantity the laboratory computes and import nothing from zeta, so the same machinery would serve a chemistry laboratory; three tests enforce it. Everything that knows what is being studied lives in ontology/domains/. Before the funnel is pointed at anything unsettled it has to reproduce history: five claims whose status later work has established — proved, still open, disproved, provably equivalent to an open problem, and one constructed coincidence — are replayed through it and must land where that later work says they belong. The case that matters is Mertens' conjecture, which every computation feasible for a century supported and which is false. The funnel does not endorse it, and the harness refuses to register a case that expects it to, so the suite cannot be edited into agreement.

Read ontology/README.md before touching any of it; §7–§9.3 there is the honest statement of what the layer cannot express and where its own validation is thinner than it looks. Run it with scripts/13_discovery_run.py. Nothing it produces is evidence for RH: a survivor is a lead, and "not recognised offline" is the absence of a lookup — there is no network — never a claim of novelty. Its ledger lives in conjectures/, which is gitignored, because a list of unreviewed leads published under a repository that is otherwise checked would be read as a set of claims.

Docs, in numbered reading order:

DocLeans onWhat it covers
00-orientation.mdThis document: statement, stakes, status, scope.
01-sums-integrals-and-continuation.mdcore.pyHarmonic series and the pole at s=1; Euler–Maclaurin as the sum-vs-integral bridge; how ζ(-1) = -1/12 is forced; how the code actually evaluates ζ everywhere.
02-theta-heat-and-modularity.mdcore.pyTheta as the heat kernel on the circle; Poisson summation; the modular relation θ(1/x) = √x·θ(x).
03-functional-equation.mdcore.pyζ as the Mellin transform of theta; the functional equation derived line by line from 02's modularity.
04-explicit-formula.mdexplicit.py, zeros.pyZeros ↔ primes as an identity: ψ(x) from waves, one per zero, and the primes' spectrum. The payoff of 0103.
05-de-bruijn-newman.mdheatflow.pyHeat flow on Ξ; zero collisions; Λ ∈ [0, 0.2] and RH ⟺ Λ = 0.
06-hilbert-polya-and-gue.mdstatistics.pyThe spectral dream, Berry–Keating, Montgomery–Odlyzko, GUE statistics on your laptop.
07-equivalences-and-criteria.mdseveralA catalogue of statements exactly equivalent to RH, with honest notes on which reformulations ever led anywhere.
08-why-it-is-hard.mdThe failure catalogue: what each known technique provably cannot do, and why numerics cannot decide RH.
09-new-ontologies.mdWhat "RH needs new mathematics" means: the Weil-conjectures precedent, the F1 / Connes / Deninger programmes, and how to stress-test a proposed new ontology.
10-trace-formulas-and-connes.mdweil.pyThe Weil explicit formula as a trace formula (spectrum ↔ orbits); Selberg's working analogue; Connes' programme; the positivity criterion, run live.
11-f1-and-the-missing-geometry.mdepstein.pyThe field with one element, Borger's and Connes–Consani's attempts, Deninger's dynamical programme — the hunt for the geometry under ℤ.
12-how-hard-problems-die.mdfinitefield.py, criteria.py, li.pyA kill board: eight problems that fell, the mechanism that killed each (ontology rebuild, bridge, finite reduction, effective squeeze, flow, insight, equivalence web), and an honest scoring of which of them RH's live formulations touch — and which it provably does not.
13-moments.mdmoments.pyThe external-data contract for the moments programme: LMFDB/Odlyzko formats, exact base-plus-offset storage, validation, provenance, and deliberate non-goals.
14-how-new-mathematics-gets-invented.mdfinitefield.py, epstein.pyCompanion to the kill board, one level earlier: eleven recurring ways new mathematics has appeared (posit the object, negate an axiom, change the base ring, object-valued invariants, dictionaries, compute for anomalies, …), each scored against docs/11's missing Frobenius over ℤ. Historical, not testable — flagged as such in the document.

Supporting directories: scripts/, figures/, data/ (cached zero tables and scan results), tests/ (every module has a test file — the defect functions are tested to tight tolerances), references/, and conjectures/ — the discovery ledger, gitignored, a private notebook of unreviewed leads. Publish ontology.metrics.render_text, never the log.

Recommended reading order. 00 → 01 → 02 → 03 → 04 is a single argument and should be read in sequence: continuation gives you a function with zeros at all, theta/modularity gives the functional equation, and the explicit formula shows why the zeros are the primes. After 04: read 05 for the heat-flow frontier (it builds directly on 02 and 03), 06 for the statistical picture, 07 and 08 in either order to calibrate what "equivalent to RH" and "progress on RH" actually mean, and 09 for what a genuinely new attack would have to look like. 10 and 11 are deeper digests of the two live research programmes 09 sketches — trace formulas/Connes and F1/Deninger — each backed by a module (zeta/weil.py, zeta/epstein.py) and a demo (scripts/07, scripts/08). 12 closes the course by widening the sample: how eight other famous problems actually died, and where RH sits on that board — backed by zeta/finitefield.py, zeta/criteria.py and zeta/li.py (scripts/1012), with zeta/rigor.py and scripts/09 supplying the certified-computation standard §3.1 of 08 insists on. If you have one hour, read 01 and 04 and run the explicit-formula code.

8. Canonical sources

For the specific results of §4, go to the papers: Conrey (J. reine angew. Math. 399, 1989); Platt–Trudgian (Bull. London Math. Soc., 2021); Rodgers–Tao (Forum of Mathematics, Pi, 2020); Polymath 15 (Research in the Mathematical Sciences, 2019); Guth–Maynard (arXiv, 2024).

Where to go next

  1. Read 01-sums-integrals-and-continuation.md and get zeta/core.py evaluating ζ at s = 0.3 + 7.1i, where the defining series is meaningless — by two independent methods that agree. Convince yourself the continued value is forced, not chosen.
  2. Read 02 and 03 as a pair: the heat kernel's self-similarity is the functional equation. Then find the first zero at t = 14.134725... yourself with zeta.zeros.zeros_by_sign_change, and understand why Hardy's real-valued Z(t) reduces zero-finding to hunting sign changes.
  3. Read 04-explicit-formula.md, which is the payoff. Add zeros one at a time to the ψ(x) sum and watch the prime staircase materialize out of waves. This is the moment the subject stops being formal.
  4. If you want the live frontier rather than the foundations, skip to 05-de-bruijn-newman.md and the Λ ∈ [0, 0.2] story, then 08-why-it-is-hard.md to see precisely why none of this — and no computation — closes the gap.

Keep §6 in view throughout. The purpose is to understand the question well enough to respect it.