Skip to content

Commit c6f154b

Browse files
Yu-Misakaxroblot
authored andcommitted
feat(NumberTheory): zeros of Riemann zeta on compact sets are finite (leanprover-community#37328)
Greetings! This PR proves that any compact subset of `ℂ` meets the zero set of the Riemann zeta function in only finitely many points (`riemannZeta_zeroes_on_Compact_finite`). This result in used in AlexKontorovich/PrimeNumberTheoremAnd#750
1 parent 2cbea1a commit c6f154b

4 files changed

Lines changed: 87 additions & 0 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5558,6 +5558,7 @@ public import Mathlib.NumberTheory.LSeries.PrimesInAP
55585558
public import Mathlib.NumberTheory.LSeries.RiemannZeta
55595559
public import Mathlib.NumberTheory.LSeries.SumCoeff
55605560
public import Mathlib.NumberTheory.LSeries.ZMod
5561+
public import Mathlib.NumberTheory.LSeries.ZetaZeros
55615562
public import Mathlib.NumberTheory.LegendreSymbol.AddCharacter
55625563
public import Mathlib.NumberTheory.LegendreSymbol.Basic
55635564
public import Mathlib.NumberTheory.LegendreSymbol.GaussEisensteinLemmas

Mathlib/NumberTheory/Harmonic/ZetaAsymp.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,10 @@ lemma _root_.riemannZeta_one_ne_zero : riemannZeta 1 ≠ 0 := by
420420
exact (lt_trans Real.exp_one_lt_d9 (by norm_num)).trans_le
421421
<| mul_le_mul_of_nonneg_left two_le_pi (by simp)
422422

423+
lemma _root_.riemannZeta_eventually_ne_zero_nhds_one : ∀ᶠ s in 𝓝 1, riemannZeta s ≠ 0 := by
424+
filter_upwards [eventually_nhdsWithin_iff.1 <| riemannZeta_residue_one.eventually_ne one_ne_zero]
425+
grind [riemannZeta_one_ne_zero]
426+
423427
end val_at_one
424428

425429
end ZetaAsymptotics

Mathlib/NumberTheory/LSeries/RiemannZeta.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ lemma HurwitzZeta.expZeta_zero : expZeta 0 = riemannZeta := by
137137
theorem differentiableAt_riemannZeta {s : ℂ} (hs' : s ≠ 1) : DifferentiableAt ℂ riemannZeta s :=
138138
differentiableAt_hurwitzZetaEven _ hs'
139139

140+
lemma differentiableOn_riemannZeta :
141+
DifferentiableOn ℂ riemannZeta {1}ᶜ :=
142+
fun _ hs ↦ (differentiableAt_riemannZeta hs).differentiableWithinAt
143+
144+
lemma analyticOn_riemannZeta :
145+
AnalyticOnNhd ℂ riemannZeta {1}ᶜ :=
146+
differentiableOn_riemannZeta.analyticOnNhd isOpen_compl_singleton
147+
140148
/-- We have `ζ(0) = -1 / 2`. -/
141149
theorem riemannZeta_zero : riemannZeta 0 = -1 / 2 := by
142150
simp_rw [riemannZeta, hurwitzZetaEven, Function.update_self, if_true]
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/-
2+
Copyright (c) 2026 Huanyu Zheng. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Huanyu Zheng
5+
-/
6+
module
7+
8+
public import Mathlib.NumberTheory.LSeries.Nonvanishing
9+
10+
/-!
11+
# Discreteness of the zeros of the Riemann zeta function
12+
13+
We show that the zeros of the Riemann zeta function form a discrete subset of `ℂ`,
14+
so that in particular any compact subset of `ℂ` contains only finitely many zeros.
15+
16+
## Main declarations
17+
18+
* `riemannZetaZeros`: The zeros of Riemann zeta function.
19+
20+
## Main results
21+
22+
* `isClosed_riemannZetaZeros`: `riemannZetaZeros` is closed.
23+
24+
* `isDiscrete_riemannZetaZeros`: `riemannZetaZeros` is discrete.
25+
26+
* `IsCompact.inter_riemannZetaZeros_finite`: for any compact set `S : Set ℂ`, the intersection
27+
`S ∩ riemannZetaZeros` is finite.
28+
-/
29+
30+
@[expose] public section
31+
32+
/-- The zeros of Riemann's ζ-function. -/
33+
def riemannZetaZeros : Set ℂ := riemannZeta ⁻¹' {0}
34+
35+
lemma mem_riemannZetaZeros {z : ℂ} :
36+
z ∈ riemannZetaZeros ↔ riemannZeta z = 0 := .rfl
37+
38+
/-- The complement of the zero set of `riemannZeta` is codiscrete within `{1}ᶜ`. -/
39+
private lemma riemannZetaZeros_codiscreteWithin_compl_one :
40+
riemannZetaZerosᶜ ∈ Filter.codiscreteWithin {1}ᶜ := by
41+
refine analyticOn_riemannZeta.preimage_zero_mem_codiscreteWithin (x := 2) ?_ (by simp) ?_
42+
· exact riemannZeta_ne_zero_of_one_le_re Nat.one_le_ofNat
43+
· exact isConnected_compl_singleton_of_one_lt_rank (by simp) 1
44+
45+
/-- The complement of the zero set of `riemannZeta` is codiscrete. -/
46+
private lemma compl_riemannZetaZeros_mem_codiscrete :
47+
riemannZetaZerosᶜ ∈ Filter.codiscrete ℂ := by
48+
have := riemannZetaZeros_codiscreteWithin_compl_one
49+
simp only [mem_codiscreteWithin, Set.mem_compl_iff, Set.mem_singleton_iff, sdiff_compl,
50+
Set.inf_eq_inter, Filter.disjoint_principal_right, mem_codiscrete, compl_compl] at this ⊢
51+
intro x
52+
rcases eq_or_ne x 1 with rfl | hx
53+
· exact riemannZeta_eventually_ne_zero_nhds_one.filter_mono nhdsWithin_le_nhds
54+
· exact Filter.mem_of_superset (this x hx)
55+
(by grind [riemannZeta_one_ne_zero, mem_riemannZetaZeros])
56+
57+
lemma isClosed_riemannZetaZeros : IsClosed riemannZetaZeros :=
58+
by simpa using (mem_codiscrete'.mp compl_riemannZetaZeros_mem_codiscrete).1
59+
60+
lemma isDiscrete_riemannZetaZeros : IsDiscrete riemannZetaZeros :=
61+
by simpa using (mem_codiscrete'.mp compl_riemannZetaZeros_mem_codiscrete).2
62+
63+
/-- Any compact subset of `ℂ` contains only finitely many zeros of the Riemann zeta function. -/
64+
lemma IsCompact.inter_riemannZetaZeros_finite {S : Set ℂ} (hS : IsCompact S) :
65+
(S ∩ riemannZetaZeros).Finite := by
66+
apply (hS.inter_right isClosed_riemannZetaZeros).finite
67+
exact isDiscrete_riemannZetaZeros.mono Set.inter_subset_right
68+
69+
open Filter in
70+
lemma tendsto_riemannZeta_cofinite_cocompact :
71+
Tendsto ((↑) : riemannZetaZeros → ℂ) cofinite (cocompact ℂ) :=
72+
isClosed_riemannZetaZeros.tendsto_coe_cofinite_of_isDiscrete isDiscrete_riemannZetaZeros
73+
74+
end

0 commit comments

Comments
 (0)