Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit cca4078

Browse files
committed
feat (number_theory/zeta_function): relate to Dirichlet series (#19131)
This PR adds two important properties of the Riemann zeta function: firstly, it is differentiable away from `s = 1` (which is easy for `s ≠ 0`, but much harder at `s = 0`); secondly, for `1 < re s` the zeta function is given by the usual Dirichlet series. Just for fun, we also add a formal statement of the Riemann hypothesis.
1 parent e137999 commit cca4078

3 files changed

Lines changed: 215 additions & 9 deletions

File tree

src/analysis/special_functions/gamma/basic.lean

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,19 @@ end
447447

448448
end Gamma_has_deriv
449449

450+
/-- At `s = 0`, the Gamma function has a simple pole with residue 1. -/
451+
lemma tendsto_self_mul_Gamma_nhds_zero : tendsto (λ z : ℂ, z * Gamma z) (𝓝[≠] 0) (𝓝 1) :=
452+
begin
453+
rw (show 𝓝 (1 : ℂ) = 𝓝 (Gamma (0 + 1)), by simp only [zero_add, complex.Gamma_one]),
454+
convert (tendsto.mono_left _ nhds_within_le_nhds).congr'
455+
(eventually_eq_of_mem self_mem_nhds_within complex.Gamma_add_one),
456+
refine continuous_at.comp _ (continuous_id.add continuous_const).continuous_at,
457+
refine (complex.differentiable_at_Gamma _ (λ m, _)).continuous_at,
458+
rw [zero_add, ←of_real_nat_cast, ←of_real_neg, ←of_real_one, ne.def, of_real_inj],
459+
refine (lt_of_le_of_lt _ zero_lt_one).ne',
460+
exact neg_nonpos.mpr (nat.cast_nonneg _),
461+
end
462+
450463
end complex
451464

452465
namespace real

src/analysis/special_functions/gamma/beta.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,14 @@ begin
476476
{ rintro ⟨m, rfl⟩, exact Gamma_neg_nat_eq_zero m },
477477
end
478478

479+
/-- A weaker, but easier-to-apply, version of `complex.Gamma_ne_zero`. -/
480+
lemma Gamma_ne_zero_of_re_pos {s : ℂ} (hs : 0 < re s) : Gamma s ≠ 0 :=
481+
begin
482+
refine Gamma_ne_zero (λ m, _),
483+
contrapose! hs,
484+
simpa only [hs, neg_re, ←of_real_nat_cast, of_real_re, neg_nonpos] using nat.cast_nonneg _,
485+
end
486+
479487
end complex
480488

481489
namespace real

src/number_theory/zeta_function.lean

Lines changed: 194 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Copyright (c) 2023 David Loeffler. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: David Loeffler
55
-/
6-
import analysis.mellin_transform
6+
import analysis.special_functions.gamma.beta
77
import number_theory.modular_forms.jacobi_theta
88

99
/-!
@@ -24,13 +24,16 @@ I haven't checked exactly what they are).
2424
## Main results:
2525
2626
* `differentiable_completed_zeta₀` : the function `Λ₀(s)` is entire.
27-
* `differentiable_at_completed_zeta`: the function `Λ(s)` is differentiable away from `s = 0` and
27+
* `differentiable_at_completed_zeta` : the function `Λ(s)` is differentiable away from `s = 0` and
2828
`s = 1`.
29+
* `differentiable_at_riemann_zeta` : the function `ζ(s)` is differentiable away from `s = 1`.
30+
* `zeta_eq_tsum_of_one_lt_re` : for `1 < re s`, we have
31+
`ζ(s) = ∑' (n : ℕ), 1 / (n + 1) ^ s`.
2932
3033
## Outline of proofs:
3134
3235
We define two related functions on the reals, `zeta_kernel₁` and `zeta_kernel₂`. The first is
33-
`(Θ (t * I) - 1) / 2`, where `θ` is Jacobi's theta function; its Mellin transform is exactly the
36+
`(θ (t * I) - 1) / 2`, where `θ` is Jacobi's theta function; its Mellin transform is exactly the
3437
completed zeta function. The second is obtained by subtracting a linear combination of powers on
3538
the interval `Ioc 0 1` to give a function with exponential decay at both `0` and `∞`. We then define
3639
`riemann_completed_zeta₀` as the Mellin transform of the second zeta kernel, and define
@@ -67,9 +70,7 @@ details. -/
6770
(λ s : ℂ, ↑π ^ (s / 2) * riemann_completed_zeta s / Gamma (s / 2)) 0 (-1 / 2)
6871

6972
/- Note the next lemma is true by definition; what's hard is to show that with this definition, `ζ`
70-
is continuous (and indeed analytic) at 0.
71-
72-
TODO: Prove this -- this will be in a future PR. -/
73+
is continuous (and indeed analytic) at 0, see `differentiable_riemann_zeta` below. -/
7374
/-- We have `ζ(0) = -1 / 2`. -/
7475
lemma riemann_zeta_zero : riemann_zeta 0 = -1 / 2 :=
7576
begin
@@ -292,6 +293,94 @@ begin
292293
exact differentiable_at_id.sub (differentiable_at_const _) },
293294
end
294295

296+
/-- The Riemann zeta function is differentiable away from `s = 1`. -/
297+
theorem differentiable_at_riemann_zeta {s : ℂ} (hs' : s ≠ 1) :
298+
differentiable_at ℂ riemann_zeta s :=
299+
begin
300+
/- First claim: the result holds at `t` for `t ≠ 0`. Note we will need to use this for the case
301+
`s = 0` also, as a hypothesis for the removable-singularity criterion. -/
302+
have c1 : ∀ (t : ℂ) (ht : t ≠ 0) (ht' : t ≠ 1), differentiable_at ℂ
303+
(λ u : ℂ, ↑π ^ (u / 2) * riemann_completed_zeta u / Gamma (u / 2)) t,
304+
{ intros t ht ht',
305+
apply differentiable_at.mul,
306+
{ refine (differentiable_at.const_cpow _ _).mul (differentiable_at_completed_zeta ht ht'),
307+
{ exact differentiable_at.div_const differentiable_at_id _ },
308+
{ exact or.inl (of_real_ne_zero.mpr pi_pos.ne') } },
309+
{ refine differentiable_one_div_Gamma.differentiable_at.comp t _,
310+
exact differentiable_at.div_const differentiable_at_id _ } },
311+
/- Second claim: the limit at `s = 0` exists and is equal to `-1 / 2`. -/
312+
have c2 : tendsto (λ s : ℂ, ↑π ^ (s / 2) * riemann_completed_zeta s / Gamma (s / 2))
313+
(𝓝[≠] 0) (𝓝 $ -1 / 2),
314+
{ have h1 : tendsto (λ z : ℂ, (π : ℂ) ^ (z / 2)) (𝓝 0) (𝓝 1),
315+
{ convert (continuous_at_const_cpow (of_real_ne_zero.mpr pi_pos.ne')).comp _,
316+
{ simp_rw [function.comp_app, zero_div, cpow_zero] },
317+
{ exact continuous_at_id.div continuous_at_const two_ne_zero } },
318+
suffices h2 : tendsto (λ z, riemann_completed_zeta z / Gamma (z / 2)) (𝓝[≠] 0) (𝓝 $ -1 / 2),
319+
{ convert (h1.mono_left nhds_within_le_nhds).mul h2,
320+
{ ext1 x, rw mul_div }, { simp only [one_mul] } },
321+
suffices h3 : tendsto (λ z, (riemann_completed_zeta z * (z / 2)) / (z / 2 * Gamma (z / 2)))
322+
(𝓝[≠] 0) (𝓝 $ -1 / 2),
323+
{ refine tendsto.congr' (eventually_eq_of_mem self_mem_nhds_within (λ z hz, _)) h3,
324+
rw [←div_div, mul_div_cancel _ (div_ne_zero hz two_ne_zero)] },
325+
have h4 : tendsto (λ z : ℂ, z / 2 * Gamma (z / 2)) (𝓝[≠] 0) (𝓝 1),
326+
{ refine tendsto_self_mul_Gamma_nhds_zero.comp _,
327+
rw [tendsto_nhds_within_iff, (by simp : 𝓝 (0 : ℂ) = 𝓝 (0 / 2))],
328+
exact ⟨(tendsto_id.div_const _).mono_left nhds_within_le_nhds,
329+
eventually_of_mem self_mem_nhds_within (λ x hx, div_ne_zero hx two_ne_zero)⟩ },
330+
suffices : tendsto (λ z, riemann_completed_zeta z * z / 2) (𝓝[≠] 0) (𝓝 (-1 / 2 : ℂ)),
331+
{ have := this.div h4 one_ne_zero,
332+
simp_rw [div_one, mul_div_assoc] at this,
333+
exact this },
334+
refine tendsto.div _ tendsto_const_nhds two_ne_zero,
335+
simp_rw [riemann_completed_zeta, add_mul, sub_mul],
336+
rw show 𝓝 (-1 : ℂ) = 𝓝 (0 - 1 + 0), by rw [zero_sub, add_zero],
337+
refine (tendsto.sub _ _).add _,
338+
{ refine tendsto.mono_left _ nhds_within_le_nhds,
339+
have : continuous_at riemann_completed_zeta₀ 0,
340+
from (differentiable_completed_zeta₀).continuous.continuous_at,
341+
simpa only [id.def, mul_zero] using tendsto.mul this tendsto_id },
342+
{ refine tendsto_const_nhds.congr' (eventually_eq_of_mem self_mem_nhds_within (λ t ht, _)),
343+
simp_rw one_div_mul_cancel ht },
344+
{ refine tendsto.mono_left _ nhds_within_le_nhds,
345+
suffices : continuous_at (λ z : ℂ, 1 / (z - 1)) 0,
346+
by simpa only [id.def, mul_zero] using tendsto.mul this tendsto_id,
347+
refine continuous_at_const.div (continuous_at_id.sub continuous_at_const) _,
348+
simpa only [zero_sub] using neg_ne_zero.mpr one_ne_zero } },
349+
-- Now the main proof.
350+
rcases ne_or_eq s 0 with hs | rfl,
351+
{ -- The easy case: `s ≠ 0`
352+
have : {(0 : ℂ)}ᶜ ∈ 𝓝 s, from is_open_compl_singleton.mem_nhds hs,
353+
refine (c1 s hs hs').congr_of_eventually_eq (eventually_eq_of_mem this (λ x hx, _)),
354+
unfold riemann_zeta,
355+
apply function.update_noteq hx },
356+
{ -- The hard case: `s = 0`.
357+
rw [riemann_zeta, ←(lim_eq_iff ⟨-1 / 2, c2⟩).mpr c2],
358+
have S_nhds : {(1 : ℂ)}ᶜ ∈ 𝓝 (0 : ℂ), from is_open_compl_singleton.mem_nhds hs',
359+
refine ((complex.differentiable_on_update_lim_of_is_o S_nhds
360+
(λ t ht, (c1 t ht.2 ht.1).differentiable_within_at) _) 0 hs').differentiable_at S_nhds,
361+
simp only [zero_div, div_zero, complex.Gamma_zero, mul_zero, cpow_zero, sub_zero],
362+
-- Remains to show completed zeta is `o (s ^ (-1))` near 0.
363+
refine (is_O_const_of_tendsto c2 $ one_ne_zero' ℂ).trans_is_o _,
364+
rw is_o_iff_tendsto',
365+
{ exact tendsto.congr (λ x, by rw [←one_div, one_div_one_div]) nhds_within_le_nhds },
366+
{ exact eventually_of_mem self_mem_nhds_within (λ x hx hx', (hx $ inv_eq_zero.mp hx').elim) } }
367+
end
368+
369+
/-- The trivial zeroes of the zeta function. -/
370+
lemma riemann_zeta_neg_two_mul_nat_add_one (n : ℕ) : riemann_zeta (-2 * (n + 1)) = 0 :=
371+
begin
372+
have : (-2 : ℂ) * (n + 1) ≠ 0,
373+
from mul_ne_zero (neg_ne_zero.mpr two_ne_zero) (nat.cast_add_one_ne_zero n),
374+
rw [riemann_zeta, function.update_noteq this,
375+
(show (-2) * ((n : ℂ) + 1) / 2 = -↑(n + 1), by { push_cast, ring }),
376+
complex.Gamma_neg_nat_eq_zero, div_zero],
377+
end
378+
379+
/-- A formal statement of the Riemann hypothesis – constructing a term of this type is worth a
380+
million dollars. -/
381+
def riemann_hypothesis : Prop :=
382+
∀ (s : ℂ) (hs : riemann_completed_zeta s = 0) (hs' : ¬∃ (n : ℕ), s = -2 * (n + 1)), s.re = 1 / 2
383+
295384
/-!
296385
## Relating the Mellin transforms of the two zeta kernels
297386
-/
@@ -310,7 +399,7 @@ end
310399

311400
/-- Evaluate the Mellin transform of the "fudge factor" in `zeta_kernel₂` -/
312401
lemma has_mellin_one_div_sqrt_sub_one_div_two_Ioc {s : ℂ} (hs : 1 / 2 < s.re) :
313-
has_mellin ((Ioc 0 1).indicator (λ t, (1 - 1 / (↑(sqrt t) : ℂ)) / 2)) s
402+
has_mellin ((Ioc 0 1).indicator (λ t, (1 - 1 / (sqrt t : ℂ)) / 2)) s
314403
(1 / (2 * s) - 1 / (2 * s - 1)) :=
315404
begin
316405
have step1 : has_mellin (indicator (Ioc 0 1) (λ t, 1 - 1 / ↑(sqrt t) : ℝ → ℂ)) s
@@ -319,8 +408,8 @@ begin
319408
have b := has_mellin_one_div_sqrt_Ioc hs,
320409
simpa only [a.2, b.2, ←indicator_sub] using has_mellin_sub a.1 b.1 },
321410
-- todo: implement something like "indicator.const_div" (blocked by the port for now)
322-
rw (show (Ioc 0 1).indicator (λ t, (1 - 1 / (↑(sqrt t) : ℂ)) / 2) =
323-
λ t, ((Ioc 0 1).indicator (λ t, (1 - 1 / (↑(sqrt t) : ℂ))) t) / 2,
411+
rw (show (Ioc 0 1).indicator (λ t, (1 - 1 / (sqrt t : ℂ)) / 2) =
412+
λ t, ((Ioc 0 1).indicator (λ t, (1 - 1 / (sqrt t : ℂ))) t) / 2,
324413
by { ext1 t, simp_rw [div_eq_inv_mul, indicator_mul_right] }),
325414
simp_rw [has_mellin, mellin_div_const, step1.2, sub_div, div_div],
326415
refine ⟨step1.1.div_const _, _⟩,
@@ -349,3 +438,99 @@ begin
349438
rw mul_div_cancel' _ (two_ne_zero' ℂ),
350439
abel
351440
end
441+
442+
/-!
443+
## Relating the first zeta kernel to the Dirichlet series
444+
-/
445+
446+
/-- Auxiliary lemma for `mellin_zeta_kernel₁_eq_tsum`, computing the Mellin transform of an
447+
individual term in the series. -/
448+
lemma integral_cpow_mul_exp_neg_pi_mul_sq {s : ℂ} (hs : 0 < s.re) (n : ℕ) :
449+
∫ t : ℝ in Ioi 0, (t : ℂ) ^ (s - 1) * rexp (-π * t * (n + 1) ^ 2) =
450+
↑π ^ -s * complex.Gamma s * (1 / (n + 1) ^ (2 * s)) :=
451+
begin
452+
rw [complex.Gamma_eq_integral hs, Gamma_integral_eq_mellin],
453+
conv_rhs { congr, rw [←smul_eq_mul, ←mellin_comp_mul_left _ _ pi_pos] },
454+
have : (1 / ((n : ℂ) + 1) ^ (2 * s)) = ↑(((n : ℝ) + 1) ^ (2 : ℝ)) ^ (-s),
455+
{ rw [(by push_cast: ((n : ℂ) + 1) = ↑( (n : ℝ) + 1)),
456+
(by push_cast : (2 * s) = (↑(2 : ℝ) * s)),
457+
cpow_mul_of_real_nonneg, one_div, cpow_neg],
458+
rw [←nat.cast_succ],
459+
exact nat.cast_nonneg _ },
460+
conv_rhs { rw [this, mul_comm, ←smul_eq_mul] },
461+
rw [← mellin_comp_mul_right _ _ (show 0 < ((n : ℝ) + 1) ^ (2 : ℝ), by positivity)],
462+
refine set_integral_congr measurable_set_Ioi (λ t ht, _),
463+
simp_rw smul_eq_mul,
464+
congr' 3,
465+
conv_rhs { rw [←nat.cast_two, rpow_nat_cast] },
466+
ring
467+
end
468+
469+
lemma mellin_zeta_kernel₁_eq_tsum {s : ℂ} (hs : 1 / 2 < s.re):
470+
mellin zeta_kernel₁ s = π ^ (-s) * Gamma s * ∑' (n : ℕ), 1 / (n + 1) ^ (2 * s) :=
471+
begin
472+
let bd : ℕ → ℝ → ℝ := λ n t, t ^ (s.re - 1) * exp (-π * t * (n + 1) ^ 2),
473+
let f : ℕ → ℝ → ℂ := λ n t, t ^ (s - 1) * exp (-π * t * (n + 1) ^ 2),
474+
have hm : measurable_set (Ioi (0:ℝ)), from measurable_set_Ioi,
475+
have h_norm : ∀ (n : ℕ) {t : ℝ} (ht : 0 < t), ‖f n t‖ = bd n t,
476+
{ intros n t ht,
477+
rw [norm_mul, complex.norm_eq_abs, complex.norm_eq_abs, complex.abs_of_nonneg (exp_pos _).le,
478+
abs_cpow_eq_rpow_re_of_pos ht, sub_re, one_re] },
479+
have hf_meas : ∀ (n : ℕ), ae_strongly_measurable (f n) (volume.restrict $ Ioi 0),
480+
{ intro n,
481+
refine (continuous_on.mul _ _).ae_strongly_measurable hm,
482+
{ exact (continuous_at.continuous_on
483+
(λ x hx, continuous_at_of_real_cpow_const _ _ $ or.inr $ ne_of_gt hx)) },
484+
{ apply continuous.continuous_on,
485+
exact continuous_of_real.comp (continuous_exp.comp
486+
((continuous_const.mul continuous_id').mul continuous_const)) } },
487+
have h_le : ∀ (n : ℕ), ∀ᵐ (t : ℝ) ∂volume.restrict (Ioi 0), ‖f n t‖ ≤ bd n t,
488+
from λ n, (ae_restrict_iff' hm).mpr (ae_of_all _ (λ t ht, le_of_eq (h_norm n ht))),
489+
have h_sum0 : ∀ {t : ℝ} (ht : 0 < t), has_sum (λ n, f n t) (t ^ (s - 1) * zeta_kernel₁ t),
490+
{ intros t ht,
491+
have := (has_sum_of_real.mpr (summable_exp_neg_pi_mul_nat_sq ht).has_sum).mul_left
492+
((t : ℂ) ^ (s - 1)),
493+
simpa only [of_real_mul, ←mul_assoc, of_real_bit0, of_real_one, mul_comm _ (2 : ℂ),
494+
of_real_sub, of_real_one, of_real_tsum] using this },
495+
have h_sum' : ∀ᵐ (t : ℝ) ∂volume.restrict (Ioi 0), has_sum (λ (n : ℕ), f n t)
496+
(t ^ (s - 1) * zeta_kernel₁ t),
497+
from (ae_restrict_iff' hm).mpr (ae_of_all _ (λ t ht, h_sum0 ht)),
498+
have h_sum : ∀ᵐ (t : ℝ) ∂volume.restrict (Ioi 0), summable (λ n : ℕ, bd n t),
499+
{ refine (ae_restrict_iff' hm).mpr (ae_of_all _ (λ t ht, _)),
500+
simpa only [λ n, h_norm n ht] using summable_norm_iff.mpr (h_sum0 ht).summable },
501+
have h_int : integrable (λ t : ℝ, ∑' (n : ℕ), bd n t) (volume.restrict (Ioi 0)),
502+
{ refine integrable_on.congr_fun (mellin_convergent_of_is_O_rpow_exp pi_pos
503+
locally_integrable_zeta_kernel₁ is_O_at_top_zeta_kernel₁ is_O_zero_zeta_kernel₁ hs).norm
504+
(λ t ht, _) hm,
505+
simp_rw [tsum_mul_left, norm_smul, complex.norm_eq_abs ((t : ℂ) ^ _),
506+
abs_cpow_eq_rpow_re_of_pos ht, sub_re, one_re],
507+
rw [zeta_kernel₁, ←of_real_tsum, complex.norm_eq_abs, complex.abs_of_nonneg],
508+
exact tsum_nonneg (λ n, (exp_pos _).le) },
509+
simpa only [integral_cpow_mul_exp_neg_pi_mul_sq (one_half_pos.trans hs), tsum_mul_left] using
510+
(has_sum_integral_of_dominated_convergence bd hf_meas h_le h_sum h_int h_sum').tsum_eq.symm,
511+
end
512+
513+
lemma completed_zeta_eq_tsum_of_one_lt_re {s : ℂ} (hs : 1 < re s) :
514+
riemann_completed_zeta s = π ^ (-s / 2) * Gamma (s / 2) * ∑' (n : ℕ), 1 / (n + 1) ^ s :=
515+
begin
516+
rw [completed_zeta_eq_mellin_of_one_lt_re hs, mellin_zeta_kernel₁_eq_tsum, neg_div,
517+
mul_div_cancel' _ (two_ne_zero' ℂ)],
518+
rw (show s / 2 = ↑(2⁻¹ : ℝ) * s, by { push_cast, rw mul_comm, refl }),
519+
rwa [of_real_mul_re, ←div_eq_inv_mul, div_lt_div_right (zero_lt_two' ℝ)]
520+
end
521+
522+
/-- The Riemann zeta function agrees with the naive Dirichlet-series definition when the latter
523+
converges. (Note that this is false without the assumption: when `re s ≤ 1` the sum is divergent,
524+
and we use a different definition to obtain the analytic continuation to all `s`.) -/
525+
theorem zeta_eq_tsum_of_one_lt_re {s : ℂ} (hs : 1 < re s) :
526+
riemann_zeta s = ∑' (n : ℕ), 1 / (n + 1) ^ s :=
527+
begin
528+
have : s ≠ 0, by { contrapose! hs, rw [hs, zero_re], exact zero_le_one },
529+
rw [riemann_zeta, function.update_noteq this, completed_zeta_eq_tsum_of_one_lt_re hs,
530+
←mul_assoc, neg_div, cpow_neg, mul_inv_cancel_left₀, mul_div_cancel_left],
531+
{ apply Gamma_ne_zero_of_re_pos,
532+
rw [←of_real_one, ←of_real_bit0, div_eq_mul_inv, ←of_real_inv, mul_comm, of_real_mul_re],
533+
exact mul_pos (inv_pos_of_pos two_pos) (zero_lt_one.trans hs), },
534+
{ rw [ne.def, cpow_eq_zero_iff, not_and_distrib, ←ne.def, of_real_ne_zero],
535+
exact or.inl (pi_pos.ne') }
536+
end

0 commit comments

Comments
 (0)