From 889b53437cb6e016a4bebe09f6c557ee6dbe9e3c Mon Sep 17 00:00:00 2001 From: Vasily Ilin Date: Wed, 21 Oct 2026 10:32:04 +0000 Subject: [PATCH 1/5] Import Iwaniec's linear sieve and Jacobsthal bound --- LeanPool/IwaniecLinearSieve.lean | 20 + LeanPool/IwaniecLinearSieve/Basic.lean | 42 + LeanPool/IwaniecLinearSieve/Definitions.lean | 104 + LeanPool/IwaniecLinearSieve/Imports.lean | 55 + LeanPool/IwaniecLinearSieve/Jacobsthal.lean | 41 + .../Jacobsthal/Reduction.lean | 187 + .../Jacobsthal/ShiftedSieve.lean | 474 ++ .../LinearSieve/Calculus.lean | 221 + .../LinearSieve/Corollaries.lean | 624 +++ .../IwaniecLinearSieve/LinearSieve/Crude.lean | 437 ++ .../IwaniecLinearSieve/LinearSieve/Defs.lean | 47 + .../IwaniecLinearSieve/LinearSieve/Depth.lean | 330 ++ .../LinearSieve/Estimate.lean | 239 + .../LinearSieve/LemmaEleven.lean | 463 ++ .../LinearSieve/LemmaSeven.lean | 168 + .../LinearSieve/TheoremFive.lean | 468 ++ .../LinearSieve/TheoremFiveAux.lean | 190 + .../LinearSieve/TheoremFiveCount.lean | 458 ++ .../LinearSieve/TheoremFour.lean | 601 +++ .../LinearSieve/TheoremFourAsymp.lean | 390 ++ .../LinearSieve/TheoremFourAux.lean | 264 ++ LeanPool/IwaniecLinearSieve/PrimeSums.lean | 29 + .../IwaniecLinearSieve/PrimeSums/Error.lean | 213 + .../IwaniecLinearSieve/PrimeSums/Lemma13.lean | 423 ++ .../IwaniecLinearSieve/PrimeSums/Mertens.lean | 263 ++ .../PrimeSums/NthPrime.lean | 86 + .../IwaniecLinearSieve/PrimeSums/Product.lean | 241 + .../PrimeSums/SummationByParts.lean | 139 + LeanPool/IwaniecLinearSieve/Rosser.lean | 517 +++ .../IwaniecLinearSieve/SieveFunctions.lean | 29 + .../SieveFunctions/Bounds.lean | 332 ++ .../SieveFunctions/Defs.lean | 319 ++ .../SieveFunctions/LemmaFive.lean | 328 ++ .../SieveFunctions/Series.lean | 249 ++ .../SieveMajorants/Defs.lean | 359 ++ .../SieveMajorants/Delay.lean | 189 + .../SieveMajorants/Lemmas.lean | 576 +++ .../SieveMajorants/Majorants.lean | 217 + .../SieveMajorants/Properties.lean | 275 ++ .../PrimeNumberTheoremAnd/Auxiliary.lean | 86 + .../PrimeNumberTheoremAnd/EulerMaclaurin.lean | 108 + .../PrimeNumberTheoremAnd/MediumPNT.lean | 3881 +++++++++++++++++ .../PrimeNumberTheoremAnd/MellinCalculus.lean | 1470 +++++++ .../PrimeNumberTheoremAnd/Rectangle.lean | 305 ++ .../ResidueCalcOnRectangles.lean | 1301 ++++++ .../PrimeNumberTheoremAnd/StrongPNT.lean | 2754 ++++++++++++ .../PrimeNumberTheoremAnd/ZetaBounds.lean | 3487 +++++++++++++++ .../PrimeNumberTheoremAnd/ZetaConj.lean | 79 + LeanPool/projects/iwaniec-linear-sieve.yaml | 56 + 49 files changed, 24134 insertions(+) create mode 100644 LeanPool/IwaniecLinearSieve.lean create mode 100644 LeanPool/IwaniecLinearSieve/Basic.lean create mode 100644 LeanPool/IwaniecLinearSieve/Definitions.lean create mode 100644 LeanPool/IwaniecLinearSieve/Imports.lean create mode 100644 LeanPool/IwaniecLinearSieve/Jacobsthal.lean create mode 100644 LeanPool/IwaniecLinearSieve/Jacobsthal/Reduction.lean create mode 100644 LeanPool/IwaniecLinearSieve/Jacobsthal/ShiftedSieve.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/Calculus.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/Corollaries.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/Crude.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/Defs.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/Depth.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/Estimate.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/LemmaEleven.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/LemmaSeven.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFive.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveAux.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveCount.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFour.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFourAsymp.lean create mode 100644 LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFourAux.lean create mode 100644 LeanPool/IwaniecLinearSieve/PrimeSums.lean create mode 100644 LeanPool/IwaniecLinearSieve/PrimeSums/Error.lean create mode 100644 LeanPool/IwaniecLinearSieve/PrimeSums/Lemma13.lean create mode 100644 LeanPool/IwaniecLinearSieve/PrimeSums/Mertens.lean create mode 100644 LeanPool/IwaniecLinearSieve/PrimeSums/NthPrime.lean create mode 100644 LeanPool/IwaniecLinearSieve/PrimeSums/Product.lean create mode 100644 LeanPool/IwaniecLinearSieve/PrimeSums/SummationByParts.lean create mode 100644 LeanPool/IwaniecLinearSieve/Rosser.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveFunctions.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveFunctions/Bounds.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveFunctions/Defs.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveFunctions/LemmaFive.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveFunctions/Series.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveMajorants/Defs.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveMajorants/Delay.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveMajorants/Lemmas.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveMajorants/Majorants.lean create mode 100644 LeanPool/IwaniecLinearSieve/SieveMajorants/Properties.lean create mode 100644 LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/Auxiliary.lean create mode 100644 LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/EulerMaclaurin.lean create mode 100644 LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MediumPNT.lean create mode 100644 LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MellinCalculus.lean create mode 100644 LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/Rectangle.lean create mode 100644 LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean create mode 100644 LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/StrongPNT.lean create mode 100644 LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaBounds.lean create mode 100644 LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaConj.lean create mode 100644 LeanPool/projects/iwaniec-linear-sieve.yaml diff --git a/LeanPool/IwaniecLinearSieve.lean b/LeanPool/IwaniecLinearSieve.lean new file mode 100644 index 000000000..e3970f781 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve.lean @@ -0,0 +1,20 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Jacobsthal + +/-! +# Iwaniec's linear sieve and Jacobsthal's bound + +Source: doi:10.1515/dema-1978-0121, url:https://github.com/jasondavies/iwaniec-linear-sieve/tree/c8d01549d2ae640b36ec198c1f0f6495f1b036cf +Authors: Jason Davies, PrimeNumberTheoremAnd contributors +Status: verified +Main declarations: `IwaniecLinearSieve.iwaniecBound` +Tags: analytic-number-theory, sieve-theory, jacobsthal-function, prime-number-theorem +MSC: 11N35, 11N36, 11N25 +-/ diff --git a/LeanPool/IwaniecLinearSieve/Basic.lean b/LeanPool/IwaniecLinearSieve/Basic.lean new file mode 100644 index 000000000..9753fa279 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Basic.lean @@ -0,0 +1,42 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Definitions +import Mathlib.NumberTheory.Chebyshev + +/-! +# Shared notation + +Iwaniec works with primes below a real bound `z`. For `p : ℕ` and `z : ℝ` we have `p < z` iff +`p < ⌈z⌉₊`, so the primes below `z` are `Nat.primesBelow ⌈z⌉₊`. +-/ + +@[expose] public section + +open Real + +namespace IwaniecLinearSieve + +/-- `P(z) = ∏_{p < z} p`. -/ +noncomputable def primorialLT (z : ℝ) : ℕ := ∏ p ∈ primesLT z, p + +/-- Iwaniec's `R(z) = ∏_{p < z} (1 - 1/p)` (his `R_k` with `k = 1`). -/ +noncomputable def R (z : ℝ) : ℝ := ∏ p ∈ primesLT z, (1 - (p : ℝ)⁻¹) + +theorem mem_primesLT {z : ℝ} {p : ℕ} : p ∈ primesLT z ↔ p.Prime ∧ (p : ℝ) < z := by + simp [primesLT, Nat.mem_primesBelow, Nat.lt_ceil, and_comm] + +theorem R_nonneg (z : ℝ) : 0 ≤ R z := + Finset.prod_nonneg fun p hp ↦ sub_nonneg.2 <| inv_le_one_of_one_le₀ <| by + exact_mod_cast (mem_primesLT.1 hp).1.one_lt.le + +theorem R_pos (z : ℝ) : 0 < R z := + Finset.prod_pos fun p hp ↦ sub_pos.2 <| inv_lt_one_of_one_lt₀ <| by + exact_mod_cast (mem_primesLT.1 hp).1.one_lt + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/Definitions.lean b/LeanPool/IwaniecLinearSieve/Definitions.lean new file mode 100644 index 000000000..dc5adc47a --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Definitions.lean @@ -0,0 +1,104 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic +public import Mathlib.NumberTheory.PrimeCounting +import Mathlib.NumberTheory.Chebyshev + +/-! +# The definitions in the advertised statements + +Shared definitions of sifted sets, sieve functions and delay-equation majorants. +Their analytic and combinatorial properties are proved in the modules below. +-/ + +@[expose] public section + +open Real Finset + +namespace IwaniecLinearSieve + +/-! ## Sifted sets ([I71, §1]) -/ + +/-- The primes `p < z`. -/ +noncomputable def primesLT (z : ℝ) : Finset ℕ := Nat.primesBelow ⌈z⌉₊ + +/-- The primes `p < z` with `p ∤ k`. -/ +noncomputable def primesLTk (k : ℕ) (z : ℝ) : Finset ℕ := (primesLT z).filter fun p ↦ ¬ p ∣ k + +/-- Iwaniec's `R_k(z) = ∏_{p < z, p ∤ k} (1 - 1/p)`. -/ +noncomputable def Rk (k : ℕ) (z : ℝ) : ℝ := ∏ p ∈ primesLTk k z, (1 - (p : ℝ)⁻¹) + +/-- Iwaniec's `A_k(M; z)`: the number of terms of `M` not divisible by any prime `p < z` +with `p ∤ k`. -/ +noncomputable def siftedCount (k : ℕ) (M : Multiset ℤ) (z : ℝ) : ℕ := + M.countP fun a ↦ ∀ p ∈ primesLTk k z, ¬ (p : ℤ) ∣ a + +/-- Iwaniec's `|M_d|`: the number of terms of `M` divisible by `d`. -/ +def multiplesCount (M : Multiset ℤ) (d : ℕ) : ℕ := M.countP fun a ↦ (d : ℤ) ∣ a + +/-! ## The sieve functions `f` and `F` ([I71, §3, (3.1)–(3.7)]) -/ + +/-- The formula `3 log (3 / (s - 1)) + s - 4` for `g₂` on `[2, 4]`. -/ +noncomputable def gTwoFormula (s : ℝ) : ℝ := 3 * log (3 / (s - 1)) + s - 4 + +/-- Left end of the domain of `g i` in [I71]: `2` for even `i`, `3` for odd `i`. -/ +noncomputable def gLower (i : ℕ) : ℝ := if Even i then 2 else 3 + +/-- The kernel `t ↦ h (t - 1) / (t - 1)`, with the denominator replaced by `max (t - 1) 1` so that +it is continuous on `ℝ` whenever `h` is. It agrees with `h (t - 1) / (t - 1)` for `t ≥ 2`. -/ +noncomputable def shiftKernel (h : ℝ → ℝ) (t : ℝ) : ℝ := h (t - 1) / max (t - 1) 1 + +/-- Iwaniec's functions `g_n` of [I71, (3.1)–(3.3)], extended to all of `ℝ`: +`g₂(s) = 3 log (3 / (s - 1)) + s - 4` on `[2, 4]` and `0` for `s ≥ 4`, and +`g_{n+1}(s) = ∫_s^∞ g_n(t - 1) / (t - 1) dt` for `s` at least `gLower (n + 1)`. +Outside the domains of [I71] the argument is clamped: the even functions are constant on +`s ≤ 2`, the odd ones on `s ≤ 3`, and `g 0 = g 1 = 0`. The upper limit `n + 5 = (n + 3) + 2` +of the integral can replace `∞` because `g (n + 2) s = 0` for `s ≥ n + 4`. -/ +noncomputable def g : ℕ → ℝ → ℝ + | 0, _ => 0 + | 1, _ => 0 + | 2, s => gTwoFormula (max 2 (min s 4)) + | n + 3, s => ∫ t in max s (gLower (n + 3))..((n : ℝ) + 5), shiftKernel (g (n + 2)) t + +/-- Iwaniec's `f(s) = Σ_{i ≥ 1} g_{2i}(s)` [I71, (3.6)]; constant (`= f(2) = 2`) for `s ≤ 2`. -/ +noncomputable def fSieve (s : ℝ) : ℝ := ∑' n : ℕ, g (2 * n + 2) s + +/-- Iwaniec's `F(s) = Σ_{i ≥ 1} g_{2i+1}(s)` [I71, (3.7)]; constant (`= F(3)`) for `s ≤ 3`. -/ +noncomputable def FSieve (s : ℝ) : ℝ := ∑' n : ℕ, g (2 * n + 3) s + +/-! ## The function `𝔐` ([I71, §3, Definition]) -/ + +namespace Delay + +/-- One Picard-type step: `y₀` up to `3`, then integrate `k x * y (x - 1)` from `3`. -/ +noncomputable def step (k y₀ y : ℝ → ℝ) (s : ℝ) : ℝ := + y₀ (min s 3) + ∫ x in (3 : ℝ)..max s 3, k x * y (x - 1) + +/-- The iterates of `step`; the `n`-th one is correct on `(-∞, n + 3]`. -/ +noncomputable def iter (k y₀ : ℝ → ℝ) : ℕ → ℝ → ℝ + | 0 => y₀ + | n + 1 => step k y₀ (iter k y₀ n) + +/-- The solution `y` of the delay equation `y s = y₀ s` for `s ≤ 3` and +`y s = y₀ 3 + ∫ x in 3..s, k x * y (x - 1)` for `s ≥ 3`. -/ +noncomputable def sol (k y₀ : ℝ → ℝ) (s : ℝ) : ℝ := iter k y₀ ⌈s⌉₊ s + +end Delay + +/-- The kernel `x / (x - 1)²` of the delay equations, frozen to the left of `3`. -/ +noncomputable def delayKer (x : ℝ) : ℝ := max x 3 / (max x 3 - 1) ^ 2 + +/-- Initial values of `𝔚` on `[2, 3]` (constant to the left of `2`). -/ +noncomputable def initW (s : ℝ) : ℝ := 1 / (max s 2 - 1) - log (max s 2 - 1) + +/-- Iwaniec's `𝔐` [I71, §3, Definition]: `𝔐(s) = 2 + 1/(s - 1) - log (s - 1)` on `[2, 3]` +(constant `3` to the left of `2`) and `𝔐'(s) = -s/(s - 1)² 𝔐(s - 1)` for `s > 3`. -/ +noncomputable def bigM : ℝ → ℝ := Delay.sol (fun x => -delayKer x) (fun s => 2 + initW s) + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/Imports.lean b/LeanPool/IwaniecLinearSieve/Imports.lean new file mode 100644 index 000000000..d1f6726cb --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Imports.lean @@ -0,0 +1,55 @@ +/- +Copyright (c) 2026 Lean Pool contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Lean Pool contributors +-/ +module -- shake: keep-all --deprecated_module: ignore + +-- Generated project imports; run `lake exe mk_all`. +public import LeanPool.IwaniecLinearSieve +public import LeanPool.IwaniecLinearSieve.Basic +public import LeanPool.IwaniecLinearSieve.Definitions +public import LeanPool.IwaniecLinearSieve.Jacobsthal +public import LeanPool.IwaniecLinearSieve.Jacobsthal.Reduction +public import LeanPool.IwaniecLinearSieve.Jacobsthal.ShiftedSieve +public import LeanPool.IwaniecLinearSieve.LinearSieve.Calculus +public import LeanPool.IwaniecLinearSieve.LinearSieve.Corollaries +public import LeanPool.IwaniecLinearSieve.LinearSieve.Crude +public import LeanPool.IwaniecLinearSieve.LinearSieve.Defs +public import LeanPool.IwaniecLinearSieve.LinearSieve.Depth +public import LeanPool.IwaniecLinearSieve.LinearSieve.Estimate +public import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaEleven +public import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaSeven +public import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFive +public import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFiveAux +public import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFiveCount +public import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFour +public import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFourAsymp +public import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFourAux +public import LeanPool.IwaniecLinearSieve.PrimeSums +public import LeanPool.IwaniecLinearSieve.PrimeSums.Error +public import LeanPool.IwaniecLinearSieve.PrimeSums.Lemma13 +public import LeanPool.IwaniecLinearSieve.PrimeSums.Mertens +public import LeanPool.IwaniecLinearSieve.PrimeSums.NthPrime +public import LeanPool.IwaniecLinearSieve.PrimeSums.Product +public import LeanPool.IwaniecLinearSieve.PrimeSums.SummationByParts +public import LeanPool.IwaniecLinearSieve.Rosser +public import LeanPool.IwaniecLinearSieve.SieveFunctions +public import LeanPool.IwaniecLinearSieve.SieveFunctions.Bounds +public import LeanPool.IwaniecLinearSieve.SieveFunctions.Defs +public import LeanPool.IwaniecLinearSieve.SieveFunctions.LemmaFive +public import LeanPool.IwaniecLinearSieve.SieveFunctions.Series +public import LeanPool.IwaniecLinearSieve.SieveMajorants.Defs +public import LeanPool.IwaniecLinearSieve.SieveMajorants.Delay +public import LeanPool.IwaniecLinearSieve.SieveMajorants.Lemmas +public import LeanPool.IwaniecLinearSieve.SieveMajorants.Majorants +public import LeanPool.IwaniecLinearSieve.SieveMajorants.Properties +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.Auxiliary +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.EulerMaclaurin +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.MediumPNT +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.MellinCalculus +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.Rectangle +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.ResidueCalcOnRectangles +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.StrongPNT +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.ZetaBounds +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.ZetaConj diff --git a/LeanPool/IwaniecLinearSieve/Jacobsthal.lean b/LeanPool/IwaniecLinearSieve/Jacobsthal.lean new file mode 100644 index 000000000..30e369651 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Jacobsthal.lean @@ -0,0 +1,41 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Jacobsthal.Reduction +import LeanPool.IwaniecLinearSieve.PrimeSums.NthPrime +import LeanPool.IwaniecLinearSieve.PrimeSums.Product + +/-! +# Jacobsthal's problem ([I78]) + +Iwaniec's application of the linear sieve: if `m` consecutive integers are each divisible by one +of `r ≥ 2` given primes, then `m ≪ (r log r)²`. The shifted sieve ([I78, Lemma 1], +`Jacobsthal/ShiftedSieve.lean`) transfers the Rosser weights for the first `r` primes to any `r` +primes; `Jacobsthal/Reduction.lean` combines it with `linearSieveEstimate`. + +This port preserves the dependency closure of the corollary. The upstream repository also +formalizes other results of [I78], which are outside this import's scope. + +The sieve definitions, statements and proofs were produced by AI agents under Jason Davies's +supervision. The vendored strong PNT proofs come from PrimeNumberTheoremAnd and its contributors; +their upstream revision is recorded in the project card and each vendor module. +-/ + +@[expose] public section + +namespace IwaniecLinearSieve + +/-- **Iwaniec's theorem** ([I78, Corollary]): if `m` consecutive integers are each divisible by +one of `r ≥ 2` given primes, then `m ≪ (r log r)²`. -/ +theorem iwaniecBound : + ∃ C : ℝ, ∀ S : Finset ℕ, (∀ p ∈ S, p.Prime) → 2 ≤ S.card → + ∀ (x : ℤ) (m : ℕ), (∀ k < m, ∃ p ∈ S, (p : ℤ) ∣ x + k) → + (m : ℝ) ≤ C * ((S.card : ℝ) * Real.log S.card) ^ 2 := + iwaniecBound_of_estimates linearSieveEstimate R_lower nth_prime_le + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/Jacobsthal/Reduction.lean b/LeanPool/IwaniecLinearSieve/Jacobsthal/Reduction.lean new file mode 100644 index 000000000..db90ee570 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Jacobsthal/Reduction.lean @@ -0,0 +1,187 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.Estimate +import LeanPool.IwaniecLinearSieve.Jacobsthal.ShiftedSieve +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds + +/-! +# Reduction of Jacobsthal's problem to the linear sieve ([I78, §3]) + +`iwaniecBound_of_estimates` derives Iwaniec's bound `m ≪ (r log r)²` for the length `m` of a run +of consecutive integers each divisible by one of `r ≥ 2` given primes, from three analytic inputs +taken as hypotheses: + +* `LinearSieveEstimate` (proved as `linearSieveEstimate`): [I71]'s bounds (main term and support + size) for Rosser's lower-bound sieve at level `y = C₀ z²`, i.e. (5) and (6) of [I78, Lemma 2]; +* `R(z) ≫ 1 / log z` (Mertens); +* `p_r ≪ r log r` for the `r`-th prime. + +The proof is [I78, §3]: the shifted sieve (`shiftedSieve`) with `X = m`, for which the sifted set +is empty, gives `m ∏_{q ∈ S} (1 - 1/q) · (∑_{D⁻} μ(d)/d) / R(z) ≤ |D⁻|`. +-/ + +@[expose] public section + +open Finset Real + +namespace IwaniecLinearSieve + +/-- From the linear sieve estimate and `R(z) ≫ 1 / log z`: if `π(z)` primes cover `m` +consecutive integers, then `m ≪ z²`. -/ +theorem exists_covering_length_le (hL : LinearSieveEstimate) + (hR : ∃ c > 0, ∀ z ≥ 2, c / log z ≤ R z) : + ∃ K z₁ : ℝ, ∀ z ≥ z₁, ∀ S : Finset ℕ, (∀ p ∈ S, p.Prime) → #S = #(primesLT z) → + ∀ (x : ℤ) (m : ℕ), (∀ k < m, ∃ p ∈ S, (p : ℤ) ∣ x + k) → (m : ℝ) ≤ K * z ^ 2 := by + obtain ⟨C₀, c, K, z₀, hc, hL⟩ := hL + obtain ⟨c', hc', hR⟩ := hR + refine ⟨K / (c * c'), max z₀ 2, fun z hz S hS hcard x m hm ↦ ?_⟩ + have hz0 : z₀ ≤ z := (le_max_left _ _).trans hz + have hz2 : 2 ≤ z := (le_max_right _ _).trans hz + have hlog : 0 < log z := log_pos (by linarith) + have hRz := R_pos z + set M := rosserMain true (C₀ * z ^ 2) z + obtain ⟨hmain, hcount⟩ := hL z hz0 + have hsieve := shiftedSieve (C₀ * z ^ 2) hS hcard x m + have hzero : (range m).filter (fun k : ℕ ↦ ∀ q ∈ S, ¬ (q : ℤ) ∣ x + k) = ∅ := by + rw [filter_eq_empty_iff] + intro k hk h + obtain ⟨q, hq, hqk⟩ := hm k (mem_range.1 hk) + exact h q hq hqk + rw [hzero, card_empty, Nat.cast_zero] at hsieve + -- `M ≥ R(z) c / log z` + have hM : R z * (c / log z) ≤ M := by nlinarith + have hM0 : 0 ≤ M := (mul_nonneg hRz.le (div_pos hc hlog).le).trans hM + have hprod := R_le_prod_of_card_eq hS hcard + have h1 : (m : ℝ) * M ≤ #(rosserSet true (C₀ * z ^ 2) z) := by + have : (m : ℝ) * M ≤ m * (∏ q ∈ S, (1 - (q : ℝ)⁻¹)) * (M / R z) := by + rw [mul_assoc] + refine mul_le_mul_of_nonneg_left ?_ m.cast_nonneg + calc M = R z * (M / R z) := by field_simp + _ ≤ _ := mul_le_mul_of_nonneg_right hprod (div_nonneg hM0 hRz.le) + linarith + have hRlog : c' ≤ R z * log z := by + have := hR z hz2 + rwa [div_le_iff₀ hlog] at this + -- `m c c' ≤ m c R(z) log z ≤ M m log z · log z ≤ K z²` + have h2 : (m : ℝ) * (c * c') ≤ K * z ^ 2 := by + have hm0 : (0 : ℝ) ≤ m := m.cast_nonneg + have e1 : (m : ℝ) * (c * c') ≤ (m : ℝ) * (R z * (c / log z)) * log z ^ 2 := by + have : (m : ℝ) * (R z * (c / log z)) * log z ^ 2 = m * c * (R z * log z) := by + field_simp + rw [this, ← mul_assoc] + exact mul_le_mul_of_nonneg_left hRlog (mul_nonneg hm0 hc.le) + have e2 : (m : ℝ) * (R z * (c / log z)) * log z ^ 2 ≤ K * z ^ 2 / log z ^ 2 * log z ^ 2 := by + refine mul_le_mul_of_nonneg_right ?_ (sq_nonneg _) + exact (mul_le_mul_of_nonneg_left hM hm0).trans (h1.trans hcount) + have e3 : K * z ^ 2 / log z ^ 2 * log z ^ 2 = K * z ^ 2 := by + field_simp + linarith + rw [div_mul_eq_mul_div, le_div_iff₀ (mul_pos hc hc')] + linarith + + +/-- The primes below `p_N + 1`, where `p_N = Nat.nth Nat.Prime (N - 1)` is the `N`-th prime, are +the first `N` primes. -/ +theorem card_primesLT_nth_prime_add_one (n : ℕ) : + #(primesLT ((Nat.nth Nat.Prime n : ℝ) + 1)) = n + 1 := by + rw [primesLT, show (Nat.nth Nat.Prime n : ℝ) + 1 = ((Nat.nth Nat.Prime n + 1 : ℕ) : ℝ) by + push_cast; ring, Nat.ceil_natCast, Nat.primesBelow_card_eq_primeCounting', Nat.primeCounting', + Nat.count_succ_eq_succ_count (Nat.prime_nth_prime n), + Nat.count_nth_of_infinite Nat.infinite_setOfPred_prime] + +/-- Any finite set of `r ≤ N` primes extends to a set of exactly `N` primes. -/ +theorem exists_superset_card_eq {S : Finset ℕ} (hS : ∀ p ∈ S, p.Prime) {N : ℕ} (hN : #S ≤ N) : + ∃ S' : Finset ℕ, S ⊆ S' ∧ (∀ p ∈ S', p.Prime) ∧ #S' = N := by + set U := primesLT ((Nat.nth Nat.Prime N : ℝ) + 1) + have hU : #U = N + 1 := card_primesLT_nth_prime_add_one N + have : N - #S ≤ #(U \ S) := (Nat.sub_le_sub_right (by omega) _).trans (le_card_sdiff S U) + obtain ⟨T, hTU, hT⟩ := exists_subset_card_eq this + refine ⟨S ∪ T, subset_union_left, fun p hp ↦ ?_, ?_⟩ + · rcases mem_union.1 hp with hp | hp + · exact hS p hp + · exact prime_of_mem_primesLT (sdiff_subset (hTU hp)) + · rw [card_union_of_disjoint (disjoint_of_subset_right hTU disjoint_sdiff), hT] + omega + + +/-- **Iwaniec's bound for Jacobsthal's function** ([I78, Corollary]), assuming the linear sieve +estimate of [I71], the lower bound `R(z) ≫ 1 / log z`, and the bound `p_r ≪ r log r` for the +`r`-th prime: if `r ≥ 2` primes cover `m` consecutive integers, then `m ≪ (r log r)²`. + +Given `S` with `#S = r`, we enlarge `S` to `N = N₀ r` primes (so that `z = p_N + 1 ≥ z₀`) and +apply `exists_covering_length_le` with `z = p_N + 1`, so that `primesLT z` consists of the first +`N` primes. -/ +theorem iwaniecBound_of_estimates (hL : LinearSieveEstimate) + (hR : ∃ c > 0, ∀ z ≥ 2, c / log z ≤ R z) + (hp : ∃ C, ∀ r ≥ 2, (Nat.nth Nat.Prime (r - 1) : ℝ) ≤ C * r * log r) : + ∃ C : ℝ, ∀ S : Finset ℕ, (∀ p ∈ S, p.Prime) → 2 ≤ S.card → + ∀ (x : ℤ) (m : ℕ), (∀ k < m, ∃ p ∈ S, (p : ℤ) ∣ x + k) → + (m : ℝ) ≤ C * ((S.card : ℝ) * Real.log S.card) ^ 2 := by + obtain ⟨K, z₁, hK⟩ := exists_covering_length_le hL hR + obtain ⟨Cp, hCp⟩ := hp + set N₀ : ℕ := ⌈z₁⌉₊ + 2 + set B : ℝ := N₀ * (log N₀ / log 2 + 1) + refine ⟨max K 0 * (|Cp| * B + 1) ^ 2, fun S hS hr x m hm ↦ ?_⟩ + set r := #S + set N := N₀ * r + have hrN : r ≤ N := Nat.le_mul_of_pos_left r (by omega) + have hN2 : 2 ≤ N := hr.trans hrN + obtain ⟨S', hSS', hS', hcard'⟩ := exists_superset_card_eq hS hrN + set p := Nat.nth Nat.Prime (N - 1) + set z : ℝ := p + 1 + have hcardz : #(primesLT z) = N := by + rw [card_primesLT_nth_prime_add_one] + omega + have hz : z₁ ≤ z := by + have h1 := Nat.add_two_le_nth_prime (N - 1) + have h2 : N₀ ≤ N := Nat.le_mul_of_pos_right _ (by omega) + have h3 : z₁ ≤ ⌈z₁⌉₊ := Nat.le_ceil z₁ + have h4 : (⌈z₁⌉₊ : ℝ) + 1 ≤ p := by exact_mod_cast (by omega : ⌈z₁⌉₊ + 1 ≤ p) + simp only [z] + linarith + have hmz := hK z hz S' hS' (hcard'.trans hcardz.symm) x m fun k hk ↦ + let ⟨q, hq, h⟩ := hm k hk + ⟨q, hSS' hq, h⟩ + -- `z ≤ (|Cp| B + 1) r log r` + have hlog2 : (0.69 : ℝ) < log 2 := by linarith [Real.log_two_gt_d9] + have hr' : (2 : ℝ) ≤ r := by exact_mod_cast hr + have hlogr : log 2 ≤ log r := log_le_log (by norm_num) hr' + have hrlogr : 1 ≤ (r : ℝ) * log r := by nlinarith + have hN₀ : (1 : ℝ) ≤ N₀ := by exact_mod_cast (by omega : 1 ≤ N₀) + have hlogN : log N ≤ (log N₀ / log 2 + 1) * log r := by + rw [Nat.cast_mul, log_mul (by positivity) (by positivity)] + have : log N₀ ≤ log N₀ / log 2 * log r := by + rw [div_mul_eq_mul_div, le_div_iff₀ (by linarith)] + exact mul_le_mul_of_nonneg_left hlogr (log_nonneg hN₀) + linarith + have hN : (2 : ℝ) ≤ N := by exact_mod_cast hN2 + have hNlogN0 : 0 ≤ (N : ℝ) * log N := mul_nonneg (by linarith) (log_nonneg (by linarith)) + have hpN : (p : ℝ) ≤ |Cp| * (B * (r * log r)) := by + have h1 := hCp N hN2 + have h2 : (N : ℝ) * log N ≤ B * (r * log r) := by + calc (N : ℝ) * log N = N₀ * r * log N := by simp [N] + _ ≤ N₀ * r * ((log N₀ / log 2 + 1) * log r) := + mul_le_mul_of_nonneg_left hlogN (by positivity) + _ = B * (r * log r) := by ring + calc (p : ℝ) ≤ Cp * N * log N := h1 + _ = Cp * (N * log N) := by ring + _ ≤ |Cp| * (N * log N) := mul_le_mul_of_nonneg_right (le_abs_self _) hNlogN0 + _ ≤ |Cp| * (B * (r * log r)) := mul_le_mul_of_nonneg_left h2 (abs_nonneg _) + have hz' : z ≤ (|Cp| * B + 1) * (r * log r) := by + simp only [z] + nlinarith + have hz0 : 0 ≤ z := by positivity + calc (m : ℝ) ≤ K * z ^ 2 := hmz + _ ≤ max K 0 * z ^ 2 := mul_le_mul_of_nonneg_right (le_max_left _ _) (sq_nonneg _) + _ ≤ max K 0 * ((|Cp| * B + 1) * (r * log r)) ^ 2 := + mul_le_mul_of_nonneg_left (pow_le_pow_left₀ hz0 hz' 2) (le_max_right _ _) + _ = _ := by ring + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/Jacobsthal/ShiftedSieve.lean b/LeanPool/IwaniecLinearSieve/Jacobsthal/ShiftedSieve.lean new file mode 100644 index 000000000..fe68b83c7 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Jacobsthal/ShiftedSieve.lean @@ -0,0 +1,474 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Rosser +import Mathlib.Algebra.Order.Ring.Star +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Data.Int.CardIntervalMod +import Mathlib.Data.Rat.Star +import Mathlib.NumberTheory.Chebyshev +import Mathlib.Order.Interval.Finset.Box +import Mathlib.Tactic.Polynomial.Basic + +/-! +# Iwaniec's shifted sieve ([I78, Lemma 1]) + +Let `S` be any set of `r = π(z)` primes, and match `S` with the primes below `z` in increasing +order, `l : S → primesLT z`, so that `l(q) ≤ q`. Rosser's lower-bound weights `λ_d = μ(d)` on +`d ∈ D⁻` (supported on divisors of `P(z)`) are pulled back along `l` to divisors of +`Q = ∏_{q ∈ S} q`. Writing divisors of squarefree numbers as sets of primes, the weights are +`rosserWeight y z A` for `A ⊆ primesLT z`. + +* `sum_powerset_div_prod`: `∑_{A ⊆ T} w(A)/∏_A g = ∏_T (1 - 1/g) ∑_{B ⊆ T} σ(B)/∏_B (g - 1)`. +* `prod_mul_sum_div_le_sum`: the comparison of main terms under condition (−). +* `shiftedSieve`: [I78, Lemma 1] for `X` consecutive integers. +* `R_le_prod_of_card_eq`: `R(z) ≤ ∏_{q ∈ S} (1 - 1/q)`. +-/ + +@[expose] public section + +open Finset ArithmeticFunction +open scoped ArithmeticFunction.Moebius + +namespace IwaniecLinearSieve + +/-! ### Matching an arbitrary set of primes with the first primes -/ + +/-- If every element of `S` lying below some element of `T` belongs to `T` (e.g. `T` is the set of +the first `r` primes and `S` is any set of primes), then the `i`-th element of `T` is at most the +`i`-th element of `S`. -/ +theorem orderEmbOfFin_le_orderEmbOfFin {T S : Finset ℕ} {r : ℕ} (hT : #T = r) (hS : #S = r) + (hdown : ∀ q ∈ S, ∀ t ∈ T, q < t → q ∈ T) (i : Fin r) : + T.orderEmbOfFin hT i ≤ S.orderEmbOfFin hS i := by + by_contra h + push Not at h + set t := T.orderEmbOfFin hT i + have h1 : (Iic i).map (S.orderEmbOfFin hS).toEmbedding ⊆ T.filter (· < t) := by + intro u hu + obtain ⟨j, hj, rfl⟩ := mem_map.1 hu + have hlt : S.orderEmbOfFin hS j < t := + lt_of_le_of_lt ((S.orderEmbOfFin hS).monotone (mem_Iic.1 hj)) h + exact mem_filter.2 ⟨hdown _ (S.orderEmbOfFin_mem hS j) t (T.orderEmbOfFin_mem hT i) hlt, hlt⟩ + have h2 : T.filter (· < t) ⊆ (Iio i).map (T.orderEmbOfFin hT).toEmbedding := by + intro u hu + obtain ⟨huT, hut⟩ := mem_filter.1 hu + have : u ∈ Set.range (T.orderEmbOfFin hT) := by + rw [range_orderEmbOfFin] + exact huT + obtain ⟨j, rfl⟩ := this + exact mem_map.2 ⟨j, mem_Iio.2 ((T.orderEmbOfFin hT).lt_iff_lt.1 hut), rfl⟩ + have := card_le_card (h1.trans h2) + simp [Fin.card_Iic, Fin.card_Iio] at this + +/-- The order-preserving bijection between two finite sets of the same size moves every element +of `T` upwards, provided every element of `S` below an element of `T` lies in `T`. -/ +theorem exists_bijOn_le {T S : Finset ℕ} (hcard : #S = #T) + (hdown : ∀ q ∈ S, ∀ t ∈ T, q < t → q ∈ T) : + ∃ e : ℕ → ℕ, Set.BijOn e T S ∧ ∀ p ∈ T, p ≤ e p := by + classical + let iT := T.orderIsoOfFin rfl + let iS := S.orderIsoOfFin hcard + refine ⟨fun p ↦ if hp : p ∈ T then (iS (iT.symm ⟨p, hp⟩) : ℕ) else p, ⟨?_, ?_, ?_⟩, ?_⟩ + · intro p hp + simp only [mem_coe] at hp + simp only [hp, dite_true, mem_coe] + exact (iS _).2 + · intro p hp q hq hpq + simp only [mem_coe] at hp hq + simp only [hp, hq, dite_true] at hpq + have := iT.symm.injective (iS.injective (Subtype.ext hpq)) + exact congrArg Subtype.val this + · intro q hq + simp only [mem_coe] at hq + refine ⟨iT (iS.symm ⟨q, hq⟩), (iT _).2, ?_⟩ + simp + · intro p hp + simp only [hp, dite_true] + have h1 : p = T.orderEmbOfFin rfl (iT.symm ⟨p, hp⟩) := by + rw [← coe_orderIsoOfFin_apply] + simp [iT] + have h2 : (iS (iT.symm ⟨p, hp⟩) : ℕ) = S.orderEmbOfFin hcard (iT.symm ⟨p, hp⟩) := + coe_orderIsoOfFin_apply _ _ _ + conv_lhs => rw [h1] + rw [h2] + exact orderEmbOfFin_le_orderEmbOfFin rfl hcard hdown _ + + +/-! ### Möbius inversion over subsets -/ +theorem sum_powerset_filter_superset_prod {T A : Finset ℕ} (hA : A ⊆ T) (h : ℕ → ℝ) : + ∑ B ∈ T.powerset with A ⊆ B, ∏ p ∈ B, h p = (∏ p ∈ A, h p) * ∏ p ∈ T \ A, (1 + h p) := by + rw [prod_one_add, mul_sum] + refine sum_nbij' (fun B ↦ B \ A) (fun C ↦ A ∪ C) ?_ ?_ ?_ ?_ ?_ + · intro B hB + simp only [mem_filter, mem_powerset] at hB ⊢ + exact sdiff_subset_sdiff hB.1 le_rfl + · intro C hC + simp only [mem_filter, mem_powerset] at hC ⊢ + exact ⟨union_subset hA (hC.trans sdiff_subset), subset_union_left⟩ + · intro B hB + simp only [mem_filter, mem_powerset] at hB + exact union_sdiff_of_subset hB.2 + · intro C hC + simp only [mem_powerset] at hC + exact union_sdiff_cancel_left (disjoint_of_subset_right hC disjoint_sdiff) + · intro B hB + simp only [mem_filter, mem_powerset] at hB + rw [← prod_union disjoint_sdiff, union_sdiff_of_subset hB.2] + +/-- The identity behind [I78, Lemma 1]: for weights `w` on the subsets of `T` (i.e. on the +divisors of `∏_{p ∈ T} p`) with partial sums `σ(B) = ∑_{A ⊆ B} w(A)`, +`∑_{A ⊆ T} w(A) / ∏_{p ∈ A} g(p) = ∏_{p ∈ T} (1 - 1/g(p)) ∑_{B ⊆ T} σ(B) / ∏_{p ∈ B} (g(p) - 1)`. -/ +theorem sum_powerset_div_prod (T : Finset ℕ) (g : ℕ → ℝ) (hg : ∀ p ∈ T, g p ≠ 0 ∧ g p ≠ 1) + (w : Finset ℕ → ℝ) : + ∑ A ∈ T.powerset, w A / ∏ p ∈ A, g p = + (∏ p ∈ T, (1 - (g p)⁻¹)) * + ∑ B ∈ T.powerset, (∑ A ∈ B.powerset, w A) / ∏ p ∈ B, (g p - 1) := by + simp_rw [mul_sum, sum_div, mul_sum, div_eq_mul_inv, ← prod_inv_distrib] + rw [sum_comm' (t' := T.powerset) (s' := fun A ↦ T.powerset.filter (A ⊆ ·))] + swap + · intro B A + simp only [mem_powerset, mem_filter] + constructor + · rintro ⟨hB, hA⟩ + exact ⟨⟨hB, hA⟩, hA.trans hB⟩ + · rintro ⟨⟨hB, hA⟩, -⟩ + exact ⟨hB, hA⟩ + refine sum_congr rfl fun A hA ↦ ?_ + rw [mem_powerset] at hA + rw [← mul_sum, ← mul_sum, sum_powerset_filter_superset_prod hA, mul_left_comm] + congr 1 + rw [← prod_sdiff hA, show ∀ a b c d : ℝ, a * b * (c * d) = c * b * (a * d) by intros; ring, + ← prod_mul_distrib, ← prod_mul_distrib] + rw [prod_congr rfl (s₁ := T \ A) (g := fun _ ↦ (1 : ℝ)), prod_const_one, mul_one] + · refine prod_congr rfl fun p hp ↦ ?_ + obtain ⟨h0, h1⟩ := hg p (hA hp) + have : g p - 1 ≠ 0 := sub_ne_zero.2 h1 + field_simp + · intro p hp + obtain ⟨h0, h1⟩ := hg p (sdiff_subset hp) + have : g p - 1 ≠ 0 := sub_ne_zero.2 h1 + field_simp + ring + + +/-- The main-term comparison in [I78, Lemma 1]: if the partial sums of `w` are `≤ 0` on nonempty +sets ("condition (−)") and `1 < g ≤ f` on `T`, then +`∏ (1 - 1/f) · (∑_A w(A) / ∏_A g) / ∏ (1 - 1/g) ≤ ∑_A w(A) / ∏_A f`. -/ +theorem prod_mul_sum_div_le_sum (T : Finset ℕ) (f g : ℕ → ℝ) (hg : ∀ p ∈ T, 1 < g p) + (hgf : ∀ p ∈ T, g p ≤ f p) (w : Finset ℕ → ℝ) + (hw : ∀ B ⊆ T, B.Nonempty → ∑ A ∈ B.powerset, w A ≤ 0) : + (∏ p ∈ T, (1 - (f p)⁻¹)) * + ((∑ A ∈ T.powerset, w A / ∏ p ∈ A, g p) / ∏ p ∈ T, (1 - (g p)⁻¹)) ≤ + ∑ A ∈ T.powerset, w A / ∏ p ∈ A, f p := by + have hf : ∀ p ∈ T, 1 < f p := fun p hp ↦ (hg p hp).trans_le (hgf p hp) + have hne : ∀ {h : ℕ → ℝ}, (∀ p ∈ T, 1 < h p) → ∀ p ∈ T, h p ≠ 0 ∧ h p ≠ 1 := + fun hh p hp ↦ ⟨(zero_lt_one.trans (hh p hp)).ne', (hh p hp).ne'⟩ + have hpos : ∀ {h : ℕ → ℝ}, (∀ p ∈ T, 1 < h p) → 0 < ∏ p ∈ T, (1 - (h p)⁻¹) := + fun hh ↦ prod_pos fun p hp ↦ sub_pos.2 (inv_lt_one_of_one_lt₀ (hh p hp)) + rw [sum_powerset_div_prod T g (hne hg), sum_powerset_div_prod T f (hne hf), + mul_div_cancel_left₀ _ (hpos hg).ne'] + refine mul_le_mul_of_nonneg_left (sum_le_sum fun B hB ↦ ?_) (hpos hf).le + rw [mem_powerset] at hB + rcases B.eq_empty_or_nonempty with rfl | hBne + · simp + have h0 : 0 < ∏ p ∈ B, (g p - 1) := prod_pos fun p hp ↦ sub_pos.2 (hg p (hB hp)) + have h1 : ∏ p ∈ B, (g p - 1) ≤ ∏ p ∈ B, (f p - 1) := + prod_le_prod₀ (fun p hp ↦ (sub_pos.2 (hg p (hB hp))).le) + fun p hp ↦ sub_le_sub_right (hgf p (hB hp)) 1 + rw [div_eq_mul_inv, div_eq_mul_inv] + exact mul_le_mul_of_nonpos_left (inv_anti₀ h0 h1) (hw B hB hBne) + +/-! ### Rosser's weights on subsets of the primes below `z` -/ + +/-- Sums over `rosserSet` as sums over sets of primes below `z`. -/ +theorem sum_rosserSet_eq_sum_powerset {M : Type*} [AddCommMonoid M] (lower : Bool) (y z : ℝ) + (F : Finset ℕ → M) : + ∑ d ∈ rosserSet lower y z, F d.primeFactors = + ∑ A ∈ (primesLT z).powerset, if ∏ p ∈ A, p ∈ rosserSet lower y z then F A else 0 := by + rw [← sum_filter] + have hprime : ∀ A ∈ (primesLT z).powerset, ∀ p ∈ A, p.Prime := fun A hA p hp ↦ + prime_of_mem_primesLT (mem_powerset.1 hA hp) + refine sum_nbij' Nat.primeFactors (fun A ↦ ∏ p ∈ A, p) ?_ ?_ ?_ ?_ ?_ + · intro d hd + refine mem_filter.2 ⟨mem_powerset.2 (primeFactors_subset_of_mem_rosserSet hd), ?_⟩ + rwa [Nat.prod_primeFactors_of_squarefree (squarefree_of_mem_rosserSet hd)] + · intro A hA + exact (mem_filter.1 hA).2 + · intro d hd + exact Nat.prod_primeFactors_of_squarefree (squarefree_of_mem_rosserSet hd) + · intro A hA + exact Nat.primeFactors_prod (hprime A (mem_filter.1 hA).1) + · intro d _ + rfl + +theorem sum_rosserSet_eq_sum_powerset' {M : Type*} [AddCommMonoid M] (lower : Bool) (y z : ℝ) + (G : ℕ → M) : + ∑ d ∈ rosserSet lower y z, G d = + ∑ A ∈ (primesLT z).powerset, + if ∏ p ∈ A, p ∈ rosserSet lower y z then G (∏ p ∈ A, p) else 0 := by + rw [← sum_rosserSet_eq_sum_powerset lower y z (fun A ↦ G (∏ p ∈ A, p))] + refine sum_congr rfl fun d hd ↦ ?_ + rw [Nat.prod_primeFactors_of_squarefree (squarefree_of_mem_rosserSet hd)] + +/-- `λ_A = μ(∏_{p ∈ A} p)` if `∏_{p ∈ A} p ∈ D⁻`, and `0` otherwise. -/ +noncomputable def rosserWeight (y z : ℝ) (A : Finset ℕ) : ℝ := + if ∏ p ∈ A, p ∈ rosserSet true y z then (μ (∏ p ∈ A, p) : ℝ) else 0 + +theorem sum_moebius_rosserSet_eq (y z : ℝ) (F : ℕ → ℝ) : + ∑ d ∈ rosserSet true y z, (μ d : ℝ) * F d = + ∑ A ∈ (primesLT z).powerset, rosserWeight y z A * F (∏ p ∈ A, p) := by + rw [sum_rosserSet_eq_sum_powerset'] + refine sum_congr rfl fun A _ ↦ ?_ + rw [rosserWeight] + split_ifs <;> simp + +theorem rosserMain_eq_sum_rosserWeight (y z : ℝ) : + rosserMain true y z = + ∑ A ∈ (primesLT z).powerset, rosserWeight y z A / ∏ p ∈ A, (p : ℝ) := by + have := sum_moebius_rosserSet_eq y z (fun d ↦ (d : ℝ)⁻¹) + simp only [Nat.cast_prod] at this + simp_rw [rosserMain, div_eq_mul_inv] + exact this + +theorem sum_abs_rosserWeight_le (y z : ℝ) : + ∑ A ∈ (primesLT z).powerset, |rosserWeight y z A| ≤ #(rosserSet true y z) := by + have : ∑ A ∈ (primesLT z).powerset, |rosserWeight y z A| = + ∑ d ∈ rosserSet true y z, |(μ d : ℝ)| := by + rw [sum_rosserSet_eq_sum_powerset'] + refine sum_congr rfl fun A _ ↦ ?_ + rw [rosserWeight] + split_ifs <;> simp + rw [this, card_eq_sum_ones, Nat.cast_sum, Nat.cast_one] + refine sum_le_sum fun d _ ↦ ?_ + exact_mod_cast abs_moebius_le_one + + +theorem prod_dvd_prod_iff_subset {A B : Finset ℕ} (hA : ∀ p ∈ A, p.Prime) + (hB : ∀ p ∈ B, p.Prime) : ∏ p ∈ A, p ∣ ∏ p ∈ B, p ↔ A ⊆ B := by + refine ⟨fun h ↦ ?_, fun h ↦ prod_dvd_prod_of_subset _ _ _ h⟩ + have := Nat.primeFactors_mono h (prod_ne_zero_iff.2 fun p hp ↦ (hB p hp).ne_zero) + rwa [Nat.primeFactors_prod hA, Nat.primeFactors_prod hB] at this + +/-- The sieve property in terms of subsets ("condition (−)" of [I78, Lemma 1]): +`∑_{A ⊆ B} λ_A ≤ [B = ∅]`. -/ +theorem sum_powerset_rosserWeight_le (y : ℝ) {z : ℝ} {B : Finset ℕ} (hB : B ⊆ primesLT z) : + ∑ A ∈ B.powerset, rosserWeight y z A ≤ if B = ∅ then 1 else 0 := by + have hBp : ∀ p ∈ B, p.Prime := fun p hp ↦ prime_of_mem_primesLT (hB hp) + have h1 : ∑ A ∈ B.powerset, rosserWeight y z A = + ∑ A ∈ (primesLT z).powerset, + rosserWeight y z A * (if ∏ p ∈ A, p ∣ ∏ p ∈ B, p then 1 else 0) := by + have : B.powerset = (primesLT z).powerset.filter (· ⊆ B) := by + ext A + simp only [mem_powerset, mem_filter] + exact ⟨fun h ↦ ⟨h.trans hB, h⟩, fun h ↦ h.2⟩ + rw [this, sum_filter] + refine sum_congr rfl fun A hA ↦ ?_ + simp only [prod_dvd_prod_iff_subset (fun p hp ↦ prime_of_mem_primesLT (mem_powerset.1 hA hp)) + hBp] + split_ifs <;> simp + have h2 : ∑ A ∈ (primesLT z).powerset, + rosserWeight y z A * (if ∏ p ∈ A, p ∣ ∏ p ∈ B, p then 1 else 0) = + ((∑ d ∈ (rosserSet true y z).filter (· ∣ ∏ p ∈ B, p), μ d : ℤ) : ℝ) := by + rw [← sum_moebius_rosserSet_eq y z (fun d ↦ if d ∣ ∏ p ∈ B, p then 1 else 0), sum_filter, + Int.cast_sum] + refine sum_congr rfl fun d _ ↦ ?_ + split_ifs <;> simp + have h3 := (rosserSieve_of_dvd_primorialLT (z := z) y + (prod_dvd_prod_of_subset _ _ _ hB : ∏ p ∈ B, p ∣ primorialLT z)).1 + have h4 : (∏ p ∈ B, p = 1) ↔ B = ∅ := by + constructor + · intro h + have := Nat.primeFactors_prod hBp + rw [h, Nat.primeFactors_one] at this + exact this.symm + · rintro rfl + simp + rw [h1, h2] + simp only [h4] at h3 + exact_mod_cast h3 + +/-! ### Counting multiples in an interval -/ + +/-- `|#{k < X : d ∣ x + k} - X / d| ≤ 1`. -/ +theorem abs_card_filter_dvd_sub_le (x : ℤ) (X : ℕ) {d : ℕ} (hd : 0 < d) : + |(#((range X).filter fun k : ℕ ↦ (d : ℤ) ∣ x + k) : ℝ) - X / d| ≤ 1 := by + have hcard : #((range X).filter fun k : ℕ ↦ (d : ℤ) ∣ x + k) = + #((Ico x (x + X)).filter ((d : ℤ) ∣ ·)) := by + refine card_nbij' (fun k ↦ x + k) (fun t ↦ (t - x).toNat) ?_ ?_ ?_ ?_ + · intro k hk + simp only [coe_filter, mem_range, Set.mem_ofPred_eq, mem_Ico] at hk ⊢ + exact ⟨⟨by omega, by omega⟩, hk.2⟩ + · intro t ht + simp only [coe_filter, mem_range, Set.mem_ofPred_eq, mem_Ico] at ht ⊢ + refine ⟨by omega, ?_⟩ + rw [Int.toNat_of_nonneg (by omega)] + simpa using ht.2 + · intro k _ + simp + · intro t ht + simp only [coe_filter, Set.mem_ofPred_eq, mem_Ico] at ht + simp only + omega + have h := Int.Ico_filter_dvd_card x (x + X) (r := d) (by exact_mod_cast hd) + set u : ℚ := x / (d : ℤ) + set v : ℚ := (x + X : ℤ) / (d : ℤ) + have hdq : (0 : ℚ) < (d : ℤ) := by exact_mod_cast hd + have hvu : v = u + X / d := by + simp only [v, u] + push_cast + ring + have hX : (0 : ℚ) ≤ X / d := by positivity + have hle : ⌈u⌉ ≤ ⌈v⌉ := Int.ceil_mono (by rw [hvu]; linarith) + rw [max_eq_left (sub_nonneg.2 hle)] at h + have hq : |((⌈v⌉ - ⌈u⌉ : ℤ) : ℚ) - X / d| ≤ 1 := by + have h1 := Int.le_ceil v + have h2 := Int.ceil_lt_add_one v + have h3 := Int.le_ceil u + have h4 := Int.ceil_lt_add_one u + rw [abs_le] + push_cast + constructor <;> linarith + rw [hcard] + have : (#((Ico x (x + X)).filter ((d : ℤ) ∣ ·)) : ℝ) = ((⌈v⌉ - ⌈u⌉ : ℤ) : ℝ) := by + exact_mod_cast h + rw [this] + have hq' := (Rat.cast_le (K := ℝ)).2 hq + push_cast at hq' ⊢ + exact hq' + + +/-! ### The shifted sieve -/ + +variable {z : ℝ} + +/-- [I78, Lemma 1] for an interval of `X` consecutive integers, with an explicit matching `e` +of the primes below `z` with `S` such that `p ≤ e p`. -/ +theorem shiftedSieve_of_bijOn (y : ℝ) {S : Finset ℕ} {e : ℕ → ℕ} + (he : Set.BijOn e (primesLT z) S) (hle : ∀ p ∈ primesLT z, p ≤ e p) + (hS : ∀ q ∈ S, q.Prime) (x : ℤ) (X : ℕ) : + (X : ℝ) * (∏ q ∈ S, (1 - (q : ℝ)⁻¹)) * (rosserMain true y z / R z) - + #(rosserSet true y z) ≤ + #((range X).filter fun k : ℕ ↦ ∀ q ∈ S, ¬ (q : ℤ) ∣ x + k) := by + set T := primesLT z + set w := rosserWeight y z + set n : Finset ℕ → ℕ := fun A ↦ ∏ p ∈ A, e p + have heS : ∀ p ∈ T, e p ∈ S := fun p hp ↦ he.mapsTo hp + have hePrime : ∀ p ∈ T, (e p).Prime := fun p hp ↦ hS _ (heS p hp) + have hn : ∀ A ∈ T.powerset, 0 < n A := fun A hA ↦ + prod_pos fun p hp ↦ (hePrime p (mem_powerset.1 hA hp)).pos + -- the sieve inequality for a single integer + have ha : ∀ k : ℕ, ∑ A ∈ T.powerset, w A * (if (n A : ℤ) ∣ x + k then 1 else 0) ≤ + if ∀ q ∈ S, ¬ (q : ℤ) ∣ x + k then 1 else 0 := by + intro k + set B := T.filter fun p ↦ (e p : ℤ) ∣ x + k + have hB : B ⊆ T := filter_subset _ _ + have h1 : ∀ A ∈ T.powerset, ((n A : ℤ) ∣ x + k ↔ A ⊆ B) := by + intro A hA + rw [mem_powerset] at hA + constructor + · intro h p hp + refine mem_filter.2 ⟨hA hp, (Int.natCast_dvd_natCast.2 ?_).trans h⟩ + exact dvd_prod_of_mem _ hp + · intro h + simp only [n, Nat.cast_prod] + refine prod_dvd_of_coprime ?_ fun p hp ↦ (mem_filter.1 (h hp)).2 + intro p hp q hq hpq + refine Nat.isCoprime_iff_coprime.2 ((Nat.coprime_primes (hePrime p (hA hp)) + (hePrime q (hA hq))).2 fun h' ↦ hpq (he.injOn (hA hp) (hA hq) h')) + have h2 : B = ∅ ↔ ∀ q ∈ S, ¬ (q : ℤ) ∣ x + k := by + rw [filter_eq_empty_iff] + constructor + · intro h q hq hqk + obtain ⟨p, hp, rfl⟩ := he.surjOn hq + exact h hp hqk + · intro h p hp + exact h _ (heS p hp) + have h3 : B.powerset = T.powerset.filter (· ⊆ B) := by + ext A + simp only [mem_powerset, mem_filter] + exact ⟨fun h ↦ ⟨h.trans hB, h⟩, fun h ↦ h.2⟩ + calc ∑ A ∈ T.powerset, w A * (if (n A : ℤ) ∣ x + k then 1 else 0) + = ∑ A ∈ B.powerset, w A := by + rw [h3, sum_filter] + refine sum_congr rfl fun A hA ↦ ?_ + simp only [h1 A hA] + split_ifs <;> simp + _ ≤ if B = ∅ then 1 else 0 := sum_powerset_rosserWeight_le y hB + _ = _ := by simp only [h2] + -- summing over the interval + have hb : ∑ A ∈ T.powerset, w A * #((range X).filter fun k : ℕ ↦ (n A : ℤ) ∣ x + k) ≤ + #((range X).filter fun k : ℕ ↦ ∀ q ∈ S, ¬ (q : ℤ) ∣ x + k) := by + simp_rw [natCast_card_filter, mul_sum] + rw [sum_comm] + exact sum_le_sum fun k _ ↦ ha k + -- the remainder + have hc : ∀ A ∈ T.powerset, w A * X / n A - |w A| ≤ + w A * #((range X).filter fun k : ℕ ↦ (n A : ℤ) ∣ x + k) := by + intro A hA + have h := abs_card_filter_dvd_sub_le x X (hn A hA) + have h' : |w A * (#((range X).filter fun k : ℕ ↦ (n A : ℤ) ∣ x + k) - X / n A)| ≤ |w A| := by + rw [abs_mul] + exact mul_le_of_le_one_right (abs_nonneg _) h + have := neg_abs_le (w A * (#((range X).filter fun k : ℕ ↦ (n A : ℤ) ∣ x + k) - X / n A)) + rw [mul_div_assoc] + linarith [mul_sub (w A) (#((range X).filter fun k : ℕ ↦ (n A : ℤ) ∣ x + k) : ℝ) (X / n A)] + -- the main term + have hd : (X : ℝ) * (∏ q ∈ S, (1 - (q : ℝ)⁻¹)) * (rosserMain true y z / R z) ≤ + ∑ A ∈ T.powerset, w A * X / n A := by + have hprodS : ∏ q ∈ S, (1 - (q : ℝ)⁻¹) = ∏ p ∈ T, (1 - (e p : ℝ)⁻¹) := + (prod_nbij e heS he.injOn he.surjOn fun p _ ↦ rfl).symm + have hmain := prod_mul_sum_div_le_sum T (fun p ↦ (e p : ℝ)) (fun p ↦ (p : ℝ)) + (fun p hp ↦ by exact_mod_cast (prime_of_mem_primesLT hp).one_lt) + (fun p hp ↦ by exact_mod_cast hle p hp) w + (fun B hB hBne ↦ by + simpa [hBne.ne_empty] using sum_powerset_rosserWeight_le y hB) + rw [← rosserMain_eq_sum_rosserWeight] at hmain + simp_rw [mul_div_right_comm _ (X : ℝ), ← sum_mul, mul_comm _ (X : ℝ)] + rw [mul_assoc, hprodS] + refine mul_le_mul_of_nonneg_left ?_ (Nat.cast_nonneg X) + simpa [n, R, T] using hmain + have he' := sum_abs_rosserWeight_le y z + have hsum : ∑ A ∈ T.powerset, w A * X / n A - ∑ A ∈ T.powerset, |w A| ≤ + ∑ A ∈ T.powerset, w A * #((range X).filter fun k : ℕ ↦ (n A : ℤ) ∣ x + k) := by + rw [← sum_sub_distrib] + exact sum_le_sum hc + linarith + + +/-- Any `π(z)` primes can be matched with the primes below `z` so that each prime below `z` is +matched with a prime at least as large. -/ +theorem exists_bijOn_primesLT_le {S : Finset ℕ} (hS : ∀ q ∈ S, q.Prime) + (hcard : #S = #(primesLT z)) : + ∃ e : ℕ → ℕ, Set.BijOn e (primesLT z) S ∧ ∀ p ∈ primesLT z, p ≤ e p := + exists_bijOn_le hcard fun q hq _ ht hqt ↦ + mem_primesLT.2 ⟨hS q hq, (Nat.cast_lt.2 hqt).trans (lt_of_mem_primesLT ht)⟩ + +/-- [I78, Lemma 1] (the shifted sieve) for an interval of `X` consecutive integers `x + k`, +`0 ≤ k < X`, sifted by an arbitrary set `S` of `π(z)` primes, with Rosser's lower-bound weights: +`#{k < X : (x + k, ∏_{q ∈ S} q) = 1} ≥ X ∏_{q ∈ S} (1 - 1/q) · (∑_{d ∈ D⁻} μ(d)/d) / R(z) - |D⁻|`. +-/ +theorem shiftedSieve (y : ℝ) {S : Finset ℕ} (hS : ∀ q ∈ S, q.Prime) + (hcard : #S = #(primesLT z)) (x : ℤ) (X : ℕ) : + (X : ℝ) * (∏ q ∈ S, (1 - (q : ℝ)⁻¹)) * (rosserMain true y z / R z) - + #(rosserSet true y z) ≤ + #((range X).filter fun k : ℕ ↦ ∀ q ∈ S, ¬ (q : ℤ) ∣ x + k) := by + obtain ⟨e, he, hle⟩ := exists_bijOn_primesLT_le hS hcard + exact shiftedSieve_of_bijOn y he hle hS x X + +/-- `R(z) ≤ ∏_{q ∈ S} (1 - 1/q)` for any set `S` of `π(z)` primes. -/ +theorem R_le_prod_of_card_eq {S : Finset ℕ} (hS : ∀ q ∈ S, q.Prime) + (hcard : #S = #(primesLT z)) : R z ≤ ∏ q ∈ S, (1 - (q : ℝ)⁻¹) := by + obtain ⟨e, he, hle⟩ := exists_bijOn_primesLT_le hS hcard + rw [← prod_nbij e (fun p hp ↦ he.mapsTo hp) he.injOn he.surjOn fun p _ ↦ rfl, R] + refine prod_le_prod₀ (fun p hp ↦ sub_nonneg.2 (inv_le_one_of_one_le₀ ?_)) fun p hp ↦ ?_ + · exact_mod_cast (prime_of_mem_primesLT hp).one_lt.le + · have h1 : (0 : ℝ) < p := by exact_mod_cast (prime_of_mem_primesLT hp).pos + have h2 : (p : ℝ) ≤ e p := by exact_mod_cast hle p hp + exact sub_le_sub_left (inv_anti₀ h1 h2) 1 + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/Calculus.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/Calculus.lean new file mode 100644 index 000000000..ee2093adf --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/Calculus.lean @@ -0,0 +1,221 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.Defs +public import LeanPool.IwaniecLinearSieve.SieveFunctions.LemmaFive +import LeanPool.IwaniecLinearSieve.SieveFunctions.Defs +import LeanPool.IwaniecLinearSieve.SieveMajorants.Properties +import Mathlib.NumberTheory.Chebyshev +import Mathlib.Order.CompletePartialOrder +import Std.Tactic.BVDecide.Normalize.Bool + +/-! +# Calculus identities for the majorants of [I71, §4] + +* `fSieve_eq_integral_mainMaj`: `f(s) = ∫_s^∞ M⁺(t-1)/(t-1) dt` for `s ≥ 2`, where + `M⁺ = mainMaj false = F + (3 - ·)⁺`; this combines (3.6) with + `g₂(s) = ∫_s^∞ (3 - (t-1))⁺/(t-1) dt` (`g_two_eq_integral`). +* `mainMaj_false_eq_integral`: `M⁺(s) = (3 - s)⁺ + ∫_{max s 3}^∞ f(t-1)/(t-1) dt`. +* `errMaj_eq_integral`: (3.13), (3.14) for `G lower`, on `s ≥ 2` (lower sieve) and `s ≥ 3` + (upper sieve); `errMaj false = 𝔉 = 1` on `s ≤ 3`. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory + +namespace IwaniecLinearSieve + +/-! ### `mainMaj` -/ + +@[simp] theorem mainMaj_true (s : ℝ) : mainMaj true s = fSieve s := rfl + +@[simp] theorem mainMaj_false (s : ℝ) : mainMaj false s = FSieve s + max (3 - s) 0 := rfl + +theorem continuous_mainMaj : ∀ lower, Continuous (mainMaj lower) + | true => continuous_fSieve + | false => continuous_FSieve.add ((continuous_const.sub continuous_id).max continuous_const) + +theorem mainMaj_nonneg : ∀ (lower : Bool) (s : ℝ), 0 ≤ mainMaj lower s + | true, s => fSieve_nonneg s + | false, s => add_nonneg (FSieve_nonneg s) (le_max_right _ _) + +theorem mainMaj_antitone : ∀ lower, Antitone (mainMaj lower) + | true => fSieve_antitone + | false => fun u v h => by + simp only [mainMaj_false] + exact add_le_add (FSieve_antitone h) (max_le_max (by linarith) le_rfl) + +theorem mainMaj_le_MSieve : ∀ (lower : Bool) (s : ℝ), mainMaj lower s ≤ MSieve s + | true, s => by + have := FSieve_nonneg s; have := le_max_right (3 - s) 0 + simp only [mainMaj_true, MSieve]; linarith + | false, s => by + have := fSieve_nonneg s + simp only [mainMaj_false, MSieve]; linarith + +/-- `g₂(s) = ∫_s^∞ (3 - (t-1))⁺/(t-1) dt` for `s ≥ 2`. -/ +theorem g_two_eq_integral {s : ℝ} (hs : 2 ≤ s) : + IntegrableOn (fun t => max (3 - (t - 1)) 0 / (t - 1)) (Ioi s) ∧ + g 2 s = ∫ t in Ioi s, max (3 - (t - 1)) 0 / (t - 1) := by + have hz : ∀ t : ℝ, 4 ≤ t → max (3 - (t - 1)) 0 / (t - 1) = 0 := fun t ht => by + rw [max_eq_right (by linarith), zero_div] + rcases le_or_gt s 4 with hs4 | hs4 + · have heq : EqOn (fun t : ℝ => max (3 - (t - 1)) 0 / (t - 1)) (fun t => 3 / (t - 1) - 1) + (Icc s 4) := fun t ht => by + have : 0 < t - 1 := by linarith [ht.1] + simp only + rw [max_eq_left (by linarith [ht.2])] + field_simp + have hcont : ContinuousOn (fun t : ℝ => 3 / (t - 1) - 1) (Icc s 4) := + (continuousOn_const.div (continuousOn_id.sub continuousOn_const) fun t ht => by + simp only [Pi.sub_apply, id]; linarith [ht.1]).sub continuousOn_const + obtain ⟨hI, hE⟩ := integral_Ioi_eq_of_eq_zero hs4 + (((hcont.congr heq).integrableOn_Icc).mono_set Ioc_subset_Icc_self) hz + refine ⟨hI, ?_⟩ + rw [hE, intervalIntegral.integral_congr (heq.mono (uIcc_of_le hs4).subset)] + have hderiv : ∀ t ∈ uIcc s 4, HasDerivAt (fun t => 3 * log (t - 1) - t) (3 / (t - 1) - 1) t := + fun t ht => by + rw [uIcc_of_le hs4] at ht + have h1 : t - 1 ≠ 0 := by linarith [ht.1] + have := ((((hasDerivAt_id' t).sub_const 1).log h1).const_mul 3).sub (hasDerivAt_id' t) + convert this using 1; field_simp + rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hderiv + (hcont.mono (uIcc_of_le hs4).subset |>.intervalIntegrable), g_two_eq ⟨hs, hs4⟩, + log_div (by norm_num) (by linarith)] + norm_num; ring + · obtain ⟨hI, hE⟩ := integral_Ioi_eq_of_eq_zero le_rfl (by simp) fun t ht => hz t (by linarith) + exact ⟨hI, by rw [hE, intervalIntegral.integral_same, g_two_of_four_le hs4.le]⟩ + +theorem integrableOn_mainMaj_false_shift {s : ℝ} (hs : 2 ≤ s) : + IntegrableOn (fun t => mainMaj false (t - 1) / (t - 1)) (Ioi s) := by + simp only [mainMaj_false, add_div] + exact (integrableOn_FSieve_shift hs).add (g_two_eq_integral hs).1 + +/-- `f(s) = ∫_s^∞ M⁺(t-1)/(t-1) dt` for `s ≥ 2`, with `M⁺ = F + (3 - ·)⁺` ((3.6) together with +`g_two_eq_integral`). -/ +theorem fSieve_eq_integral_mainMaj {s : ℝ} (hs : 2 ≤ s) : + fSieve s = ∫ t in Ioi s, mainMaj false (t - 1) / (t - 1) := by + simp only [mainMaj_false, add_div] + rw [integral_add (integrableOn_FSieve_shift hs) (g_two_eq_integral hs).1, + ← (g_two_eq_integral hs).2, fSieve_eq_integral hs] + +/-- `M⁺(s) = (3 - s)⁺ + ∫_{max s 3}^∞ f(t-1)/(t-1) dt` for every `s` ((3.7)). -/ +theorem mainMaj_false_eq_integral (s : ℝ) : + mainMaj false s = max (3 - s) 0 + ∫ t in Ioi (max s 3), fSieve (t - 1) / (t - 1) := by + have hF : FSieve s = FSieve (max s 3) := by + rcases le_total s 3 with h | h + · rw [max_eq_right h, FSieve_of_le_three h] + · rw [max_eq_left h] + rw [mainMaj_false, hF, FSieve_eq_integral (le_max_right _ _), add_comm] + +/-- `mainMaj` in terms of `fr`: `M true = f` and, on `s ≥ 3`, `M false = F`. -/ +theorem mainMaj_false_of_three_le {s : ℝ} (hs : 3 ≤ s) : mainMaj false s = FSieve s := by + rw [mainMaj_false, max_eq_right (by linarith), add_zero] + +/-! ### `errMaj` -/ + +@[simp] theorem errMaj_true : errMaj true = majf := rfl + +@[simp] theorem errMaj_false : errMaj false = majF := rfl + +/-- The left end of the domain of the identities (3.13), (3.14): `2` for `𝔣`, `3` for `𝔉`. -/ +def errLower : Bool → ℝ + | true => 2 + | false => 3 + +@[simp] theorem errLower_true : errLower true = 2 := rfl + +@[simp] theorem errLower_false : errLower false = 3 := rfl + +theorem two_le_errLower (lower : Bool) : 2 ≤ errLower lower := by + cases lower <;> norm_num [errLower] + +theorem errLower_le_three (lower : Bool) : errLower lower ≤ 3 := by + cases lower <;> norm_num [errLower] + +theorem sMin_le_errLower (lower : Bool) : sMin lower ≤ errLower lower := by + cases lower <;> norm_num [sMin, errLower] + +theorem errMaj_eq_majG {lower : Bool} {r : ℕ} (h : Even r ↔ lower = true) : + errMaj lower = majG r := by + cases lower + · rw [majG_of_odd (Nat.not_even_iff_odd.1 fun h' => by simpa using h.1 h')]; rfl + · rw [majG_of_even (h.2 rfl)]; rfl + +theorem majG_add_two (r : ℕ) : majG (r + 2) = majG r := by + rcases Nat.even_or_odd r with hr | hr + · rw [majG_of_even hr, majG_of_even (hr.add (by decide))] + · rw [majG_of_odd hr, majG_of_odd (hr.add_even (by decide))] + +theorem continuous_errMaj : ∀ lower, Continuous (errMaj lower) + | true => continuous_majf + | false => continuous_majF + +theorem errMaj_pos : ∀ (lower : Bool) (s : ℝ), 0 < errMaj lower s + | true, s => majf_pos s + | false, s => majF_pos s + +theorem errMaj_antitone : ∀ lower, Antitone (errMaj lower) + | true => majf_antitone + | false => majF_antitone + +theorem errMaj_mem : ∀ (lower : Bool) (s : ℝ), + bigM s / 3 ≤ errMaj lower s ∧ errMaj lower s ≤ 2 * bigM s / 3 + | true, s => majf_mem s + | false, s => majF_mem s + +theorem errMaj_le_two (lower : Bool) (s : ℝ) : errMaj lower s ≤ 2 := by + linarith [(errMaj_mem lower s).2, bigM_le_three s] + +theorem errMaj_false_of_le_three {s : ℝ} (hs : s ≤ 3) : errMaj false s = 1 := + majF_of_le_three hs + +/-- The derivative of `G lower` is `-G (!lower) (t-1) t/(t-1)²` for `t > 2` (`𝔣`) and +`t > 3` (`𝔉`). -/ +theorem hasDerivAt_errMaj : ∀ (lower : Bool) {t : ℝ}, errLower lower < t → + HasDerivAt (errMaj lower) (-(errMaj (!lower) (t - 1) * t / (t - 1) ^ 2)) t + | true, _, ht => (hasDerivAt_majf ht).congr_deriv (by simp; ring) + | false, _, ht => (hasDerivAt_majF ht).congr_deriv (by simp; ring) + +theorem tendsto_errMaj_atTop : ∀ lower, Tendsto (errMaj lower) atTop (𝓝 0) + | true => tendsto_majf_atTop + | false => tendsto_majF_atTop + +theorem errMaj_shift_pos (lower : Bool) {t : ℝ} (ht : 1 < t) : + 0 < errMaj lower (t - 1) * t / (t - 1) ^ 2 := by + have h1 : 0 < t - 1 := by linarith + have := errMaj_pos lower (t - 1) + have : 0 < t := by linarith + positivity + +/-- (3.13), (3.14): for `s ≥ 2` (`lower = true`) or `s ≥ 3` (`lower = false`), +`G lower (s) = ∫_s^∞ G (!lower) (t-1) t/(t-1)² dt`, the integrand being integrable. -/ +theorem errMaj_eq_integral (lower : Bool) {s : ℝ} (hs : errLower lower ≤ s) : + IntegrableOn (fun t => errMaj (!lower) (t - 1) * t / (t - 1) ^ 2) (Ioi s) ∧ + errMaj lower s = ∫ t in Ioi s, errMaj (!lower) (t - 1) * t / (t - 1) ^ 2 := by + have h2 := two_le_errLower lower + have hcont : ContinuousWithinAt (fun t => -errMaj lower t) (Ici s) s := + (continuous_errMaj lower).neg.continuousWithinAt + have hderiv : ∀ t ∈ Ioi s, HasDerivAt (fun t => -errMaj lower t) + (errMaj (!lower) (t - 1) * t / (t - 1) ^ 2) t := fun t ht => + (hasDerivAt_errMaj lower (hs.trans_lt ht)).neg.congr_deriv (by ring) + have hpos : ∀ t ∈ Ioi s, 0 ≤ errMaj (!lower) (t - 1) * t / (t - 1) ^ 2 := fun t ht => + (errMaj_shift_pos _ (by linarith [ht.out])).le + have hlim : Tendsto (fun t => -errMaj lower t) atTop (𝓝 0) := by + simpa using (tendsto_errMaj_atTop lower).neg + refine ⟨integrableOn_Ioi_deriv_of_nonneg hcont hderiv hpos hlim, ?_⟩ + rw [integral_Ioi_of_hasDerivAt_of_nonneg hcont hderiv hpos hlim]; ring + +/-- The finite-interval form: `∫_s^b G (!lower) (t-1) t/(t-1)² dt = G lower (s) - G lower (b)`. -/ +theorem integral_errMaj_shift (lower : Bool) {s b : ℝ} (hs : errLower lower ≤ s) (hsb : s ≤ b) : + ∫ t in s..b, errMaj (!lower) (t - 1) * t / (t - 1) ^ 2 = errMaj lower s - errMaj lower b := by + obtain ⟨hI, hE⟩ := errMaj_eq_integral lower hs + rw [hE, (errMaj_eq_integral lower (hs.trans hsb)).2, intervalIntegral.integral_Ioi_sub_Ioi hI hsb] + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/Corollaries.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/Corollaries.lean new file mode 100644 index 000000000..82f2cf608 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/Corollaries.lean @@ -0,0 +1,624 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Rosser +public import LeanPool.IwaniecLinearSieve.LinearSieve.Calculus +public import LeanPool.IwaniecLinearSieve.PrimeSums.Error +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaEleven +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaSeven +import LeanPool.IwaniecLinearSieve.PrimeSums.Lemma13 +import LeanPool.IwaniecLinearSieve.SieveMajorants.Lemmas +import LeanPool.IwaniecLinearSieve.SieveMajorants.Properties +import Mathlib.Algebra.Order.Star.Real +import Std.Tactic.BVDecide.Normalize.Bool + +/-! +# [I71, Corollaries 1 and 3 to Lemma 13] + +With `L = log y` and `t_p = L / log p`, so that the inner level of the recursion at `p` is +`(y/p, p)` with parameter `t_p - 1` (`log (y/p) = log p · (t_p - 1)`). + +* `lemma13_param`: Lemma 13 in the variable `t = L / log u`: for `F ≥ 0` antitone on `[α, β]`, + `|∑_{y^{1/β} ≤ p ≤ y^{1/α}} F(t_p)/p - ∫_α^β F(t)/t dt| ≤ C F(α) pntE(y^{1/β})` + (substitution `u = e^{L/t}` in `lemma13_mono_of_subset`). +* `cor1`: Corollary 1, for the primes `y^{1/β} ≤ p < y^{1/α}` and any `M ≥ 0` antitone on + `[α - 1, β - 1]`. +* `cor3`: Corollary 3, for the primes `y^{1/b} ≤ p` in `rosserPrimes lower y (y^{1/s})` + (the primes of the recursion), uniformly in `sMin lower ≤ s`, with `s₀ = e^{32}` and the upper + limit `ξ` replaced by any `b ≥ s₀` with `160 b² log⁴ b ≤ L²` and `y^{1/b} ≥ 2`. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory Finset + +namespace IwaniecLinearSieve + +/-! ### Lemma 13 in the variable `t = log y / log u` -/ +theorem integral_comp_log_div {F : ℝ → ℝ} {y α β : ℝ} (hy : 1 < y) (hα : 0 < α) (hαβ : α ≤ β) : + ∫ u in y ^ (1 / β)..y ^ (1 / α), F (log y / log u) / (u * log u) = + ∫ t in α..β, F t / t := by + set L := log y + have hL : 0 < L := log_pos hy + have hy0 : 0 < y := by linarith + set f : ℝ → ℝ := fun t => exp (L * t⁻¹) + set f' : ℝ → ℝ := fun t => exp (L * t⁻¹) * (L * -(t ^ 2)⁻¹) + have hpos : ∀ x ∈ uIcc α β, 0 < x := fun x hx => by + rw [uIcc_of_le hαβ] at hx; linarith [hx.1] + have hderiv : ∀ x, 0 < x → HasDerivAt f (f' x) x := fun x hx => + ((hasDerivAt_inv hx.ne').const_mul L).exp + have hfA : ∀ γ, f γ = y ^ (1 / γ) := fun γ => by + simp only [f]; rw [rpow_def_of_pos hy0, one_div] + have h := intervalIntegral.integral_comp_mul_deriv_of_deriv_nonpos (a := α) (b := β) (f := f) + (f' := f') (g := fun u => F (L / log u) / (u * log u)) + (continuousOn_of_forall_continuousAt fun x hx => (hderiv x (hpos x hx)).continuousAt) + (fun x hx => hderiv x (by + rw [min_eq_left hαβ] at hx; linarith [hx.1])) + (fun x hx => by + simp only [f'] + rw [mul_neg] + exact mul_nonpos_of_nonneg_of_nonpos (exp_pos _).le + (neg_nonpos.2 (mul_nonneg hL.le (by positivity)))) + rw [hfA, hfA, intervalIntegral.integral_symm (y ^ (1 / β)) (y ^ (1 / α))] at h + have hcongr : ∫ x in α..β, ((fun u => F (L / log u) / (u * log u)) ∘ f) x * f' x = + ∫ x in α..β, -(F x / x) := by + refine intervalIntegral.integral_congr fun x hx => ?_ + have hx0 := hpos x hx + simp only [Function.comp, f, f', log_exp] + have : L / (L * x⁻¹) = x := by field_simp + rw [this] + have := exp_pos (L * x⁻¹) + field_simp + rw [hcongr, intervalIntegral.integral_neg, neg_inj] at h + exact h.symm + +theorem log_rpow_one_div {y : ℝ} (hy : 0 < y) (γ : ℝ) : log (y ^ (1 / γ)) = log y / γ := by + rw [log_rpow hy]; ring + +/-- For `u ∈ [y^{1/β}, y^{1/α}]`, `log y / log u ∈ [α, β]`. -/ +theorem div_log_mem_Icc {y α β u : ℝ} (hy : 1 < y) (hα : 0 < α) (hαβ : α ≤ β) + (hu : u ∈ Icc (y ^ (1 / β)) (y ^ (1 / α))) : 0 < log u ∧ log y / log u ∈ Icc α β := by + have hL : 0 < log y := log_pos hy + have hy0 : 0 < y := by linarith + have hβ : 0 < β := hα.trans_le hαβ + have hB0 : 0 < y ^ (1 / β) := rpow_pos_of_pos hy0 _ + have hu0 : 0 < u := hB0.trans_le hu.1 + have h1 : log y / β ≤ log u := log_rpow_one_div hy0 β ▸ log_le_log hB0 hu.1 + have h2 : log u ≤ log y / α := log_rpow_one_div hy0 α ▸ log_le_log hu0 hu.2 + have hlu : 0 < log u := (div_pos hL hβ).trans_le h1 + refine ⟨hlu, ?_, ?_⟩ + · rw [le_div_iff₀ hlu]; rw [le_div_iff₀ hα] at h2; linarith + · rw [div_le_iff₀ hlu]; rw [div_le_iff₀ hβ] at h1; linarith + +/-- [I71, Lemma 13] in the variable `t = log y / log u`: for `F ≥ 0` antitone on `[α, β]`, and any +set `S` of primes between those in `(y^{1/β}, y^{1/α})` and those in `[y^{1/β}, y^{1/α}]`, +`|∑_{p ∈ S} F(t_p)/p - ∫_α^β F(t)/t dt| ≤ C F(α) pntE(y^{1/β})`. -/ +theorem lemma13_param : ∃ C, 0 ≤ C ∧ ∀ (F : ℝ → ℝ) (y α β : ℝ) (S : Finset ℕ), 1 < y → 0 < α → + α ≤ β → 2 ≤ y ^ (1 / β) → AntitoneOn F (Icc α β) → (∀ t ∈ Icc α β, 0 ≤ F t) → + (∀ p ∈ S, p.Prime ∧ y ^ (1 / β) ≤ p ∧ (p : ℝ) ≤ y ^ (1 / α)) → + (∀ p : ℕ, p.Prime → y ^ (1 / β) < p → (p : ℝ) < y ^ (1 / α) → p ∈ S) → + |∑ p ∈ S, F (log y / log p) / p - ∫ t in α..β, F t / t| ≤ C * F α * pntE (y ^ (1 / β)) := by + obtain ⟨C, hC0, hC⟩ := lemma13_mono_of_subset + refine ⟨C, hC0, fun F y α β S hy hα hαβ hB hF hF0 hS1 hS2 => ?_⟩ + have hL : 0 < log y := log_pos hy + have hy0 : 0 < y := by linarith + have hBA : y ^ (1 / β) ≤ y ^ (1 / α) := + rpow_le_rpow_of_exponent_le hy.le (one_div_le_one_div_of_le hα hαβ) + have hmono : MonotoneOn (fun u => F (log y / log u)) (Icc (y ^ (1 / β)) (y ^ (1 / α))) := by + intro u hu v hv huv + obtain ⟨hlu, hmu⟩ := div_log_mem_Icc hy hα hαβ hu + obtain ⟨hlv, hmv⟩ := div_log_mem_Icc hy hα hαβ hv + exact hF hmv hmu (div_le_div_of_nonneg_left hL.le hlu + (log_le_log (by linarith [hu.1]) huv)) + have h := hC (fun u => F (log y / log u)) (y ^ (1 / α)) (y ^ (1 / β)) S hB hBA hmono + (fun u hu => hF0 _ (div_log_mem_Icc hy hα hαβ hu).2) hS1 hS2 + rwa [integral_comp_log_div hy hα hαβ, log_rpow_one_div hy0, div_div_cancel₀ hL.ne'] at h + +/-! ### Corollary 1 -/ +theorem log_div_prime_eq {y : ℝ} {p : ℕ} (hy : 0 < y) (hp : 1 < p) : + log (y / p) = log p * (log y / log p - 1) := by + have hlp : 0 < log (p : ℝ) := log_pos (by exact_mod_cast hp) + rw [log_div hy.ne' (by positivity), mul_sub, mul_div_cancel₀ _ hlp.ne', mul_one] + +/-- `log y / log p ≥ α` for `p ≤ y^{1/α}`. -/ +theorem le_div_log_of_le_rpow {y α : ℝ} {p : ℕ} (hy : 1 < y) (hα : 0 < α) (hp : 1 < p) + (hpA : (p : ℝ) ≤ y ^ (1 / α)) : α ≤ log y / log p := by + have hlp : 0 < log (p : ℝ) := log_pos (by exact_mod_cast hp) + have h := log_le_log (by positivity) hpA + rw [log_rpow_one_div (by linarith)] at h + rw [le_div_iff₀ hlp]; rw [le_div_iff₀ hα] at h; linarith + +theorem antitoneOn_div_sub_one : AntitoneOn (fun t : ℝ => t / (t - 1)) (Ioi 1) := by + intro u hu v hv huv + have hu1 : 0 < u - 1 := by linarith [hu.out] + have hv1 : 0 < v - 1 := by linarith [hv.out] + simp only + rw [div_le_div_iff₀ hv1 hu1]; nlinarith + +/-- [I71, Corollary 1 to Lemma 13]: for `M ≥ 0` antitone on `[α - 1, β - 1]`, `2 ≤ α ≤ β`, +`y^{1/β} ≥ 2`, +`|∑_{y^{1/β} ≤ p < y^{1/α}} M(t_p - 1)/(p log (y/p)) - L⁻¹ ∫_α^β M(t-1)/(t-1) dt| + ≤ C M(α - 1) pntE(y^{1/β}) / L`. -/ +theorem cor1 : ∃ C, 0 ≤ C ∧ ∀ (M : ℝ → ℝ) (y α β : ℝ), 1 < y → 2 ≤ α → α ≤ β → + 2 ≤ y ^ (1 / β) → AntitoneOn M (Icc (α - 1) (β - 1)) → (∀ t ∈ Icc (α - 1) (β - 1), 0 ≤ M t) → + |∑ p ∈ (primesLT (y ^ (1 / α))).filter (fun p : ℕ => y ^ (1 / β) ≤ p), + M (log y / log p - 1) / (p * log (y / p)) - + (∫ t in α..β, M (t - 1) / (t - 1)) / log y| ≤ + C * M (α - 1) * pntE (y ^ (1 / β)) / log y := by + obtain ⟨C, hC0, hC⟩ := lemma13_param + refine ⟨2 * C, by linarith, fun M y α β hy hα hαβ hB hM hM0 => ?_⟩ + have hL : 0 < log y := log_pos hy + have hy0 : 0 < y := by linarith + set F : ℝ → ℝ := fun t => M (t - 1) * (t / (t - 1)) / log y with hFdef + have hMt : AntitoneOn (fun t => M (t - 1)) (Icc α β) := fun u hu v hv huv => + hM ⟨by linarith [hu.1], by linarith [hu.2]⟩ ⟨by linarith [hv.1], by linarith [hv.2]⟩ + (by linarith) + have hF : AntitoneOn F (Icc α β) := by + have := antitoneOn_mul_of_nonneg hMt (antitoneOn_div_sub_one.mono fun t ht => + show (1 : ℝ) < t by linarith [ht.1]) + (fun t ht => hM0 _ ⟨by linarith [ht.1], by linarith [ht.2]⟩) + fun t ht => div_nonneg (by linarith [ht.1]) (by linarith [ht.1]) + exact fun u hu v hv huv => div_le_div_of_nonneg_right (this hu hv huv) hL.le + have hF0 : ∀ t ∈ Icc α β, 0 ≤ F t := fun t ht => + div_nonneg (mul_nonneg (hM0 _ ⟨by linarith [ht.1], by linarith [ht.2]⟩) + (div_nonneg (by linarith [ht.1]) (by linarith [ht.1]))) hL.le + have h := hC F y α β ((primesLT (y ^ (1 / α))).filter (fun p : ℕ => y ^ (1 / β) ≤ p)) hy + (by linarith) hαβ hB hF hF0 + (fun p hp => by + rw [mem_filter, mem_primesLT] at hp + exact ⟨hp.1.1, hp.2, hp.1.2.le⟩) + (fun p hp h1 h2 => by + rw [mem_filter, mem_primesLT]; exact ⟨⟨hp, h2⟩, h1.le⟩) + have hsum : ∑ p ∈ (primesLT (y ^ (1 / α))).filter (fun p : ℕ => y ^ (1 / β) ≤ p), + F (log y / log p) / p = ∑ p ∈ (primesLT (y ^ (1 / α))).filter + (fun p : ℕ => y ^ (1 / β) ≤ p), M (log y / log p - 1) / (p * log (y / p)) := by + refine sum_congr rfl fun p hp => ?_ + rw [mem_filter, mem_primesLT] at hp + have hp1 := hp.1.1.one_lt + have hlp : 0 < log (p : ℝ) := log_pos (by exact_mod_cast hp1) + have ht := le_div_log_of_le_rpow hy (by linarith) hp1 hp.1.2.le + rw [log_div_prime_eq hy0 hp1] + simp only [F] + have : (p : ℝ) ≠ 0 := by positivity + field_simp + have hint : ∫ t in α..β, F t / t = (∫ t in α..β, M (t - 1) / (t - 1)) / log y := by + rw [← intervalIntegral.integral_div] + refine intervalIntegral.integral_congr fun t ht => ?_ + rw [uIcc_of_le hαβ] at ht + have : 0 < t := by linarith [ht.1] + have : t - 1 ≠ 0 := by linarith [ht.1] + simp only [F] + field_simp + have hFα : F α ≤ 2 * M (α - 1) / log y := by + have hMα := hM0 (α - 1) ⟨le_rfl, by linarith⟩ + have : α / (α - 1) ≤ 2 := by rw [div_le_iff₀ (by linarith)]; linarith + simp only [F] + exact div_le_div_of_nonneg_right (by nlinarith) hL.le + rw [hsum, hint] at h + refine h.trans ?_ + calc C * F α * pntE (y ^ (1 / β)) ≤ C * (2 * M (α - 1) / log y) * pntE (y ^ (1 / β)) := by + have := pntE_pos (y ^ (1 / β)) + gcongr + _ = 2 * C * M (α - 1) * pntE (y ^ (1 / β)) / log y := by ring + +/-- [I71, Corollary 1 to Lemma 13], one-sided form. -/ +theorem cor1_le : ∃ C, 0 ≤ C ∧ ∀ (M : ℝ → ℝ) (y α β : ℝ), 1 < y → 2 ≤ α → α ≤ β → + 2 ≤ y ^ (1 / β) → AntitoneOn M (Icc (α - 1) (β - 1)) → (∀ t ∈ Icc (α - 1) (β - 1), 0 ≤ M t) → + ∑ p ∈ (primesLT (y ^ (1 / α))).filter (fun p : ℕ => y ^ (1 / β) ≤ p), + M (log y / log p - 1) / (p * log (y / p)) ≤ + (∫ t in α..β, M (t - 1) / (t - 1)) / log y + C * M (α - 1) * pntE (y ^ (1 / β)) / log y := by + obtain ⟨C, hC0, hC⟩ := cor1 + exact ⟨C, hC0, fun M y α β hy hα hαβ hB hM hM0 => by + linarith [(abs_le.1 (hC M y α β hy hα hαβ hB hM hM0)).2]⟩ + +/-! ### Corollary 3 -/ + +/-- `G'(s-1) s²/(s-1)² ≤ 32 s² G(s)` for `s ≥ 2` (Lemma 8 and the Corollary to Lemma 6). -/ +theorem errMaj_shift_sq_le (lower lower' : Bool) {s : ℝ} (hs : 2 ≤ s) : + errMaj lower' (s - 1) * (s ^ 2 / (s - 1) ^ 2) ≤ 32 * s ^ 2 * errMaj lower s := by + have hs1 : 0 < s - 1 := by linarith + have hq : s ^ 2 / (s - 1) ^ 2 ≤ 4 := by + rw [div_le_iff₀ (pow_pos hs1 2)]; nlinarith + have hq0 : 0 ≤ s ^ 2 / (s - 1) ^ 2 := by positivity + have hG' := errMaj_pos lower' (s - 1) + have hG := (errMaj_mem lower s).1 + have h8 : errMaj lower' (s - 1) ≤ 8 * s ^ 2 * errMaj lower s := by + rcases le_total 3 s with h3 | h3 + · have := (errMaj_mem lower' (s - 1)).2 + have := bigM_sub_one_lt h3 + nlinarith + · have := errMaj_le_two lower' (s - 1) + have hB : bigM 3 ≤ bigM s := bigM_antitone h3 + have := bigM_three_gt + have : 1 / 2 ≤ errMaj lower s := by linarith + nlinarith + calc errMaj lower' (s - 1) * (s ^ 2 / (s - 1) ^ 2) ≤ 8 * s ^ 2 * errMaj lower s * 4 := + mul_le_mul h8 hq hq0 (by have := errMaj_pos lower s; positivity) + _ = 32 * s ^ 2 * errMaj lower s := by ring + +/-- `(1 + t² log⁵ t / L²)^{5(t-1)} ≤ δ(a, y)` for `1 ≤ t ≤ a`. -/ +theorem growth_le_delta {y t a : ℝ} (ht : 1 ≤ t) (hta : t ≤ a) : + (1 + t ^ 2 * log t ^ 5 / log y ^ 2) ^ (5 * (t - 1)) ≤ delta a y := by + have hlt := log_nonneg ht + have hla : log t ≤ log a := log_le_log (by linarith) hta + have hx0 := lsx_nonneg (log y) ht + have hxa : t ^ 2 * log t ^ 5 / log y ^ 2 ≤ a ^ 2 * log a ^ 5 / log y ^ 2 := by + gcongr + rw [delta] + calc (1 + t ^ 2 * log t ^ 5 / log y ^ 2) ^ (5 * (t - 1)) + ≤ (1 + a ^ 2 * log a ^ 5 / log y ^ 2) ^ (5 * (t - 1)) := + rpow_le_rpow (by linarith) (by linarith) (by linarith) + _ ≤ _ := rpow_le_rpow_of_exponent_le (by linarith) (by linarith) + +/-- The summand of Corollary 3: with `t = t_p ≥ 2`, `log (y/p) = L (t-1)/t`, so +`δ(t - 1, y/p) G(t-1) / (p log² (y/p)) + ≤ (1 + t² log⁵ t / L²)^{5(t-1)} G(t-1) (t²/(t-1)²) / L² / p`. -/ +theorem cor3_summand_le {G : ℝ → ℝ} {y : ℝ} {p : ℕ} (hy : 1 < y) (hp : 1 < p) + (ht : 2 ≤ log y / log p) (hG : 0 ≤ G (log y / log p - 1)) : + delta (log y / log p - 1) (y / p) * G (log y / log p - 1) / (p * log (y / p) ^ 2) ≤ + (1 + (log y / log p) ^ 2 * log (log y / log p) ^ 5 / log y ^ 2) ^ + (5 * (log y / log p - 1)) * G (log y / log p - 1) * + ((log y / log p) ^ 2 / (log y / log p - 1) ^ 2) / log y ^ 2 / p := by + have hlp : 0 < log (p : ℝ) := log_pos (by exact_mod_cast hp) + have hy0 : 0 < y := by linarith + have hyp := log_div_prime_eq hy0 hp + set t := log y / log p with htdef + have hLt : log y = log p * t := by rw [htdef]; field_simp + have ht1 : 0 < t - 1 := by linarith + have hp0 : (0 : ℝ) < p := by positivity + have hb : (t - 1) ^ 2 * log (t - 1) ^ 5 / log (y / p) ^ 2 = + t ^ 2 * log (t - 1) ^ 5 / log y ^ 2 := by + rw [hyp, hLt]; field_simp + have hl1 : 0 ≤ log (t - 1) := log_nonneg (by linarith) + have hl2 : log (t - 1) ≤ log t := log_le_log ht1 (by linarith) + have hbase : t ^ 2 * log (t - 1) ^ 5 / log y ^ 2 ≤ t ^ 2 * log t ^ 5 / log y ^ 2 := by + gcongr + have hb0 : 0 ≤ t ^ 2 * log (t - 1) ^ 5 / log y ^ 2 := by positivity + rw [delta, hb] + have hrest : G (t - 1) / (p * log (y / p) ^ 2) = + G (t - 1) * (t ^ 2 / (t - 1) ^ 2) / log y ^ 2 / p := by + rw [hyp, hLt]; field_simp + calc (1 + t ^ 2 * log (t - 1) ^ 5 / log y ^ 2) ^ (5 * (t - 1)) * G (t - 1) / + (p * log (y / p) ^ 2) + = (1 + t ^ 2 * log (t - 1) ^ 5 / log y ^ 2) ^ (5 * (t - 1)) * + (G (t - 1) / (p * log (y / p) ^ 2)) := by ring + _ ≤ (1 + t ^ 2 * log t ^ 5 / log y ^ 2) ^ (5 * (t - 1)) * + (G (t - 1) / (p * log (y / p) ^ 2)) := by + gcongr + _ = _ := by rw [hrest]; ring + +theorem errMaj_not_eq_majG (lower : Bool) : errMaj (!lower) = majG (if lower then 1 else 0) := by + cases lower + · simp [majG_of_even (⟨0, rfl⟩ : Even 0)] + · simp [majG_of_odd odd_one] + +theorem errMaj_eq_majG_succ (lower : Bool) : + errMaj lower = majG ((if lower then 1 else 0) + 1) := by + cases lower + · simp [majG_of_odd odd_one] + · simp [majG_of_even (⟨1, rfl⟩ : Even 2)] + +/-- Corollary 3 on `[s, b]` with `e^{32} ≤ s` (Lemmas 11, 12 and 13). `S` is any set of primes +between those in `(y^{1/b}, y^{1/s})` and those in `[y^{1/b}, y^{1/s}]`. -/ +theorem cor3_large : ∃ C, 0 ≤ C ∧ ∀ (lower : Bool) (y s b : ℝ) (S : Finset ℕ), 1 < y → + exp 32 ≤ s → s ≤ b → 2 ≤ y ^ (1 / b) → b ^ 2 * log b ^ 4 ≤ log y ^ 2 / 160 → + (∀ p ∈ S, p.Prime ∧ y ^ (1 / b) ≤ p ∧ (p : ℝ) ≤ y ^ (1 / s)) → + (∀ p : ℕ, p.Prime → y ^ (1 / b) < p → (p : ℝ) < y ^ (1 / s) → p ∈ S) → + ∑ p ∈ S, delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) ≤ + delta s y * errMaj lower s / log y ^ 2 * (1 + C * b ^ 2 * pntE (y ^ (1 / b))) := by + obtain ⟨C, hC0, hC⟩ := lemma13_param + refine ⟨32 * C, by linarith, fun lower y s b S hy hs hsb hB hb hS1 hS2 => ?_⟩ + set r : ℕ := if lower then 1 else 0 + have hG' := errMaj_not_eq_majG lower + have hGs : errMaj lower s = majG (r + 1) s := by rw [errMaj_eq_majG_succ] + have hL : 0 < log y := log_pos hy + have hL2 : 0 < log y ^ 2 := by positivity + have hs4 := four_lt_of_exp_le hs + set Φ : ℝ → ℝ := fun t => (1 + t ^ 2 * log t ^ 5 / log y ^ 2) ^ (5 * (t - 1)) * majG r (t - 1) * + (t ^ 2 / (t - 1) ^ 2) / log y ^ 2 with hΦdef + have hΦ : AntitoneOn Φ (Icc s b) := fun u hu v hv huv => + div_le_div_of_nonneg_right (antitoneOn_cor3Weight r hs hb hu hv huv) hL2.le + have hΦ0 : ∀ t ∈ Icc s b, 0 ≤ Φ t := fun t ht => by + have ht1 : (1 : ℝ) ≤ t := by linarith [ht.1] + have := lsx_nonneg (log y) ht1 + have := majG_pos r (t - 1) + exact div_nonneg (mul_nonneg (mul_nonneg (rpow_pos_of_pos (by linarith) _).le this.le) + (by positivity)) hL2.le + have h13 := hC Φ y s b S hy (by linarith) hsb hB hΦ hΦ0 hS1 hS2 + have hsum : ∑ p ∈ S, delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) ≤ ∑ p ∈ S, Φ (log y / log p) / p := by + refine sum_le_sum fun p hp => ?_ + obtain ⟨hpp, hpB, hpA⟩ := hS1 p hp + have ht := (div_log_mem_Icc hy (by linarith) hsb ⟨hpB, hpA⟩).2 + rw [hG'] + exact cor3_summand_le hy hpp.one_lt (by linarith [ht.1]) (majG_pos _ _).le + have hint : ∫ t in s..b, Φ t / t = (∫ t in s..b, (1 + t ^ 2 * log t ^ 5 / log y ^ 2) ^ + (5 * (t - 1)) * majG r (t - 1) * t / (t - 1) ^ 2) / log y ^ 2 := by + rw [← intervalIntegral.integral_div] + refine intervalIntegral.integral_congr fun t ht => ?_ + rw [uIcc_of_le hsb] at ht + have : t ≠ 0 := by linarith [ht.1] + have : t - 1 ≠ 0 := by linarith [ht.1] + simp only [Φ] + field_simp + have h11 := lemma11 r hs hsb hb + have hΦs : Φ s ≤ delta s y * (32 * s ^ 2 * majG (r + 1) s) / log y ^ 2 := by + have h1 := growth_le_delta (y := y) (by linarith : (1 : ℝ) ≤ s) le_rfl + have h2 := errMaj_shift_sq_le lower (!lower) (by linarith : (2 : ℝ) ≤ s) + rw [hG', hGs] at h2 + have h3 : 0 ≤ majG r (s - 1) * (s ^ 2 / (s - 1) ^ 2) := by + have := majG_pos r (s - 1); positivity + change (1 + s ^ 2 * log s ^ 5 / log y ^ 2) ^ (5 * (s - 1)) * majG r (s - 1) * + (s ^ 2 / (s - 1) ^ 2) / log y ^ 2 ≤ _ + rw [mul_assoc _ (majG r (s - 1))] + exact div_le_div_of_nonneg_right (mul_le_mul h1 h2 h3 (delta_pos (by linarith) y).le) + hL2.le + rw [abs_le] at h13 + rw [hint] at h13 + have hpE := pntE_pos (y ^ (1 / b)) + have hδ := delta_pos (by linarith : (1 : ℝ) ≤ s) y + have hG := majG_pos (r + 1) s + have hsb2 : s ^ 2 ≤ b ^ 2 := by gcongr + rw [hGs] + have e1 : C * Φ s * pntE (y ^ (1 / b)) ≤ + C * (delta s y * (32 * s ^ 2 * majG (r + 1) s) / log y ^ 2) * pntE (y ^ (1 / b)) := by + gcongr + have e2 : C * (delta s y * (32 * s ^ 2 * majG (r + 1) s) / log y ^ 2) * pntE (y ^ (1 / b)) ≤ + delta s y * majG (r + 1) s / log y ^ 2 * (32 * C * b ^ 2 * pntE (y ^ (1 / b))) := by + have h0 : 0 ≤ C * delta s y * majG (r + 1) s * pntE (y ^ (1 / b)) * 32 := + mul_nonneg (mul_nonneg (mul_nonneg (mul_nonneg hC0 hδ.le) hG.le) hpE.le) (by norm_num) + calc C * (delta s y * (32 * s ^ 2 * majG (r + 1) s) / log y ^ 2) * pntE (y ^ (1 / b)) + = C * delta s y * majG (r + 1) s * pntE (y ^ (1 / b)) * 32 * s ^ 2 / log y ^ 2 := by + ring + _ ≤ C * delta s y * majG (r + 1) s * pntE (y ^ (1 / b)) * 32 * b ^ 2 / log y ^ 2 := + div_le_div_of_nonneg_right (mul_le_mul_of_nonneg_left hsb2 h0) hL2.le + _ = _ := by ring + have e3 : (∫ t in s..b, (1 + t ^ 2 * log t ^ 5 / log y ^ 2) ^ (5 * (t - 1)) * + majG r (t - 1) * t / (t - 1) ^ 2) / log y ^ 2 ≤ delta s y * majG (r + 1) s / log y ^ 2 := + div_le_div_of_nonneg_right h11.le hL2.le + calc _ ≤ ∑ p ∈ S, Φ (log y / log p) / p := hsum + _ ≤ _ := by nlinarith + +/-- Corollary 3 on `[s, a]` with `a ≤ e^{32}`: here `δ(t_p - 1, y/p) ≤ δ(e^{32}, y)` and Lemma 13 +is applied to `G'(t-1) t²/(t-1)²` directly. -/ +theorem cor3_small : ∃ C, 0 ≤ C ∧ ∀ (lower : Bool) (y s a : ℝ) (S : Finset ℕ), 1 < y → + errLower lower ≤ s → s ≤ a → a ≤ exp 32 → 2 ≤ y ^ (1 / a) → + (∀ p ∈ S, p.Prime ∧ y ^ (1 / a) ≤ p ∧ (p : ℝ) ≤ y ^ (1 / s)) → + (∀ p : ℕ, p.Prime → y ^ (1 / a) < p → (p : ℝ) < y ^ (1 / s) → p ∈ S) → + ∑ p ∈ S, delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) ≤ + delta (exp 32) y / log y ^ 2 * + (errMaj lower s - errMaj lower a + C * s ^ 2 * errMaj lower s * pntE (y ^ (1 / a))) := by + obtain ⟨C, hC0, hC⟩ := lemma13_param + refine ⟨32 * C, by linarith, fun lower y s a S hy hs hsa ha hB hS1 hS2 => ?_⟩ + have hs2 : 2 ≤ s := (two_le_errLower lower).trans hs + have hL : 0 < log y := log_pos hy + have hL2 : 0 < log y ^ 2 := by positivity + set F : ℝ → ℝ := fun t => errMaj (!lower) (t - 1) * (t ^ 2 / (t - 1) ^ 2) with hFdef + have hF : AntitoneOn F (Icc s a) := + antitoneOn_mul_of_nonneg (fun u _ v _ huv => errMaj_antitone _ (by linarith)) + (antitoneOn_sq_div_sq_sub_one.mono fun t ht => show (1 : ℝ) < t by linarith [ht.1]) + (fun t _ => (errMaj_pos _ _).le) fun t _ => by positivity + have hF0 : ∀ t ∈ Icc s a, 0 ≤ F t := fun t _ => by + have := errMaj_pos (!lower) (t - 1); positivity + have h13 := hC F y s a S hy (by linarith) hsa hB hF hF0 hS1 hS2 + have hδ0 : 0 ≤ delta (exp 32) y := + (delta_pos (by linarith [four_lt_of_exp_le (le_refl (exp 32))]) y).le + have hsum : ∑ p ∈ S, delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) ≤ delta (exp 32) y / log y ^ 2 * ∑ p ∈ S, F (log y / log p) / p := by + rw [mul_sum] + refine sum_le_sum fun p hp => ?_ + obtain ⟨hpp, hpB, hpA⟩ := hS1 p hp + have ht := (div_log_mem_Icc hy (by linarith) hsa ⟨hpB, hpA⟩).2 + refine (cor3_summand_le hy hpp.one_lt (by linarith [ht.1]) (errMaj_pos _ _).le).trans ?_ + have hg := growth_le_delta (y := y) (by linarith [ht.1] : (1 : ℝ) ≤ log y / log p) + (ht.2.trans ha) + have hF1 : 0 ≤ F (log y / log p) := hF0 _ ht + have hp0 : (0 : ℝ) < p := by exact_mod_cast hpp.pos + calc _ = (1 + (log y / log p) ^ 2 * log (log y / log p) ^ 5 / log y ^ 2) ^ + (5 * (log y / log p - 1)) * F (log y / log p) / log y ^ 2 / p := by + simp only [F]; ring + _ ≤ delta (exp 32) y * F (log y / log p) / log y ^ 2 / p := by gcongr + _ = _ := by ring + have hint : ∫ t in s..a, F t / t = errMaj lower s - errMaj lower a := by + rw [← integral_errMaj_shift lower hs hsa] + refine intervalIntegral.integral_congr fun t ht => ?_ + rw [uIcc_of_le hsa] at ht + have : t ≠ 0 := by linarith [ht.1] + have : t - 1 ≠ 0 := by linarith [ht.1] + simp only [F] + field_simp + have hFs : F s ≤ 32 * s ^ 2 * errMaj lower s := errMaj_shift_sq_le lower (!lower) hs2 + rw [abs_le, hint] at h13 + have hpE := pntE_pos (y ^ (1 / a)) + have hmain : ∑ p ∈ S, F (log y / log p) / p ≤ + errMaj lower s - errMaj lower a + 32 * C * s ^ 2 * errMaj lower s * pntE (y ^ (1 / a)) := by + have : C * F s * pntE (y ^ (1 / a)) ≤ + C * (32 * s ^ 2 * errMaj lower s) * pntE (y ^ (1 / a)) := by gcongr + linarith [h13.2] + calc _ ≤ _ := hsum + _ ≤ _ := mul_le_mul_of_nonneg_left hmain (div_nonneg hδ0 hL2.le) + +theorem rpow_one_div_le_rpow_one_div {y u v : ℝ} (hy : 1 ≤ y) (hu : 0 < u) (huv : u ≤ v) : + y ^ (1 / v) ≤ y ^ (1 / u) := + rpow_le_rpow_of_exponent_le hy (one_div_le_one_div_of_le hu huv) + +/-- [I71, Corollary 3 to Lemma 13] for the primes `y^{1/b} ≤ p < y^{1/s}`, `errLower lower ≤ s` +(so `s ≥ 2`, and `s ≥ 3` for the upper sieve, where (3.13) holds). -/ +theorem cor3_primesLT : ∃ C, 0 ≤ C ∧ ∀ (lower : Bool) (y s b : ℝ), 1 < y → + errLower lower ≤ s → exp 32 ≤ b → 2 ≤ y ^ (1 / b) → b ^ 2 * log b ^ 4 ≤ log y ^ 2 / 160 → + ∑ p ∈ (primesLT (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / b) ≤ p), + delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) ≤ + delta (max s (exp 32)) y * errMaj lower s / log y ^ 2 * + (1 + C * b ^ 2 * pntE (y ^ (1 / b))) := by + obtain ⟨C₁, hC₁, h₁⟩ := cor3_large + obtain ⟨C₂, hC₂, h₂⟩ := cor3_small + refine ⟨C₁ + C₂, by linarith, fun lower y s b hy hs hb32 hB hb => ?_⟩ + set s₀ := exp 32 with hs₀ + have hs2 : 2 ≤ s := (two_le_errLower lower).trans hs + have hs₀4 : 4 < s₀ := four_lt_of_exp_le le_rfl + have hL2 : 0 < log y ^ 2 := by have := log_pos hy; positivity + have hpE := pntE_pos (y ^ (1 / b)) + have hGs := errMaj_pos lower s + set S := (primesLT (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / b) ≤ p) with hS + have hRHS : 0 ≤ delta (max s s₀) y * errMaj lower s / log y ^ 2 * + (1 + (C₁ + C₂) * b ^ 2 * pntE (y ^ (1 / b))) := by + have := delta_pos (by linarith [le_max_left s s₀] : (1 : ℝ) ≤ max s s₀) y + have : 0 ≤ (C₁ + C₂) * b ^ 2 * pntE (y ^ (1 / b)) := + mul_nonneg (mul_nonneg (by linarith) (sq_nonneg b)) hpE.le + positivity + rcases lt_or_ge b s with hbs | hsb + · -- no primes + have hempty : S = ∅ := by + refine Finset.eq_empty_of_forall_notMem fun p hp => ?_ + rw [hS, mem_filter, mem_primesLT] at hp + have := rpow_one_div_le_rpow_one_div hy.le (by linarith) hbs.le + linarith [hp.1.2, hp.2] + rw [hempty, sum_empty] + exact hRHS + rcases le_total s₀ s with hs₀s | hss₀ + · -- `s ≥ s₀`: Lemma 11 directly + rw [max_eq_left hs₀s] + refine (h₁ lower y s b S hy hs₀s hsb hB hb (fun p hp => ?_) fun p hp h1 h2 => ?_).trans ?_ + · rw [hS, mem_filter, mem_primesLT] at hp; exact ⟨hp.1.1, hp.2, hp.1.2.le⟩ + · rw [hS, mem_filter, mem_primesLT]; exact ⟨⟨hp, h2⟩, h1.le⟩ + · have := delta_pos (by linarith : (1 : ℝ) ≤ s) y + gcongr + linarith + -- `s < s₀`: split at `y^{1/s₀}` + rw [max_eq_right hss₀] + have hB₀ : y ^ (1 / b) ≤ y ^ (1 / s₀) := rpow_one_div_le_rpow_one_div hy.le (by linarith) hb32 + have hB₀s : y ^ (1 / s₀) ≤ y ^ (1 / s) := rpow_one_div_le_rpow_one_div hy.le (by linarith) hss₀ + rw [← sum_filter_add_sum_filter_not S (fun p : ℕ => y ^ (1 / s₀) ≤ p)] + have e₁ := h₂ lower y s s₀ (S.filter fun p : ℕ => y ^ (1 / s₀) ≤ p) hy hs hss₀ le_rfl + (by linarith) (fun p hp => by + rw [mem_filter, hS, mem_filter, mem_primesLT] at hp + exact ⟨hp.1.1.1, hp.2, hp.1.1.2.le⟩) + (fun p hp h1 h2 => by + rw [mem_filter, hS, mem_filter, mem_primesLT] + exact ⟨⟨⟨hp, h2⟩, by linarith⟩, h1.le⟩) + have e₂ := h₁ lower y s₀ b (S.filter fun p : ℕ => ¬ y ^ (1 / s₀) ≤ p) hy le_rfl hb32 hB hb + (fun p hp => by + rw [mem_filter, hS, mem_filter, mem_primesLT] at hp + exact ⟨hp.1.1.1, hp.1.2, (not_le.1 hp.2).le⟩) + (fun p hp h1 h2 => by + rw [mem_filter, hS, mem_filter, mem_primesLT] + exact ⟨⟨⟨hp, by linarith⟩, h1.le⟩, not_le.2 h2⟩) + refine (add_le_add e₁ e₂).trans ?_ + -- combine + have hδ := delta_pos (by linarith : (1 : ℝ) ≤ s₀) y + have hG₀ := errMaj_pos lower s₀ + have hGG : errMaj lower s₀ ≤ errMaj lower s := errMaj_antitone lower hss₀ + have hpE₀ : pntE (y ^ (1 / s₀)) ≤ pntE (y ^ (1 / b)) := + pntE_le_pntE (by linarith) hB₀ + have hsb2 : s ^ 2 * pntE (y ^ (1 / s₀)) ≤ b ^ 2 * pntE (y ^ (1 / b)) := by + have : s ^ 2 ≤ b ^ 2 := by gcongr + exact mul_le_mul this hpE₀ (pntE_pos _).le (sq_nonneg b) + have i1 : C₂ * errMaj lower s * (s ^ 2 * pntE (y ^ (1 / s₀))) ≤ + C₂ * errMaj lower s * (b ^ 2 * pntE (y ^ (1 / b))) := + mul_le_mul_of_nonneg_left hsb2 (mul_nonneg hC₂ hGs.le) + have i2 : C₁ * (b ^ 2 * pntE (y ^ (1 / b))) * errMaj lower s₀ ≤ + C₁ * (b ^ 2 * pntE (y ^ (1 / b))) * errMaj lower s := + mul_le_mul_of_nonneg_left hGG (mul_nonneg hC₁ (mul_nonneg (sq_nonneg b) hpE.le)) + have hinner : errMaj lower s - errMaj lower s₀ + + C₂ * s ^ 2 * errMaj lower s * pntE (y ^ (1 / s₀)) + + errMaj lower s₀ * (1 + C₁ * b ^ 2 * pntE (y ^ (1 / b))) ≤ + errMaj lower s * (1 + (C₁ + C₂) * b ^ 2 * pntE (y ^ (1 / b))) := by + nlinarith + have hk : 0 ≤ delta s₀ y / log y ^ 2 := div_nonneg hδ.le hL2.le + calc delta s₀ y / log y ^ 2 * (errMaj lower s - errMaj lower s₀ + + C₂ * s ^ 2 * errMaj lower s * pntE (y ^ (1 / s₀))) + + delta s₀ y * errMaj lower s₀ / log y ^ 2 * (1 + C₁ * b ^ 2 * pntE (y ^ (1 / b))) + = delta s₀ y / log y ^ 2 * (errMaj lower s - errMaj lower s₀ + + C₂ * s ^ 2 * errMaj lower s * pntE (y ^ (1 / s₀)) + + errMaj lower s₀ * (1 + C₁ * b ^ 2 * pntE (y ^ (1 / b)))) := by ring + _ ≤ delta s₀ y / log y ^ 2 * + (errMaj lower s * (1 + (C₁ + C₂) * b ^ 2 * pntE (y ^ (1 / b)))) := + mul_le_mul_of_nonneg_left hinner hk + _ = _ := by ring + +/-- `p < y^{1/max s 3} ↔ p < y^{1/s} ∧ p³ < y` (for `y > 1`, `s > 0`, `p ≥ 0`). -/ +theorem lt_rpow_one_div_max_three {y s x : ℝ} (hy : 1 < y) (hs : 0 < s) (hx : 0 ≤ x) : + x < y ^ (1 / max s 3) ↔ x < y ^ (1 / s) ∧ x ^ 3 < y := by + have h3 : x < y ^ (1 / (3 : ℝ)) ↔ x ^ 3 < y := by + rw [one_div, lt_rpow_inv_iff_of_pos hx (by linarith) (by norm_num)] + norm_cast + rcases le_total s 3 with hs3 | hs3 + · rw [max_eq_right hs3, h3] + have := rpow_one_div_le_rpow_one_div hy.le hs hs3 + constructor + · intro h; exact ⟨lt_of_lt_of_le (h3.2 h) this, h⟩ + · exact fun h => h.2 + · rw [max_eq_left hs3] + have := rpow_one_div_le_rpow_one_div hy.le (by norm_num) hs3 + exact ⟨fun h => ⟨h, h3.1 (lt_of_lt_of_le h this)⟩, fun h => h.1⟩ + +/-- [I71, Corollary 3 to Lemma 13], for the primes of the Rosser recursion: with +`t_p = log y / log p`, `s₀ = e^{32}`, `sMin lower ≤ s`, any `b ≥ s₀` with `y^{1/b} ≥ 2` and +`160 b² log⁴ b ≤ log² y` (e.g. `b = ξ(y)` for large `y`, `exists_xi_large`), + +`∑_{p ∈ rosserPrimes lower y (y^{1/s}), p ≥ y^{1/b}} + δ(t_p - 1, y/p) G(!lower)(t_p - 1) / (p log² (y/p)) + ≤ δ(max s s₀, y) G(lower)(s) / L² · (1 + C b² pntE(y^{1/b}))`. + +For the upper sieve and `s < 3` the primes are those `< y^{1/3}` and `𝔉(s) = 𝔉(3) = 1`, so this +reduces to `s = 3`. -/ +theorem cor3 : ∃ C, 0 ≤ C ∧ ∀ (lower : Bool) (y s b : ℝ), 1 < y → sMin lower ≤ s → + exp 32 ≤ b → 2 ≤ y ^ (1 / b) → b ^ 2 * log b ^ 4 ≤ log y ^ 2 / 160 → + ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / b) ≤ p), + delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) ≤ + delta (max s (exp 32)) y * errMaj lower s / log y ^ 2 * + (1 + C * b ^ 2 * pntE (y ^ (1 / b))) := by + obtain ⟨C, hC0, hC⟩ := cor3_primesLT + refine ⟨C, hC0, fun lower y s b hy hs hb32 hB hb => ?_⟩ + cases lower + · -- upper sieve: replace `s` by `max s 3` + have hs1 : (1 : ℝ) ≤ s := hs + have hset : (rosserPrimes false y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / b) ≤ p) = + (primesLT (y ^ (1 / max s 3))).filter (fun p : ℕ => y ^ (1 / b) ≤ p) := by + ext p + simp only [mem_filter, mem_rosserPrimes, mem_primesLT, Bool.false_eq_true, false_or] + rw [lt_rpow_one_div_max_three hy (by linarith) (Nat.cast_nonneg p)] + tauto + have hG : errMaj false (max s 3) = errMaj false s := by + rcases le_total s 3 with h | h + · rw [max_eq_right h, errMaj_false_of_le_three le_rfl, errMaj_false_of_le_three h] + · rw [max_eq_left h] + have hmax : max (max s 3) (exp 32) = max s (exp 32) := by + have : (3 : ℝ) ≤ exp 32 := by linarith [four_lt_of_exp_le (le_refl (exp 32))] + rw [max_assoc, max_eq_right this] + rw [hset, ← hG, ← hmax] + exact hC false y (max s 3) b hy (le_max_right _ _) hb32 hB hb + · rw [rosserPrimes_true] + exact hC true y s b hy hs hb32 hB hb + +/-- The hypothesis `160 b² log⁴ b ≤ L²` passes to smaller `b ≥ 1`. -/ +theorem sq_mul_log_pow_four_le_of_le {b b' X : ℝ} (hb : 1 ≤ b) (hbb' : b ≤ b') + (h : b' ^ 2 * log b' ^ 4 ≤ X) : b ^ 2 * log b ^ 4 ≤ X := by + have := log_nonneg hb + have : log b ≤ log b' := log_le_log (by linarith) hbb' + have : b ^ 2 * log b ^ 4 ≤ b' ^ 2 * log b' ^ 4 := by gcongr + linarith + +/-- Corollary 3 with `b = ξ(y)`, for `y ≥ y₀`. -/ +theorem cor3_xi : ∃ C y₀ : ℝ, 0 ≤ C ∧ ∀ (lower : Bool) (y s : ℝ), y₀ ≤ y → sMin lower ≤ s → + ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p), + delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) ≤ + delta (max s (exp 32)) y * errMaj lower s / log y ^ 2 * + (1 + C * xi y ^ 2 * pntE (y ^ (1 / xi y))) := by + obtain ⟨C, hC0, hC⟩ := cor3 + obtain ⟨y₀, hy₀⟩ := exists_xi_large + refine ⟨C, y₀, hC0, fun lower y s hy hs => ?_⟩ + obtain ⟨h1, h2, h3, h4⟩ := hy₀ y hy + exact hC lower y s (xi y) h1 hs h2 h4 h3 + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/Crude.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/Crude.lean new file mode 100644 index 000000000..b713b43aa --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/Crude.lean @@ -0,0 +1,437 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.PrimeSums.Product +public import LeanPool.IwaniecLinearSieve.Rosser +import LeanPool.IwaniecLinearSieve.LinearSieve.Depth +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Tactic.Polynomial.Basic + +/-! +# The crude bound for deep terms ([I71, pp. 24, 27]) + +A failing tuple `p₁ > ⋯ > p_l` (all `< z`) of depth `l` satisfies `p₁ ⋯ p_l p_l² ≥ y`, so +`z^{l+2} > y`; it contributes `R(p_l)/(p₁ ⋯ p_l) ≤ 1/(p₁ ⋯ p_l)`, and the sum of +`1/(p₁ ⋯ p_l)` over `z > p₁ > ⋯ > p_l` is at most `(∑_{p ξ-3} (∑_{p u} X^l / l! ≤ 2 (e X / u)^u` for +`2 e X ≤ u`) and `SLT_le_loglog` (`SLT z ≤ log log z + C`) this gives `fail_le_tail`: + z^{u+2} ≤ y, SLT z ≤ X, 2 e X ≤ u → fail lower r y z ≤ 2 (e X / u)^u + = 2 exp (-(u log u) + u log X + u). + +For the counts ([I71, p. 27]): elements with `l ≥ 2` prime factors (`l ≥ 1` for the upper sieve) +are `< y`, and `∑_{d ∈ D, ω(d) = l} 1/d ≤ SLT(z)^l / l!`, so +`#{d ∈ D | ω(d) ≥ k} ≤ y ∑_{k ≤ l ≤ π(z)} SLT(z)^l / l!` (`card_filter_le_mul_sum`); also +`#{d ∈ D | ω(d) = l} ≤ π(z)^l / l!` (`card_filter_eq_le_pow_div`). +-/ + +@[expose] public section + +open Finset Real + +namespace IwaniecLinearSieve + +/-! ### Discrete integration -/ + +/-- `a^{n+1} + (n+1) a^n b ≤ (a + b)^{n+1}` for `a, b ≥ 0`. -/ +theorem pow_succ_add_mul_le_add_pow {a b : ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (n : ℕ) : + a ^ (n + 1) + (n + 1) * a ^ n * b ≤ (a + b) ^ (n + 1) := by + induction n with + | zero => simp + | succ n ih => + have h1 : 0 ≤ a ^ n := pow_nonneg ha n + have h2 : 0 ≤ (n + 1 : ℝ) * a ^ n * b * b := by positivity + calc a ^ (n + 1 + 1) + ((n + 1 : ℕ) + 1 : ℝ) * a ^ (n + 1) * b + ≤ (a + b) * (a ^ (n + 1) + (n + 1) * a ^ n * b) := by + push_cast + rw [pow_succ a (n + 1), pow_succ a n] + nlinarith [mul_nonneg h1 hb] + _ ≤ (a + b) * (a + b) ^ (n + 1) := by gcongr + _ = (a + b) ^ (n + 1 + 1) := by ring + +/-- Discrete form of `∫ F(t)^n dF(t) ≤ F^{n+1}/(n+1)`: for weights `w ≥ 0` on a finite set +of naturals, `∑_{p ∈ s} (∑_{q ∈ s, q < p} w q)^n w p ≤ (∑_{q ∈ s} w q)^{n+1} / (n+1)`. -/ +theorem sum_pow_sum_lt_mul_le (s : Finset ℕ) {w : ℕ → ℝ} (hw : ∀ p ∈ s, 0 ≤ w p) (n : ℕ) : + ∑ p ∈ s, (∑ q ∈ s.filter (· < p), w q) ^ n * w p ≤ (∑ q ∈ s, w q) ^ (n + 1) / (n + 1) := by + induction s using Finset.induction_on_max with + | empty => simp + | insert a s hlt ih => + have has : a ∉ s := fun h ↦ lt_irrefl a (hlt a h) + have hw' : ∀ p ∈ s, 0 ≤ w p := fun p hp ↦ hw p (mem_insert_of_mem hp) + have hwa : 0 ≤ w a := hw a (mem_insert_self a s) + have hfa : (insert a s).filter (· < a) = s := by + ext q + simp only [mem_filter, mem_insert] + constructor + · rintro ⟨rfl | hq, hqa⟩ + · exact absurd hqa (lt_irrefl _) + · exact hq + · intro hq + exact ⟨Or.inr hq, hlt q hq⟩ + have hfp : ∀ p ∈ s, (insert a s).filter (· < p) = s.filter (· < p) := by + intro p hp + rw [filter_insert, ite_eq_right (not_lt.2 (hlt p hp).le)] + have hsum : ∑ p ∈ s, (∑ q ∈ (insert a s).filter (· < p), w q) ^ n * w p = + ∑ p ∈ s, (∑ q ∈ s.filter (· < p), w q) ^ n * w p := + sum_congr rfl fun p hp ↦ by rw [hfp p hp] + rw [sum_insert has, sum_insert has, hfa, hsum] + have hS : 0 ≤ ∑ q ∈ s, w q := sum_nonneg hw' + have := pow_succ_add_mul_le_add_pow hS hwa n + have hn : (0 : ℝ) < n + 1 := by positivity + calc (∑ q ∈ s, w q) ^ n * w a + ∑ p ∈ s, (∑ q ∈ s.filter (· < p), w q) ^ n * w p + ≤ (∑ q ∈ s, w q) ^ n * w a + (∑ q ∈ s, w q) ^ (n + 1) / (n + 1) := by + gcongr + exact ih hw' + _ ≤ (w a + ∑ q ∈ s, w q) ^ (n + 1) / (n + 1) := by + rw [add_comm (w a), le_div_iff₀ hn, add_mul, div_mul_cancel₀ _ hn.ne'] + nlinarith + +/-- `∑_{p < z} SLT(p)^n / p ≤ SLT(z)^{n+1} / (n+1)`. -/ +theorem sum_SLT_pow_div_le (n : ℕ) (z : ℝ) : + ∑ p ∈ primesLT z, SLT p ^ n / p ≤ SLT z ^ (n + 1) / (n + 1) := by + have h := sum_pow_sum_lt_mul_le (primesLT z) (w := fun p ↦ (p : ℝ)⁻¹) + (fun p _ ↦ by positivity) n + refine le_of_eq_of_le (sum_congr rfl fun p hp ↦ ?_) h + rw [filter_lt_primesLT hp, SLT, div_eq_mul_inv] + +/-- `∑_{p < z} (SLT(p)^n / n!) / p ≤ SLT(z)^{n+1} / (n+1)!`. -/ +theorem sum_SLT_pow_div_factorial_div_le (n : ℕ) (z : ℝ) : + ∑ p ∈ primesLT z, SLT p ^ n / n.factorial / p ≤ + SLT z ^ (n + 1) / (n + 1).factorial := by + have h := sum_SLT_pow_div_le n z + have hf : (0 : ℝ) < n.factorial := by exact_mod_cast n.factorial_pos + calc ∑ p ∈ primesLT z, SLT p ^ n / n.factorial / p + = (∑ p ∈ primesLT z, SLT p ^ n / p) / n.factorial := by + rw [sum_div] + exact sum_congr rfl fun p _ ↦ by ring + _ ≤ SLT z ^ (n + 1) / (n + 1) / n.factorial := by gcongr + _ = SLT z ^ (n + 1) / (n + 1).factorial := by + rw [Nat.factorial_succ] + push_cast + rw [div_div, mul_comm] + +theorem SLT_nonneg (z : ℝ) : 0 ≤ SLT z := sum_nonneg fun p _ ↦ by positivity + +theorem R_le_one (z : ℝ) : R z ≤ 1 := + prod_le_one₀ (fun p hp ↦ sub_nonneg.2 <| inv_le_one_of_one_le₀ <| by + exact_mod_cast (mem_primesLT.1 hp).1.one_lt.le) fun p _ ↦ one_sub_inv_le_one p + +/-! ### The crude bound for `fail` -/ + +/-- The crude bound in "shifted" form: depth `l + 1` contributes only if `y < z^{l+3}`. -/ +theorem fail_le_sum_ite (lower : Bool) (r : ℕ) (y z : ℝ) : + fail lower r y z ≤ ∑ l ∈ range r, + if y < z ^ (l + 3) then SLT z ^ (l + 1) / (l + 1).factorial else 0 := by + induction r generalizing lower y z with + | zero => simp + | succ r ih => + -- the contribution of depth `≥ 2` + have hA : ∑ p ∈ rosserPrimes lower y z, fail (!lower) r (y / p) p / p ≤ + ∑ l ∈ range r, if y < z ^ (l + 1 + 3) then + SLT z ^ (l + 1 + 1) / (l + 1 + 1).factorial else 0 := by + calc ∑ p ∈ rosserPrimes lower y z, fail (!lower) r (y / p) p / p + ≤ ∑ p ∈ primesLT z, fail (!lower) r (y / p) p / p := + sum_le_sum_of_subset_of_nonneg rosserPrimes_subset fun p _ _ ↦ + div_nonneg (fail_nonneg _ _ _ _) p.cast_nonneg + _ ≤ ∑ p ∈ primesLT z, (∑ l ∈ range r, if y / p < (p : ℝ) ^ (l + 3) then + SLT p ^ (l + 1) / (l + 1).factorial else 0) / p := by + gcongr with p + exact ih _ _ _ + _ = ∑ l ∈ range r, ∑ p ∈ primesLT z, (if y / p < (p : ℝ) ^ (l + 3) then + SLT p ^ (l + 1) / (l + 1).factorial else 0) / p := by + simp_rw [sum_div] + exact sum_comm + _ ≤ _ := by + refine sum_le_sum fun l _ ↦ ?_ + split_ifs with hyz + · calc ∑ p ∈ primesLT z, (if y / p < (p : ℝ) ^ (l + 3) then + SLT p ^ (l + 1) / (l + 1).factorial else 0) / p + ≤ ∑ p ∈ primesLT z, SLT p ^ (l + 1) / (l + 1).factorial / p := by + gcongr with p + split_ifs + · exact le_rfl + · have := SLT_nonneg p + positivity + _ ≤ _ := sum_SLT_pow_div_factorial_div_le (l + 1) z + · refine (sum_eq_zero fun p hp ↦ ?_).le + rw [ite_eq_right, zero_div] + intro h + have hpos : (0 : ℝ) < p := by exact_mod_cast (prime_of_mem_primesLT hp).pos + rw [div_lt_iff₀ hpos, ← pow_succ] at h + exact hyz (h.trans (pow_lt_pow_left₀ (lt_of_mem_primesLT hp) hpos.le + (by omega))) + -- the contribution of depth `1` + have hE : ∑ p ∈ (primesLT z).filter (fun p : ℕ ↦ ¬ (p : ℝ) ^ 3 < y), R p / p ≤ + if y < z ^ (0 + 3) then SLT z ^ (0 + 1) / (0 + 1).factorial else 0 := by + split_ifs with hyz + · simp only [zero_add, pow_one, Nat.factorial_one, Nat.cast_one, div_one, SLT] + calc ∑ p ∈ (primesLT z).filter (fun p : ℕ ↦ ¬ (p : ℝ) ^ 3 < y), R p / p + ≤ ∑ p ∈ (primesLT z).filter (fun p : ℕ ↦ ¬ (p : ℝ) ^ 3 < y), (p : ℝ)⁻¹ := by + gcongr with p + rw [div_eq_mul_inv] + exact mul_le_of_le_one_left (by positivity) (R_le_one p) + _ ≤ ∑ p ∈ primesLT z, (p : ℝ)⁻¹ := + sum_le_sum_of_subset_of_nonneg (filter_subset _ _) fun p _ _ ↦ by positivity + · refine (sum_eq_zero fun p hp ↦ ?_).le + rw [mem_filter] at hp + exact absurd ((not_lt.1 hp.2).trans_lt (pow_lt_pow_left₀ (lt_of_mem_primesLT hp.1) + p.cast_nonneg (by norm_num))) hyz + rw [sum_range_succ'] + cases lower + · rw [fail_false_succ] + exact add_le_add hA hE + · rw [fail_true_succ, ← rosserPrimes_true, ← add_zero (∑ p ∈ _, _ / _)] + refine add_le_add hA ?_ + have := SLT_nonneg z + split_ifs <;> positivity + +/-- [I71, p. 24]: the deficits are bounded by the sum of `SLT(z)^l / l!` over the depths +`1 ≤ l ≤ r` for which `y < z^{l+2}`. -/ +theorem fail_le_sum_SLT_pow (lower : Bool) (r : ℕ) (y z : ℝ) : + fail lower r y z ≤ ∑ l ∈ Icc 1 r with y < z ^ (l + 2), SLT z ^ l / l.factorial := by + refine (fail_le_sum_ite lower r y z).trans_eq ?_ + rw [sum_filter] + refine sum_nbij' (· + 1) (· - 1) ?_ ?_ ?_ ?_ ?_ + · intro l hl + simp only [mem_range, mem_Icc] at hl ⊢ + omega + · intro l hl + simp only [mem_range, mem_Icc] at hl ⊢ + omega + · intro l _ + simp + · intro l hl + simp only [mem_Icc] at hl + omega + · intro l _ + simp only [show l + 3 = l + 1 + 2 by ring] + +/-! ### Tail estimates -/ + +/-- `X^k / k! ≤ (e X / k)^k`. -/ +theorem pow_div_factorial_le_pow {X : ℝ} (hX : 0 ≤ X) (k : ℕ) : + X ^ k / k.factorial ≤ (exp 1 * X / k) ^ k := by + rcases k.eq_zero_or_pos with rfl | hk + · simp + have hk' : (0 : ℝ) < k := by exact_mod_cast hk + have hf : (0 : ℝ) < k.factorial := by exact_mod_cast k.factorial_pos + have h := pow_div_factorial_le_exp _ hk'.le k + rw [div_le_iff₀ hf] at h + rw [div_pow, mul_pow, ← exp_nat_mul, mul_one, div_le_div_iff₀ hf (by positivity)] + calc X ^ k * k ^ k ≤ X ^ k * (exp k * k.factorial) := by gcongr + _ = exp k * X ^ k * k.factorial := by ring + +/-- [I71, p. 24]: the tail `∑_{l > u} X^l / l!` (over any finite set of `l > u`) is at most +`2 (e X / u)^u` when `2 e X ≤ u`. -/ +theorem sum_pow_div_factorial_le {X u : ℝ} (hX : 0 ≤ X) (hu : 0 < u) (h : 2 * exp 1 * X ≤ u) + (s : Finset ℕ) (hs : ∀ l ∈ s, u < l) : + ∑ l ∈ s, X ^ l / l.factorial ≤ 2 * (exp 1 * X / u) ^ u := by + set k := ⌊u⌋₊ + 1 with hk + have huk : u < k := by rw [hk]; push_cast; exact Nat.lt_floor_add_one u + have hks : ∀ l ∈ s, k ≤ l := fun l hl ↦ by + rw [hk, Nat.add_one_le_iff, Nat.floor_lt hu.le] + exact hs l hl + have he : 1 ≤ exp 1 := one_le_exp zero_le_one + have h2X : 2 * X ≤ k + 1 := by nlinarith + have hf : (0 : ℝ) < k.factorial := by exact_mod_cast k.factorial_pos + -- each term is at most `X^k/k! · 2^{-(l-k)}` + have hterm : ∀ j : ℕ, X ^ (k + j) / (k + j).factorial ≤ + X ^ k / k.factorial * (1 / 2) ^ j := by + intro j + have h1 : ((k.factorial * (k + 1) ^ j : ℕ) : ℝ) ≤ (k + j).factorial := by + exact_mod_cast Nat.factorial_mul_pow_le_factorial + push_cast at h1 + have hpos : (0 : ℝ) < k.factorial * (k + 1) ^ j := by positivity + calc X ^ (k + j) / (k + j).factorial ≤ X ^ (k + j) / (k.factorial * (k + 1) ^ j) := by + gcongr + _ = X ^ k / k.factorial * (X / (k + 1)) ^ j := by + rw [pow_add, div_pow] + field_simp + _ ≤ X ^ k / k.factorial * (1 / 2) ^ j := by + refine mul_le_mul_of_nonneg_left (pow_le_pow_left₀ (by positivity) ?_ j) + (by positivity) + rw [div_le_iff₀ (by positivity)] + linarith + set N := s.sup id + 1 + have hsub : s ⊆ Ico k N := fun l hl ↦ + mem_Ico.2 ⟨hks l hl, Nat.lt_succ_of_le (le_sup (f := id) hl)⟩ + calc ∑ l ∈ s, X ^ l / l.factorial + ≤ ∑ l ∈ s, X ^ k / k.factorial * (1 / 2) ^ (l - k) := by + refine sum_le_sum fun l hl ↦ ?_ + have := hterm (l - k) + rwa [Nat.add_sub_cancel' (hks l hl)] at this + _ ≤ ∑ l ∈ Ico k N, X ^ k / k.factorial * (1 / 2) ^ (l - k) := + sum_le_sum_of_subset_of_nonneg hsub fun _ _ _ ↦ by positivity + _ = X ^ k / k.factorial * ∑ j ∈ range (N - k), (1 / 2 : ℝ) ^ j := by + rw [← mul_sum, sum_Ico_eq_sum_range] + simp + _ ≤ X ^ k / k.factorial * 2 := by + gcongr + exact sum_geometric_two_le _ + _ ≤ (exp 1 * X / k) ^ k * 2 := by gcongr; exact pow_div_factorial_le_pow hX k + _ ≤ (exp 1 * X / u) ^ (k : ℝ) * 2 := by + rw [rpow_natCast] + gcongr + _ ≤ (exp 1 * X / u) ^ u * 2 := by + refine mul_le_mul_of_nonneg_right ?_ (by norm_num) + refine rpow_le_rpow_of_exponent_ge' (by positivity) ?_ hu.le huk.le + rw [div_le_one hu] + nlinarith [exp_pos 1] + _ = 2 * (exp 1 * X / u) ^ u := mul_comm _ _ + +/-- `(e X / u)^u = exp (-(u log u) + u log X + u)`. -/ +theorem exp_one_mul_div_rpow {X u : ℝ} (hX : 0 < X) (hu : 0 < u) : + (exp 1 * X / u) ^ u = exp (-(u * log u) + u * log X + u) := by + rw [rpow_def_of_pos (by positivity), log_div (by positivity) hu.ne', + log_mul (exp_pos 1).ne' hX.ne', log_exp] + ring_nf + +/-- The crude bound in the form used in [I71, p. 24]: if `z^{u+2} ≤ y` (i.e. `s ≥ u + 2` for +`z = y^{1/s}`), `SLT z ≤ X` and `2 e X ≤ u`, then `fail lower r y z ≤ 2 (e X / u)^u`. -/ +theorem fail_le_tail {lower : Bool} {r : ℕ} {y z X u : ℝ} (hz : 1 < z) (hu : 0 < u) + (hyz : z ^ (u + 2) ≤ y) (hX : SLT z ≤ X) (h : 2 * exp 1 * X ≤ u) : + fail lower r y z ≤ 2 * (exp 1 * X / u) ^ u := by + refine (fail_le_sum_SLT_pow lower r y z).trans ((sum_le_sum fun l _ ↦ ?_).trans + (sum_pow_div_factorial_le ((SLT_nonneg z).trans hX) hu h _ fun l hl ↦ ?_)) + · gcongr + exact SLT_nonneg z + · have hl := (mem_filter.1 hl).2 + rw [← rpow_natCast] at hl + have := (rpow_lt_rpow_left_iff hz).1 (hyz.trans_lt hl) + push_cast at this + linarith + +/-- `fail_le_tail` with `z = y^{1/s}`: for `y > 1`, `s > 2`, `SLT (y^{1/s}) ≤ X` and +`2 e X ≤ s - 2`, `fail lower r y y^{1/s} ≤ 2 (e X / (s - 2))^{s - 2}`. -/ +theorem fail_rpow_le_tail {lower : Bool} {r : ℕ} {y s X : ℝ} (hy : 1 < y) (hs : 2 < s) + (hX : SLT (y ^ s⁻¹) ≤ X) (h : 2 * exp 1 * X ≤ s - 2) : + fail lower r y (y ^ s⁻¹) ≤ 2 * (exp 1 * X / (s - 2)) ^ (s - 2) := by + have hs0 : 0 < s := by linarith + refine fail_le_tail (one_lt_rpow hy (inv_pos.2 hs0)) (by linarith) ?_ hX h + rw [sub_add_cancel, ← rpow_mul (by linarith), inv_mul_cancel₀ hs0.ne', rpow_one] + +/-- `SLT z ≤ log log z + C` for `z ≥ 2`. -/ +theorem SLT_le_loglog : ∃ C : ℝ, ∀ z ≥ 2, SLT z ≤ log (log z) + C := by + obtain ⟨c₅, C, hC⟩ := S_asymp + refine ⟨c₅ + |C|, fun z hz ↦ ?_⟩ + have h1 := (S_sub_SLT (by linarith : (0 : ℝ) < z)).1 + have h2 := (abs_le.1 (hC z hz)).2 + have h3 : C * pntE z ≤ |C| := by + calc + C * pntE z ≤ |C| * pntE z := + mul_le_mul_of_nonneg_right (le_abs_self C) (pntE_nonneg z) + _ ≤ |C| * 1 := mul_le_mul_of_nonneg_left (pntE_le_one z) (abs_nonneg C) + _ = |C| := mul_one _ + linarith + +/-! ### Counts -/ + +/-- `∑_{d ∈ D, ω(d) = l} 1/d ≤ SLT(z)^l / l!`. -/ +theorem sum_inv_filter_card_primeFactors_eq_le (lower : Bool) (y z : ℝ) (l : ℕ) : + ∑ d ∈ (rosserSet lower y z).filter (fun d ↦ #d.primeFactors = l), (d : ℝ)⁻¹ ≤ + SLT z ^ l / l.factorial := by + induction l generalizing lower y z with + | zero => + rw [sum_filter, sum_rosserSet] + simp only [Nat.primeFactors_one, card_empty, ite_true, Nat.cast_one, inv_one, pow_zero, + Nat.factorial_zero, div_one] + refine (add_eq_left.2 (sum_eq_zero fun p hp ↦ sum_eq_zero fun e he ↦ ?_)).le + rw [card_primeFactors_mul_of_mem_rosserSet + (prime_of_mem_primesLT (rosserPrimes_subset hp)) he, ite_eq_right (Nat.succ_ne_zero _)] + | succ l ih => + rw [sum_filter, sum_rosserSet] + simp only [Nat.primeFactors_one, card_empty, Nat.cast_one, inv_one] + rw [ite_eq_right (Nat.succ_ne_zero l).symm, zero_add] + calc ∑ p ∈ rosserPrimes lower y z, ∑ e ∈ rosserSet (!lower) (y / p) p, + (if #(p * e).primeFactors = l + 1 then ((p * e : ℕ) : ℝ)⁻¹ else 0) + = ∑ p ∈ rosserPrimes lower y z, (∑ e ∈ (rosserSet (!lower) (y / p) p).filter + (fun e ↦ #e.primeFactors = l), (e : ℝ)⁻¹) / p := by + refine sum_congr rfl fun p hp ↦ ?_ + rw [sum_filter, sum_div] + refine sum_congr rfl fun e he ↦ ?_ + rw [card_primeFactors_mul_of_mem_rosserSet + (prime_of_mem_primesLT (rosserPrimes_subset hp)) he] + simp only [add_left_inj] + split_ifs + · push_cast + rw [mul_inv, div_eq_mul_inv, mul_comm] + · simp + _ ≤ ∑ p ∈ rosserPrimes lower y z, SLT p ^ l / l.factorial / p := by + gcongr with p + exact ih _ _ _ + _ ≤ ∑ p ∈ primesLT z, SLT p ^ l / l.factorial / p := + sum_le_sum_of_subset_of_nonneg rosserPrimes_subset fun p _ _ ↦ by + have := SLT_nonneg p + positivity + _ ≤ _ := sum_SLT_pow_div_factorial_div_le l z + +/-- [I71, p. 27]: the number of elements of `rosserSet lower y z` with at least `k` prime +factors, for `k ≥ 2` (`k ≥ 1` for the upper sieve), is at most +`y ∑_{k ≤ l ≤ π(z)} SLT(z)^l / l!`. -/ +theorem card_filter_le_mul_sum {lower : Bool} {y z : ℝ} {k : ℕ} (hy : 0 ≤ y) + (hk : (if lower then 2 else 1) ≤ k) : + (#((rosserSet lower y z).filter fun d ↦ k ≤ #d.primeFactors) : ℝ) ≤ + y * ∑ l ∈ Icc k #(primesLT z), SLT z ^ l / l.factorial := by + set D := (rosserSet lower y z).filter fun d ↦ k ≤ #d.primeFactors + calc (#D : ℝ) = ∑ d ∈ D, (1 : ℝ) := by simp + _ ≤ ∑ d ∈ D, y * (d : ℝ)⁻¹ := by + refine sum_le_sum fun d hd ↦ ?_ + obtain ⟨hd, hkd⟩ := mem_filter.1 hd + have hdy := lt_of_mem_rosserSet hd (hk.trans hkd) + have hd0 : (0 : ℝ) < d := by exact_mod_cast pos_of_mem_rosserSet hd + rw [← div_eq_mul_inv, le_div_iff₀ hd0, one_mul] + exact hdy.le + _ = y * ∑ l ∈ Icc k #(primesLT z), ∑ d ∈ D.filter (fun d ↦ #d.primeFactors = l), + (d : ℝ)⁻¹ := by + rw [← mul_sum, sum_fiberwise_of_maps_to] + intro d hd + obtain ⟨hd, hkd⟩ := mem_filter.1 hd + exact mem_Icc.2 ⟨hkd, card_le_card (primeFactors_subset_of_mem_rosserSet hd)⟩ + _ ≤ y * ∑ l ∈ Icc k #(primesLT z), SLT z ^ l / l.factorial := by + gcongr with l + refine le_trans ?_ (sum_inv_filter_card_primeFactors_eq_le lower y z l) + refine sum_le_sum_of_subset_of_nonneg ?_ fun _ _ _ ↦ by positivity + exact filter_subset_filter _ (filter_subset _ _) + +/-- [I71, p. 27]: `#{d ∈ D | ω(d) ≥ k} ≤ 2 y (e X / u)^u` for `u < k`, `SLT z ≤ X` and +`2 e X ≤ u`, where `k ≥ 2` (`k ≥ 1` for the upper sieve). -/ +theorem card_filter_le_tail {lower : Bool} {y z X u : ℝ} {k : ℕ} (hy : 0 ≤ y) + (hk : (if lower then 2 else 1) ≤ k) (hu : 0 < u) (huk : u < k) (hX : SLT z ≤ X) + (h : 2 * exp 1 * X ≤ u) : + (#((rosserSet lower y z).filter fun d ↦ k ≤ #d.primeFactors) : ℝ) ≤ + 2 * y * (exp 1 * X / u) ^ u := by + refine (card_filter_le_mul_sum hy hk).trans ?_ + rw [mul_assoc, mul_left_comm] + refine mul_le_mul_of_nonneg_left ((sum_le_sum fun l _ ↦ ?_).trans + (sum_pow_div_factorial_le ((SLT_nonneg z).trans hX) hu h _ fun l hl ↦ ?_)) hy + · gcongr + exact SLT_nonneg z + · exact huk.trans_le (by exact_mod_cast (mem_Icc.1 hl).1) + +/-- The number of elements of `rosserSet lower y z` with exactly `l` prime factors is at most +`π(z)^l / l!`. -/ +theorem card_filter_eq_le_pow_div (lower : Bool) (y z : ℝ) (l : ℕ) : + (#((rosserSet lower y z).filter fun d ↦ #d.primeFactors = l) : ℝ) ≤ + (#(primesLT z) : ℝ) ^ l / l.factorial := by + refine le_trans ?_ (Nat.choose_le_pow_div l _) + have : #((rosserSet lower y z).filter fun d ↦ #d.primeFactors = l) ≤ + #((primesLT z).powersetCard l) := by + refine card_le_card_of_injOn (fun d ↦ d.primeFactors) (fun d hd ↦ ?_) fun d hd e he h ↦ ?_ + · obtain ⟨hd, hl⟩ := mem_filter.1 hd + exact mem_powersetCard.2 ⟨primeFactors_subset_of_mem_rosserSet hd, hl⟩ + · have hd' := squarefree_of_mem_rosserSet (mem_filter.1 hd).1 + have he' := squarefree_of_mem_rosserSet (mem_filter.1 he).1 + rw [← Nat.prod_primeFactors_of_squarefree hd', ← Nat.prod_primeFactors_of_squarefree he'] + exact congrArg (fun T ↦ ∏ p ∈ T, p) h + rw [card_powersetCard] at this + exact_mod_cast this + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/Defs.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/Defs.lean new file mode 100644 index 000000000..c3aec7b06 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/Defs.lean @@ -0,0 +1,47 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.SieveMajorants.Majorants +import Mathlib.NumberTheory.Chebyshev + +/-! +# Notation for [I71, §4] + +`L = log y`, `ξ(y) = log y / (log log 3y)^{11/5}`, `δ(s, y) = (1 + s² log⁵ s / log² y)^{5s}`. +The main-term majorants are `f` (lower sieve) and `F + (3 - s)⁺` (upper sieve, which also +contains the depth-one deficit); the error majorants are `𝔣` and `𝔉`. +-/ + +@[expose] public section + +open Real + +namespace IwaniecLinearSieve + +/-- Iwaniec's `ξ = log y / (log log 3y)^{11/5}`. -/ +noncomputable def xi (y : ℝ) : ℝ := log y / log (log (3 * y)) ^ (11 / 5 : ℝ) + +/-- Iwaniec's compensation factor `(1 + s² log⁵ s / log² y)^{5s}`. -/ +noncomputable def delta (s y : ℝ) : ℝ := (1 + s ^ 2 * log s ^ 5 / log y ^ 2) ^ (5 * s) + +/-- Main-term majorants: `f` for the lower sieve, `F + (3 - s)⁺` for the upper sieve. -/ +noncomputable def mainMaj : Bool → ℝ → ℝ + | true, s => fSieve s + | false, s => FSieve s + max (3 - s) 0 + +/-- Error majorants `G`: `𝔣` for the lower sieve, `𝔉` for the upper sieve. -/ +noncomputable def errMaj : Bool → ℝ → ℝ + | true => majf + | false => majF + +/-- The smallest sifting parameter `s`: `2` for the lower sieve, `1` for the upper sieve. -/ +def sMin : Bool → ℝ + | true => 2 + | false => 1 + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/Depth.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/Depth.lean new file mode 100644 index 000000000..62fa246b7 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/Depth.lean @@ -0,0 +1,330 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Rosser +import Mathlib.Algebra.Order.Ring.Star +import Mathlib.Algebra.Order.Star.Real +import Mathlib.NumberTheory.Chebyshev +import Mathlib.Tactic.Polynomial.Basic +import Std.Tactic.BVDecide.Normalize.Bool + +/-! +# Depth stabilisation of Rosser's sieve ([I71, pp. 23, 26]) + +A failing tuple `p₁ > ⋯ > p_l` of depth `l ≥ 3` passed the test at index `l - 2`, so +`p₁ ⋯ p_{l-1} < p₁ ⋯ p_{l-2} p_{l-2}² < y`; an element `d = p₁ ⋯ p_l` of `rosserSet lower y z` +satisfies `d < y` as soon as `l ≥ 2` (or `l ≥ 1` for the upper sieve). Hence if every product of +`r` distinct primes below `z` is at least `y` (`LeProdPrimesLT r y z`), the recursion stops at +depth `r`: + +* `fail_add_eq`: `2 ≤ r → LeProdPrimesLT r y z → fail lower (r + j) y z = fail lower r y z`; +* `card_filter_rosserSet_add_eq`: + `1 ≤ r → LeProdPrimesLT (r + 1) y z → #{d ∈ D | ω(d) ≤ r + j} = #{d ∈ D | ω(d) ≤ r}`. + +Products of `r` distinct primes are at least `(r + 1)!` (`factorial_card_add_one_le_prod`), and +`(r + 1)! ≥ y` once `r + 2 > 2 log y / log log y` and `y` is large (`exists_le_factorial`), which +gives [I71]'s "if `m + 1 > 2 log y / log log y` then `Q_{m+1, y} = Q_{m-1, y}`" +(`exists_fail_add_eq`, `exists_card_filter_rosserSet_add_eq`). +-/ + +@[expose] public section + +open Finset Real + +namespace IwaniecLinearSieve + +/-- `y` is at most every product of `r` distinct primes below `z` (vacuous if there are fewer +than `r` such primes). -/ +def LeProdPrimesLT (r : ℕ) (y z : ℝ) : Prop := + ∀ T ⊆ primesLT z, #T = r → y ≤ ∏ p ∈ T, (p : ℝ) + +variable {lower : Bool} {r : ℕ} {y z : ℝ} {p d : ℕ} + +theorem one_le_prod_primes {T : Finset ℕ} {z : ℝ} (hT : T ⊆ primesLT z) : + 1 ≤ ∏ p ∈ T, (p : ℝ) := + one_le_prod₀ fun p hp ↦ by exact_mod_cast (prime_of_mem_primesLT (hT hp)).one_lt.le + +/-- One level down the recursion. -/ +theorem LeProdPrimesLT.div (h : LeProdPrimesLT (r + 1) y z) (hp : p ∈ primesLT z) : + LeProdPrimesLT r (y / p) p := by + intro T hT hcard + have hpT : p ∉ T := fun h ↦ notMem_primesLT_self (hT h) + have hpos : (0 : ℝ) < p := by exact_mod_cast (prime_of_mem_primesLT hp).pos + have := h (insert p T) (insert_subset hp (hT.trans (primesLT_natCast_subset hp))) + (by rw [card_insert_of_notMem hpT, hcard]) + rw [prod_insert hpT] at this + rwa [div_le_iff₀' hpos] + +theorem LeProdPrimesLT.succ (h : LeProdPrimesLT r y z) : LeProdPrimesLT (r + 1) y z := by + intro T hT hcard + obtain ⟨a, ha⟩ := card_pos.1 (by omega : 0 < #T) + rw [← mul_prod_erase T _ ha] + have h1 := h (T.erase a) ((erase_subset a T).trans hT) (by rw [card_erase_of_mem ha, hcard]; rfl) + have h2 : (1 : ℝ) ≤ a := by exact_mod_cast (prime_of_mem_primesLT (hT ha)).one_lt.le + have h3 := one_le_prod_primes ((erase_subset a T).trans hT) + nlinarith + +theorem LeProdPrimesLT.mono {s : ℕ} (h : LeProdPrimesLT r y z) (hrs : r ≤ s) : + LeProdPrimesLT s y z := by + induction s, hrs using Nat.le_induction with + | base => exact h + | succ s _ ih => exact ih.succ + +/-- A product of `#T` distinct integers `≥ 2` is at least `(#T + 1)!`. -/ +theorem factorial_card_add_one_le_prod (T : Finset ℕ) (hT : ∀ n ∈ T, 2 ≤ n) : + (#T + 1).factorial ≤ ∏ n ∈ T, n := by + induction T using Finset.induction_on_max with + | empty => simp + | insert a T hlt ih => + have haT : a ∉ T := fun h ↦ lt_irrefl a (hlt a h) + rw [card_insert_of_notMem haT, prod_insert haT, Nat.factorial_succ] + have hsub : T ⊆ Ico 2 a := fun n hn ↦ mem_Ico.2 ⟨hT n (mem_insert_of_mem hn), hlt n hn⟩ + have hcard : #T + 2 ≤ a := by + have := card_le_card hsub + have h2 := hT a (mem_insert_self a T) + simp only [Nat.card_Ico] at this + omega + exact Nat.mul_le_mul (by omega) (ih fun n hn ↦ hT n (mem_insert_of_mem hn)) + +theorem leProdPrimesLT_of_le_factorial (h : y ≤ (r + 1).factorial) : LeProdPrimesLT r y z := by + intro T hT hcard + refine h.trans ?_ + rw [← hcard] + have h := (Nat.cast_le (α := ℝ)).2 (factorial_card_add_one_le_prod T fun n hn ↦ + (prime_of_mem_primesLT (hT hn)).two_le) + push_cast at h + exact h + +/-! ### Stabilisation of `fail` -/ +theorem fail_succ_congr {a b : ℕ} + (h : ∀ p ∈ rosserPrimes lower y z, fail (!lower) a (y / p) p = fail (!lower) b (y / p) p) : + fail lower (a + 1) y z = fail lower (b + 1) y z := by + cases lower <;> simp only [Bool.not_false, Bool.not_true] at h + · rw [fail_false_succ, fail_false_succ] + congr 1 + exact sum_congr rfl fun p hp ↦ by rw [h p hp] + · rw [fail_true_succ, fail_true_succ] + exact sum_congr rfl fun p hp ↦ by rw [h p (by simpa using hp)] + +/-- If every product of `r ≥ 2` distinct primes below `z` is at least `y`, the deficits do not +change beyond depth `r`. -/ +theorem fail_add_eq (hr : 2 ≤ r) (h : LeProdPrimesLT r y z) (j : ℕ) : + fail lower (r + j) y z = fail lower r y z := by + induction r, hr using Nat.le_induction generalizing lower y z with + | base => + rw [show 2 + j = (1 + j) + 1 by omega] + refine fail_succ_congr fun p hp ↦ ?_ + have hpz := rosserPrimes_subset hp + have hpos : (0 : ℝ) < p := by exact_mod_cast (prime_of_mem_primesLT hpz).pos + -- `y / p ≤ q` for every prime `q < p` + have h1 : ∀ q ∈ primesLT p, y / p ≤ q := fun q hq ↦ by + have := (h.div hpz) {q} (singleton_subset_iff.2 hq) (card_singleton (α := ℕ) q) + simpa using this + rw [Nat.add_comm 1 j] + cases lower + · -- the upper sieve: `p³ < y`, so there is no prime `q < p` at all + rw [mem_rosserPrimes] at hp + have hp3 : (p : ℝ) ^ 3 < y := hp.2.resolve_left (by simp) + simp only [Bool.not_false, fail_true_succ] + refine sum_congr rfl fun q hq ↦ absurd (h1 q hq) ?_ + have hqp := lt_of_mem_primesLT hq + have hq0 : (0 : ℝ) ≤ q := q.cast_nonneg + have hp1 : (1 : ℝ) ≤ p := by exact_mod_cast (prime_of_mem_primesLT hpz).one_lt.le + rw [not_le, lt_div_iff₀' hpos] + have h2 : (p : ℝ) * q < p * p := mul_lt_mul_of_pos_left hqp hpos + have h3 : (p : ℝ) ^ 2 ≤ p ^ 3 := pow_le_pow_right₀ hp1 (by norm_num) + nlinarith + · -- the lower sieve: the next prime `q` would need `q³ < y / p ≤ q` + simp only [Bool.not_true, fail_false_succ] + congr 1 + refine sum_congr rfl fun q hq ↦ absurd (h1 q (rosserPrimes_subset hq)) ?_ + rw [mem_rosserPrimes] at hq + have hq3 : (q : ℝ) ^ 3 < y / p := hq.2.resolve_left (by simp) + have hq1 : (1 : ℝ) ≤ q := by + exact_mod_cast (prime_of_mem_primesLT hq.1).one_lt.le + rw [not_le] + have h2 : (q : ℝ) ≤ q ^ 3 := le_self_pow₀ hq1 (by norm_num) + linarith + | succ r hr ih => + rw [show r + 1 + j = (r + j) + 1 by omega] + exact fail_succ_congr fun p hp ↦ ih (h.div (rosserPrimes_subset hp)) + +theorem fail_add_eq_of_le_factorial (hr : 2 ≤ r) (h : y ≤ (r + 1).factorial) (j : ℕ) : + fail lower (r + j) y z = fail lower r y z := + fail_add_eq hr (leProdPrimesLT_of_le_factorial h) j + +/-! ### Stabilisation of the depth-truncated counts -/ + +/-- Elements of `rosserSet lower y z` with at least two prime factors (at least one for the +upper sieve) are smaller than `y`. -/ +theorem lt_of_mem_rosserSet (hd : d ∈ rosserSet lower y z) + (hω : (if lower then 2 else 1) ≤ #d.primeFactors) : (d : ℝ) < y := by + induction z using primesLT_induction generalizing lower y d with + | h z ih => + rcases mem_rosserSet.1 hd with rfl | ⟨p, hp, e, he, rfl⟩ + · cases lower <;> simp at hω + have hpz := rosserPrimes_subset hp + have hpp := prime_of_mem_primesLT hpz + have hpos : (0 : ℝ) < p := by exact_mod_cast hpp.pos + rw [card_primeFactors_mul_of_mem_rosserSet hpp he] at hω + have key : (if (!lower) then 2 else 1) ≤ #e.primeFactors → ((p * e : ℕ) : ℝ) < y := by + intro h + have := ih p hpz he h + push_cast + rwa [lt_div_iff₀' hpos] at this + cases lower + · rw [mem_rosserPrimes] at hp + have hp3 : (p : ℝ) ^ 3 < y := hp.2.resolve_left (by simp) + by_cases h2 : 2 ≤ #e.primeFactors + · exact key (by simpa using h2) + -- `e` has at most one prime factor, each below `p` + have he' : e ≤ p ^ #e.primeFactors := by + conv_lhs => rw [← Nat.prod_primeFactors_of_squarefree (squarefree_of_mem_rosserSet he)] + exact prod_le_pow_card _ _ _ fun q hq ↦ + (Nat.cast_lt.1 (lt_of_mem_primesLT (primeFactors_subset_of_mem_rosserSet he hq))).le + have hpe : p * e ≤ p ^ 3 := by + calc p * e ≤ p * p ^ #e.primeFactors := Nat.mul_le_mul_left p he' + _ = p ^ (#e.primeFactors + 1) := by ring + _ ≤ p ^ 3 := Nat.pow_le_pow_right hpp.pos (by omega) + exact lt_of_le_of_lt (by exact_mod_cast hpe) hp3 + · exact key (by simp at hω ⊢; omega) + +/-- If every product of `r + 1 ≥ 2` distinct primes below `z` is at least `y`, no element of +`rosserSet lower y z` has more than `r` prime factors. -/ +theorem card_primeFactors_le_of_mem_rosserSet (hr : 1 ≤ r) (h : LeProdPrimesLT (r + 1) y z) + (hd : d ∈ rosserSet lower y z) : #d.primeFactors ≤ r := by + by_contra hlt + obtain ⟨T, hT, hcard⟩ := exists_subset_card_eq (s := d.primeFactors) (n := r + 1) (by omega) + have hdy := lt_of_mem_rosserSet hd (by split_ifs <;> omega) + have hyT := h T (hT.trans (primeFactors_subset_of_mem_rosserSet hd)) hcard + have hTd : ∏ p ∈ T, p ≤ d := by + refine Nat.le_of_dvd (pos_of_mem_rosserSet hd) ?_ + conv_rhs => rw [← Nat.prod_primeFactors_of_squarefree (squarefree_of_mem_rosserSet hd)] + exact prod_dvd_prod_of_subset _ _ _ hT + have : (∏ p ∈ T, (p : ℝ)) ≤ d := by + have h' := (Nat.cast_le (α := ℝ)).2 hTd + push_cast at h' + exact h' + linarith + +theorem card_filter_rosserSet_add_eq (hr : 1 ≤ r) (h : LeProdPrimesLT (r + 1) y z) (j : ℕ) : + #((rosserSet lower y z).filter fun d ↦ #d.primeFactors ≤ r + j) = + #((rosserSet lower y z).filter fun d ↦ #d.primeFactors ≤ r) := by + congr 1 + refine filter_congr fun d hd ↦ ⟨fun _ ↦ card_primeFactors_le_of_mem_rosserSet hr h hd, + fun h ↦ h.trans (Nat.le_add_right r j)⟩ + +/-! ### The numerical form -/ + +/-- `n (log n - 1) ≤ log n!`. -/ +theorem mul_log_sub_one_le_log_factorial (n : ℕ) : + (n : ℝ) * (log n - 1) ≤ log n.factorial := by + rcases n.eq_zero_or_pos with rfl | hn + · simp + have hn' : (0 : ℝ) < n := by exact_mod_cast hn + have h := pow_div_factorial_le_exp _ hn'.le n + have hf : (0 : ℝ) < n.factorial := by exact_mod_cast n.factorial_pos + rw [div_le_iff₀ hf] at h + have := log_le_log (by positivity) h + rw [log_pow, log_mul (exp_pos _).ne' hf.ne', log_exp] at this + linarith + +/-- `log x ≤ 2 √x`. -/ +theorem log_le_two_mul_sqrt {x : ℝ} (hx : 0 ≤ x) : log x ≤ 2 * √x := by + have := log_le_rpow_div hx (by norm_num : (0 : ℝ) < 1 / 2) + rw [← sqrt_eq_rpow] at this + linarith + +/-- [I71, p. 23]: if `r + 2 > 2 log y / log log y` and `y` is large then `y ≤ (r + 1)!`, so every +product of `r` distinct primes is at least `y`; moreover `r ≥ 2`. -/ +theorem exists_le_factorial : ∃ y₀ : ℝ, ∀ y ≥ y₀, ∀ r : ℕ, + 2 * log y / log (log y) < r + 2 → 2 ≤ r ∧ y ≤ (r + 1).factorial := by + refine ⟨exp (exp 49), fun y hy r hr ↦ ?_⟩ + have hy0 : 0 < y := (exp_pos _).trans_le hy + set L := log y with hL + set ℓ := log L with hℓ + have hL49 : exp 49 ≤ L := by rw [hL, le_log_iff_exp_le hy0]; exact hy + have hL0 : 0 < L := (exp_pos _).trans_le hL49 + have hℓ49 : 49 ≤ ℓ := by rw [hℓ, le_log_iff_exp_le hL0]; exact hL49 + have hℓ0 : 0 < ℓ := by linarith + -- `ℓ ≤ L / 4` + have hsqrtL : 64 ≤ L := by + have := quadratic_le_exp_of_nonneg (by norm_num : (0 : ℝ) ≤ 49) + linarith + have hℓL : 4 * ℓ ≤ L := by + have h1 := log_le_two_mul_sqrt hL0.le + have h2 : 8 ≤ √L := by + rw [show (8 : ℝ) = √64 by rw [show (64 : ℝ) = 8 ^ 2 by norm_num, sqrt_sq (by norm_num)]] + exact sqrt_le_sqrt hsqrtL + have h3 : √L * √L = L := mul_self_sqrt hL0.le + nlinarith + have hratio : 4 ≤ L / ℓ := by rw [le_div_iff₀ hℓ0]; linarith + have h2Lℓ : 2 * L / ℓ = 2 * (L / ℓ) := by ring + refine ⟨by exact_mod_cast (by linarith : (2 : ℝ) ≤ r), ?_⟩ + -- `log ℓ ≤ (ℓ - 3) / 3` + have hlogℓ : 3 * log ℓ + 3 ≤ ℓ := by + have h1 := log_le_two_mul_sqrt hℓ0.le + have h2 : 7 ≤ √ℓ := by + rw [show (7 : ℝ) = √49 by rw [show (49 : ℝ) = 7 ^ 2 by norm_num, sqrt_sq (by norm_num)]] + exact sqrt_le_sqrt hℓ49 + have h3 : √ℓ * √ℓ = ℓ := mul_self_sqrt hℓ0.le + nlinarith + set m := 3 * L / (2 * ℓ) with hm + have hm0 : 0 < m := by positivity + set n : ℕ := r + 1 with hn + have hn_cast : (n : ℝ) = r + 1 := by rw [hn]; push_cast; ring + have hmn : m ≤ n := by + rw [hn_cast, hm] + have : 3 * L / (2 * ℓ) = 3 / 2 * (L / ℓ) := by field_simp + rw [this] + linarith + have hlogm : ℓ - log ℓ ≤ log m := by + rw [hm, log_div (by positivity) (by positivity), log_mul (by norm_num) hL0.ne', + log_mul (by norm_num) hℓ0.ne', ← hℓ] + have : log 2 ≤ log 3 := log_le_log (by norm_num) (by norm_num) + linarith + have hkey : L ≤ m * (log m - 1) := by + have h1 : 2 * ℓ / 3 ≤ log m - 1 := by linarith + calc L = m * (2 * ℓ / 3) := by rw [hm]; field_simp + _ ≤ m * (log m - 1) := by gcongr + have hmono : m * (log m - 1) ≤ n * (log n - 1) := by + have h1 : log m ≤ log n := log_le_log hm0 hmn + have h2 : 0 ≤ log m - 1 := by + by_contra h + have : m * (log m - 1) < 0 := mul_neg_of_pos_of_neg hm0 (not_le.1 h) + linarith + nlinarith + have hfact := mul_log_sub_one_le_log_factorial n + have : L ≤ log n.factorial := by linarith + rw [hL, ← exp_le_exp, exp_log hy0, exp_log (by exact_mod_cast n.factorial_pos)] at this + exact this + +/-- [I71, p. 23]: for `y ≥ y₀` and `r + 2 > 2 log y / log log y`, the deficits do not change +beyond depth `r`. -/ +theorem exists_fail_add_eq : ∃ y₀ : ℝ, ∀ y ≥ y₀, ∀ (lower : Bool) (r : ℕ) (z : ℝ), + 2 * log y / log (log y) < r + 2 → ∀ j, fail lower (r + j) y z = fail lower r y z := by + obtain ⟨y₀, hy₀⟩ := exists_le_factorial + refine ⟨y₀, fun y hy lower r z hr j ↦ ?_⟩ + obtain ⟨h2, hf⟩ := hy₀ y hy r hr + exact fail_add_eq_of_le_factorial h2 hf j + +/-- [I71, p. 26]: for `y ≥ y₀` and `r + 2 > 2 log y / log log y`, no element of +`rosserSet lower y z` has more than `r - 1` prime factors; in particular the depth-truncated +counts do not change beyond depth `r`. -/ +theorem exists_card_filter_rosserSet_add_eq : ∃ y₀ : ℝ, ∀ y ≥ y₀, ∀ (lower : Bool) (r : ℕ) + (z : ℝ), 2 * log y / log (log y) < r + 2 → ∀ j, + #((rosserSet lower y z).filter fun d ↦ #d.primeFactors ≤ r - 1 + j) = + #((rosserSet lower y z).filter fun d ↦ #d.primeFactors ≤ r - 1) := by + obtain ⟨y₀, hy₀⟩ := exists_le_factorial + refine ⟨y₀, fun y hy lower r z hr j ↦ ?_⟩ + obtain ⟨h2, hf⟩ := hy₀ y hy r hr + have h := leProdPrimesLT_of_le_factorial (z := z) hf + rw [show r = r - 1 + 1 by omega] at h + exact card_filter_rosserSet_add_eq (by omega) h j + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/Estimate.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/Estimate.lean new file mode 100644 index 000000000..41b51d7dd --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/Estimate.lean @@ -0,0 +1,239 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.PrimeSums.Error +public import LeanPool.IwaniecLinearSieve.Rosser +import LeanPool.IwaniecLinearSieve.LinearSieve.Calculus +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaEleven +import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFive +import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFour +import Mathlib.Algebra.Order.Star.Real + +/-! +# The linear sieve at level `C₀ z²` ([I71, Theorems 4–5]; [I78, Lemma 2]) + +With `y = C₀ z²` the sifting parameter is `s = log y / log z = 2 + log C₀ / log z`. Theorem 4, +`f(s) ≤ s - 3 log(s - 1)` (from `f(2) = 2`) and `R_asymp` show that the deficit `R(z) - V⁻(y, z)` +of the lower-bound sieve is at most `R(z) (1 - 1/log z)` once `log C₀` exceeds the error constant +of Theorem 4, so the main term is `≥ R(z)/log z`; Theorem 5 bounds the support by `≪ z²/log² z`. +-/ + +@[expose] public section + +open Real Filter Finset + +namespace IwaniecLinearSieve + +/-- The estimates for Rosser's lower-bound sieve at level `y = C₀ z²` which [I78, Lemma 2] quotes +from [I71]: with `s = log y / log z = 2 + log C₀ / log z`, + +* (6) `∑_{n ∣ P} σ_n / φ(n) = (∑_{d ∈ D⁻} μ(d)/d) / R(z) ≥ c / log z`, i.e. + `R(z) - ∑_{d ∈ D⁻} μ(d)/d ≤ R(z) (1 - c / log z)`; +* (5) `∑ |λ_n| = |D⁻| ≪ y / log² y ≪ z² / log² z`, + +for all `z ≥ z₀`. -/ +def LinearSieveEstimate : Prop := + ∃ C₀ c K z₀ : ℝ, 0 < c ∧ ∀ z ≥ z₀, + R z - rosserMain true (C₀ * z ^ 2) z ≤ R z * (1 - c / log z) ∧ + (#(rosserSet true (C₀ * z ^ 2) z) : ℝ) ≤ K * z ^ 2 / log z ^ 2 + +/-- `y^{1/s} = z` for `y = C₀ z²` and `s = log y / log z`. -/ +theorem rpow_one_div_log_div {y z : ℝ} (hy : 0 < y) (hz : 1 < z) (hyl : log y ≠ 0) : + y ^ (1 / (log y / log z)) = z := by + have hlz : log z ≠ 0 := (log_pos hz).ne' + rw [rpow_def_of_pos hy, show log y * (1 / (log y / log z)) = log z by field_simp, + exp_log (by linarith)] + +/-- `log (1 + x) ≥ x / (1 + x)` for `x ≥ 0`. -/ +theorem div_one_add_le_log_one_add {x : ℝ} (hx : 0 ≤ x) : x / (1 + x) ≤ log (1 + x) := by + have h := log_le_sub_one_of_pos (show 0 < (1 + x)⁻¹ by positivity) + rw [log_inv] at h + have : (1 + x)⁻¹ - 1 = -(x / (1 + x)) := by field_simp; ring + linarith + +/-- If `0 ≤ x ≤ 1/2` and `s ≥ 2 + x`, then `log(s - 1) ≥ 2x/3`. +This supplies the logarithmic gain in the linear sieve estimate and Theorem 2. -/ +theorem two_mul_div_three_le_log_sub_one {x s : ℝ} (hx : 0 ≤ x) (hxhalf : x ≤ 1 / 2) + (hs : 2 + x ≤ s) : 2 * x / 3 ≤ log (s - 1) := by + calc 2 * x / 3 = x / (3 / 2) := by ring + _ ≤ x / (1 + x) := + div_le_div_of_nonneg_left hx (by positivity) (by linarith only [hxhalf]) + _ ≤ log (1 + x) := div_one_add_le_log_one_add hx + _ ≤ log (s - 1) := log_le_log (by positivity) (by linarith only [hs]) + +/-- `pntE z · log z → 0`. -/ +theorem tendsto_pntE_mul_log : Tendsto (fun z => pntE z * log z) atTop (nhds 0) := by + have hu : Tendsto (fun z : ℝ => pntκ * √(log z)) atTop atTop := + (tendsto_sqrt_atTop.comp tendsto_log_atTop).const_mul_atTop pntκ_pos + have h := (tendsto_pow_mul_exp_neg_atTop_nhds_zero 2).comp hu + have h' := h.div_const (pntκ ^ 2) + rw [zero_div] at h' + refine h'.congr' ?_ + filter_upwards [eventually_ge_atTop 1] with z hz + have hl : 0 ≤ log z := log_nonneg hz + simp only [Function.comp, pntE] + rw [mul_pow, sq_sqrt hl, neg_mul] + field_simp [pntκ_pos.ne'] + +/-- For `2 ≤ s ≤ 5/2`, choosing `A = B + 5` absorbs the bounded sieve error `B` +and leaves a saving of `4/ℓ²`. -/ +theorem sieve_error_absorption {A B s ℓ : ℝ} (hA : A = B + 5) (hB : 0 ≤ B) + (hs2 : 2 ≤ s) (hs25 : s ≤ 5 / 2) (hℓ : 0 < ℓ) : + (s - 2 * A / ℓ) / (s * ℓ) + B / (s * ℓ) ^ 2 ≤ 1 / ℓ - 4 / ℓ ^ 2 := by + have hs0 : 0 < s := by linarith only [hs2] + have hkey : 4 * s ^ 2 ≤ 2 * A * s - B := by + have hmargin : 2 * A * s - B - 4 * s ^ 2 = + B * (2 * s - 1) + 2 * s * (5 - 2 * s) := by rw [hA]; ring + have hBterm := mul_nonneg hB (by linarith only [hs2] : (0 : ℝ) ≤ 2 * s - 1) + have hsterm := mul_nonneg (by positivity : (0 : ℝ) ≤ 2 * s) + (by linarith only [hs25] : (0 : ℝ) ≤ 5 - 2 * s) + linarith only [hmargin, hBterm, hsterm] + have hsaving : 4 / ℓ ^ 2 ≤ (2 * A * s - B) / (s ^ 2 * ℓ ^ 2) := by + calc 4 / ℓ ^ 2 = (4 * s ^ 2) / (s ^ 2 * ℓ ^ 2) := by field_simp + _ ≤ (2 * A * s - B) / (s ^ 2 * ℓ ^ 2) := + div_le_div_of_nonneg_right hkey (by positivity) + calc (s - 2 * A / ℓ) / (s * ℓ) + B / (s * ℓ) ^ 2 = + 1 / ℓ - (2 * A * s - B) / (s ^ 2 * ℓ ^ 2) := by field_simp; ring + _ ≤ 1 / ℓ - 4 / ℓ ^ 2 := sub_le_sub le_rfl hsaving + +/-- If the PNT error `e` satisfies `eℓ ≤ 3c`, the saving `4c/ℓ²` leaves the +factor `1 - 1/ℓ` against the lower estimate `(c - e)/ℓ` for `R(z)`. -/ +theorem pnt_error_absorption {c e ℓ : ℝ} (hℓ : 0 < ℓ) (he0 : 0 ≤ e) + (he : e * ℓ ≤ 3 * c) : + c / ℓ - 4 * c / ℓ ^ 2 ≤ (c - e) / ℓ * (1 - 1 / ℓ) := by + have herror : e / ℓ ≤ 3 * c / ℓ ^ 2 := by + calc e / ℓ = (e * ℓ) / ℓ ^ 2 := by field_simp + _ ≤ 3 * c / ℓ ^ 2 := div_le_div_of_nonneg_right he (sq_nonneg ℓ) + have hremaining : 0 ≤ e / ℓ ^ 2 := div_nonneg he0 (sq_nonneg ℓ) + have hsplit : 4 * c / ℓ ^ 2 = c / ℓ ^ 2 + 3 * c / ℓ ^ 2 := by ring + calc c / ℓ - 4 * c / ℓ ^ 2 + ≤ c / ℓ - c / ℓ ^ 2 - e / ℓ + e / ℓ ^ 2 := by + linarith only [herror, hremaining, hsplit] + _ = (c - e) / ℓ * (1 - 1 / ℓ) := by field_simp; ring + +/-- [I78, Lemma 2], from [I71, Theorems 4 and 5]: at level `C₀ z²` the +Rosser lower-bound sieve leaves a main term `≫ R(z)/log z`, and its support has size +`≪ z² / log² z`. -/ +theorem linearSieveEstimate : LinearSieveEstimate := by + obtain ⟨cR, hcR, CR, hR⟩ := R_asymp + have hCR : 0 ≤ CR := by + have h2 := hR 2 le_rfl + exact nonneg_of_mul_nonneg_left ((abs_nonneg _).trans h2) (pntE_pos 2) + obtain ⟨c₇, hc₇, h4⟩ := theorem4 hcR hR + obtain ⟨K, y₀, h5⟩ := theorem5_card_rosserSet_le + set D := (1 + 9 * Real.log 3 ^ 5) ^ (15 : ℝ) with hD + have hD0 : 0 ≤ D := by positivity + set B := 2 * c₇ * D with hB + have hB0 : 0 ≤ B := by positivity + set A := B + 5 with hA + set C₀ := exp A with hC₀ + have hC₀0 : 0 < C₀ := exp_pos A + clear_value D B A C₀ + have hyz : Tendsto (fun z : ℝ => C₀ * z ^ 2) atTop atTop := + (tendsto_pow_atTop two_ne_zero).const_mul_atTop hC₀0 + have hev : ∀ᶠ z : ℝ in atTop, 2 * A ≤ log z ∧ 2 ≤ z ∧ CR * pntE z * log z ≤ 3 * cR ∧ + y₀ ≤ C₀ * z ^ 2 ∧ 3 ≤ xi (C₀ * z ^ 2) := by + refine (tendsto_log_atTop.eventually_ge_atTop (2 * A)).and + ((eventually_ge_atTop 2).and ?_) + refine (((tendsto_pntE_mul_log.const_mul CR).eventually + (eventually_le_nhds (show CR * 0 < 3 * cR by linarith))).mono + fun z hz => by linarith).and ?_ + exact (hyz.eventually_ge_atTop y₀).and ((tendsto_xi.comp hyz).eventually_ge_atTop 3) + obtain ⟨z₀, hz₀⟩ := eventually_atTop.1 hev + refine ⟨C₀, 1, |K| * C₀, z₀, one_pos, fun z hz => ?_⟩ + obtain ⟨hlz, hz2, hpnt, hy₀, hxi⟩ := hz₀ z hz + set ℓ := log z with hℓ + set y := C₀ * z ^ 2 with hy + have hA5 : 5 ≤ A := by linarith + have hℓ10 : 10 ≤ ℓ := by linarith + have hℓ0 : 0 < ℓ := by linarith + have hz1 : 1 < z := by linarith + have hy0 : 0 < y := by positivity + have hL : log y = A + 2 * ℓ := by + rw [hy, log_mul hC₀0.ne' (by positivity), log_pow, hC₀, log_exp]; push_cast; ring + set s := log y / ℓ with hs + have hsℓ : s * ℓ = log y := by rw [hs]; field_simp + have hs2 : 2 ≤ s := by rw [hs, le_div_iff₀ hℓ0]; linarith + have hs25 : s ≤ 5 / 2 := by rw [hs, div_le_iff₀ hℓ0]; linarith + have hzs : y ^ (1 / s) = z := rpow_one_div_log_div hy0 hz1 (by rw [hL]; positivity) + clear_value s y ℓ + have hL1 : 1 ≤ log y := by rw [hL]; linarith + constructor + · -- main term + set r := #(primesLT z) + 1 + have hfail := (fail_eq_of_card_lt (z := z) (r := r) (by omega) y).1 + have hy1 : 1 < y := by + have hz21 : 1 < z ^ 2 := by nlinarith + have hC₀1 : 1 ≤ C₀ := by rw [hC₀]; exact one_le_exp (by linarith) + rw [hy]; nlinarith + have h4' := h4 r true y s hy1 (by simpa [sMin] using hs2) (by linarith) + rw [hzs, hfail] at h4' + -- the main function + have hf : fSieve s ≤ s - 3 * log (s - 1) := by + have := one_sub_fSieve_div_ge s ⟨hs2, by linarith⟩ + have hs0 : 0 < s := by linarith + rw [ge_iff_le, div_le_iff₀ hs0, sub_mul, div_mul_cancel₀ _ hs0.ne'] at this + linarith + have hlog : 2 * A / (3 * ℓ) ≤ log (s - 1) := by + have hx : s - 1 = 1 + A / ℓ := by + rw [hs, hL]; field_simp; ring + have hxA : A / ℓ ≤ 1 / 2 := by rw [div_le_iff₀ hℓ0]; linarith only [hlz] + calc 2 * A / (3 * ℓ) = 2 * (A / ℓ) / 3 := by ring + _ ≤ log (s - 1) := + two_mul_div_three_le_log_sub_one (by positivity) hxA (by linarith only [hx]) + -- the error term + have herr : c₇ * ((r : ℝ) / (r + 1)) * delta s y * errMaj true s ≤ B := by + have hδ : delta s y ≤ D := hD ▸ delta_le_of_le_three (s := s) (by linarith) (by linarith) hL1 + have hδ0 := delta_pos (by linarith : (1 : ℝ) ≤ s) y + have hG := errMaj_le_two true s + have hG0 := (errMaj_pos true s).le + have hφ : (r : ℝ) / (r + 1) ≤ 1 := by rw [div_le_one (by positivity)]; linarith + have hφ0 : (0 : ℝ) ≤ (r : ℝ) / (r + 1) := by positivity + calc c₇ * ((r : ℝ) / (r + 1)) * delta s y * errMaj true s ≤ c₇ * 1 * D * 2 := by + gcongr + _ = B := by rw [hB]; ring + have hdef : R z - rosserMain true y z ≤ cR / ℓ - 4 * cR / ℓ ^ 2 := by + refine h4'.trans ?_ + have hmain : mainMaj true s / log y + c₇ * ((r : ℝ) / (r + 1)) * delta s y * + errMaj true s / log y ^ 2 ≤ (s - 2 * A / ℓ) / log y + B / log y ^ 2 := by + rw [mainMaj_true] + have h3 : 3 * (2 * A / (3 * ℓ)) = 2 * A / ℓ := by field_simp + gcongr + linarith only [hf, hlog, h3] + have hfin : (s - 2 * A / ℓ) / log y + B / log y ^ 2 ≤ 1 / ℓ - 4 / ℓ ^ 2 := by + rw [← hsℓ] + exact sieve_error_absorption hA hB0 hs2 hs25 hℓ0 + calc cR * (mainMaj true s / log y + c₇ * ((r : ℝ) / (r + 1)) * delta s y * + errMaj true s / log y ^ 2) ≤ cR * (1 / ℓ - 4 / ℓ ^ 2) := by + exact mul_le_mul_of_nonneg_left (hmain.trans hfin) hcR.le + _ = cR / ℓ - 4 * cR / ℓ ^ 2 := by ring + -- The PNT comparison converts the deficit estimate into a bound relative to `R(z)`. + have hRz : (cR - CR * pntE z) / ℓ ≤ R z := by + rw [div_le_iff₀ hℓ0] + have hRlower := (abs_le.1 (hR z hz2)).1 + rw [← hℓ] at hRlower + linarith only [hRlower] + have h1 : 0 ≤ 1 - 1 / ℓ := by + rw [sub_nonneg, div_le_one hℓ0]; linarith + calc R z - rosserMain true y z ≤ cR / ℓ - 4 * cR / ℓ ^ 2 := hdef + _ ≤ (cR - CR * pntE z) / ℓ * (1 - 1 / ℓ) := + pnt_error_absorption hℓ0 (mul_nonneg hCR (pntE_pos z).le) hpnt + _ ≤ R z * (1 - 1 / ℓ) := mul_le_mul_of_nonneg_right hRz h1 + · -- support + have h := h5 y hy₀ s ⟨hs2, by linarith⟩ + rw [hzs] at h + refine h.trans ?_ + have hLℓ : ℓ ^ 2 ≤ log y ^ 2 := by + rw [hL]; exact pow_le_pow_left₀ hℓ0.le (by linarith) 2 + calc K * y / log y ^ 2 ≤ |K| * y / log y ^ 2 := by + gcongr; exact le_abs_self K + _ ≤ |K| * y / ℓ ^ 2 := by + gcongr + _ = |K| * C₀ * z ^ 2 / ℓ ^ 2 := by rw [hy]; ring + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/LemmaEleven.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/LemmaEleven.lean new file mode 100644 index 000000000..8704a1193 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/LemmaEleven.lean @@ -0,0 +1,463 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.Defs +import LeanPool.IwaniecLinearSieve.LinearSieve.Calculus +import LeanPool.IwaniecLinearSieve.SieveMajorants.Lemmas +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Algebra.Ring.IsFormallyReal +import Mathlib.Analysis.Complex.ExponentialBounds +import Mathlib.NumberTheory.Chebyshev + +/-! +# [I71, Lemmas 11 and 12] + +Write `L = log y`, `x(t) = t² log⁵ t / L²`, `w(t) = t² log⁴ t / L²` and +`A_a(t) = (1 + x(t))^{5(t - a)}` (so `δ(t, y) = A_0(t)`). The logarithmic derivative of `A_a` is +`E_a(t) = 5 log (1 + x) + 5 (t - a) x'/(1 + x) ≤ w (15 log t + 25)` (`rate_bound`). +With the Corollary to Lemma 10 (`c₃ = 4`), `G_{r+1}(t) log t < 4 G_r(t-1) t/(t-1)²`, this gives, +for `log t ≥ 32` and `160 w(t) ≤ 1`: + +* `lemma11`: `∫_s^b A_1(t) G_r(t-1) t/(t-1)² dt < δ(s) G_{r+1}(s)` for `e^{32} ≤ s ≤ b` with + `160 b² log⁴ b ≤ L²` ([I71, (3.15)]; [I71] has `s₀ = e^{(120 c₃)^{5/2}}` and the + condition `100 c₃ ξ² log⁴ ξ < L²`); +* `lemma12`: `A_1(t) G_{r+1}(t)` is antitone on `[s, b]`; +* `antitoneOn_cor3Weight`: `A_1(t) G_r(t-1) t²/(t-1)²` is antitone on `[s, b]` (this is the + monotonicity of `b(x)` in the proof of [I71, Corollary 3]; [I71] refers to Lemma 12 for it). + +Finally `exists_xi_large`: for large `y`, `ξ(y) ≥ e^{32}`, `160 ξ² log⁴ ξ ≤ L²` and `y^{1/ξ} ≥ 2`, +via `xi_sq_mul_log_pow_four_div_le : ξ² log⁴ ξ / L² ≤ (log log 3y)^{-2/5}`. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory + +namespace IwaniecLinearSieve + +/-! ### The growth factor `(1 + t² log⁵ t / L²)^{5(t-a)}` -/ +theorem hasDerivAt_lsx (L : ℝ) {t : ℝ} (ht : 0 < t) : + HasDerivAt (fun t => t ^ 2 * log t ^ 5 / L ^ 2) + ((2 * t * log t ^ 5 + 5 * t * log t ^ 4) / L ^ 2) t := by + have h := ((hasDerivAt_pow 2 t).mul ((hasDerivAt_log ht.ne').pow 5)).div_const (L ^ 2) + simp only [Pi.pow_apply, Pi.mul_apply] at h + convert h using 1 + field_simp + ring + +theorem lsx_nonneg (L : ℝ) {t : ℝ} (ht : 1 ≤ t) : 0 ≤ t ^ 2 * log t ^ 5 / L ^ 2 := by + have := log_nonneg ht + positivity + +theorem hasDerivAt_growth (L a : ℝ) {t : ℝ} (ht : 1 ≤ t) : + HasDerivAt (fun t => (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - a))) + ((1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - a)) * + (5 * log (1 + t ^ 2 * log t ^ 5 / L ^ 2) + 5 * (t - a) * + ((2 * t * log t ^ 5 + 5 * t * log t ^ 4) / L ^ 2) / + (1 + t ^ 2 * log t ^ 5 / L ^ 2))) t := by + set x := t ^ 2 * log t ^ 5 / L ^ 2 + have hx : 0 < 1 + x := by linarith [lsx_nonneg L ht] + have h := ((hasDerivAt_lsx L (by linarith)).const_add 1).rpow + (((hasDerivAt_id' t).sub_const a).const_mul 5) hx + convert h using 1 + rw [rpow_sub_one hx.ne'] + field_simp + ring + +/-- The scalar consequences of `4E ≤ W(60u + 100)` when `u ≥ 32` and `0 ≤ W ≤ 1/160`. -/ +theorem rate_bound_of_small_weight {u W E : ℝ} (hu : 32 ≤ u) (hW0 : 0 ≤ W) + (hW : W ≤ 1 / 160) (hE : 4 * E ≤ W * (60 * u + 100)) : + 4 * E ≤ u - 1 ∧ 4 * E * (1 + 5 * (W * u)) ≤ 5 * (W * u) * u := by + have hu0 : 0 ≤ u := by linarith only [hu] + have hWu : 0 ≤ W * u := mul_nonneg hW0 hu0 + constructor + · have h := mul_le_mul_of_nonneg_right hW (by linarith only [hu] : 0 ≤ 60 * u + 100) + linarith only [hE, h, hu] + · calc 4 * E * (1 + 5 * (W * u)) ≤ W * (60 * u + 100) * (1 + 5 * (W * u)) := + mul_le_mul_of_nonneg_right hE (by linarith only [hWu]) + _ ≤ 5 * (W * u) * u := by + have h := mul_le_mul_of_nonneg_left + (mul_le_mul_of_nonneg_right hW hu0) hW0 + nlinarith only [h, hWu, hu, hW0] + +/-- The logarithmic derivative of `(1 + x)^{5(t-a)}` is at most `w (15 log t + 25)`; the +consequences used below. -/ +theorem rate_bound {L a t : ℝ} (ha : 0 ≤ a) (ha1 : a ≤ 1) (ht1 : 1 ≤ t) (ht : 32 ≤ log t) + (hw : t ^ 2 * log t ^ 4 / L ^ 2 ≤ 1 / 160) : + 0 ≤ 5 * log (1 + t ^ 2 * log t ^ 5 / L ^ 2) + 5 * (t - a) * + ((2 * t * log t ^ 5 + 5 * t * log t ^ 4) / L ^ 2) / (1 + t ^ 2 * log t ^ 5 / L ^ 2) ∧ + 4 * (5 * log (1 + t ^ 2 * log t ^ 5 / L ^ 2) + 5 * (t - a) * + ((2 * t * log t ^ 5 + 5 * t * log t ^ 4) / L ^ 2) / (1 + t ^ 2 * log t ^ 5 / L ^ 2)) + ≤ log t - 1 ∧ + 4 * (5 * log (1 + t ^ 2 * log t ^ 5 / L ^ 2) + 5 * (t - a) * + ((2 * t * log t ^ 5 + 5 * t * log t ^ 4) / L ^ 2) / (1 + t ^ 2 * log t ^ 5 / L ^ 2)) * + (1 + 5 * (t ^ 2 * log t ^ 5 / L ^ 2)) ≤ 5 * (t ^ 2 * log t ^ 5 / L ^ 2) * log t := by + set u := log t + set W := t ^ 2 * u ^ 4 / L ^ 2 with hW + have hW0 : 0 ≤ W := by positivity + have hx : t ^ 2 * u ^ 5 / L ^ 2 = W * u := by rw [hW]; ring + have hx' : t * ((2 * t * u ^ 5 + 5 * t * u ^ 4) / L ^ 2) = W * (2 * u + 5) := by rw [hW]; ring + have hd0 : 0 ≤ (2 * t * u ^ 5 + 5 * t * u ^ 4) / L ^ 2 := by positivity + rw [hx] + set E := 5 * log (1 + W * u) + 5 * (t - a) * ((2 * t * u ^ 5 + 5 * t * u ^ 4) / L ^ 2) / + (1 + W * u) with hE + have hWu : 0 ≤ W * u := mul_nonneg hW0 (by linarith only [ht]) + have h1 : 0 ≤ log (1 + W * u) := log_nonneg (by linarith only [hWu]) + have h2 : log (1 + W * u) ≤ W * u := by + have := log_le_sub_one_of_pos (by linarith only [hWu] : 0 < 1 + W * u) + linarith only [this] + have h3 : 0 ≤ (t - a) * ((2 * t * u ^ 5 + 5 * t * u ^ 4) / L ^ 2) / (1 + W * u) := + div_nonneg (mul_nonneg (by linarith only [ht1, ha1]) hd0) (by linarith only [hWu]) + have h4 : (t - a) * ((2 * t * u ^ 5 + 5 * t * u ^ 4) / L ^ 2) / (1 + W * u) ≤ + W * (2 * u + 5) := by + calc (t - a) * ((2 * t * u ^ 5 + 5 * t * u ^ 4) / L ^ 2) / (1 + W * u) + ≤ (t - a) * ((2 * t * u ^ 5 + 5 * t * u ^ 4) / L ^ 2) := + div_le_self (mul_nonneg (by linarith only [ht1, ha1]) hd0) + (by linarith only [hWu]) + _ ≤ t * ((2 * t * u ^ 5 + 5 * t * u ^ 4) / L ^ 2) := + mul_le_mul_of_nonneg_right (by linarith only [ha]) hd0 + _ = W * (2 * u + 5) := hx' + have hE0 : 0 ≤ E := by rw [hE, mul_assoc 5, mul_div_assoc]; positivity + have hE1 : 4 * E ≤ W * (60 * u + 100) := by + rw [hE, mul_assoc 5 (t - a), mul_div_assoc] + linarith only [h2, h4] + exact ⟨hE0, rate_bound_of_small_weight ht hW0 hw hE1⟩ + +/-! ### The Corollary to Lemma 10 in the form used here -/ +theorem majG_succ_mul_log_lt (r : ℕ) {t : ℝ} (ht : 2 ≤ t) : + majG (r + 1) t * log t < 4 * (majG r (t - 1) * t / (t - 1) ^ 2) := by + have h := majG_succ_mul_log_div_lt r ht + have hK : 0 < majG r (t - 1) * t := mul_pos (majG_pos r _) (by linarith) + have h1 : 0 < (t - 1) ^ 2 := by nlinarith + rw [div_lt_iff₀ hK] at h + rw [mul_div_assoc', lt_div_iff₀ h1] + linarith + +theorem five_add_neg_one_pow_div_le (r : ℕ) : (5 + (-1 : ℝ) ^ r) / 2 ≤ 3 := by + rcases Nat.even_or_odd r with hr | hr + · rw [hr.neg_one_pow]; norm_num + · rw [hr.neg_one_pow]; norm_num + +/-! ### The range `e^{32} ≤ t ≤ b`, `160 b² log⁴ b ≤ L²` -/ + +/-- On `[e^{32}, b]` with `160 b² log⁴ b ≤ L²`: `1 ≤ t`, `32 ≤ log t` and `160 w(t) ≤ 1`. -/ +theorem range_facts {L t b : ℝ} (ht : exp 32 ≤ t) (htb : t ≤ b) + (hb : b ^ 2 * log b ^ 4 ≤ L ^ 2 / 160) : + 1 ≤ t ∧ 32 ≤ log t ∧ t ^ 2 * log t ^ 4 / L ^ 2 ≤ 1 / 160 ∧ 0 < L ^ 2 := by + have ht1 : 1 ≤ t := le_trans (by linarith [add_one_le_exp (32 : ℝ)]) ht + have hlt : 32 ≤ log t := (le_log_iff_exp_le (by linarith)).2 ht + have hlb : log t ≤ log b := log_le_log (by linarith) htb + have h4 : t ^ 2 * log t ^ 4 ≤ b ^ 2 * log b ^ 4 := by + have : 0 ≤ log t := by linarith + gcongr + have hpos : 0 < t ^ 2 * log t ^ 4 := by + have : 0 < log t := by linarith + have : 0 < t := by linarith + positivity + have hL : 0 < L ^ 2 := by linarith + refine ⟨ht1, hlt, ?_, hL⟩ + rw [div_le_iff₀ hL]; linarith + +/-- `(1 + x)^{5(t-1)} = (1 + x)^{5t} / (1 + x)^5`. -/ +theorem rpow_five_mul_sub_one {x : ℝ} (hx : 0 < x) (t : ℝ) : + x ^ (5 * (t - 1)) = x ^ (5 * t) / x ^ 5 := by + rw [show 5 * (t - 1) = 5 * t - 5 by ring, rpow_sub hx] + norm_cast + +theorem continuousAt_growth (L a : ℝ) {t : ℝ} (ht : 1 ≤ t) : + ContinuousAt (fun t => (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - a))) t := + (hasDerivAt_growth L a ht).continuousAt + +theorem continuousOn_lemma11_integrand (L : ℝ) (r : ℕ) {s b : ℝ} (hs : 2 ≤ s) : + ContinuousOn (fun t => (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - 1)) * majG r (t - 1) * t / + (t - 1) ^ 2) (Icc s b) := by + refine continuousOn_of_forall_continuousAt fun t ht => ?_ + have ht1 : t - 1 ≠ 0 := by linarith [ht.1] + exact (((continuousAt_growth L 1 (by linarith [ht.1])).mul + ((continuous_majG r).continuousAt.comp (continuous_sub_right 1).continuousAt)).mul + continuousAt_id).div ((continuous_sub_right 1).continuousAt.pow 2) (pow_ne_zero 2 ht1) + +theorem delta_eq_growth (s y : ℝ) : + delta s y = (1 + s ^ 2 * log s ^ 5 / log y ^ 2) ^ (5 * (s - 0)) := by + rw [delta, sub_zero] + +theorem delta_pos {s : ℝ} (hs : 1 ≤ s) (y : ℝ) : 0 < delta s y := by + have := lsx_nonneg (log y) hs + exact rpow_pos_of_pos (by linarith) _ + +/-- The algebraic decay estimate in Lemma 11: the bound on the growth rate `E` +and `G ℓ ≤ 4K` imply `K / (1 + x)⁵ ≤ K - EG`. -/ +theorem lemma11_decay_bound {x E G K ℓ : ℝ} (hx : 0 ≤ x) (hE : 0 ≤ E) + (hK : 0 ≤ K) (hℓ : 0 < ℓ) (hG : G * ℓ ≤ 4 * K) + (hrate : 4 * E * (1 + 5 * x) ≤ 5 * x * ℓ) : + K / (1 + x) ^ 5 ≤ K - E * G := by + have hx5 : 0 < 1 + 5 * x := by linarith only [hx] + have hbern : 1 + 5 * x ≤ (1 + x) ^ 5 := + one_add_mul_le_pow (by linarith only [hx]) 5 + have hEG : E * G * (1 + 5 * x) ≤ 5 * x * K := by + have h1 := mul_le_mul_of_nonneg_left hG hE + have h2 := mul_le_mul_of_nonneg_right h1 hx5.le + have h3 := mul_le_mul_of_nonneg_right hrate hK + apply le_of_mul_le_mul_left (a := ℓ) _ hℓ + nlinarith only [h2, h3] + calc K / (1 + x) ^ 5 ≤ K / (1 + 5 * x) := + div_le_div_of_nonneg_left hK hx5 hbern + _ ≤ K - E * G := by + rw [div_le_iff₀ hx5] + nlinarith only [hEG] + +/-- [I71, Lemma 11] ((3.15)), with `s₀ = e^{32}`, `c₃ = 4`, and the upper limit `ξ` replaced by any +`b` with `160 b² log⁴ b ≤ log² y`: +`∫_s^b (1 + t² log⁵ t / L²)^{5(t-1)} G_r(t-1) t/(t-1)² dt < δ(s, y) G_{r+1}(s)`. -/ +theorem lemma11 (r : ℕ) {y s b : ℝ} (hs : exp 32 ≤ s) (hsb : s ≤ b) + (hb : b ^ 2 * log b ^ 4 ≤ log y ^ 2 / 160) : + ∫ t in s..b, (1 + t ^ 2 * log t ^ 5 / log y ^ 2) ^ (5 * (t - 1)) * majG r (t - 1) * t / + (t - 1) ^ 2 < delta s y * majG (r + 1) s := by + set L := log y + have hs3 : 3 < s := by linarith [add_one_le_exp (32 : ℝ)] + -- `τ(t) = δ(t) G_{r+1}(t)` and its derivative + set τ : ℝ → ℝ := fun t => delta t y * majG (r + 1) t + have hτd : ∀ t, 3 < t → HasDerivAt τ + ((1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - 0)) * + (5 * log (1 + t ^ 2 * log t ^ 5 / L ^ 2) + 5 * (t - 0) * + ((2 * t * log t ^ 5 + 5 * t * log t ^ 4) / L ^ 2) / + (1 + t ^ 2 * log t ^ 5 / L ^ 2)) * majG (r + 1) t + + (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - 0)) * + (-(majG r (t - 1) * t / (t - 1) ^ 2))) t := fun t ht => by + have h1 := hasDerivAt_growth L 0 (t := t) (by linarith) + have h2 := hasDerivAt_majG_succ r (t := t) (by linarith [five_add_neg_one_pow_div_le r]) + have := h1.mul h2 + simp only [τ, delta_eq_growth] + exact this + have key := intervalIntegral.integral_le_sub_of_hasDeriv_right_of_le (g := fun t => -τ t) + (φ := fun t => (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - 1)) * majG r (t - 1) * t / + (t - 1) ^ 2) hsb + (continuousOn_of_forall_continuousAt fun t ht => (hτd t (by linarith [ht.1])).continuousAt.neg) + (fun t ht => (hτd t (by linarith [ht.1])).neg.hasDerivWithinAt) + ((continuousOn_lemma11_integrand L r (by linarith)).integrableOn_Icc) ?_ + · have hτb : 0 < τ b := mul_pos (delta_pos (by linarith) y) (majG_pos _ _) + simp only [τ] at key hτb ⊢ + linarith + -- the pointwise inequality `-τ' ≥ (1 + x)^{5(t-1)} G_r(t-1) t/(t-1)²` + intro t ht + have ht3 : 3 < t := by linarith [ht.1] + obtain ⟨ht1, hlt, hw, hL⟩ := range_facts (L := L) (hs.trans ht.1.le) ht.2.le hb + obtain ⟨hE0, -, hE2⟩ := rate_bound (L := L) (a := 0) le_rfl zero_le_one ht1 hlt hw + set x := t ^ 2 * log t ^ 5 / L ^ 2 + set E := 5 * log (1 + x) + 5 * (t - 0) * ((2 * t * log t ^ 5 + 5 * t * log t ^ 4) / L ^ 2) / + (1 + x) + have hK0 : 0 < majG r (t - 1) * t / (t - 1) ^ 2 := + div_pos (mul_pos (majG_pos r _) (by linarith only [ht3])) + (sq_pos_of_pos (by linarith only [ht3])) + set K := majG r (t - 1) * t / (t - 1) ^ 2 with hK + set G := majG (r + 1) t + have hx0 : 0 ≤ x := lsx_nonneg L ht1 + have hG : G * log t < 4 * K := majG_succ_mul_log_lt r (by linarith only [ht3]) + have hP : 0 < (1 + x) ^ (5 * (t - 0)) := rpow_pos_of_pos (by linarith only [hx0]) _ + have hdecay := lemma11_decay_bound hx0 hE0 hK0.le + (by linarith only [hlt] : 0 < log t) hG.le hE2 + change (1 + x) ^ (5 * (t - 1)) * majG r (t - 1) * t / (t - 1) ^ 2 ≤ + -((1 + x) ^ (5 * (t - 0)) * E * G + (1 + x) ^ (5 * (t - 0)) * -K) + rw [rpow_five_mul_sub_one (by linarith)] + simp only [sub_zero] at hP ⊢ + calc (1 + x) ^ (5 * t) / (1 + x) ^ 5 * majG r (t - 1) * t / (t - 1) ^ 2 + = (1 + x) ^ (5 * t) * (K / (1 + x) ^ 5) := by rw [hK]; ring + _ ≤ (1 + x) ^ (5 * t) * (K - E * G) := mul_le_mul_of_nonneg_left hdecay hP.le + _ = _ := by ring + +/-! ### Lemma 12 and the monotonicity used in Corollary 3 -/ +theorem four_lt_of_exp_le {t : ℝ} (ht : exp 32 ≤ t) : 4 < t := by + linarith [add_one_le_exp (32 : ℝ)] + +/-- If the growth rate satisfies `4E ≤ ℓ` and the decay satisfies `Gℓ ≤ 4K`, then +`EG ≤ K` for `G ≥ 0`. This is the scalar comparison used in Lemma 12. -/ +theorem growth_le_decay {E G K ℓ : ℝ} (hG : 0 ≤ G) (hE : 4 * E ≤ ℓ) + (hdecay : G * ℓ ≤ 4 * K) : E * G ≤ K := by + have h := (mul_le_mul_of_nonneg_left hE hG).trans hdecay + nlinarith only [h] + +/-- If `g ≥ 0` has derivative `-k` with `g ℓ ≤ 4 k` and `ℓ ≥ log t - 1`, then +`(1 + x)^{5(t-1)} g(t)` is antitone on `[s, b]` (for `e^{32} ≤ s`, `160 b² log⁴ b ≤ L²`). -/ +theorem antitoneOn_growth_mul {L s b : ℝ} {g k ℓ : ℝ → ℝ} (hs : exp 32 ≤ s) + (hb : b ^ 2 * log b ^ 4 ≤ L ^ 2 / 160) (hg : ∀ t ∈ Icc s b, HasDerivAt g (-k t) t) + (hg0 : ∀ t ∈ Icc s b, 0 ≤ g t) (hgk : ∀ t ∈ Icc s b, g t * ℓ t ≤ 4 * k t) + (hℓ : ∀ t ∈ Icc s b, log t - 1 ≤ ℓ t) : + AntitoneOn (fun t => (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - 1)) * g t) (Icc s b) := by + let A : ℝ → ℝ := fun t => (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - 1)) + let E : ℝ → ℝ := fun t => 5 * log (1 + t ^ 2 * log t ^ 5 / L ^ 2) + 5 * (t - 1) * + ((2 * t * log t ^ 5 + 5 * t * log t ^ 4) / L ^ 2) / (1 + t ^ 2 * log t ^ 5 / L ^ 2) + -- `A' = AE` and `g' = -k`, so the product has derivative `A(Eg - k)`. + have hd : ∀ t ∈ Icc s b, + HasDerivAt (fun t => A t * g t) (A t * (E t * g t - k t)) t := by + intro t ht + have hA : HasDerivAt A (A t * E t) t := + hasDerivAt_growth L 1 (range_facts (hs.trans ht.1) ht.2 hb).1 + convert hA.mul (hg t ht) using 1 + ring + -- The rate bound and the decay hypothesis give `Eg ≤ k`, hence a nonpositive derivative. + have hnonpos : ∀ t ∈ Icc s b, A t * (E t * g t - k t) ≤ 0 := by + intro t ht + obtain ⟨ht1, hlt, hw, -⟩ := range_facts (hs.trans ht.1) ht.2 hb + obtain ⟨-, hE, -⟩ := rate_bound (L := L) (a := 1) zero_le_one le_rfl ht1 hlt hw + have hdecay : E t * g t ≤ k t := + growth_le_decay (hg0 t ht) (hE.trans (hℓ t ht)) (hgk t ht) + have hA0 : 0 ≤ A t := + (rpow_pos_of_pos (by linarith only [lsx_nonneg L ht1]) _).le + exact mul_nonpos_of_nonneg_of_nonpos hA0 (sub_nonpos.2 hdecay) + exact antitoneOn_of_hasDerivWithinAt_nonpos (convex_Icc s b) + (continuousOn_of_forall_continuousAt fun t ht => (hd t ht).continuousAt) + (fun t ht => (hd t (interior_subset ht)).hasDerivWithinAt) + (fun t ht => hnonpos t (interior_subset ht)) + +/-- [I71, Lemma 12]: `μ(t) = (1 + t² log⁵ t / L²)^{5(t-1)} G_{r+1}(t)` is antitone on `[s, b]` +for `e^{32} ≤ s` and `160 b² log⁴ b ≤ L²`. -/ +theorem lemma12 (r : ℕ) {L s b : ℝ} (hs : exp 32 ≤ s) (hb : b ^ 2 * log b ^ 4 ≤ L ^ 2 / 160) : + AntitoneOn (fun t => (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - 1)) * majG (r + 1) t) + (Icc s b) := by + refine antitoneOn_growth_mul (k := fun t => majG r (t - 1) * t / (t - 1) ^ 2) (ℓ := log) hs hb + (fun t ht => ?_) (fun t _ => (majG_pos _ _).le) (fun t ht => ?_) fun t _ => by linarith + · exact hasDerivAt_majG_succ r (by + linarith [five_add_neg_one_pow_div_le r, four_lt_of_exp_le (hs.trans ht.1)]) + · exact (majG_succ_mul_log_lt r (by linarith [four_lt_of_exp_le (hs.trans ht.1)])).le + +theorem log_sub_one_ge {t : ℝ} (ht : 2 ≤ t) : log t - 1 ≤ log (t - 1) := by + have h1 : 0 < t - 1 := by linarith + have h := log_le_sub_one_of_pos (div_pos (by linarith : (0 : ℝ) < t) h1) + rw [log_div (by linarith) h1.ne'] at h + have : t / (t - 1) - 1 ≤ 1 := by + rw [div_sub_one h1.ne', div_le_one h1]; linarith + linarith + +theorem antitoneOn_sq_div_sq_sub_one : AntitoneOn (fun t : ℝ => t ^ 2 / (t - 1) ^ 2) (Ioi 1) := by + intro u hu v hv huv + have hu1 : 0 < u - 1 := by linarith [hu.out] + have hv1 : 0 < v - 1 := by linarith [hv.out] + have h : v / (v - 1) ≤ u / (u - 1) := by + rw [div_le_div_iff₀ hv1 hu1]; nlinarith + have h0 : 0 ≤ v / (v - 1) := div_nonneg (by linarith) hv1.le + simp only + rw [← div_pow, ← div_pow] + exact pow_le_pow_left₀ h0 h 2 + +theorem antitoneOn_mul_of_nonneg {f g : ℝ → ℝ} {S : Set ℝ} (hf : AntitoneOn f S) + (hg : AntitoneOn g S) (hf0 : ∀ t ∈ S, 0 ≤ f t) (hg0 : ∀ t ∈ S, 0 ≤ g t) : + AntitoneOn (fun t => f t * g t) S := fun u hu v hv huv => + mul_le_mul (hf hu hv huv) (hg hu hv huv) (hg0 v hv) (hf0 u hu) + +/-- The weight in the proof of [I71, Corollary 3]: +`(1 + t² log⁵ t / L²)^{5(t-1)} G_r(t-1) t²/(t-1)²` is antitone on `[s, b]`. -/ +theorem antitoneOn_cor3Weight (r : ℕ) {L s b : ℝ} (hs : exp 32 ≤ s) + (hb : b ^ 2 * log b ^ 4 ≤ L ^ 2 / 160) : + AntitoneOn (fun t => (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - 1)) * majG r (t - 1) * + (t ^ 2 / (t - 1) ^ 2)) (Icc s b) := by + have hfacts : ∀ t ∈ Icc s b, 4 < t := fun t ht => four_lt_of_exp_le (hs.trans ht.1) + have hψ : AntitoneOn (fun t => (1 + t ^ 2 * log t ^ 5 / L ^ 2) ^ (5 * (t - 1)) * + majG r (t - 1)) (Icc s b) := by + refine antitoneOn_growth_mul + (k := fun t => majG (r + 1) (t - 1 - 1) * (t - 1) / (t - 1 - 1) ^ 2) + (ℓ := fun t => log (t - 1)) hs hb (fun t ht => ?_) (fun t _ => (majG_pos _ _).le) + (fun t ht => ?_) fun t ht => log_sub_one_ge (by linarith [hfacts t ht]) + · have h := hasDerivAt_majG_succ (r + 1) (t := t - 1) + (by linarith [five_add_neg_one_pow_div_le (r + 1), hfacts t ht]) + rw [majG_add_two] at h + exact h.comp_sub_const t 1 + · have h := majG_succ_mul_log_lt (r + 1) (t := t - 1) (by linarith [hfacts t ht]) + rw [majG_add_two] at h + exact h.le + refine antitoneOn_mul_of_nonneg hψ + (antitoneOn_sq_div_sq_sub_one.mono fun t ht => show (1 : ℝ) < t by linarith [hfacts t ht]) + (fun t ht => ?_) fun t _ => by positivity + have := lsx_nonneg L (by linarith [hfacts t ht] : (1 : ℝ) ≤ t) + exact mul_nonneg (rpow_pos_of_pos (by linarith) _).le (majG_pos _ _).le + +/-! ### The size of `ξ` -/ + +/-- `ξ² log⁴ ξ / L² ≤ (log log 3y)^{-2/5}` (cf. [I71, proof of Lemma 11]). -/ +theorem xi_sq_mul_log_pow_four_div_le {y : ℝ} (hy : 1 < y) (hℓ : 1 ≤ log (log (3 * y))) + (hξ : 1 ≤ xi y) : + xi y ^ 2 * log (xi y) ^ 4 / log y ^ 2 ≤ log (log (3 * y)) ^ (-(2 / 5 : ℝ)) := by + set ℓ := log (log (3 * y)) with hℓdef + set L := log y with hL + have hL0 : 0 < L := log_pos hy + have hℓ0 : 0 < ℓ := by linarith + have hP : 1 ≤ ℓ ^ (11 / 5 : ℝ) := one_le_rpow hℓ (by norm_num) + have hξL : xi y ≤ L := by + rw [xi]; exact div_le_self hL0.le hP + have h3 : L ≤ log (3 * y) := by + rw [log_mul (by norm_num) (by linarith)]; linarith [log_nonneg (by norm_num : (1 : ℝ) ≤ 3)] + have hlogξ : log (xi y) ≤ ℓ := log_le_log (by linarith) (by linarith) + have hlogξ0 : 0 ≤ log (xi y) := log_nonneg hξ + have hsq : xi y ^ 2 / L ^ 2 = (ℓ ^ (22 / 5 : ℝ))⁻¹ := by + have hx : xi y = L / ℓ ^ (11 / 5 : ℝ) := rfl + have h2 : (ℓ ^ (11 / 5 : ℝ)) ^ 2 = ℓ ^ (22 / 5 : ℝ) := by + rw [← rpow_natCast, ← rpow_mul hℓ0.le]; norm_num + rw [hx, div_pow, h2] + field_simp + have hP' : 0 < ℓ ^ (22 / 5 : ℝ) := rpow_pos_of_pos hℓ0 _ + calc xi y ^ 2 * log (xi y) ^ 4 / L ^ 2 = log (xi y) ^ 4 * (xi y ^ 2 / L ^ 2) := by ring + _ ≤ ℓ ^ 4 * (ℓ ^ (22 / 5 : ℝ))⁻¹ := by + rw [hsq]; gcongr + _ = ℓ ^ (-(2 / 5 : ℝ)) := by + rw [← rpow_natCast, ← rpow_neg hℓ0.le, ← rpow_add hℓ0]; norm_num + +theorem tendsto_log_log_three_mul : Tendsto (fun y : ℝ => log (log (3 * y))) atTop atTop := + tendsto_log_atTop.comp (tendsto_log_atTop.comp (tendsto_id.const_mul_atTop (by norm_num))) + +/-- `ξ(y) → ∞`. -/ +theorem tendsto_xi : Tendsto xi atTop atTop := by + have hv : Tendsto (fun y : ℝ => log (3 * y)) atTop atTop := + tendsto_log_atTop.comp (tendsto_id.const_mul_atTop (by norm_num)) + have ho := (isLittleO_log_rpow_rpow_atTop (11 / 5 : ℝ) (by norm_num : (0 : ℝ) < 1 / 2)).bound + (by norm_num : (0 : ℝ) < 1) + have hbound : ∀ᶠ y in atTop, log (3 * y) ^ (1 / 2 : ℝ) / 2 ≤ xi y := by + filter_upwards [hv.eventually ho, hv.eventually (eventually_ge_atTop (exp 1)), + hv.eventually (eventually_ge_atTop (2 * log 3)), eventually_gt_atTop 1] with y h1 h2 h3 hy + simp only [one_mul] at h1 h2 h3 + have hv0 : 0 < log (3 * y) := by linarith [exp_pos 1] + have hℓ : 1 ≤ log (log (3 * y)) := (le_log_iff_exp_le hv0).2 h2 + rw [norm_of_nonneg (rpow_nonneg (by linarith) _), + norm_of_nonneg (rpow_nonneg hv0.le _)] at h1 + have hL : log y = log (3 * y) - log 3 := by + rw [log_mul (by norm_num) (by linarith)]; ring + have hP : 0 < log (log (3 * y)) ^ (11 / 5 : ℝ) := rpow_pos_of_pos (by linarith) _ + have hsq : 0 < log (3 * y) ^ (1 / 2 : ℝ) := rpow_pos_of_pos hv0 _ + have hsq2 : log (3 * y) ^ (1 / 2 : ℝ) * log (3 * y) ^ (1 / 2 : ℝ) = log (3 * y) := by + rw [← rpow_add hv0]; norm_num + rw [xi, hL, le_div_iff₀ hP] + calc log (3 * y) ^ (1 / 2 : ℝ) / 2 * log (log (3 * y)) ^ (11 / 5 : ℝ) + ≤ log (3 * y) ^ (1 / 2 : ℝ) / 2 * log (3 * y) ^ (1 / 2 : ℝ) := by gcongr + _ = log (3 * y) / 2 := by rw [div_mul_eq_mul_div, hsq2] + _ ≤ log (3 * y) - log 3 := by linarith + exact tendsto_atTop_mono' atTop hbound + (((tendsto_rpow_atTop (by norm_num : (0 : ℝ) < 1 / 2)).comp hv).atTop_div_const (by norm_num)) + +/-- For `y` large: `ξ(y) ≥ e^{32}`, `160 ξ² log⁴ ξ ≤ log² y` and `y^{1/ξ} ≥ 2`, so that +Lemmas 11, 12 and Corollary 3 apply up to `b = ξ(y)`. -/ +theorem exists_xi_large : ∃ y₀ : ℝ, ∀ y ≥ y₀, 1 < y ∧ exp 32 ≤ xi y ∧ + xi y ^ 2 * log (xi y) ^ 4 ≤ log y ^ 2 / 160 ∧ 2 ≤ y ^ (1 / xi y) := by + have hsmall : ∀ᶠ y in atTop, log (log (3 * y)) ^ (-(2 / 5 : ℝ)) ≤ 1 / 160 := + ((tendsto_rpow_neg_atTop (by norm_num : (0 : ℝ) < 2 / 5)).comp + tendsto_log_log_three_mul).eventually (eventually_le_nhds (by norm_num)) + obtain ⟨y₀, hy₀⟩ := eventually_atTop.1 (hsmall.and ((tendsto_xi.eventually + (eventually_ge_atTop (exp 32))).and ((tendsto_log_log_three_mul.eventually + (eventually_ge_atTop 1)).and (eventually_gt_atTop 1)))) + refine ⟨y₀, fun y hy => ?_⟩ + obtain ⟨h1, h2, h3, h4⟩ := hy₀ y hy + have hξ1 : 1 ≤ xi y := le_trans (by linarith [add_one_le_exp (32 : ℝ)]) h2 + have hL0 : 0 < log y := log_pos h4 + refine ⟨h4, h2, ?_, ?_⟩ + · have := (xi_sq_mul_log_pow_four_div_le h4 h3 hξ1).trans h1 + rwa [div_le_iff₀ (by positivity), div_mul_eq_mul_div, one_mul] at this + · have hℓ0 : 0 < log (log (3 * y)) := by linarith + have hP : 0 < log (log (3 * y)) ^ (11 / 5 : ℝ) := rpow_pos_of_pos hℓ0 _ + rw [rpow_def_of_pos (by linarith), xi, mul_one_div, div_div_cancel₀ hL0.ne'] + have : 1 ≤ log (log (3 * y)) ^ (11 / 5 : ℝ) := one_le_rpow h3 (by norm_num) + calc (2 : ℝ) ≤ exp 1 := by linarith [exp_one_gt_d9] + _ ≤ _ := exp_le_exp.2 this + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/LemmaSeven.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/LemmaSeven.lean new file mode 100644 index 000000000..f3b8055e1 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/LemmaSeven.lean @@ -0,0 +1,168 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.Defs +public import LeanPool.IwaniecLinearSieve.SieveFunctions.LemmaFive +import LeanPool.IwaniecLinearSieve.LinearSieve.Calculus +import LeanPool.IwaniecLinearSieve.SieveMajorants.Delay +import LeanPool.IwaniecLinearSieve.SieveMajorants.Lemmas +import LeanPool.IwaniecLinearSieve.SieveMajorants.Properties +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds +import Mathlib.NumberTheory.Chebyshev + +/-! +# [I71, Lemma 7]: `f_r(s) < M(s) < 4 𝔐(s)` for `s ≥ 2` + +Here `M = MSieve = f + F + (3 - ·)⁺`. On `[2, 3]`, `M(s) = (F(3) + 3)(1 - log (s - 1))` by (3.9), +and `F(3) + 3 < 4` by `fSieve_four_add`. For `s > 3` we follow [I71]: at a first crossing `s`, +`(s-1) M(s) = ∫_{s-1}^s M ≤ 4 ∫_{s-1}^s 𝔐 ≤ 4 (s-1)² 𝔐(s) / s < 4 (s-1) 𝔐(s)`, using +`lemma5Q = 0` and (3.12). + +The bound `M(s) ≤ 4𝔐(s)` fails for `s < 2`, where `M(s) = 5 + F(3) - s` grows and `𝔐 = 3`. + +Consequences used in the induction of [I71, §4] (with Lemma 8 and the Corollary to Lemma 6): +`mainMaj_le_errMaj : 2 ≤ s → M lower (s) ≤ 12 G lower' (s)` and +`mainMaj_sub_one_le : 1 ≤ s → M lower (s - 1) ≤ 48 s² G lower' (s)`. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory + +namespace IwaniecLinearSieve + +/-- `F(3) + 3 < 4`, from `f(4) + (F(3) + 3) log 3 = 4`. -/ +theorem FSieve_three_add_lt_four : FSieve 3 + 3 < 4 := by + have h := fSieve_four_add + have h4 := fSieve_pos 4 + have hl := one_lt_log_three + have hK : 0 < FSieve 3 + 3 := by linarith [FSieve_nonneg 3] + nlinarith + +theorem MSieve_eq_on_Icc {s : ℝ} (hs : s ∈ Icc (2 : ℝ) 3) : + MSieve s = (FSieve 3 + 3) * (1 - log (s - 1)) := by + rw [MSieve_of_le_three hs.2, fSieve_eq_on_Icc ⟨hs.1, by linarith [hs.2]⟩]; ring + +theorem MSieve_lt_four_mul_bigM_of_le_three {s : ℝ} (hs : s ∈ Icc (2 : ℝ) 3) : + MSieve s < 4 * bigM s := by + rw [MSieve_eq_on_Icc hs, bigM_eq hs.1 hs.2] + have h1 : 0 < s - 1 := by linarith [hs.1] + have hl0 : 0 ≤ log (s - 1) := log_nonneg (by linarith [hs.1]) + have hl1 : log (s - 1) < 1 := by + rw [log_lt_iff_lt_exp h1]; linarith [hs.2, exp_one_gt_d9] + have hK := FSieve_three_add_lt_four + have hinv : 0 < 1 / (s - 1) := by positivity + nlinarith + +/-- `(s - 1) M(s) = ∫_{s-1}^s M` for `s ≥ 3` (this is `lemma5Q s = 0`). -/ +theorem sub_one_mul_MSieve {s : ℝ} (hs : 3 ≤ s) : + (s - 1) * MSieve s = ∫ x in (s - 1)..s, MSieve x := by + have h := lemma5Q_const hs + rw [lemma5Q_three, lemma5Q] at h + linarith + +/-- `∫_{s-1}^s 𝔐 ≤ (s-1)² 𝔐(s)/s` for `s ≥ 3`, from (3.12). -/ +theorem integral_bigM_le {s : ℝ} (hs : 3 ≤ s) : + ∫ x in (s - 1)..s, bigM x ≤ (s - 1) ^ 2 * bigM s / s := by + have hs0 : 0 < s := by linarith + have hc : 0 < 1 - 1 / (2 * (s - 1) ^ 2) := by + have : 1 / (2 * (s - 1) ^ 2) < 1 := by + rw [div_lt_one (by nlinarith)]; nlinarith + linarith + have hle : ∫ x in (s - 1)..s, (1 - 1 / (2 * (s - 1) ^ 2)) * bigM x ≤ + ∫ x in (s - 1)..s, (1 - 1 / (2 * x ^ 2)) * bigM x := by + refine intervalIntegral.integral_mono_on (by linarith) + (continuous_bigM.intervalIntegrable _ _ |>.const_mul _) + ((continuousOn_weight_mul continuous_bigM (by linarith)).intervalIntegrable_of_Icc + (by linarith)) fun x hx => ?_ + have hx1 : 0 < s - 1 := by linarith + have : 1 / (2 * x ^ 2) ≤ 1 / (2 * (s - 1) ^ 2) := by + apply one_div_le_one_div_of_le (by positivity) + have := hx.1; nlinarith + exact mul_le_mul_of_nonneg_right (by linarith) (bigM_pos x).le + rw [intervalIntegral.integral_const_mul, ← bigM_integral_identity hs] at hle + have hkey : (1 - 1 / (2 * (s - 1) ^ 2)) * ((s - 1) ^ 2 * bigM s / s) = + ((s - 1) ^ 2 - 1 / 2) * bigM s / s := by + have h0 : s - 1 ≠ 0 := by linarith + have : (1 - 1 / (2 * (s - 1) ^ 2)) * (s - 1) ^ 2 = (s - 1) ^ 2 - 1 / 2 := by + field_simp + calc _ = ((1 - 1 / (2 * (s - 1) ^ 2)) * (s - 1) ^ 2) * bigM s / s := by ring + _ = _ := by rw [this] + rw [← hkey] at hle + exact le_of_mul_le_mul_left hle hc + +/-- [I71, Lemma 7], upper bound: `M(s) < 4 𝔐(s)` for `s ≥ 2`. -/ +theorem MSieve_lt_four_mul_bigM {s : ℝ} (hs : 2 ≤ s) : MSieve s < 4 * bigM s := by + rcases le_total s 3 with h3 | h3 + · exact MSieve_lt_four_mul_bigM_of_le_three ⟨hs, h3⟩ + refine sub_pos.1 <| pos_of_first_crossing (f := fun s => 4 * bigM s - MSieve s) (a₀ := 2) + (a := 3) ((continuous_bigM.const_smul (4 : ℝ)).sub continuous_MSieve).continuousOn + (fun x hx => (sub_pos.2 (MSieve_lt_four_mul_bigM_of_le_three hx)).le) + (sub_pos.2 (MSieve_lt_four_mul_bigM_of_le_three ⟨by norm_num, le_rfl⟩)) ?_ s h3 + intro s hs3 hnn _ + have hs0 : 0 < s := by linarith + have hint : ∫ x in (s - 1)..s, MSieve x ≤ ∫ x in (s - 1)..s, 4 * bigM x := + intervalIntegral.integral_mono_on (by linarith) (continuous_MSieve.intervalIntegrable _ _) + ((continuous_bigM.intervalIntegrable _ _).const_mul _) fun x hx => by + linarith [hnn x ⟨by linarith [hx.1], hx.2⟩] + rw [intervalIntegral.integral_const_mul, ← sub_one_mul_MSieve hs3.le] at hint + have hB := integral_bigM_le hs3.le + have hMs := bigM_pos s + have h1 : (s - 1) * MSieve s ≤ 4 * ((s - 1) ^ 2 * bigM s / s) := by nlinarith + have h2 : 4 * ((s - 1) ^ 2 * bigM s / s) < (s - 1) * (4 * bigM s) := by + rw [div_eq_mul_inv] + have : (s - 1) * s⁻¹ < 1 := by rw [← div_eq_mul_inv, div_lt_one hs0]; linarith + have hs1 : 0 < s - 1 := by linarith + nlinarith [mul_pos hs1 hMs] + have := lt_of_le_of_lt h1 h2 + have hs1 : 0 < s - 1 := by linarith + nlinarith + +/-- [I71, Lemma 7]: `f_r(s) < M(s) ≤ 4 𝔐(s)` for `s ≥ 2`. -/ +theorem lemma7 (r : ℕ) {s : ℝ} (hs : 2 ≤ s) : fr r s < MSieve s ∧ MSieve s ≤ 4 * bigM s := + ⟨fr_lt_MSieve r s, (MSieve_lt_four_mul_bigM hs).le⟩ + +theorem mainMaj_lt_four_mul_bigM (lower : Bool) {s : ℝ} (hs : 2 ≤ s) : + mainMaj lower s < 4 * bigM s := + (mainMaj_le_MSieve lower s).trans_lt (MSieve_lt_four_mul_bigM hs) + +/-- `M lower (s) ≤ 12 G lower' (s)` for `s ≥ 2`. -/ +theorem mainMaj_le_errMaj (lower lower' : Bool) {s : ℝ} (hs : 2 ≤ s) : + mainMaj lower s ≤ 12 * errMaj lower' s := by + linarith [mainMaj_lt_four_mul_bigM lower hs, (errMaj_mem lower' s).1] + +/-- `M(s - 1) < 16 s² 𝔐(s)` for `s ≥ 3` (Lemmas 7 and 8). -/ +theorem MSieve_sub_one_lt {s : ℝ} (hs : 3 ≤ s) : MSieve (s - 1) < 16 * s ^ 2 * bigM s := by + have h1 := MSieve_lt_four_mul_bigM (s := s - 1) (by linarith) + have h2 := bigM_sub_one_lt hs + linarith + +theorem bigM_three_gt : 3 / 2 < bigM 3 := by + rw [bigM_three]; linarith [log_two_lt_d9] + +/-- The comparison of Corollary 1's error term with the error majorant: +`M lower (s - 1) ≤ 48 s² G lower' (s)` for `s ≥ 1` (any flags). -/ +theorem mainMaj_sub_one_le (lower lower' : Bool) {s : ℝ} (hs : 1 ≤ s) : + mainMaj lower (s - 1) ≤ 48 * s ^ 2 * errMaj lower' s := by + have hG := (errMaj_mem lower' s).1 + have hM := mainMaj_le_MSieve lower (s - 1) + rcases le_total 3 s with h3 | h3 + · have := MSieve_sub_one_lt h3 + nlinarith + · have h0 : MSieve (s - 1) ≤ MSieve 0 := MSieve_antitone (by linarith) + rw [MSieve_of_le_three (s := 0) (by norm_num), fSieve_of_le_two (by norm_num), + fSieve_two] at h0 + have hK := FSieve_three_add_lt_four + have hB : bigM 3 ≤ bigM s := bigM_antitone h3 + have := bigM_three_gt + have hs2 : 1 ≤ s ^ 2 := by nlinarith + have : 24 ≤ 48 * s ^ 2 * errMaj lower' s := by nlinarith + linarith + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFive.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFive.lean new file mode 100644 index 000000000..ad809a1aa --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFive.lean @@ -0,0 +1,468 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.Defs +public import LeanPool.IwaniecLinearSieve.PrimeSums.Error +public import LeanPool.IwaniecLinearSieve.Rosser +import LeanPool.IwaniecLinearSieve.LinearSieve.Corollaries +import LeanPool.IwaniecLinearSieve.LinearSieve.Depth +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaEleven +import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFiveCount +import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFourAux +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Data.Finset.Slice + +/-! +# [I71, Theorem 5]: the size of the support of the Rosser weights + +For `y > 1`, `sMin lower ≤ s ≤ ξ(y)` and every depth `r`, + #{d ∈ rosserSet lower y y^{1/s} | ω(d) ≤ r} ≤ c₇ · (r+1)/(r+2) · δ(s, y) · G(s) · y / log² y + +(`theorem5`), where `G = errMaj lower` (`𝔣` for the lower sieve, `𝔉` for the upper sieve). This +is [I71, (4.11)] with the depth shifted by one (`A_{r,y}` there counts `r + 1` levels of the +recursion, whence `r/(r+1)` and `G_{r+1}`); with our recursion (`card_filter_rosserSet_succ`) the +count at flag `lower` is compared with `errMaj lower`. Consequence (`card_rosserSet_le`): +`#(rosserSet true y y^{1/s}) ≪ y / log² y` uniformly for `s ∈ [2, 3]`. + +The proof follows [I71, pp. 26–27], by induction on `r` for both flags at once: + +* `y < c₈`: the count is at most `y` (`card_rosserSet_le`), and `c₇` is chosen large; +* `y ≥ c₈` and `r + 3 > 2 log y / log log y`: the count does not change from depth `r` to `r + 1` + (`exists_card_filter_rosserSet_add_eq`); +* otherwise Lemma 17 is split at `w = y^{1/(ξ-1)}`: the primes `p ≥ w` are handled by the + induction hypothesis at `(y/p, t_p - 1)` and Corollary 3, the primes `p < w` give at most + `#(rosserSet lower y w)`, which is small by the crude count (`exists_card_small`). The losses + (Corollary 3's factor `1 + C ξ² pntE(y^{1/ξ})`, `δ(max s s₀) ≤ δ(s) δ(s₀)`, the crude part) + are absorbed by `(r+2)/(r+3) - (r+1)/(r+2) ≥ (log log y)² / (4 log² y)`. +-/ + +@[expose] public section + +open Real Filter Finset + +namespace IwaniecLinearSieve.TheoremFive + +/-- The statement of Theorem 5 at depth `r` with constant `c₇`. -/ +def Bound (c₇ : ℝ) (r : ℕ) : Prop := + ∀ (lower : Bool) (y s : ℝ), 1 < y → sMin lower ≤ s → s ≤ xi y → + (#{d ∈ rosserSet lower y (y ^ (1 / s)) | #d.primeFactors ≤ r} : ℝ) ≤ + c₇ * ((r + 1) / (r + 2)) * delta s y * errMaj lower s * y / log y ^ 2 + +/-! ### The inner level + +Theorems 4 and 5 use the same inner-parameter estimates. These wrappers retain the +Theorem 5 statements while sharing the proofs from `TheoremFour`. +-/ + +/-- For `p ∈ rosserPrimes lower y y^{1/s}`: `p < y`, and the inner parameter `t_p - 1` is in the +domain of the opposite flag. -/ +theorem rosserPrimes_facts {lower : Bool} {y s : ℝ} {p : ℕ} (hy : 1 < y) (hs : sMin lower ≤ s) + (hp : p ∈ rosserPrimes lower y (y ^ (1 / s))) : + 1 < p ∧ (p : ℝ) < y ∧ sMin (!lower) ≤ log y / log p - 1 := by + exact ⟨(prime_of_mem_primesLT (rosserPrimes_subset hp)).one_lt, + TheoremFour.prime_lt_of_mem_rosserPrimes hy (one_le_of_sMin_le hs) hp, + TheoremFour.sMin_le_inner hy hs hp⟩ + +/-- `t - 1 ≤ ξ(y/p)` for `t = t_p ≤ ξ(y)`, `1 < p < y`. -/ +theorem sub_one_le_xi_div {y : ℝ} {p : ℕ} (hy : 1 < y) (hp : 1 < p) (hpy : (p : ℝ) < y) + (ht : log y / log p ≤ xi y) : log y / log p - 1 ≤ xi (y / p) := by + apply TheoremFour.inner_le_xi hy hp hpy + -- Convert the logarithmic hypothesis to the prime cutoff used in Theorem 4. + have hp0 : (0 : ℝ) < p := by positivity + have hlp : 0 < log (p : ℝ) := log_pos (by exact_mod_cast hp) + rw [← log_le_log_iff (rpow_pos_of_pos (zero_lt_one.trans hy) _) hp0, + log_rpow_one_div (zero_lt_one.trans hy), div_le_iff₀ (xi_pos hy)] + simpa only [mul_comm] using (div_le_iff₀ hlp).1 ht + +/-- `(y/p)^{1/(t_p - 1)} = p`. -/ +theorem rpow_inv_sub_one_eq {y : ℝ} {p : ℕ} (hp : 1 < p) (hpy : (p : ℝ) < y) : + (y / p) ^ (1 / (log y / log p - 1)) = p := by + exact TheoremFour.rpow_inner_eq hp hpy + +/-- The induction hypothesis at the inner level `(y/p, t_p - 1)`, for `t_p ≤ ξ(y)`. -/ +theorem inner_le {c₇ : ℝ} {r : ℕ} (ih : Bound c₇ r) {lower : Bool} {y s : ℝ} (hy : 1 < y) + (hs : sMin lower ≤ s) {p : ℕ} (hp : p ∈ rosserPrimes lower y (y ^ (1 / s))) + (ht : log y / log p ≤ xi y) : + (#{d ∈ rosserSet (!lower) (y / p) p | #d.primeFactors ≤ r} : ℝ) ≤ + c₇ * ((r + 1) / (r + 2)) * y * (delta (log y / log p - 1) (y / p) * + errMaj (!lower) (log y / log p - 1) / (p * log (y / p) ^ 2)) := by + obtain ⟨hp1, hpy, hsp⟩ := rosserPrimes_facts hy hs hp + have hp0 : (0 : ℝ) < p := by exact_mod_cast (zero_lt_one.trans hp1) + have hyp : 1 < y / p := by rw [lt_div_iff₀ hp0]; linarith + have h := ih (!lower) (y / p) (log y / log p - 1) hyp hsp (sub_one_le_xi_div hy hp1 hpy ht) + rw [rpow_inv_sub_one_eq hp1 hpy] at h + refine h.trans (le_of_eq ?_) + field_simp + +/-- Sum the inner induction bounds over `p ≥ y^{1/(ξ-1)}`, then enlarge the prime range +to `p ≥ y^{1/ξ}` so that Corollary 3 applies. -/ +theorem sum_inner_le {c₇ : ℝ} (hc₇ : 0 ≤ c₇) {r : ℕ} (ih : Bound c₇ r) + {lower : Bool} {y s : ℝ} (hy : 1 < y) (hs : sMin lower ≤ s) (hξ : 1 < xi y) : + ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter + (fun p : ℕ => y ^ (1 / (xi y - 1)) ≤ p), + (#{d ∈ rosserSet (!lower) (y / p) p | #d.primeFactors ≤ r} : ℝ) ≤ + c₇ * ((r + 1) / (r + 2)) * y * + ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter + (fun p : ℕ => y ^ (1 / xi y) ≤ p), + delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) := by + set P := rosserPrimes lower y (y ^ (1 / s)) + set w := y ^ (1 / (xi y - 1)) with hw + set φ : ℝ := ((r : ℝ) + 1) / (r + 2) + set term : ℕ → ℝ := fun p => delta (log y / log p - 1) (y / p) * + errMaj (!lower) (log y / log p - 1) / (p * log (y / p) ^ 2) with hterm + have hφ0 : 0 ≤ φ := by positivity + calc + _ ≤ ∑ p ∈ P.filter (fun p : ℕ => w ≤ p), c₇ * φ * y * term p := by + refine sum_le_sum fun p hp => ?_ + obtain ⟨hpP, hwp⟩ := mem_filter.1 hp + obtain ⟨hp1, -, -⟩ := rosserPrimes_facts hy hs hpP + have hp1' : (1 : ℝ) < p := by exact_mod_cast hp1 + have hlp : 0 < log (p : ℝ) := log_pos hp1' + have ht : log y / log p ≤ xi y := by + have hlog := log_le_log (by positivity) hwp + rw [hw, log_rpow_one_div (by linarith)] at hlog + rw [div_le_iff₀ (by linarith)] at hlog + rw [div_le_iff₀ hlp] + nlinarith only [hlog, hlp] + exact inner_le ih hy hs hpP ht + _ ≤ ∑ p ∈ P.filter (fun p : ℕ => y ^ (1 / xi y) ≤ p), c₇ * φ * y * term p := by + refine sum_le_sum_of_subset_of_nonneg (fun p hp => ?_) fun p hp _ => ?_ + · obtain ⟨hpP, hwp⟩ := mem_filter.1 hp + exact mem_filter.2 ⟨hpP, (rpow_one_div_le_rpow_one_div hy.le (by linarith) + (by linarith)).trans hwp⟩ + · obtain ⟨-, -, hsp⟩ := rosserPrimes_facts hy hs (mem_filter.1 hp).1 + have := delta_pos (one_le_of_sMin_le hsp) (y / p) + have := errMaj_pos (!lower) (log y / log p - 1) + simp only [hterm] + positivity + _ = _ := (mul_sum ..).symm + +/-! ### Closing the induction -/ +theorem delta_max_le {s s₀ : ℝ} (hs : 1 ≤ s) (hs₀ : 1 ≤ s₀) (y : ℝ) : + delta (max s s₀) y ≤ delta s y * delta s₀ y := by + simpa only [mul_comm] using TheoremFour.delta_max_le hs hs₀ y + +/-- The gain from depth `r` to `r + 1`: `(r+2)/(r+3) - (r+1)/(r+2) ≥ ℓ²/(4L²)` when +`r + 3 ≤ 2L/ℓ`. -/ +theorem gap_le {r : ℕ} {L ℓ : ℝ} (hL : 0 < L) (hℓ : 0 < ℓ) (h : (r : ℝ) + 3 ≤ 2 * L / ℓ) : + 2 * (ℓ ^ 2 / (8 * L ^ 2)) ≤ ((r : ℝ) + 1 + 1) / (r + 1 + 2) - (r + 1) / (r + 2) := by + have hr : (0 : ℝ) ≤ r := r.cast_nonneg + have e : ((r : ℝ) + 1 + 1) / (r + 1 + 2) - (r + 1) / (r + 2) = 1 / ((r + 2) * (r + 3)) := by + field_simp; ring + rw [e, le_div_iff₀ (by positivity)] + rw [le_div_iff₀ hℓ] at h + have h2 : ((r + 3) * ℓ) ^ 2 ≤ (2 * L) ^ 2 := by gcongr + have : (r + 2) * (r + 3) * ℓ ^ 2 ≤ 4 * L ^ 2 := by nlinarith [sq_nonneg ℓ] + rw [show 2 * (ℓ ^ 2 / (8 * L ^ 2)) * ((r + 2) * (r + 3)) = + (r + 2) * (r + 3) * ℓ ^ 2 / (4 * L ^ 2) by field_simp; ring] + rw [div_le_one (by positivity)] + exact this + +/-- The final algebra of the inductive step. -/ +theorem close_step {c₇ φ φ' Q X ε : ℝ} (hc₇ : 1 ≤ c₇) (hQ : 0 ≤ Q) (hφ1 : φ ≤ 1) + (hX0 : 0 ≤ X) (hX : X ≤ ε) (hgap : 2 * ε ≤ φ' - φ) : + Q * ε + c₇ * φ * Q * (1 + X) ≤ c₇ * φ' * Q := by + have hε : 0 ≤ ε := hX0.trans hX + have h1 : φ * X ≤ ε := (mul_le_of_le_one_left hX0 hφ1).trans hX + have h2 : ε ≤ φ' - φ - φ * X := by linarith + have h3 : c₇ * ε ≤ c₇ * (φ' - φ - φ * X) := mul_le_mul_of_nonneg_left h2 (by linarith) + have h4 : ε ≤ c₇ * ε := le_mul_of_one_le_left hε hc₇ + nlinarith [mul_le_mul_of_nonneg_left (h4.trans h3) hQ] + +/-- The main case of the inductive step ([I71, p. 27]): `y` large and +`r + 3 ≤ 2 log y / log log y`. The hypotheses are the large-`y` facts: the crude count +(`exists_card_small`), Corollary 3 (`cor3_xi`) and the slack (`exists_slack`). -/ +theorem step_main {c₇ C : ℝ} (hc₇ : 1 ≤ c₇) {r : ℕ} (ih : Bound c₇ r) {lower : Bool} {y s : ℝ} + (hy : 1 < y) (hs : sMin lower ≤ s) (hξ32 : exp 32 ≤ xi y) + (hsmall : 1 + (#(rosserSet lower y (y ^ (1 / (xi y - 1)))) : ℝ) ≤ + delta s y * errMaj lower s * y / (8 * log y ^ 4)) + (hcor : ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p), + delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) ≤ + delta (max s (exp 32)) y * errMaj lower s / log y ^ 2 * + (1 + C * xi y ^ 2 * pntE (y ^ (1 / xi y)))) + (hC : 0 ≤ C) + (hslack : delta (exp 32) y * (1 + C * xi y ^ 2 * pntE (y ^ (1 / xi y))) - 1 ≤ + log (log y) ^ 2 / (8 * log y ^ 2)) + (hℓ : 1 ≤ log (log y)) (hmain : (r : ℝ) + 3 ≤ 2 * log y / log (log y)) : + (#{d ∈ rosserSet lower y (y ^ (1 / s)) | #d.primeFactors ≤ r + 1} : ℝ) ≤ + c₇ * ((((r + 1 : ℕ) : ℝ) + 1) / (((r + 1 : ℕ) : ℝ) + 2)) * delta s y * errMaj lower s * y / + log y ^ 2 := by + have hL0 : 0 < log y := log_pos hy + have hs1 := one_le_of_sMin_le hs + have hξ1 : 1 < xi y := by linarith only [four_lt_of_exp_le hξ32] + set L := log y + set w := y ^ (1 / (xi y - 1)) + set φ : ℝ := ((r : ℝ) + 1) / (r + 2) with hφ + set E := C * xi y ^ 2 * pntE (y ^ (1 / xi y)) + set Q := delta s y * errMaj lower s * y / L ^ 2 with hQ + -- Each loss is at most `ε`; the depth increment supplies at least `2ε`. + set ε := log (log y) ^ 2 / (8 * L ^ 2) with hε + set X := delta (exp 32) y * (1 + E) - 1 with hX + have hδs := delta_pos hs1 y + have hGs := errMaj_pos lower s + have hQ0 : 0 ≤ Q := by positivity + have hφ0 : 0 ≤ φ := by positivity + have hφ1 : φ ≤ 1 := by rw [hφ, div_le_one (by positivity)]; linarith + have hE0 : 0 ≤ E := by have := pntE_pos (y ^ (1 / xi y)); positivity + have hs₀ : (1 : ℝ) ≤ exp 32 := one_le_exp (by norm_num) + have hδ₀ := one_le_delta hs₀ y + have hX0 : 0 ≤ X := by + rw [hX] + nlinarith only [hδ₀, hE0] + -- The crude count uses at most `Qε` of the induction gap. + have hsmallPart : (#(rosserSet lower y w) : ℝ) ≤ Q * ε := by + calc + _ ≤ 1 + (#(rosserSet lower y w) : ℝ) := by linarith only + _ ≤ delta s y * errMaj lower s * y / (8 * L ^ 4) := hsmall + _ = Q * (1 / (8 * L ^ 2)) := by rw [hQ]; ring + _ ≤ Q * ε := by + rw [hε] + have : (1 : ℝ) ≤ log (log y) ^ 2 := by nlinarith only [hℓ] + gcongr + -- The inner induction bounds and Corollary 3 give the main term with relative loss `X`. + have hlargePart : ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter + (fun p : ℕ => w ≤ p), + (#{d ∈ rosserSet (!lower) (y / p) p | #d.primeFactors ≤ r} : ℝ) ≤ + c₇ * φ * Q * (1 + X) := by + refine (sum_inner_le (zero_le_one.trans hc₇) ih hy hs hξ1).trans ?_ + calc + _ ≤ c₇ * φ * y * + (delta (max s (exp 32)) y * errMaj lower s / L ^ 2 * (1 + E)) := by + exact mul_le_mul_of_nonneg_left hcor (by positivity) + _ = c₇ * φ * (y * errMaj lower s / L ^ 2 * (1 + E)) * + delta (max s (exp 32)) y := by ring + _ ≤ c₇ * φ * (y * errMaj lower s / L ^ 2 * (1 + E)) * + (delta s y * delta (exp 32) y) := by + exact mul_le_mul_of_nonneg_left (delta_max_le hs1 hs₀ y) (by positivity) + _ = c₇ * φ * Q * (1 + X) := by rw [hQ, hX]; ring + have hgap := gap_le (r := r) hL0 (zero_lt_one.trans_le hℓ) hmain + have hgoal : c₇ * ((((r + 1 : ℕ) : ℝ) + 1) / (((r + 1 : ℕ) : ℝ) + 2)) * delta s y * + errMaj lower s * y / L ^ 2 = c₇ * (((r : ℝ) + 1 + 1) / (r + 1 + 2)) * Q := by + rw [hQ]; push_cast; ring + rw [hgoal] + calc + _ ≤ #(rosserSet lower y w) + ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter + (fun p : ℕ => w ≤ p), + (#{d ∈ rosserSet (!lower) (y / p) p | #d.primeFactors ≤ r} : ℝ) := + card_filter_succ_le r lower y (y ^ (1 / s)) w + _ ≤ Q * ε + c₇ * φ * Q * (1 + X) := add_le_add hsmallPart hlargePart + _ ≤ _ := close_step hc₇ hQ0 hφ1 hX0 hslack hgap + +/-! ### The small-`y` case -/ + +/-- `ξ(y) ≤ log c₈ / (log log 3)^{11/5}` for `1 < y < c₈`. -/ +theorem xi_le_of_lt {y c₈ : ℝ} (hy : 1 < y) (hyc : y < c₈) : + xi y ≤ log c₈ / log (log 3) ^ (11 / 5 : ℝ) := by + have h3 := one_lt_log_three + have hll : 0 < log (log 3) := log_pos h3 + have hlam : log (log 3) ≤ lam y := by + unfold lam + exact log_le_log (by linarith) (log_le_log (by norm_num) (by linarith)) + rw [xi_eq_lam] + exact div_le_div₀ (log_nonneg (by linarith)) (log_le_log (by linarith) hyc.le) + (rpow_pos_of_pos hll _) (rpow_le_rpow hll.le hlam (by norm_num)) + +/-- For `1 < y < c₈` the count is at most `y`, which is at most the bound once +`c₇ ≥ 2 log² c₈ / min (𝔣(Ξ), 𝔉(Ξ))` with `Ξ = log c₈ / (log log 3)^{11/5}`. -/ +theorem small_le {c₈ c₇ : ℝ} + (hc₇ : 2 * log c₈ ^ 2 / min (errMaj true (log c₈ / log (log 3) ^ (11 / 5 : ℝ))) + (errMaj false (log c₈ / log (log 3) ^ (11 / 5 : ℝ))) ≤ c₇) + (r : ℕ) (lower : Bool) {y s : ℝ} (hy : 1 < y) (hyc : y < c₈) (hs : sMin lower ≤ s) + (hsξ : s ≤ xi y) : + (#{d ∈ rosserSet lower y (y ^ (1 / s)) | #d.primeFactors ≤ r} : ℝ) ≤ + c₇ * ((r + 1) / (r + 2)) * delta s y * errMaj lower s * y / log y ^ 2 := by + set Ξ := log c₈ / log (log 3) ^ (11 / 5 : ℝ) with hΞ + set Gm := min (errMaj true Ξ) (errMaj false Ξ) with hGm + have hGm0 : 0 < Gm := lt_min (errMaj_pos _ _) (errMaj_pos _ _) + have hs1 := one_le_of_sMin_le hs + have hL0 : 0 < log y := log_pos hy + have hLc : log y ≤ log c₈ := log_le_log (by linarith) hyc.le + have hG : Gm ≤ errMaj lower s := by + have h1 : errMaj lower Ξ ≤ errMaj lower s := + errMaj_antitone lower (hsξ.trans (xi_le_of_lt hy hyc)) + cases lower + · exact (min_le_right _ _).trans h1 + · exact (min_le_left _ _).trans h1 + have hδ := one_le_delta hs1 y + have hφ : (1 : ℝ) / 2 ≤ ((r : ℝ) + 1) / (r + 2) := by + rw [div_le_div_iff₀ (by norm_num) (by positivity)]; linarith [r.cast_nonneg (α := ℝ)] + have hc₇' : 2 * log c₈ ^ 2 ≤ c₇ * Gm := by rwa [div_le_iff₀ hGm0] at hc₇ + have hcount : (#{d ∈ rosserSet lower y (y ^ (1 / s)) | #d.primeFactors ≤ r} : ℝ) ≤ y := + (Nat.cast_le.2 (card_filter_le _ _)).trans (card_rosserSet_le hy hs1) + refine hcount.trans ?_ + rw [le_div_iff₀ (by positivity)] + have hc₇0 : 0 ≤ c₇ := by + have := mul_nonneg (by norm_num : (0 : ℝ) ≤ 2) (sq_nonneg (log c₈)) + nlinarith + have key : log y ^ 2 ≤ c₇ * (((r : ℝ) + 1) / (r + 2)) * delta s y * errMaj lower s := by + have h1 : log y ^ 2 ≤ log c₈ ^ 2 := by gcongr + have h2 : c₇ * Gm / 2 ≤ c₇ * (((r : ℝ) + 1) / (r + 2)) * delta s y * errMaj lower s := by + have : c₇ * Gm / 2 = c₇ * (1 / 2) * 1 * Gm := by ring + rw [this] + gcongr + linarith + nlinarith + +/-! ### Theorem 5 -/ +theorem exists_bound : ∃ c₇ : ℝ, 1 ≤ c₇ ∧ ∀ r, Bound c₇ r := by + obtain ⟨y₁, hsmall⟩ := exists_card_small + obtain ⟨C, y₂, hC0, hcor⟩ := cor3_xi + obtain ⟨y₃, hslack⟩ := exists_slack C hC0 + obtain ⟨y₄, hdepth⟩ := exists_card_filter_rosserSet_add_eq + obtain ⟨y₅, hxi⟩ := exists_xi_large + -- Choose one threshold beyond which all five estimates apply. + have hlarge := (eventually_ge_atTop (3 : ℝ)).and + ((eventually_atTop.2 ⟨y₁, hsmall⟩).and + ((eventually_atTop.2 ⟨y₂, fun y hy lower s hs ↦ hcor lower y s hy hs⟩).and + ((eventually_atTop.2 ⟨y₃, hslack⟩).and + ((eventually_atTop.2 ⟨y₄, hdepth⟩).and (eventually_atTop.2 ⟨y₅, hxi⟩))))) + obtain ⟨c₈, hlarge⟩ := eventually_atTop.1 hlarge + set c₇ := max 1 (2 * log c₈ ^ 2 / min (errMaj true (log c₈ / log (log 3) ^ (11 / 5 : ℝ))) + (errMaj false (log c₈ / log (log 3) ^ (11 / 5 : ℝ)))) with hc₇ + have hc₇1 : 1 ≤ c₇ := le_max_left _ _ + refine ⟨c₇, hc₇1, fun r => ?_⟩ + induction r with + | zero => + intro lower y s hy hs hsξ + rcases lt_or_ge y c₈ with hyc | hyc + · exact small_le (le_max_right _ _) 0 lower hy hyc hs hsξ + obtain ⟨hy3, hsmall, -, -, -, -⟩ := hlarge y hyc + have hL1 : 1 ≤ log y := by + have := log_le_log (by norm_num) hy3 + linarith [one_lt_log_three] + have h := hsmall lower s hs hsξ + rw [card_filter_rosserSet_zero] + have hN : (0 : ℝ) ≤ #(rosserSet lower y (y ^ (1 / (xi y - 1)))) := Nat.cast_nonneg _ + have hQ : 0 ≤ delta s y * errMaj lower s * y := by + have := delta_pos (one_le_of_sMin_le hs) y + have := errMaj_pos lower s + have : 0 < y := by linarith + positivity + push_cast + have : delta s y * errMaj lower s * y / (8 * log y ^ 4) ≤ + c₇ * ((0 + 1) / (0 + 2)) * delta s y * errMaj lower s * y / log y ^ 2 := by + rw [div_le_div_iff₀ (by positivity) (by positivity)] + have h4 : log y ^ 2 ≤ 4 * log y ^ 4 := by + have h1 : 1 ≤ log y ^ 2 := by nlinarith + nlinarith [mul_le_mul_of_nonneg_left h1 (sq_nonneg (log y))] + have h5 : delta s y * errMaj lower s * y * log y ^ 2 ≤ + delta s y * errMaj lower s * y * (4 * log y ^ 4) := + mul_le_mul_of_nonneg_left h4 hQ + nlinarith [mul_le_mul_of_nonneg_right hc₇1 (mul_nonneg hQ (pow_pos (by linarith : + (0 : ℝ) < log y) 4).le)] + linarith + | succ r ih => + intro lower y s hy hs hsξ + rcases lt_or_ge y c₈ with hyc | hyc + · exact small_le (le_max_right _ _) (r + 1) lower hy hyc hs hsξ + obtain ⟨-, hsmall, hcor, hslack, hdepth, hxi⟩ := hlarge y hyc + by_cases hdeep : 2 * log y / log (log y) < ((r + 1 : ℕ) : ℝ) + 2 + · -- the depth has stabilised + have h := hdepth lower (r + 1) (y ^ (1 / s)) hdeep 1 + simp only [Nat.add_sub_cancel] at h + rw [h] + refine (ih lower y s hy hs hsξ).trans ?_ + have hQ : 0 ≤ delta s y * errMaj lower s * y / log y ^ 2 := by + have := delta_pos (one_le_of_sMin_le hs) y + have := errMaj_pos lower s + have : 0 < y := by linarith + positivity + have hφ : ((r : ℝ) + 1) / (r + 2) ≤ (((r + 1 : ℕ) : ℝ) + 1) / (((r + 1 : ℕ) : ℝ) + 2) := by + push_cast + rw [div_le_div_iff₀ (by positivity) (by positivity)]; nlinarith + calc c₇ * ((r + 1) / (r + 2)) * delta s y * errMaj lower s * y / log y ^ 2 + = c₇ * ((r + 1) / (r + 2)) * (delta s y * errMaj lower s * y / log y ^ 2) := by ring + _ ≤ c₇ * ((((r + 1 : ℕ) : ℝ) + 1) / (((r + 1 : ℕ) : ℝ) + 2)) * + (delta s y * errMaj lower s * y / log y ^ 2) := by gcongr + _ = _ := by ring + · -- the main case + obtain ⟨-, hξ32, -, -⟩ := hxi + obtain ⟨hsl, hℓ⟩ := hslack + have hmain : (r : ℝ) + 3 ≤ 2 * log y / log (log y) := by + push_cast at hdeep; linarith + exact step_main hc₇1 ih hy hs hξ32 (hsmall lower s hs hsξ) + (hcor lower s hs) hC0 hsl hℓ hmain + +end IwaniecLinearSieve.TheoremFive + +namespace IwaniecLinearSieve + +open Finset TheoremFive + +/-- [I71, Theorem 5] (in the indexing of our recursion): there is `c₇` such that for all depths +`r`, both sieves, `y > 1` and `sMin lower ≤ s ≤ ξ(y)`, the number of elements of +`rosserSet lower y y^{1/s}` with at most `r` prime factors is at most +`c₇ (r+1)/(r+2) δ(s, y) G(s) y / log² y`, with `G = errMaj lower` (`𝔣` or `𝔉`). -/ +theorem theorem5 : ∃ c₇ : ℝ, 0 ≤ c₇ ∧ ∀ (r : ℕ) (lower : Bool) (y s : ℝ), 1 < y → + sMin lower ≤ s → s ≤ xi y → + (#{d ∈ rosserSet lower y (y ^ (1 / s)) | #d.primeFactors ≤ r} : ℝ) ≤ + c₇ * ((r + 1) / (r + 2)) * delta s y * errMaj lower s * y / Real.log y ^ 2 := by + obtain ⟨c₇, hc₇, h⟩ := exists_bound + exact ⟨c₇, by linarith, fun r => h r⟩ + +/-- `δ(s, y) ≤ (1 + 9 log⁵ 3)^{15}` for `1 ≤ s ≤ 3` and `log y ≥ 1`. -/ +theorem delta_le_of_le_three {s y : ℝ} (hs1 : 1 ≤ s) (hs3 : s ≤ 3) (hy : 1 ≤ Real.log y) : + delta s y ≤ (1 + 9 * Real.log 3 ^ 5) ^ (15 : ℝ) := by + have hl0 : 0 ≤ Real.log s := Real.log_nonneg hs1 + have hl3 : Real.log s ≤ Real.log 3 := Real.log_le_log (by linarith) hs3 + have hx : s ^ 2 * Real.log s ^ 5 / Real.log y ^ 2 ≤ 9 * Real.log 3 ^ 5 := by + rw [div_le_iff₀ (by positivity)] + have h1 : s ^ 2 ≤ 9 := by nlinarith + have h2 : Real.log s ^ 5 ≤ Real.log 3 ^ 5 := by gcongr + have h3 : 1 ≤ Real.log y ^ 2 := by nlinarith + have h4 : s ^ 2 * Real.log s ^ 5 ≤ 9 * Real.log 3 ^ 5 := + mul_le_mul h1 h2 (by positivity) (by norm_num) + have h5 : 0 ≤ Real.log 3 ^ 5 := by positivity + nlinarith + have hx0 : 0 ≤ s ^ 2 * Real.log s ^ 5 / Real.log y ^ 2 := by positivity + rw [delta] + calc (1 + s ^ 2 * Real.log s ^ 5 / Real.log y ^ 2) ^ (5 * s) + ≤ (1 + 9 * Real.log 3 ^ 5) ^ (5 * s) := Real.rpow_le_rpow (by linarith) (by linarith) + (by linarith) + _ ≤ (1 + 9 * Real.log 3 ^ 5) ^ (15 : ℝ) := + Real.rpow_le_rpow_of_exponent_le (by linarith) (by linarith) + +/-- The consequence of Theorem 5 used for `LinearSieveEstimate`: the lower-bound sieve support +has `#(rosserSet true y y^{1/s}) ≪ y / log² y` uniformly for `2 ≤ s ≤ 3`. -/ +theorem theorem5_card_rosserSet_le : ∃ K y₀ : ℝ, ∀ y ≥ y₀, ∀ s ∈ Set.Icc (2 : ℝ) 3, + (#(rosserSet true y (y ^ (1 / s))) : ℝ) ≤ K * y / Real.log y ^ 2 := by + obtain ⟨c₇, hc₇, h5⟩ := theorem5 + obtain ⟨y₅, hxi⟩ := exists_xi_large + set D := (1 + 9 * Real.log 3 ^ 5) ^ (15 : ℝ) with hD + refine ⟨c₇ * D * 2, max y₅ 3, fun y hy s hs => ?_⟩ + obtain ⟨hy1, hξ, -, -⟩ := hxi y (le_of_max_le_left hy) + have hy3 : 3 ≤ y := le_of_max_le_right hy + have hL1 : 1 ≤ Real.log y := by + have := Real.log_le_log (by norm_num) hy3 + linarith [one_lt_log_three] + have hsξ : s ≤ xi y := hs.2.trans (by linarith [Real.add_one_le_exp (32 : ℝ)]) + set z := y ^ (1 / s) + have hall : (rosserSet true y z).filter (fun d => #d.primeFactors ≤ #(primesLT z)) = + rosserSet true y z := + filter_true_of_mem fun d hd => card_le_card (primeFactors_subset_of_mem_rosserSet hd) + have h := h5 #(primesLT z) true y s hy1 hs.1 hsξ + rw [hall] at h + refine h.trans ?_ + have hδ := delta_le_of_le_three (by linarith [hs.1]) hs.2 hL1 (y := y) + have hδ0 := delta_pos (by linarith [hs.1] : (1 : ℝ) ≤ s) y + have hG := errMaj_le_two true s + have hG0 := errMaj_pos true s + have hφ : ((#(primesLT z) : ℕ) + 1 : ℝ) / ((#(primesLT z) : ℕ) + 2) ≤ 1 := by + rw [div_le_one (by positivity)]; linarith + have hφ0 : (0 : ℝ) ≤ ((#(primesLT z) : ℕ) + 1 : ℝ) / ((#(primesLT z) : ℕ) + 2) := by positivity + have hyL : 0 ≤ y / Real.log y ^ 2 := by positivity + calc c₇ * ((#(primesLT z) + 1) / (#(primesLT z) + 2)) * delta s y * errMaj true s * y / + Real.log y ^ 2 + = c₇ * ((#(primesLT z) + 1) / (#(primesLT z) + 2)) * delta s y * errMaj true s * + (y / Real.log y ^ 2) := by ring + _ ≤ c₇ * 1 * D * 2 * (y / Real.log y ^ 2) := by gcongr + _ = c₇ * D * 2 * y / Real.log y ^ 2 := by ring + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveAux.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveAux.lean new file mode 100644 index 000000000..014377dc0 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveAux.lean @@ -0,0 +1,190 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.Defs +public import LeanPool.IwaniecLinearSieve.PrimeSums.Error +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaEleven +import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFourAsymp +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds + +/-! +# Real-variable estimates for [I71, Theorem 5] + +With `L = log y`, `λ = log log 3y` (`TheoremFive.lam`) and `ξ = L / λ^{11/5}` (`xi`), this file +collects the "for `y ≥ y₀`" facts used in the proof of Theorem 5: + +* `eventually_scalar`: `λ`, `log λ`, `λ^{1/5}` are large, `λ - 1 ≤ log L ≤ λ`, `24 λ ≤ ξ`, + `16 λ² ≤ L`, `λ/2 ≤ log (ξ/2)`, `4 log λ + c ≤ log ξ ≤ λ`; +* `crude_exponent_le`: the comparison of the crude count of `rosserSet lower y y^{1/(ξ-1)}` with + `y exp(-ξ log ξ + (3/2) ξ log λ) / (8 L⁴)` ([I71, p. 27]); +* `exists_slack`: the losses `δ(e^{32}, y) (1 + C ξ² pntE(y^{1/ξ})) - 1` of Corollary 3 are at + most `(log log y)² / (8 L²)`, reusing `TheoremFour.eventually_delta_mul_le`. +-/ + +@[expose] public section + +open Real Filter Topology + +namespace IwaniecLinearSieve.TheoremFive + +/-- `λ(y) = log log 3y`, the denominator variable of `ξ(y) = log y / λ^{11/5}`. -/ +noncomputable def lam (y : ℝ) : ℝ := log (log (3 * y)) + +theorem xi_eq_lam (y : ℝ) : xi y = log y / lam y ^ (11 / 5 : ℝ) := rfl + +theorem tendsto_lam : Tendsto lam atTop atTop := tendsto_log_log_three_mul + +/-- `α + β log x ≤ x` for large `x`. -/ +theorem eventually_add_mul_log_le (α β : ℝ) : ∀ᶠ x in atTop, α + β * log x ≤ x := by + have hε : (0 : ℝ) < 1 / (2 * (|β| + 1)) := by positivity + filter_upwards [isLittleO_log_id_atTop.bound hε, eventually_ge_atTop (2 * α), + eventually_ge_atTop 1] with x hx hxα hx1 + have hl : 0 ≤ log x := log_nonneg hx1 + rw [norm_of_nonneg hl, id, norm_of_nonneg (by linarith)] at hx + have h1 : β * log x ≤ |β| * log x := mul_le_mul_of_nonneg_right (le_abs_self β) hl + have h2 : |β| * log x ≤ x / 2 := by + have hq : |β| / (|β| + 1) ≤ 1 := by + rw [div_le_one (by positivity)]; linarith + calc |β| * log x ≤ |β| * (1 / (2 * (|β| + 1)) * x) := by gcongr + _ = |β| / (|β| + 1) * (x / 2) := by field_simp + _ ≤ 1 * (x / 2) := by gcongr + _ = x / 2 := one_mul _ + linarith + +theorem one_lt_log_three : 1 < log 3 := by + rw [lt_log_iff_exp_lt (by norm_num)] + linarith [exp_one_lt_d9] + +theorem lam_pos {y : ℝ} (hy : 1 < y) : 0 < lam y := by + have h3 : log 3 + log y = log (3 * y) := (log_mul (by norm_num) (by linarith)).symm + have := log_pos hy + exact log_pos (by linarith [one_lt_log_three]) + +/-- `log ξ = log L - (11/5) log λ`. -/ +theorem log_xi_eq {y : ℝ} (hy : 1 < y) : log (xi y) = log (log y) - 11 / 5 * log (lam y) := by + rw [xi_eq_lam, log_div (log_pos hy).ne' (rpow_pos_of_pos (lam_pos hy) _).ne', + log_rpow (lam_pos hy)] + +theorem xi_pos {y : ℝ} (hy : 1 < y) : 0 < xi y := + div_pos (log_pos hy) (rpow_pos_of_pos (lam_pos hy) _) + +/-- The scalar facts about `L = log y`, `λ = lam y` and `ξ = xi y` used for Theorem 5, valid for +large `y`; `c ≥ 100` is a free threshold. -/ +theorem eventually_scalar (c : ℝ) (hc : 100 ≤ c) : ∀ᶠ y in atTop, + 3 ≤ y ∧ c ≤ log (lam y) ∧ c ≤ lam y ^ (1 / 5 : ℝ) ∧ c ≤ lam y ∧ + log (log y) ≤ lam y ∧ lam y - 1 ≤ log (log y) ∧ + 24 * lam y ≤ xi y ∧ 16 * lam y ^ 2 ≤ log y ∧ lam y / 2 ≤ log (xi y / 2) ∧ + 4 * log (lam y) + c ≤ log (xi y) ∧ log (xi y) ≤ lam y := by + filter_upwards [eventually_ge_atTop 3, tendsto_lam.eventually (eventually_ge_atTop c), + (tendsto_log_atTop.comp tendsto_lam).eventually (eventually_ge_atTop c), + ((tendsto_rpow_atTop (by norm_num : (0 : ℝ) < 1 / 5)).comp tendsto_lam).eventually + (eventually_ge_atTop c), + tendsto_lam.eventually (eventually_add_mul_log_le (c + 10) 8)] with y hy3 h1 h2 h3 h4 + simp only [Function.comp] at h2 h3 + have hy : 1 < y := by linarith + have hL : 1 < log y := by + have := log_le_log (by norm_num) hy3; linarith [one_lt_log_three] + have hL0 : 0 < log y := by linarith + have hlam := lam_pos hy + have h3y : log (3 * y) = log 3 + log y := log_mul (by norm_num) (by linarith) + have ha : 0 ≤ log (lam y) := by linarith + -- `log L ≤ λ ≤ log L + 1` + have hℓ1 : log (log y) ≤ lam y := by + unfold lam; exact log_le_log hL0 (by rw [h3y]; linarith [one_lt_log_three]) + have hℓ2 : lam y - 1 ≤ log (log y) := by + have hle : log (3 * y) ≤ exp 1 * log y := by + have : log 3 ≤ log y := log_le_log (by norm_num) hy3 + have : 2 ≤ exp 1 := by linarith [add_one_le_exp (1 : ℝ)] + rw [h3y]; nlinarith + have := log_le_log (by rw [h3y]; linarith [one_lt_log_three]) hle + rw [log_mul (exp_pos 1).ne' hL0.ne', log_exp] at this + unfold lam; linarith + have hlogξ := log_xi_eq hy + have hξ := xi_pos hy + have hl2 : log 2 ≤ 1 := by linarith [log_le_sub_one_of_pos (by norm_num : (0 : ℝ) < 2)] + have hl16 : log 16 ≤ 15 := by linarith [log_le_sub_one_of_pos (by norm_num : (0 : ℝ) < 16)] + have hl24 : log 24 ≤ 23 := by linarith [log_le_sub_one_of_pos (by norm_num : (0 : ℝ) < 24)] + refine ⟨hy3, h2, h3, h1, hℓ1, hℓ2, ?_, ?_, ?_, ?_, ?_⟩ + · rw [← log_le_log_iff (by positivity) hξ, log_mul (by norm_num) hlam.ne'] + linarith + · have h := (log_le_log_iff (by positivity) hL0).1 (by + rw [log_mul (by norm_num) (by positivity), log_pow]; push_cast + linarith : log (16 * lam y ^ 2) ≤ log (log y)) + exact h + · rw [log_div hξ.ne' (by norm_num)] + linarith + · linarith + · linarith + +/-! ### The crude part ([I71, p. 27]) -/ + +/-- The comparison at the bottom of [I71, p. 27], in exponential form: with `ℓ = log L`, +`8 L⁴ (1 + e^{L + 2ξ - L/λ} + 2 e^{L - ξ log ξ + ξ a + 5ξ}) ≤ e^{L - ξ log ξ + (3/2) ξ a}` +(here `a = log λ`), under the scalar facts of `eventually_scalar`. -/ +theorem crude_exponent_le {L ℓ lam ξ a : ℝ} (hL : 0 < L) (hℓ : ℓ = log L) (hℓlam : ℓ ≤ lam) + (hlam : 100 ≤ lam) (ha : 12 ≤ a) (hxilam : 4 * (ξ * lam ^ 2) ≤ L) (h24 : 24 * lam ≤ ξ) + (h16 : 16 * lam ^ 2 ≤ L) (hlogξ : log ξ ≤ lam) : + 8 * L ^ 4 * (1 + exp (L + 2 * ξ - L / lam) + 2 * exp (L - ξ * log ξ + ξ * a + 5 * ξ)) ≤ + exp (L - ξ * log ξ + 3 / 2 * ξ * a) := by + have hlam0 : 0 < lam := by linarith + have hξ0 : 0 < ξ := by linarith + have h8 : 8 * L ^ 4 = exp (log 8 + 4 * ℓ) := by + rw [exp_add, exp_log (by norm_num), hℓ, + show (4 : ℝ) * log L = log (L ^ 4) by rw [log_pow]; norm_num, exp_log (by positivity)] + have hl3 : log 3 ≤ 2 := by linarith [log_le_sub_one_of_pos (by norm_num : (0 : ℝ) < 3)] + have hl8 : log 8 ≤ 7 := by linarith [log_le_sub_one_of_pos (by norm_num : (0 : ℝ) < 8)] + have hl2 : log 2 ≤ 1 := by linarith [log_le_sub_one_of_pos (by norm_num : (0 : ℝ) < 2)] + set T := L - ξ * log ξ + 3 / 2 * ξ * a with hT + have h3 : exp T = 3 * exp (T - log 3) := by + rw [exp_sub, exp_log (by norm_num)]; field_simp + -- `ξ log ξ + 2 ξ ≤ L / (2λ)` and `8 + 4λ ≤ L / (2λ)` + have hLl : ξ * log ξ + 2 * ξ ≤ L / (2 * lam) := by + rw [le_div_iff₀ (by positivity)] + have : ξ * log ξ ≤ ξ * lam := mul_le_mul_of_nonneg_left hlogξ hξ0.le + nlinarith + have hLm : 8 + 4 * lam ≤ L / (2 * lam) := by + rw [le_div_iff₀ (by positivity)]; nlinarith + have hLlam : L / lam ≤ L := div_le_self hL.le (by linarith) + have hξa : 0 ≤ ξ * a := by positivity + have e1 : 8 * L ^ 4 ≤ exp (T - log 3) := by + rw [h8, exp_le_exp, hT] + have : L / lam = 2 * (L / (2 * lam)) := by field_simp + nlinarith + have e2 : 8 * L ^ 4 * exp (L + 2 * ξ - L / lam) ≤ exp (T - log 3) := by + rw [h8, ← exp_add, exp_le_exp, hT] + have : L / lam = 2 * (L / (2 * lam)) := by field_simp + nlinarith + have e3 : 8 * L ^ 4 * (2 * exp (L - ξ * log ξ + ξ * a + 5 * ξ)) ≤ exp (T - log 3) := by + rw [h8, mul_left_comm, ← exp_add, ← exp_log (by norm_num : (0 : ℝ) < 2), ← exp_add, + exp_le_exp, hT] + have : 6 * ξ ≤ 1 / 2 * ξ * a := by nlinarith + nlinarith + rw [h3] + nlinarith + +/-! ### The slack ([I71, (4.2), (4.6)]) -/ + +/-- `(1 + x)^p ≤ e^{p x}` for `x ≥ 0`, `p ≥ 0`. -/ +theorem one_add_rpow_le_exp {x p : ℝ} (hx : 0 ≤ x) (hp : 0 ≤ p) : (1 + x) ^ p ≤ exp (p * x) := by + rw [rpow_def_of_pos (by linarith), exp_le_exp, mul_comm] + gcongr + linarith [log_le_sub_one_of_pos (by linarith : (0 : ℝ) < 1 + x)] + +/-- For every `C ≥ 0` and large `y`, with `s₀ = e^{32}` and `ℓ = log log y`: +`δ(s₀, y) (1 + C ξ² pntE(y^{1/ξ})) - 1 ≤ ℓ² / (8 L²)` and `ℓ ≥ 1`. -/ +theorem exists_slack (C : ℝ) (hC : 0 ≤ C) : ∃ y₀ : ℝ, ∀ y ≥ y₀, + delta (exp 32) y * (1 + C * xi y ^ 2 * pntE (y ^ (1 / xi y))) - 1 ≤ + log (log y) ^ 2 / (8 * log y ^ 2) ∧ 1 ≤ log (log y) := by + apply eventually_atTop.1 + filter_upwards [TheoremFour.eventually_delta_mul_le C hC, + (tendsto_log_atTop.comp tendsto_log_atTop).eventually (eventually_ge_atTop (1 : ℝ))] + with y hslack hloglog + exact ⟨sub_le_iff_le_add'.2 hslack, hloglog⟩ + +end IwaniecLinearSieve.TheoremFive diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveCount.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveCount.lean new file mode 100644 index 000000000..050dde37d --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveCount.lean @@ -0,0 +1,458 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFiveAux +public import LeanPool.IwaniecLinearSieve.PrimeSums.Product +public import LeanPool.IwaniecLinearSieve.Rosser +import LeanPool.IwaniecLinearSieve.LinearSieve.Corollaries +import LeanPool.IwaniecLinearSieve.LinearSieve.Crude +import LeanPool.IwaniecLinearSieve.LinearSieve.Depth +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaEleven +import LeanPool.IwaniecLinearSieve.SieveMajorants.Lemmas +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds +import Mathlib.Data.Finset.Slice +import Mathlib.Tactic.Polynomial.Basic + +/-! +# Counting lemmas for [I71, Theorem 5] + +* `card_rosserSet_le`: `#(rosserSet lower y y^{1/s}) ≤ y` for `y > 1`, `s ≥ 1` (all elements are + `< y`); this is the small-`y` case. +* `card_filter_succ_le`: Lemma 17 split at a level `w`: the primes `p < w` give at most + `#(rosserSet lower y w)`. +* `card_rosserSet_rpow_le`: the crude count of `rosserSet lower y w` for `w = y^{1/(ξ-1)}` + ([I71, p. 27]): elements with at most `K ≈ ξ(1 - 2/λ)` prime factors are counted by + `π(w)^l / l!`, the others by `card_filter_le_tail`. +* `exists_card_small`: for large `y` and `sMin lower ≤ s ≤ ξ`, + `1 + #(rosserSet lower y y^{1/(ξ-1)}) ≤ δ(s, y) G(s) y / (8 L⁴)`. +-/ + +@[expose] public section + +open Real Filter Finset + +namespace IwaniecLinearSieve.TheoremFive + +variable {lower : Bool} {y z s : ℝ} + +/-- For `y > 1` and `s ≥ 1`, every element of `rosserSet lower y y^{1/s}` is `< y`. -/ +theorem lt_of_mem_rosserSet_rpow (hy : 1 < y) (hs : 1 ≤ s) {d : ℕ} + (hd : d ∈ rosserSet lower y (y ^ (1 / s))) : (d : ℝ) < y := by + by_cases hω : (if lower then 2 else 1) ≤ #d.primeFactors + · exact lt_of_mem_rosserSet hd hω + have hsq := squarefree_of_mem_rosserSet hd + have hz : y ^ (1 / s) ≤ y := by + conv_rhs => rw [← rpow_one y] + exact rpow_le_rpow_of_exponent_le hy.le (by rw [div_le_one (by linarith)]; exact hs) + rcases Nat.lt_or_ge #d.primeFactors 1 with h0 | h1 + · have : d.primeFactors = ∅ := card_eq_zero.1 (by omega) + rw [Nat.primeFactors_eq_empty] at this + have hd1 : d = 1 := by have := pos_of_mem_rosserSet hd; omega + rw [hd1]; simpa using hy + · -- one prime factor `q < z ≤ y` + have h1' : #d.primeFactors = 1 := by split_ifs at hω <;> omega + obtain ⟨q, hq⟩ := card_eq_one.1 h1' + have hdq : d = q := by + rw [← Nat.prod_primeFactors_of_squarefree hsq, hq, prod_singleton] + have hqz := lt_of_mem_primesLT + (primeFactors_subset_of_mem_rosserSet hd (by rw [hq]; exact mem_singleton_self q)) + rw [hdq]; linarith + +/-- The small-`y` case: `#(rosserSet lower y y^{1/s}) ≤ y` for `y > 1`, `s ≥ 1`. -/ +theorem card_rosserSet_le (hy : 1 < y) (hs : 1 ≤ s) : + (#(rosserSet lower y (y ^ (1 / s))) : ℝ) ≤ y := by + have hsub : rosserSet lower y (y ^ (1 / s)) ⊆ Ico 1 ⌈y⌉₊ := fun d hd ↦ by + have := lt_of_mem_rosserSet_rpow hy hs hd + exact mem_Ico.2 ⟨pos_of_mem_rosserSet hd, Nat.lt_ceil.2 this⟩ + have h := card_le_card hsub + rw [Nat.card_Ico] at h + have hc := Nat.ceil_lt_add_one (by linarith : (0 : ℝ) ≤ y) + have : ((⌈y⌉₊ - 1 : ℕ) : ℝ) ≤ y := by + rw [Nat.cast_sub (Nat.one_le_iff_ne_zero.2 (by positivity))] + push_cast; linarith + exact (Nat.cast_le.2 h).trans this + +/-- Lemma 17 split at `w`: the primes `p < w` contribute (with the `1`) at most +`#(rosserSet lower y w)`. -/ +theorem card_filter_succ_le (n : ℕ) (lower : Bool) (y z w : ℝ) : + (#((rosserSet lower y z).filter fun d ↦ #d.primeFactors ≤ n + 1) : ℝ) ≤ + #(rosserSet lower y w) + ∑ p ∈ (rosserPrimes lower y z).filter (fun p : ℕ ↦ w ≤ p), + (#((rosserSet (!lower) (y / p) p).filter fun d ↦ #d.primeFactors ≤ n) : ℝ) := by + rw [card_filter_rosserSet_succ, ← sum_filter_add_sum_filter_not (rosserPrimes lower y z) + (fun p : ℕ ↦ (p : ℝ) < w)] + push_cast + have hsub : (rosserPrimes lower y z).filter (fun p : ℕ ↦ (p : ℝ) < w) ⊆ + rosserPrimes lower y w := fun p hp ↦ by + rw [mem_filter, mem_rosserPrimes, mem_primesLT] at hp + rw [mem_rosserPrimes, mem_primesLT] + exact ⟨⟨hp.1.1.1, hp.2⟩, hp.1.2⟩ + have h1 : (1 : ℝ) + ∑ p ∈ (rosserPrimes lower y z).filter (fun p : ℕ ↦ (p : ℝ) < w), + (#((rosserSet (!lower) (y / p) p).filter fun d ↦ #d.primeFactors ≤ n) : ℝ) ≤ + #(rosserSet lower y w) := by + calc _ ≤ (1 : ℝ) + ∑ p ∈ rosserPrimes lower y w, + (#((rosserSet (!lower) (y / p) p).filter fun d ↦ #d.primeFactors ≤ n) : ℝ) := by + gcongr + _ = (#((rosserSet lower y w).filter fun d ↦ #d.primeFactors ≤ n + 1) : ℝ) := by + rw [card_filter_rosserSet_succ, Nat.cast_add, Nat.cast_one, Nat.cast_sum] + _ ≤ #(rosserSet lower y w) := by exact_mod_cast card_filter_le _ _ + have h2 : (rosserPrimes lower y z).filter (fun p : ℕ ↦ ¬ (p : ℝ) < w) = + (rosserPrimes lower y z).filter (fun p : ℕ ↦ w ≤ p) := + filter_congr fun p _ ↦ not_lt + rw [h2] + linarith + +theorem card_primesLT_le {w : ℝ} (hw : 0 ≤ w) : (#(primesLT w) : ℝ) ≤ w + 1 := by + have h : #(primesLT w) ≤ ⌈w⌉₊ := by + unfold primesLT Nat.primesBelow + exact (card_filter_le _ _).trans (card_range _).le + exact (Nat.cast_le.2 h).trans (Nat.ceil_lt_add_one hw).le + +/-- Elements with at most `K` prime factors: at most `(K + 1) (2w)^K` of them (`w ≥ 1`). -/ +theorem card_filter_le_le (lower : Bool) (y : ℝ) {w : ℝ} (hw : 1 ≤ w) (K : ℕ) : + (#((rosserSet lower y w).filter fun d ↦ #d.primeFactors ≤ K) : ℝ) ≤ + (K + 1) * (2 * w) ^ K := by + set D := (rosserSet lower y w).filter fun d ↦ #d.primeFactors ≤ K + have hmaps : Set.MapsTo (fun d ↦ #d.primeFactors) (D : Set ℕ) (range (K + 1)) := by + intro d hd + simp only [coe_filter, Set.mem_ofPred_eq, D] at hd + simpa [Nat.lt_succ_iff] using hd.2 + rw [card_eq_sum_card_fiberwise hmaps] + push_cast + have hπ : (#(primesLT w) : ℝ) ≤ 2 * w := by linarith [card_primesLT_le (by linarith : 0 ≤ w)] + calc ∑ l ∈ range (K + 1), (#(D.filter fun d ↦ #d.primeFactors = l) : ℝ) + ≤ ∑ l ∈ range (K + 1), (2 * w) ^ K := by + refine sum_le_sum fun l hl ↦ ?_ + have hlK : l ≤ K := Nat.lt_succ_iff.1 (mem_range.1 hl) + have h1 : (#(D.filter fun d ↦ #d.primeFactors = l) : ℝ) ≤ + #((rosserSet lower y w).filter fun d ↦ #d.primeFactors = l) := by + exact_mod_cast card_le_card (filter_subset_filter _ (filter_subset _ _)) + refine h1.trans ((card_filter_eq_le_pow_div lower y w l).trans ?_) + have hf : (1 : ℝ) ≤ l.factorial := by exact_mod_cast l.factorial_pos + calc (#(primesLT w) : ℝ) ^ l / l.factorial ≤ (#(primesLT w) : ℝ) ^ l := + div_le_self (by positivity) hf + _ ≤ (2 * w) ^ l := by gcongr + _ ≤ (2 * w) ^ K := pow_le_pow_right₀ (by linarith) hlK + _ = (K + 1) * (2 * w) ^ K := by simp + +/-- The cutoff `u = ξ(1 - 2/λ)` leaves a saving of `1/λ` in the exponent of `w`. -/ +theorem count_cutoff_ratio_le {ξ m : ℝ} (hm : 0 < m) (hξ : 1 < ξ) (hmξ : m ≤ ξ) : + ξ * (1 - 2 / m) / (ξ - 1) ≤ 1 - 1 / m := by + rw [div_le_iff₀ (sub_pos.2 hξ)] + have hratio : 1 ≤ ξ / m := (le_div_iff₀ hm).2 (by simpa using hmξ) + have hinv : 0 ≤ 1 / m := by positivity + calc ξ * (1 - 2 / m) = ξ - 2 * (ξ / m) := by ring + _ ≤ ξ - ξ / m - 1 + 1 / m := by linarith only [hratio, hinv] + _ = (1 - 1 / m) * (ξ - 1) := by ring + +/-- Replacing `ξ` by the cutoff `u = ξ(1 - 2/λ)` loses at most `3ξ` in `u log u`. -/ +theorem mul_log_count_cutoff_ge {ξ m : ℝ} (hm : 2 < m) (hξ : 0 < ξ) (hlogξ : log ξ ≤ m) : + ξ * log ξ - 3 * ξ ≤ (ξ * (1 - 2 / m)) * log (ξ * (1 - 2 / m)) := by + have hm0 : 0 < m := by linarith only [hm] + set v := 1 - 2 / m with hv + have hv0 : 0 < v := by + have : 2 / m < 1 := (div_lt_one hm0).2 hm + dsimp [v] + linarith only [this] + have hlogv : -1 ≤ v * log v := by + have h := mul_le_mul_of_nonneg_left (neg_inv_le_log hv0.le) hv0.le + simpa only [mul_neg, mul_inv_cancel₀ hv0.ne'] using h + have hlog_loss : 2 / m * log ξ ≤ 2 := by + rw [div_mul_eq_mul_div, div_le_iff₀ hm0] + linarith only [hlogξ] + have hweighted_loss := mul_le_mul_of_nonneg_left hlog_loss hξ.le + have hweighted_logv := mul_le_mul_of_nonneg_left hlogv hξ.le + calc ξ * log ξ - 3 * ξ + ≤ ξ * log ξ - ξ * (2 / m * log ξ) + ξ * (v * log v) := by + linarith only [hweighted_loss, hweighted_logv] + _ = (ξ * v) * log (ξ * v) := by rw [log_mul hξ.ne' hv0.ne', hv]; ring + +/-- The crude count of `rosserSet lower y w` for `w = y^{1/(ξ-1)}`, `ξ = xi y`, `λ = lam y` +([I71, p. 27]): +`#(rosserSet lower y w) ≤ e^{L + 2ξ - L/λ} + 2 e^{L - ξ log ξ + ξ log λ + 5ξ}`. -/ +theorem card_rosserSet_rpow_le (hy : 1 < y) (hw : 2 ≤ y ^ (1 / (xi y - 1))) + (hSLT : SLT (y ^ (1 / (xi y - 1))) ≤ 2 * lam y) (hlam : 100 ≤ lam y) + (h24 : 24 * lam y ≤ xi y) (hlogξ : log (xi y) ≤ lam y) : + (#(rosserSet lower y (y ^ (1 / (xi y - 1)))) : ℝ) ≤ + exp (log y + 2 * xi y - log y / lam y) + + 2 * exp (log y - xi y * log (xi y) + xi y * log (lam y) + 5 * xi y) := by + set L := log y with hL + set ξ := xi y + set m := lam y + set w := y ^ (1 / (ξ - 1)) with hwdef + have hL0 : 0 < L := log_pos hy + have hm0 : 0 < m := by linarith only [hlam] + have hξ1 : 1 < ξ := by linarith only [h24, hlam] + set u := ξ * (1 - 2 / m) with hu + have hv : 1 / 2 ≤ 1 - 2 / m := by + have : 2 / m ≤ 1 / 2 := by rw [div_le_iff₀ hm0]; linarith only [hlam] + linarith only [this] + have hv1 : 1 - 2 / m ≤ 1 := sub_le_self _ (by positivity) + have hu2 : ξ / 2 ≤ u := by + have h := mul_le_mul_of_nonneg_left hv (by linarith only [hξ1] : 0 ≤ ξ) + dsimp [u] + linarith only [h] + have huξ : u ≤ ξ := by + simpa only [mul_one] using + mul_le_mul_of_nonneg_left hv1 (by linarith only [hξ1] : 0 ≤ ξ) + have hu0 : 0 < u := by linarith only [hu2, hξ1] + set K := ⌊u⌋₊ with hK + have hKu : (K : ℝ) ≤ u := Nat.floor_le hu0.le + have huK : u < K + 1 := Nat.lt_floor_add_one u + have hK1 : 1 ≤ K := by + rw [hK, Nat.one_le_floor_iff] + linarith only [hu2, h24, hlam] + rw [← card_filter_add_card_filter_not (fun d ↦ #d.primeFactors ≤ K)] + push_cast + gcongr + · -- Few prime factors: bound the three factors `K + 1`, `2^u`, and `w^u`. + refine (card_filter_le_le lower y (by linarith only [hw]) K).trans ?_ + have h2w : 1 ≤ 2 * w := by linarith only [hw] + have hcount_factor : (K : ℝ) + 1 ≤ exp ξ := by + linarith only [hKu, huξ, add_one_le_exp ξ] + have htwo_power : (2 : ℝ) ^ u ≤ exp ξ := by + rw [rpow_def_of_pos (by norm_num), exp_le_exp] + have hlogtwo : log 2 ≤ 1 := by linarith only [log_le_sub_one_of_pos two_pos] + calc log 2 * u ≤ 1 * u := mul_le_mul_of_nonneg_right hlogtwo hu0.le + _ ≤ ξ := by simpa only [one_mul] using huξ + have hcutoff_power : w ^ u ≤ exp (L - L / m) := by + have hratio : u / (ξ - 1) ≤ 1 - 1 / m := + count_cutoff_ratio_le hm0 hξ1 (by linarith only [h24, hlam]) + rw [hwdef, ← rpow_mul (by linarith only [hy]), + rpow_def_of_pos (by linarith only [hy]), exp_le_exp, ← hL] + calc L * (1 / (ξ - 1) * u) = L * (u / (ξ - 1)) := by ring + _ ≤ L * (1 - 1 / m) := mul_le_mul_of_nonneg_left hratio hL0.le + _ = L - L / m := by ring + have hpower : (2 * w) ^ K ≤ exp ξ * exp (L - L / m) := by + rw [← rpow_natCast] + calc (2 * w) ^ (K : ℝ) ≤ (2 * w) ^ u := rpow_le_rpow_of_exponent_le h2w hKu + _ = 2 ^ u * w ^ u := mul_rpow (by norm_num) (by linarith only [hw]) + _ ≤ exp ξ * exp (L - L / m) := + mul_le_mul htwo_power hcutoff_power (by positivity) (exp_pos _).le + calc ((K : ℝ) + 1) * (2 * w) ^ K ≤ exp ξ * (exp ξ * exp (L - L / m)) := + mul_le_mul hcount_factor hpower (by positivity) (exp_pos _).le + _ = exp (L + 2 * ξ - L / m) := by rw [← exp_add, ← exp_add]; ring_nf + · -- Many prime factors: apply the tail bound and compare its exponent. + have hfilt : ((rosserSet lower y w).filter fun d ↦ ¬ #d.primeFactors ≤ K) = + (rosserSet lower y w).filter fun d ↦ K + 1 ≤ #d.primeFactors := + filter_congr fun d _ ↦ by omega + rw [hfilt] + have hX : 2 * exp 1 * (2 * m) ≤ u := by + have he : exp 1 ≤ 3 := by linarith only [exp_one_lt_d9] + calc 2 * exp 1 * (2 * m) ≤ 2 * 3 * (2 * m) := by gcongr + _ ≤ ξ / 2 := by linarith only [h24] + _ ≤ u := hu2 + refine (card_filter_le_tail (by linarith only [hy]) (by split_ifs <;> omega) hu0 + (by exact_mod_cast huK) hSLT hX).trans ?_ + rw [exp_one_mul_div_rpow (by positivity) hu0] + have hy' : y = exp L := (exp_log (by linarith only [hy])).symm + rw [hy', mul_assoc, ← exp_add] + refine mul_le_mul_of_nonneg_left (exp_le_exp.2 ?_) (by norm_num) + have hulog : ξ * log ξ - 3 * ξ ≤ u * log u := + mul_log_count_cutoff_ge (by linarith only [hlam]) (by linarith only [hξ1]) hlogξ + have hlog2m : log (2 * m) ≤ 1 + log m := by + rw [log_mul two_pos.ne' hm0.ne'] + linarith only [log_le_sub_one_of_pos two_pos] + have hweighted_log : u * log (2 * m) ≤ ξ * (1 + log m) := by + have h0 : 0 ≤ log (2 * m) := log_nonneg (by linarith only [hlam]) + calc u * log (2 * m) ≤ ξ * log (2 * m) := mul_le_mul_of_nonneg_right huξ h0 + _ ≤ ξ * (1 + log m) := + mul_le_mul_of_nonneg_left hlog2m (by linarith only [hξ1]) + linarith only [hulog, hweighted_log, huξ] + +/-! ### The comparison (4.9), (4.10) -/ +theorem one_le_of_sMin_le (hs : sMin lower ≤ s) : 1 ≤ s := by + cases lower <;> simp [sMin] at hs <;> linarith + +theorem one_le_delta (hs : 1 ≤ s) (y : ℝ) : 1 ≤ delta s y := + one_le_rpow (by linarith [lsx_nonneg (log y) hs]) (by linarith) + +/-- For `s ≥ ξ/2` and `log s ≥ λ/2`, the growth of `δ` supplies the factor +`exp (s (3 log λ - 5 log 128))` in [I71, (4.10)]. -/ +theorem exp_le_delta_of_half_le (hy : 1 < y) (hs : xi y / 2 ≤ s) + (hlogs : lam y / 2 ≤ log s) : + exp (s * (3 * log (lam y) - 5 * log 128)) ≤ delta s y := by + set L := log y + set ξ := xi y + set m := lam y + have hL0 : 0 < L := log_pos hy + have hξ0 : 0 < ξ := xi_pos hy + have hm0 : 0 < m := lam_pos hy + have hs0 : 0 ≤ s := by linarith only [hs, hξ0] + set a₀ := ξ ^ 2 * m ^ 5 / (128 * L ^ 2) with ha₀ + have ha₀0 : 0 < a₀ := by positivity + -- The factors `s²` and `log⁵ s` contribute `ξ² λ⁵ / 128`. + have hx : a₀ ≤ s ^ 2 * log s ^ 5 / L ^ 2 := by + calc a₀ = (ξ / 2) ^ 2 * (m / 2) ^ 5 / L ^ 2 := by rw [ha₀]; ring + _ ≤ s ^ 2 * log s ^ 5 / L ^ 2 := by gcongr + have hloga₀ : 5 * log a₀ = 3 * log m - 5 * log 128 := by + rw [ha₀, log_div (by positivity) (by positivity), log_mul (by positivity) (by positivity), + log_mul (by norm_num) (by positivity), log_pow, log_pow, log_pow, log_xi_eq hy] + push_cast + ring + calc exp (s * (3 * log m - 5 * log 128)) = a₀ ^ (5 * s) := by + rw [rpow_def_of_pos ha₀0, ← hloga₀] + ring_nf + _ ≤ (1 + s ^ 2 * log s ^ 5 / L ^ 2) ^ (5 * s) := + rpow_le_rpow ha₀0.le (by linarith only [hx]) (by positivity) + _ = delta s y := rfl + +/-- [I71, (4.9), (4.10)] in the form needed for Theorem 5: for `sMin lower ≤ s ≤ ξ`, +`exp(-ξ log ξ + (3/2) ξ log λ) ≤ δ(s, y) G(s)`, given the lower bound of Lemma 9 with constant +`c_G ≥ 0` and the scalar facts of `eventually_scalar`. For `s ≤ ξ/2` this uses Lemma 9 only; for +`s > ξ/2` it uses `δ(s, y) ≥ (s² log⁵ s / L²)^{5s} ≥ λ^{3s} 128^{-5s}`. -/ +theorem exp_le_delta_errMaj {cG : ℝ} (hcG : 0 ≤ cG) + (hG : ∀ (r : ℕ) (s : ℝ), 3 ≤ s → exp (-(s * log s) - s * log (log s) - cG * s) ≤ majG r s) + (hy : 1 < y) (h2 : 2 * (cG + 5 * log 128) ≤ log (lam y)) (h6 : 6 ≤ xi y) + (h8 : lam y / 2 ≤ log (xi y / 2)) (h9 : 4 * log (lam y) + cG ≤ log (xi y)) + (h10 : log (xi y) ≤ lam y) (lower : Bool) (hs : sMin lower ≤ s) (hsξ : s ≤ xi y) : + exp (-(xi y * log (xi y)) + 3 / 2 * xi y * log (lam y)) ≤ delta s y * errMaj lower s := by + set ξ := xi y + set a := log (lam y) + have h128 : 0 ≤ log 128 := log_nonneg (by norm_num) + have ha0 : 0 ≤ a := by linarith only [h2, hcG, h128] + have hs1 := one_le_of_sMin_le hs + have hδ1 := one_le_delta hs1 y + have hGl : ∀ t ≥ 3, exp (-(t * log t) - t * log (log t) - cG * t) ≤ errMaj lower t := by + intro t ht; rw [errMaj_eq_majG_succ]; exact hG _ t ht + have hll : ∀ t, 3 ≤ t → t ≤ ξ → log (log t) ≤ a := fun t ht htξ ↦ + log_le_log (log_pos (by linarith only [ht])) + ((log_le_log (by linarith only [ht]) htξ).trans h10) + rcases le_or_gt s (ξ / 2) with hsh | hsh + · -- `s ≤ ξ/2`: Lemma 9 at `s' = max s 3` + set s' := max s 3 + have hs'3 : 3 ≤ s' := le_max_right _ _ + have hs'h : s' ≤ ξ / 2 := max_le hsh (by linarith only [h6]) + have hGs : errMaj lower s' ≤ errMaj lower s := errMaj_antitone lower (le_max_left _ _) + have hl0 : 0 ≤ log s' := log_nonneg (by linarith only [hs'3]) + have hl1 : log s' ≤ log ξ := + log_le_log (by linarith only [hs'3]) (by linarith only [hs'h, h6]) + have hll' := hll s' hs'3 (by linarith only [hs'h, h6]) + have hmain_loss : s' * log s' ≤ ξ / 2 * log ξ := + mul_le_mul hs'h hl1 hl0 (by linarith only [h6]) + have hloglog_loss : s' * log (log s') ≤ ξ / 2 * a := + (mul_le_mul_of_nonneg_left hll' (by linarith only [hs'3])).trans + (mul_le_mul_of_nonneg_right hs'h ha0) + have hconstant_loss : cG * s' ≤ cG * (ξ / 2) := mul_le_mul_of_nonneg_left hs'h hcG + have hmargin : 0 ≤ ξ / 2 * (log ξ - 4 * a - cG) := + mul_nonneg (by linarith only [h6]) (by linarith only [h9]) + have hhalf_exponent : -(ξ * log ξ) + 3 / 2 * ξ * a ≤ + -(s' * log s') - s' * log (log s') - cG * s' := by + linarith only [hmain_loss, hloglog_loss, hconstant_loss, hmargin] + calc exp (-(ξ * log ξ) + 3 / 2 * ξ * a) + ≤ exp (-(s' * log s') - s' * log (log s') - cG * s') := exp_le_exp.2 hhalf_exponent + _ ≤ errMaj lower s' := hGl s' hs'3 + _ ≤ errMaj lower s := hGs + _ = 1 * errMaj lower s := (one_mul _).symm + _ ≤ delta s y * errMaj lower s := + mul_le_mul_of_nonneg_right hδ1 (errMaj_pos lower s).le + · -- `s > ξ/2`: the growth of `δ` + have hs3 : 3 ≤ s := by linarith only [hsh, h6] + have hs0 : 0 ≤ s := by linarith only [hs3] + have hlogs : lam y / 2 ≤ log s := + h8.trans (log_le_log (by linarith only [h6]) hsh.le) + have hδ := exp_le_delta_of_half_le hy hsh.le hlogs + have hGs : exp (-(s * log s) - s * a - cG * s) ≤ errMaj lower s := by + refine le_trans (exp_le_exp.2 ?_) (hGl s hs3) + have hloglog_loss := mul_le_mul_of_nonneg_left (hll s hs3 hsξ) hs0 + linarith only [hloglog_loss] + set c₁ := cG + 5 * log 128 with hc₁ + -- Compare the combined loss at `s` with its value at `ξ`. + have hendpoint : 0 ≤ log ξ - 2 * a + c₁ := by + dsimp [c₁] + linarith only [h9, ha0, hcG, h128] + have hcombined_loss : s * (log s - 2 * a + c₁) ≤ ξ * (log ξ - 2 * a + c₁) := by + have hlog : log s ≤ log ξ := log_le_log (by linarith only [hs3]) hsξ + calc s * (log s - 2 * a + c₁) ≤ s * (log ξ - 2 * a + c₁) := + mul_le_mul_of_nonneg_left (by linarith only [hlog]) hs0 + _ ≤ ξ * (log ξ - 2 * a + c₁) := mul_le_mul_of_nonneg_right hsξ hendpoint + have hconstant_margin : ξ * (2 * c₁) ≤ ξ * a := + mul_le_mul_of_nonneg_left h2 (by linarith only [h6]) + have hfull_exponent : -(ξ * log ξ) + 3 / 2 * ξ * a ≤ + s * (3 * a - 5 * log 128) + (-(s * log s) - s * a - cG * s) := by + rw [hc₁] at hcombined_loss hconstant_margin + linarith only [hcombined_loss, hconstant_margin] + calc exp (-(ξ * log ξ) + 3 / 2 * ξ * a) + ≤ exp (s * (3 * a - 5 * log 128) + (-(s * log s) - s * a - cG * s)) := + exp_le_exp.2 hfull_exponent + _ = exp (s * (3 * a - 5 * log 128)) * exp (-(s * log s) - s * a - cG * s) := exp_add _ _ + _ ≤ delta s y * errMaj lower s := + mul_le_mul hδ hGs (exp_pos _).le (delta_pos hs1 y).le + +/-- [I71, p. 27]: for large `y`, `sMin lower ≤ s ≤ ξ` and `w = y^{1/(ξ - 1)}`, +`1 + #(rosserSet lower y w) ≤ δ(s, y) G(s) y / (8 L⁴)`. -/ +theorem exists_card_small : ∃ y₀ : ℝ, ∀ y ≥ y₀, ∀ (lower : Bool) (s : ℝ), sMin lower ≤ s → + s ≤ xi y → 1 + (#(rosserSet lower y (y ^ (1 / (xi y - 1)))) : ℝ) ≤ + delta s y * errMaj lower s * y / (8 * log y ^ 4) := by + obtain ⟨cG₀, hG₀⟩ := majG_ge_exp + set cG := max cG₀ 0 with hcG + have hcG0 : 0 ≤ cG := le_max_right _ _ + have hG : ∀ (r : ℕ) (s : ℝ), 3 ≤ s → + exp (-(s * log s) - s * log (log s) - cG * s) ≤ majG r s := by + intro r s hs + refine le_trans (exp_le_exp.2 ?_) (hG₀ r s hs) + have : cG₀ * s ≤ cG * s := mul_le_mul_of_nonneg_right (le_max_left _ _) (by linarith) + linarith + obtain ⟨C₅, hC₅⟩ := SLT_le_loglog + obtain ⟨y₁, hy₁⟩ := exists_xi_large + set c := max 100 (max (2 * (cG + 5 * log 128)) (max cG (max C₅ 12))) with hc + have hc1 := le_max_left 100 (max (2 * (cG + 5 * log 128)) (max cG (max C₅ 12))) + have hc2 := le_max_right 100 (max (2 * (cG + 5 * log 128)) (max cG (max C₅ 12))) + have hc3 := le_max_left (2 * (cG + 5 * log 128)) (max cG (max C₅ 12)) + have hc4 := le_max_right (2 * (cG + 5 * log 128)) (max cG (max C₅ 12)) + have hc5 := le_max_left cG (max C₅ 12) + have hc6 := le_max_right cG (max C₅ 12) + have hc7 := le_max_left C₅ 12 + have hc8 := le_max_right C₅ 12 + obtain ⟨y₀, hy₀⟩ := eventually_atTop.1 + ((eventually_scalar c hc1).and (eventually_ge_atTop y₁)) + refine ⟨y₀, fun y hy lower s hs hsξ ↦ ?_⟩ + obtain ⟨⟨hy3, ha, hμ, hlam, hℓ1, -, h24, h16, h8, h9, h10⟩, hyy₁⟩ := hy₀ y hy + obtain ⟨hy1, -, -, hw2⟩ := hy₁ y hyy₁ + have hL0 : 0 < log y := log_pos hy1 + have hm0 := lam_pos hy1 + have hξ := xi_pos hy1 + -- `w = y^{1/(ξ-1)}` + have hξ1 : 0 < xi y - 1 := by linarith + have hw : 2 ≤ y ^ (1 / (xi y - 1)) := + hw2.trans (rpow_one_div_le_rpow_one_div hy1.le hξ1 (by linarith)) + have hwy : y ^ (1 / (xi y - 1)) ≤ y := by + conv_rhs => rw [← rpow_one y] + exact rpow_le_rpow_of_exponent_le hy1.le (by rw [div_le_one hξ1]; linarith) + have hSLT : SLT (y ^ (1 / (xi y - 1))) ≤ 2 * lam y := by + have h1 := hC₅ _ hw + have h2 : log (log (y ^ (1 / (xi y - 1)))) ≤ log (log y) := + log_le_log (log_pos (by linarith)) (log_le_log (by linarith) hwy) + linarith + have hcard := card_rosserSet_rpow_le (lower := lower) hy1 hw hSLT (by linarith) h24 h10 + -- `4 ξ λ² ≤ L` + have hxl : 4 * (xi y * lam y ^ 2) ≤ log y := by + have hsplit : lam y ^ (11 / 5 : ℝ) = lam y ^ 2 * lam y ^ (1 / 5 : ℝ) := by + rw [← rpow_natCast, ← rpow_add hm0]; norm_num + rw [xi_eq_lam, hsplit] + have hμ0 : 0 < lam y ^ (1 / 5 : ℝ) := rpow_pos_of_pos hm0 _ + rw [div_mul_eq_mul_div, mul_div_assoc', div_le_iff₀ (by positivity)] + have : 4 ≤ lam y ^ (1 / 5 : ℝ) := by linarith + nlinarith [mul_pos hL0 (pow_pos hm0 2)] + have hcrude := crude_exponent_le hL0 rfl hℓ1 (by linarith) (a := log (lam y)) (by linarith) + hxl h24 h16 h10 + have hB := exp_le_delta_errMaj hcG0 hG hy1 (by linarith) (by linarith) h8 (by linarith) h10 + lower hs hsξ + have hy' : exp (log y - xi y * log (xi y) + 3 / 2 * xi y * log (lam y)) = + y * exp (-(xi y * log (xi y)) + 3 / 2 * xi y * log (lam y)) := by + rw [← exp_log (by linarith : 0 < y), ← exp_add, exp_log (by linarith)]; ring_nf + rw [le_div_iff₀ (by positivity)] + calc (1 + (#(rosserSet lower y (y ^ (1 / (xi y - 1)))) : ℝ)) * (8 * log y ^ 4) + ≤ 8 * log y ^ 4 * (1 + exp (log y + 2 * xi y - log y / lam y) + + 2 * exp (log y - xi y * log (xi y) + xi y * log (lam y) + 5 * xi y)) := by + nlinarith [pow_pos hL0 4] + _ ≤ y * exp (-(xi y * log (xi y)) + 3 / 2 * xi y * log (lam y)) := hcrude.trans hy'.le + _ ≤ y * (delta s y * errMaj lower s) := by gcongr + _ = delta s y * errMaj lower s * y := by ring + +end IwaniecLinearSieve.TheoremFive diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFour.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFour.lean new file mode 100644 index 000000000..873edd18f --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFour.lean @@ -0,0 +1,601 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFourAux +public import LeanPool.IwaniecLinearSieve.PrimeSums.Product +import LeanPool.IwaniecLinearSieve.LinearSieve.Corollaries +import LeanPool.IwaniecLinearSieve.LinearSieve.Crude +import LeanPool.IwaniecLinearSieve.LinearSieve.Depth +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaEleven +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaSeven +import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFourAsymp +import LeanPool.IwaniecLinearSieve.SieveMajorants.Lemmas +import LeanPool.IwaniecLinearSieve.SieveMajorants.Properties +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds +import Std.Tactic.BVDecide.Normalize.Bool + +/-! +# [I71, Theorem 4] + +With `L = log y`, `z = y^{1/s}`, `ξ = ξ(y)`, `cR` the constant of `R_asymp`, there is `c₇` with + fail lower r y z ≤ cR (M(s)/L + c₇ r/(r+1) δ(s, y) G(s)/L²) + +for all `r`, `y > 1`, `sMin lower ≤ s ≤ ξ(y)`. + +The proof is by induction on `r` (for both sieves at once), as in [I71, pp. 23–25]: + +* small `y` (`y < y₀`): the crude bound `fail ≤ exp (SLT y₀)` ([I71, (4.8)]); +* `r + 2 > 2 L / log L`: the recursion has stabilised, `fail (r+1) = fail r`; +* otherwise split the prime sum at `w = y^{1/ξ}` (`fail_succ_le_split`). For `p ≥ w` the inner + level `(y/p, t_p - 1)` is in range (`inner_le_xi`), and the induction hypothesis, Corollary 1 + and Corollary 3 give the main term and `r/(r+1)` times the error term; the primes `p < w` are + `fail (r+1) y w`, bounded crudely. The losses are absorbed by + `(r+1)/(r+2) - r/(r+1) ≥ (r+1)/(r+2) · (log L)²/(4L²)`, as in [I71, (4.6)]. + +Compared with [I71] we split at `y^{1/ξ}` instead of `y^{1/(ξ-1)}` (then `t_p - 1 ≤ ξ(y/p)` +holds exactly), use `SLT(w) ≤ log log w + C` in the crude bound, and the upper-sieve source term +`∑_{y^{1/3} ≤ p < z} R(p)/p = R(y^{1/3}) - R(z)` replaces [I71, Lemmas 14, 16]. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory Finset + +namespace IwaniecLinearSieve.TheoremFour + +/-- Theorem 4 at depth `r` with constants `cR`, `c₇`. -/ +def Bound (cR c₇ : ℝ) (r : ℕ) : Prop := + ∀ (lower : Bool) (y s : ℝ), 1 < y → sMin lower ≤ s → s ≤ xi y → + fail lower r y (y ^ (1 / s)) ≤ + cR * (mainMaj lower s / log y + + c₇ * ((r : ℝ) / (r + 1)) * delta s y * errMaj lower s / log y ^ 2) + +theorem one_le_sMin (lower : Bool) : 1 ≤ sMin lower := by + cases lower <;> norm_num [sMin] + +/-! ### The large primes: induction hypothesis, Corollaries 1 and 3 -/ + +/-- The induction hypothesis at the inner level `(y/p, t_p - 1)`, divided by `p`. -/ +theorem ih_term {cR c₇ : ℝ} {r : ℕ} (IH : Bound cR c₇ r) {lower : Bool} {y s : ℝ} {p : ℕ} + (hy : 1 < y) (hs : sMin lower ≤ s) (hp : p ∈ rosserPrimes lower y (y ^ (1 / s))) + (hw : y ^ (1 / xi y) ≤ p) : + fail (!lower) r (y / p) p / p ≤ + cR * (mainMaj (!lower) (log y / log p - 1) / (p * log (y / p))) + + cR * c₇ * ((r : ℝ) / (r + 1)) * (delta (log y / log p - 1) (y / p) * + errMaj (!lower) (log y / log p - 1) / (p * log (y / p) ^ 2)) := by + have hs1 : 1 ≤ s := (one_le_sMin lower).trans hs + have hpy := prime_lt_of_mem_rosserPrimes hy hs1 hp + have hp1 := (prime_of_mem_primesLT (rosserPrimes_subset hp)).one_lt + have hp0 : (0 : ℝ) < p := by positivity + have hyp : 1 < y / p := by rw [one_lt_div hp0]; exact hpy + have h := IH (!lower) (y / p) (log y / log p - 1) hyp (sMin_le_inner hy hs hp) + (inner_le_xi hy hp1 hpy hw) + rw [rpow_inner_eq hp1 hpy] at h + refine (div_le_div_of_nonneg_right h hp0.le).trans_eq ?_ + field_simp + +theorem sum_ih_le {cR c₇ : ℝ} {r : ℕ} (IH : Bound cR c₇ r) {lower : Bool} {y s : ℝ} + (hy : 1 < y) (hs : sMin lower ≤ s) : + ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p), + fail (!lower) r (y / p) p / p ≤ + cR * ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p), + mainMaj (!lower) (log y / log p - 1) / (p * log (y / p)) + + cR * c₇ * ((r : ℝ) / (r + 1)) * + ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p), + delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) := by + rw [mul_sum, mul_sum, ← sum_add_distrib] + refine sum_le_sum fun p hp => ?_ + rw [mem_filter] at hp + exact ih_term IH hy hs hp.1 hp.2 + +theorem intervalIntegral_le_integral_Ioi {f : ℝ → ℝ} {a b : ℝ} (hab : a ≤ b) + (hf : IntegrableOn f (Ioi a)) (hf0 : ∀ t ∈ Ioi a, 0 ≤ f t) : + ∫ t in a..b, f t ≤ ∫ t in Ioi a, f t := by + rw [intervalIntegral.integral_of_le hab] + exact setIntegral_mono_set hf (ae_restrict_of_forall_mem measurableSet_Ioi hf0) + Ioc_subset_Ioi_self.eventuallyLE + +/-- Corollary 1 for the large primes: the main terms of the inner levels add up to `M(s)/L` +(minus the source part `(3 - s)⁺/L` of the upper sieve), up to `O(s² G(s) pntE(w)/L)`. -/ +theorem cor1_part : ∃ C, 0 ≤ C ∧ ∀ (lower : Bool) (y s : ℝ), 1 < y → sMin lower ≤ s → + s ≤ xi y → 3 ≤ xi y → 2 ≤ y ^ (1 / xi y) → + ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p), + mainMaj (!lower) (log y / log p - 1) / (p * log (y / p)) ≤ + (mainMaj lower s - (if lower then 0 else max (3 - s) 0)) / log y + + C * s ^ 2 * errMaj lower s * pntE (y ^ (1 / xi y)) / log y := by + obtain ⟨C, hC0, hC⟩ := cor1_le + refine ⟨432 * C, by positivity, fun lower y s hy hs hsξ hξ3 hw2 => ?_⟩ + have hL : 0 < log y := log_pos hy + have hs1 : 1 ≤ s := (one_le_sMin lower).trans hs + have hpE := pntE_pos (y ^ (1 / xi y)) + cases lower + · -- upper sieve: `α = max s 3`, `M = f` + simp only [Bool.not_false, mainMaj_true, Bool.false_eq_true, ite_false] + have hset : (rosserPrimes false y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p) = + (primesLT (y ^ (1 / max s 3))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p) := by + ext p + simp only [mem_filter, mem_rosserPrimes, mem_primesLT, Bool.false_eq_true, false_or] + rw [lt_rpow_one_div_max_three hy (by linarith) (Nat.cast_nonneg p)] + tauto + rw [hset] + have hα : max s 3 ≤ xi y := max_le hsξ hξ3 + have h := hC fSieve y (max s 3) (xi y) hy (by linarith [le_max_right s 3]) hα hw2 + (fSieve_antitone.antitoneOn _) (fun t _ => (fSieve_pos t).le) + refine h.trans (add_le_add ?_ ?_) + · have hint := intervalIntegral_le_integral_Ioi hα + (integrableOn_fSieve_shift (le_max_right s 3)) + (fun t ht => div_nonneg (fSieve_pos _).le (by linarith [ht.out, le_max_right s 3])) + have heq := mainMaj_false_eq_integral s + exact div_le_div_of_nonneg_right (by linarith) hL.le + · have h1 := mainMaj_sub_one_le true false (by linarith [le_max_right s 3] : 1 ≤ max s 3) + rw [mainMaj_true] at h1 + have hG : errMaj false (max s 3) = errMaj false s := by + rcases le_total s 3 with h | h + · rw [max_eq_right h, errMaj_false_of_le_three le_rfl, errMaj_false_of_le_three h] + · rw [max_eq_left h] + rw [hG] at h1 + have hsq : max s 3 ^ 2 ≤ 9 * s ^ 2 := by + rcases le_total s 3 with h | h + · rw [max_eq_right h]; nlinarith + · rw [max_eq_left h]; nlinarith + have hGs := errMaj_pos false s + have : fSieve (max s 3 - 1) ≤ 432 * s ^ 2 * errMaj false s := by nlinarith + apply div_le_div_of_nonneg_right _ hL.le + calc C * fSieve (max s 3 - 1) * pntE (y ^ (1 / xi y)) + ≤ C * (432 * s ^ 2 * errMaj false s) * pntE (y ^ (1 / xi y)) := by gcongr + _ = 432 * C * s ^ 2 * errMaj false s * pntE (y ^ (1 / xi y)) := by ring + · -- lower sieve: `α = s`, `M = F + (3 - s)⁺` + simp only [Bool.not_true, rosserPrimes_true, ite_true, sub_zero] + have hs2 : (2 : ℝ) ≤ s := hs + have h := hC (mainMaj false) y s (xi y) hy hs2 hsξ hw2 + ((mainMaj_antitone false).antitoneOn _) (fun t _ => mainMaj_nonneg false t) + refine h.trans (add_le_add ?_ ?_) + · have hint := intervalIntegral_le_integral_Ioi hsξ (integrableOn_mainMaj_false_shift hs2) + (fun t ht => div_nonneg (mainMaj_nonneg _ _) (by linarith [ht.out])) + rw [mainMaj_true, fSieve_eq_integral_mainMaj hs2] + exact div_le_div_of_nonneg_right hint hL.le + · have h1 := mainMaj_sub_one_le false true hs1 + have hGs := errMaj_pos true s + apply div_le_div_of_nonneg_right _ hL.le + calc C * mainMaj false (s - 1) * pntE (y ^ (1 / xi y)) + ≤ C * (432 * s ^ 2 * errMaj true s) * pntE (y ^ (1 / xi y)) := by + gcongr; nlinarith + _ = 432 * C * s ^ 2 * errMaj true s * pntE (y ^ (1 / xi y)) := by ring + +/-- The source term in the form needed for the induction. -/ +theorem src_le_of_le_xi {cR CR : ℝ} (hR : ∀ z ≥ 2, |R z * log z - cR| ≤ CR * pntE z) {lower : Bool} + {y s : ℝ} (hy : 1 < y) (hs : sMin lower ≤ s) (hsξ : s ≤ xi y) (hξ3 : 3 ≤ xi y) + (hw2 : 2 ≤ y ^ (1 / xi y)) : + src lower y (y ^ (1 / s)) ≤ (if lower then 0 else cR * max (3 - s) 0 / log y) + + 6 * CR * s ^ 2 * errMaj lower s * pntE (y ^ (1 / xi y)) / log y := by + have hs1 : 1 ≤ s := (one_le_sMin lower).trans hs + have hL : 0 < log y := log_pos hy + have hCR : 0 ≤ CR := by + have h := (abs_nonneg _).trans (hR 2 le_rfl) + exact nonneg_of_mul_nonneg_left h (pntE_pos 2) + have hpE := pntE_pos (y ^ (1 / xi y)) + have hE : 0 ≤ 6 * CR * s ^ 2 * errMaj lower s * pntE (y ^ (1 / xi y)) / log y := by + have := errMaj_pos lower s; positivity + cases lower + · simp only [Bool.false_eq_true, ite_false] + rcases le_total 3 s with h3 | h3 + · -- no source + have : src false y (y ^ (1 / s)) = 0 := by + rw [src, ite_eq_right_iff.2 (by simp)] + refine sum_eq_zero fun p hp => ?_ + rw [mem_filter, mem_primesLT] at hp + have hlt : (p : ℝ) < y ^ (1 / (3 : ℝ)) := hp.1.2.trans_le + (rpow_one_div_le_rpow_one_div hy.le (by norm_num) h3) + exact absurd ((not_cube_lt_iff (by linarith) p.cast_nonneg).1 hp.2) (not_le.2 hlt) + rw [this, max_eq_right (by linarith)] + simpa using hE + · refine (src_le hR hy hs1 hw2 (rpow_one_div_le_rpow_one_div hy.le (by linarith) hsξ) + (rpow_one_div_le_rpow_one_div hy.le (by norm_num) hξ3)).trans ?_ + simp only [Bool.false_eq_true, ite_false] + rw [errMaj_false_of_le_three h3] + have : 6 * CR * pntE (y ^ (1 / xi y)) ≤ 6 * CR * s ^ 2 * 1 * pntE (y ^ (1 / xi y)) := by + have : 1 ≤ s ^ 2 := by nlinarith + have := mul_nonneg hCR hpE.le + nlinarith + gcongr + · simp only [src, ite_true, zero_add] + exact hE + +/-- Corollary 1 and the source estimate together give the full main term: the source +restores the upper-sieve correction `(3 - s)⁺` subtracted from the prime sum. -/ +theorem main_sum_add_src_le {cR CR C₁ : ℝ} (hcR : 0 ≤ cR) {lower : Bool} {y s : ℝ} + (hcor1 : ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter + (fun p : ℕ => y ^ (1 / xi y) ≤ p), + mainMaj (!lower) (log y / log p - 1) / (p * log (y / p)) ≤ + (mainMaj lower s - (if lower then 0 else max (3 - s) 0)) / log y + + C₁ * s ^ 2 * errMaj lower s * pntE (y ^ (1 / xi y)) / log y) + (hsrc : src lower y (y ^ (1 / s)) ≤ (if lower then 0 else cR * max (3 - s) 0 / log y) + + 6 * CR * s ^ 2 * errMaj lower s * pntE (y ^ (1 / xi y)) / log y) : + cR * ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter + (fun p : ℕ => y ^ (1 / xi y) ≤ p), + mainMaj (!lower) (log y / log p - 1) / (p * log (y / p)) + + src lower y (y ^ (1 / s)) ≤ cR * mainMaj lower s / log y + + (cR * C₁ + 6 * CR) * s ^ 2 * errMaj lower s * pntE (y ^ (1 / xi y)) / log y := by + refine (add_le_add (mul_le_mul_of_nonneg_left hcor1 hcR) hsrc).trans_eq ?_ + cases lower <;> simp only [Bool.false_eq_true, ite_false, ite_true] <;> ring + +/-! ### Small `y` -/ +theorem SLT_mono {a b : ℝ} (hab : a ≤ b) : SLT a ≤ SLT b := by + refine sum_le_sum_of_subset_of_nonneg (fun p hp => ?_) fun p _ _ => by positivity + rw [mem_primesLT] at hp ⊢ + exact ⟨hp.1, hp.2.trans_le hab⟩ + +theorem fail_le_exp_SLT (lower : Bool) (r : ℕ) (y z : ℝ) : fail lower r y z ≤ exp (SLT z) := by + refine (fail_le_sum_SLT_pow lower r y z).trans ?_ + refine le_trans ?_ (Real.sum_le_exp_of_nonneg (SLT_nonneg z) (r + 1)) + refine sum_le_sum_of_subset_of_nonneg (fun l hl => ?_) fun l _ _ => ?_ + · rw [mem_filter, Finset.mem_Icc] at hl; rw [Finset.mem_range]; omega + · have := SLT_nonneg z; positivity + +theorem xi_le_of_le {y Y : ℝ} (hy : 1 < y) (hyY : y ≤ Y) : + xi y ≤ log Y / log (log 3) ^ (11 / 5 : ℝ) := by + have hl3 : 1 < log 3 := by + rw [lt_log_iff_exp_lt (by norm_num)]; have := exp_one_lt_d9; linarith + have hll : 0 < log (log 3) := log_pos hl3 + have hL : 0 < log y := log_pos hy + have hP : 0 < log (log 3) ^ (11 / 5 : ℝ) := rpow_pos_of_pos hll _ + have hle : log (log 3) ^ (11 / 5 : ℝ) ≤ log (log (3 * y)) ^ (11 / 5 : ℝ) := by + refine rpow_le_rpow hll.le (log_le_log (by linarith) (log_le_log (by norm_num) ?_)) + (by norm_num) + linarith + rw [xi] + calc log y / log (log (3 * y)) ^ (11 / 5 : ℝ) ≤ log y / log (log 3) ^ (11 / 5 : ℝ) := + div_le_div_of_nonneg_left hL.le hP hle + _ ≤ _ := div_le_div_of_nonneg_right (log_le_log (by linarith) hyY) hP.le + +/-- [I71, (4.8)]: for `1 < y ≤ Y` the claim at depth `r + 1` holds once `c₇` is large in terms +of `Y`. -/ +theorem small_y {cR c₇ Y : ℝ} (hcR : 0 < cR) (hY : 1 < Y) + (hc₇ : 6 * exp (SLT Y) * log Y ^ 2 / (cR * bigM (log Y / log (log 3) ^ (11 / 5 : ℝ))) ≤ c₇) + (r : ℕ) (lower : Bool) {y s : ℝ} (hy : 1 < y) (hyY : y ≤ Y) (hs : sMin lower ≤ s) + (hsξ : s ≤ xi y) : + fail lower (r + 1) y (y ^ (1 / s)) ≤ + cR * (mainMaj lower s / log y + + c₇ * (((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1)) * delta s y * errMaj lower s / + log y ^ 2) := by + set Ξ := log Y / log (log 3) ^ (11 / 5 : ℝ) + have hs1 : 1 ≤ s := (one_le_sMin lower).trans hs + have hL : 0 < log y := log_pos hy + have hLY : log y ≤ log Y := log_le_log (by linarith) hyY + have hMΞ := bigM_pos Ξ + have hG : bigM Ξ / 3 ≤ errMaj lower s := + le_trans (by gcongr; exact bigM_antitone (hsξ.trans (xi_le_of_le hy hyY))) + (errMaj_mem lower s).1 + have hδ := one_le_delta hs1 y + have hρ : (1 : ℝ) / 2 ≤ ((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1) := by + rw [div_le_div_iff₀ (by norm_num) (by positivity)]; push_cast; linarith + have hz : y ^ (1 / s) ≤ Y := by + refine le_trans ?_ hyY + calc y ^ (1 / s) ≤ y ^ (1 / (1 : ℝ)) := rpow_one_div_le_rpow_one_div hy.le one_pos hs1 + _ = y := by simp + have hfail : fail lower (r + 1) y (y ^ (1 / s)) ≤ exp (SLT Y) := + (fail_le_exp_SLT _ _ _ _).trans (exp_le_exp.2 (SLT_mono hz)) + have hc₇0 : 0 ≤ c₇ := le_trans (by positivity) hc₇ + have hM := mainMaj_nonneg lower s + -- the error term alone is large enough + have key : exp (SLT Y) ≤ cR * (c₇ * (((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1)) * delta s y * + errMaj lower s / log y ^ 2) := by + have h1 : exp (SLT Y) ≤ cR * c₇ * ((1 / 2) * (bigM Ξ / 3)) / log Y ^ 2 := by + have hK : 6 * exp (SLT Y) * log Y ^ 2 ≤ c₇ * (cR * bigM Ξ) := + (div_le_iff₀ (mul_pos hcR hMΞ)).1 hc₇ + rw [le_div_iff₀ (by have := log_pos hY; positivity)] + linarith + have hnum : cR * c₇ * ((1 / 2) * (bigM Ξ / 3)) ≤ + cR * c₇ * ((((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1)) * delta s y * errMaj lower s) := by + refine mul_le_mul_of_nonneg_left ?_ (mul_nonneg hcR.le hc₇0) + have := hMΞ.le + have := errMaj_pos lower s + calc (1 / 2 : ℝ) * (bigM Ξ / 3) ≤ (((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1)) * + (delta s y * errMaj lower s) := by + refine mul_le_mul hρ ?_ (by positivity) (by positivity) + nlinarith + _ = _ := by ring + have hc0 : 0 ≤ cR * c₇ * ((((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1)) * delta s y * + errMaj lower s) := le_trans (by positivity) hnum + have hLL : log y ^ 2 ≤ log Y ^ 2 := by gcongr + refine h1.trans ((div_le_div₀ hc0 hnum (by positivity) hLL).trans_eq (by ring)) + have : 0 ≤ cR * (mainMaj lower s / log y) := by positivity + calc fail lower (r + 1) y (y ^ (1 / s)) ≤ exp (SLT Y) := hfail + _ ≤ _ := by rw [mul_add]; linarith + +/-! ### The small primes: the crude bound against Lemma 9 -/ + +/-- [I71, (4.9), (4.10)]: for `y ≥ y₁` the depth sums at `w = y^{1/ξ}` are at most +`δ(s, y) G(s) / L⁴` for every `s ≤ ξ`. -/ +theorem crude_le : ∃ y₁ : ℝ, ∀ y ≥ y₁, ∀ (lower : Bool) (n : ℕ) (s : ℝ), sMin lower ≤ s → + s ≤ xi y → fail lower n y (y ^ (1 / xi y)) ≤ delta s y * errMaj lower s / log y ^ 4 := by + obtain ⟨c, hc⟩ := majG_ge_exp + obtain ⟨CS, hCS⟩ := SLT_le_loglog + obtain ⟨yx, hyx⟩ := exists_xi_large + set c' := max c 0 + set C' := |CS| + 1 + obtain ⟨y₁, hy₁⟩ := eventually_atTop.1 ((eventually_crude c' C' + (by simp [C'])).and (eventually_ge_atTop yx)) + refine ⟨y₁, fun y hy lower n s hs hsξ => ?_⟩ + obtain ⟨⟨hX0, h2e, hA, hB⟩, hyx'⟩ := hy₁ y hy + obtain ⟨hy1, hξ32, -, hw2⟩ := hyx y hyx' + set ξ := xi y + set X := log (log (y ^ (1 / ξ))) + C' + have hs1 : 1 ≤ s := (one_le_sMin lower).trans hs + have hξ4 : 6 ≤ ξ := by linarith [add_one_le_exp (32 : ℝ)] + have hL4 : 0 < log y ^ 4 := by have := log_pos hy1; positivity + -- the crude bound + have hfail : fail lower n y (y ^ (1 / ξ)) ≤ + 2 * (exp 1 * X / (ξ - 2)) ^ (ξ - 2) := by + rw [one_div] + refine fail_rpow_le_tail hy1 (by linarith) ?_ h2e + rw [← one_div] + have := hCS _ hw2 + have : CS ≤ C' := by simp only [C']; linarith [le_abs_self CS] + simp only [X] + linarith + -- Lemma 9 + have hG : ∀ t ≥ 3, exp (-(t * log t) - t * log (log t) - c' * t) ≤ errMaj lower t := by + intro t ht + rw [errMaj_eq_majG_succ] + refine le_trans (exp_le_exp.2 ?_) (hc _ t ht) + have : c * t ≤ c' * t := mul_le_mul_of_nonneg_right (le_max_left _ _) (by linarith) + linarith + have hGs := errMaj_pos lower s + have hmain : 2 * (exp 1 * X / (ξ - 2)) ^ (ξ - 2) * log y ^ 4 ≤ delta s y * errMaj lower s := by + rcases le_total s (ξ / 2) with h | h + · refine hA.trans ((hG _ (by linarith)).trans ?_) + calc errMaj lower (ξ / 2) ≤ errMaj lower s := errMaj_antitone lower h + _ ≤ delta s y * errMaj lower s := le_mul_of_one_le_left hGs.le (one_le_delta hs1 y) + · refine hB.trans ?_ + have hδ := delta_le_delta (by linarith : 1 ≤ ξ / 2) h y + have hGG : exp (-(ξ * log ξ) - ξ * log (log ξ) - c' * ξ) ≤ errMaj lower s := + (hG ξ (by linarith)).trans (errMaj_antitone lower hsξ) + exact mul_le_mul hδ hGG (exp_pos _).le (by linarith [one_le_delta hs1 y]) + rw [le_div_iff₀ hL4] + calc fail lower n y (y ^ (1 / ξ)) * log y ^ 4 + ≤ 2 * (exp 1 * X / (ξ - 2)) ^ (ξ - 2) * log y ^ 4 := by gcongr + _ ≤ _ := hmain + +/-! ### The inductive step -/ + +/-- `r/(r+1) ≤ (r+1)/(r+2) · (1 - ε)` when `ε (r+1)² ≤ 1`. -/ +theorem ratio_le {r : ℕ} {ε : ℝ} (hε : ε * ((r : ℝ) + 1) ^ 2 ≤ 1) : + (r : ℝ) / (r + 1) ≤ ((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1) * (1 - ε) := by + rw [show ((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1) * (1 - ε) = ((r : ℝ) + 1) * (1 - ε) / (r + 2) by + push_cast; ring] + rw [div_le_div_iff₀ (by positivity) (by positivity)] + nlinarith + +/-- The depth condition supplies the relative gain `(log L)²/(4L²)` used in [I71, (4.6)]. +Here `Λ` stands for `log L`; the estimate only needs `Λ > 0`. -/ +theorem ratio_le_of_depth {r : ℕ} {L Λ : ℝ} (hL : 0 < L) (hΛ : 0 < Λ) + (hdepth : (r : ℝ) + 2 ≤ 2 * L / Λ) : + (r : ℝ) / (r + 1) ≤ ((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1) * + (1 - Λ ^ 2 / (4 * L ^ 2)) := by + apply ratio_le + have hr : ((r : ℝ) + 2) * Λ ≤ 2 * L := (le_div_iff₀ hΛ).1 hdepth + have hr' : ((r : ℝ) + 1) * Λ ≤ 2 * L := + (mul_le_mul_of_nonneg_right (by linarith only) hΛ.le).trans hr + have hsq : (((r : ℝ) + 1) * Λ) ^ 2 ≤ (2 * L) ^ 2 := + pow_le_pow_left₀ (by positivity) hr' 2 + calc + Λ ^ 2 / (4 * L ^ 2) * ((r : ℝ) + 1) ^ 2 = + (((r : ℝ) + 1) * Λ) ^ 2 / (2 * L) ^ 2 := by ring + _ ≤ 1 := (div_le_one (by positivity)).2 hsq + +/-- The final bookkeeping of the inductive step ([I71, (4.6)]). -/ +theorem combine {cR c₇ L D M F cr E T ρ ρ' ε : ℝ} + (hF : F ≤ cr + (cR * M / L + E) + cR * c₇ * ρ * T) (hcr : cr ≤ D / L ^ 2) + (hE : E ≤ D / L ^ 2) (hT : T ≤ D * (1 + ε / 2)) (hρ : ρ ≤ ρ' * (1 - ε)) (hρ0 : 0 ≤ ρ) + (hε0 : 0 ≤ ε) (hεL : 1 / (4 * L ^ 2) ≤ ε) (hρ' : 1 / 2 ≤ ρ') (hc : 32 ≤ cR * c₇) + (hD : 0 ≤ D) (hL : 0 < L) : + F ≤ cR * M / L + cR * c₇ * ρ' * D := by + have hcc : 0 ≤ cR * c₇ := by linarith + have hD' : 0 ≤ D * (1 + ε / 2) := by positivity + have h1 : cR * c₇ * ρ * T ≤ cR * c₇ * ρ' * D * ((1 - ε) * (1 + ε / 2)) := by + calc cR * c₇ * ρ * T ≤ cR * c₇ * ρ * (D * (1 + ε / 2)) := + mul_le_mul_of_nonneg_left hT (by positivity) + _ ≤ cR * c₇ * (ρ' * (1 - ε)) * (D * (1 + ε / 2)) := by gcongr + _ = _ := by ring + have h2 : (1 - ε) * (1 + ε / 2) ≤ 1 - ε / 2 := by nlinarith + have hρ'0 : 0 ≤ ρ' := by linarith + have h3 : cR * c₇ * ρ' * D * ((1 - ε) * (1 + ε / 2)) ≤ cR * c₇ * ρ' * D * (1 - ε / 2) := + mul_le_mul_of_nonneg_left h2 (by positivity) + have hL2 : 0 < L ^ 2 := by positivity + have h4 : 4 / L ^ 2 ≤ cR * c₇ * ρ' * ε := by + have e1 : 32 * (1 / 2) ≤ cR * c₇ * ρ' := mul_le_mul hc hρ' (by norm_num) hcc + calc 4 / L ^ 2 = 32 * (1 / 2) * (1 / (4 * L ^ 2)) := by field_simp; norm_num + _ ≤ cR * c₇ * ρ' * ε := mul_le_mul e1 hεL (by positivity) (by positivity) + have h5 : 2 * (D / L ^ 2) ≤ cR * c₇ * ρ' * D * (ε / 2) := by + have := mul_le_mul_of_nonneg_left h4 hD + calc 2 * (D / L ^ 2) = D * (4 / L ^ 2) / 2 := by ring + _ ≤ D * (cR * c₇ * ρ' * ε) / 2 := by linarith + _ = _ := by ring + nlinarith + +/-- The main case of the inductive step: `y` large and `r + 2 ≤ 2 L / log L`. All analytic +inputs are hypotheses at the given `y`, `s`. -/ +theorem main_step {cR c₇ CR C₁ C₃ : ℝ} {r : ℕ} (IH : Bound cR c₇ r) (hcR : 0 < cR) + (hc₇ : 32 ≤ cR * c₇) (hCR : 0 ≤ CR) (hC₁ : 0 ≤ C₁) (hC₃ : 0 ≤ C₃) {lower : Bool} {y s : ℝ} + (hy : 1 < y) (hs : sMin lower ≤ s) (hsξ : s ≤ xi y) + (hcor1 : ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p), + mainMaj (!lower) (log y / log p - 1) / (p * log (y / p)) ≤ + (mainMaj lower s - (if lower then 0 else max (3 - s) 0)) / log y + + C₁ * s ^ 2 * errMaj lower s * pntE (y ^ (1 / xi y)) / log y) + (hsrc : src lower y (y ^ (1 / s)) ≤ (if lower then 0 else cR * max (3 - s) 0 / log y) + + 6 * CR * s ^ 2 * errMaj lower s * pntE (y ^ (1 / xi y)) / log y) + (hcor3 : ∑ p ∈ (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => y ^ (1 / xi y) ≤ p), + delta (log y / log p - 1) (y / p) * errMaj (!lower) (log y / log p - 1) / + (p * log (y / p) ^ 2) ≤ + delta (max s (exp 32)) y * errMaj lower s / log y ^ 2 * + (1 + C₃ * xi y ^ 2 * pntE (y ^ (1 / xi y)))) + (hcrude : fail lower (r + 1) y (y ^ (1 / xi y)) ≤ delta s y * errMaj lower s / log y ^ 4) + (hΛ : 1 ≤ log (log y)) + (hδ : delta (exp 32) y * (1 + C₃ * xi y ^ 2 * pntE (y ^ (1 / xi y))) ≤ + 1 + log (log y) ^ 2 / (8 * log y ^ 2)) + (hK : (cR * C₁ + 6 * CR) * xi y ^ 2 * log y ^ 3 * pntE (y ^ (1 / xi y)) ≤ 1) + (hdepth : ¬ 2 * log y / log (log y) < r + 2) : + fail lower (r + 1) y (y ^ (1 / s)) ≤ + cR * (mainMaj lower s / log y + + c₇ * (((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1)) * delta s y * errMaj lower s / + log y ^ 2) := by + set L := log y + set ξ := xi y + set w := y ^ (1 / ξ) + set Λ := log (log y) + set G := errMaj lower s + set ρ' := ((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1) + set S := (rosserPrimes lower y (y ^ (1 / s))).filter (fun p : ℕ => w ≤ p) + set M := ∑ p ∈ S, mainMaj (!lower) (L / log p - 1) / (p * log (y / p)) + set T := ∑ p ∈ S, delta (L / log p - 1) (y / p) * errMaj (!lower) (L / log p - 1) / + (p * log (y / p) ^ 2) + set D := delta s y * G / L ^ 2 with hD + set ε := Λ ^ 2 / (4 * L ^ 2) with hε + have hs1 : 1 ≤ s := (one_le_sMin lower).trans hs + have hL : 0 < L := log_pos hy + have hG := errMaj_pos lower s + have hδs := one_le_delta hs1 y + have hpE := pntE_pos w + have hD0 : 0 ≤ D := by positivity + -- Corollary 1 and the source term recover the main term, with an error of size `D/L²`. + set K := cR * C₁ + 6 * CR + have hmain : cR * M + src lower y (y ^ (1 / s)) ≤ + cR * mainMaj lower s / L + K * s ^ 2 * G * pntE w / L := + main_sum_add_src_le hcR.le hcor1 hsrc + have hE : K * s ^ 2 * G * pntE w / L ≤ D / L ^ 2 := by + have hK0 : 0 ≤ K := by positivity + have hsq : s ^ 2 ≤ ξ ^ 2 := by gcongr + rw [hD, div_div, div_le_div_iff₀ hL (by positivity)] + calc K * s ^ 2 * G * pntE w * (L ^ 2 * L ^ 2) = G * (K * s ^ 2 * L ^ 3 * pntE w) * L := by + ring + _ ≤ G * (K * ξ ^ 2 * L ^ 3 * pntE w) * L := by gcongr + _ ≤ G * 1 * L := by gcongr + _ ≤ delta s y * G * L := by + simpa only [one_mul, mul_assoc] using + mul_le_mul_of_nonneg_right hδs (by positivity : 0 ≤ G * L) + -- Corollary 3 bounds the propagated error with relative loss at most `ε/2`. + have hT : T ≤ D * (1 + ε / 2) := by + refine hcor3.trans ?_ + have hmax := delta_max_le hs1 (one_le_exp (by norm_num) : 1 ≤ exp 32) y + have hb : 0 ≤ 1 + C₃ * ξ ^ 2 * pntE w := by positivity + have hε2 : ε / 2 = Λ ^ 2 / (8 * L ^ 2) := by rw [hε]; ring + calc delta (max s (exp 32)) y * G / L ^ 2 * (1 + C₃ * ξ ^ 2 * pntE w) + ≤ delta (exp 32) y * delta s y * G / L ^ 2 * (1 + C₃ * ξ ^ 2 * pntE w) := by gcongr + _ = D * (delta (exp 32) y * (1 + C₃ * ξ ^ 2 * pntE w)) := by rw [hD]; ring + _ ≤ D * (1 + ε / 2) := by rw [hε2]; gcongr + -- The depth increment absorbs this loss and the two errors of size `D/L²`. + have hρ : (r : ℝ) / (r + 1) ≤ ρ' * (1 - ε) := + ratio_le_of_depth hL (zero_lt_one.trans_le hΛ) (not_lt.1 hdepth) + have hεL : 1 / (4 * L ^ 2) ≤ ε := by + rw [hε] + exact div_le_div_of_nonneg_right (by nlinarith only [hΛ]) (by positivity) + have hρ' : 1 / 2 ≤ ρ' := by + simp only [ρ'] + rw [div_le_div_iff₀ (by norm_num) (by positivity)]; push_cast; linarith + have hcr : fail lower (r + 1) y w ≤ D / L ^ 2 := by + refine hcrude.trans_eq ?_ + rw [hD, div_div]; ring + -- Split at `w`, apply the inner induction bounds, then combine the main sum and source. + have hwz : w ≤ y ^ (1 / s) := rpow_one_div_le_rpow_one_div hy.le (by linarith) hsξ + have hF : fail lower (r + 1) y (y ^ (1 / s)) ≤ fail lower (r + 1) y w + + (cR * mainMaj lower s / L + K * s ^ 2 * G * pntE w / L) + + cR * c₇ * ((r : ℝ) / (r + 1)) * T := by + calc + _ ≤ fail lower (r + 1) y w + ∑ p ∈ S, fail (!lower) r (y / p) p / p + + src lower y (y ^ (1 / s)) := fail_succ_le_split lower r hwz + _ ≤ fail lower (r + 1) y w + (cR * M + cR * c₇ * ((r : ℝ) / (r + 1)) * T) + + src lower y (y ^ (1 / s)) := + add_le_add (add_le_add le_rfl (sum_ih_le IH hy hs)) le_rfl + _ = fail lower (r + 1) y w + (cR * M + src lower y (y ^ (1 / s))) + + cR * c₇ * ((r : ℝ) / (r + 1)) * T := by ring + _ ≤ _ := add_le_add (add_le_add le_rfl hmain) le_rfl + calc + _ ≤ cR * mainMaj lower s / L + cR * c₇ * ρ' * D := + combine hF hcr hE hT hρ (by positivity) (by positivity) hεL hρ' hc₇ hD0 hL + _ = _ := by rw [hD]; ring + +end IwaniecLinearSieve.TheoremFour + +namespace IwaniecLinearSieve + +open TheoremFour + +/-- [I71, Theorem 4] (main terms), for `k = 1`: if `cR`, `CR` are as in `R_asymp` +(`|R(z) log z - cR| ≤ CR pntE(z)` for `z ≥ 2`), there is `c₇ ≥ 0` such that for all `r`, both +sieves, `y > 1` and `sMin lower ≤ s ≤ ξ(y)`, + +`fail lower r y (y^{1/s}) ≤ cR (M(s)/L + c₇ r/(r+1) δ(s, y) G(s)/L²)`, + +where `M = mainMaj lower` (`f`, resp. `F + (3 - s)⁺`), `G = errMaj lower` (`𝔣`, resp. `𝔉`), +`L = log y`. -/ +theorem theorem4 {cR CR : ℝ} (hcR : 0 < cR) (hR : ∀ z ≥ 2, |R z * log z - cR| ≤ CR * pntE z) : + ∃ c₇ : ℝ, 0 ≤ c₇ ∧ ∀ (r : ℕ) (lower : Bool) (y s : ℝ), 1 < y → sMin lower ≤ s → + s ≤ xi y → fail lower r y (y ^ (1 / s)) ≤ + cR * (mainMaj lower s / log y + + c₇ * ((r : ℝ) / (r + 1)) * delta s y * errMaj lower s / log y ^ 2) := by + obtain ⟨C₁, hC₁0, hC₁⟩ := cor1_part + obtain ⟨C₃, y₃, hC₃0, hC₃⟩ := cor3_xi + obtain ⟨yd, hyd⟩ := exists_fail_add_eq + obtain ⟨yx, hyx⟩ := exists_xi_large + obtain ⟨yc, hyc⟩ := crude_le + have hCR : 0 ≤ CR := + nonneg_of_mul_nonneg_left ((abs_nonneg _).trans (hR 2 le_rfl)) (pntE_pos 2) + obtain ⟨ye, hye⟩ := eventually_atTop.1 ((eventually_one_le_loglog.and + (eventually_delta_mul_le C₃ hC₃0)).and (eventually_mul_pntE_le (cR * C₁ + 6 * CR))) + set y₀ := max (max (max y₃ yd) (max yx yc)) (max ye 2) with hy₀ + set Ξ := log y₀ / log (log 3) ^ (11 / 5 : ℝ) + set c₇ := max (32 / cR) (6 * exp (SLT y₀) * log y₀ ^ 2 / (cR * bigM Ξ)) + have hY : 1 < y₀ := lt_of_lt_of_le (by norm_num) (le_trans (le_max_right ye 2) (le_max_right _ _)) + have hc₇0 : 0 ≤ c₇ := le_trans (by positivity) (le_max_left _ _) + have hc₇ : 32 ≤ cR * c₇ := by + have := le_max_left (32 / cR) (6 * exp (SLT y₀) * log y₀ ^ 2 / (cR * bigM Ξ)) + rw [div_le_iff₀ hcR] at this + linarith + refine ⟨c₇, hc₇0, fun r => ?_⟩ + change Bound cR c₇ r + induction r with + | zero => + intro lower y s hy _ _ + have := mainMaj_nonneg lower s + have := log_pos hy + simp only [fail_zero, Nat.cast_zero, zero_div, mul_zero, zero_mul, add_zero] + positivity + | succ r IH => + intro lower y s hy hs hsξ + rcases le_or_gt y y₀ with hyY | hyY + · exact small_y hcR hY (le_max_right _ _) r lower hy hyY hs hsξ + have hle : ∀ a, a ≤ y₀ → a ≤ y := fun a ha => ha.trans hyY.le + have hy₃ : y₃ ≤ y := hle _ (by simp [y₀]) + have hyd' : yd ≤ y := hle _ (by simp [y₀]) + have hyx' : yx ≤ y := hle _ (by simp [y₀]) + have hyc' : yc ≤ y := hle _ (by simp [y₀]) + have hye' : ye ≤ y := hle _ (by simp [y₀]) + have hs1 : 1 ≤ s := (one_le_sMin lower).trans hs + by_cases hdeep : 2 * log y / log (log y) < r + 2 + · -- the recursion has stabilised + rw [hyd y hyd' lower r (y ^ (1 / s)) hdeep 1] + refine (IH lower y s hy hs hsξ).trans ?_ + have hab : (r : ℝ) / (r + 1) ≤ ((r + 1 : ℕ) : ℝ) / ((r + 1 : ℕ) + 1) := by + rw [div_le_div_iff₀ (by positivity) (by positivity)]; push_cast; nlinarith + have hL2 : 0 < log y ^ 2 := by have := log_pos hy; positivity + refine mul_le_mul_of_nonneg_left (add_le_add_right (div_le_div_of_nonneg_right + (mul_le_mul_of_nonneg_right (mul_le_mul_of_nonneg_right + (mul_le_mul_of_nonneg_left hab hc₇0) (zero_le_one.trans (one_le_delta hs1 y))) + (errMaj_pos lower s).le) hL2.le) _) hcR.le + · obtain ⟨-, hξ32, -, hw2⟩ := hyx y hyx' + have hξ3 : 3 ≤ xi y := by linarith [add_one_le_exp (32 : ℝ)] + obtain ⟨⟨hΛ, hδ⟩, hK⟩ := hye y hye' + exact main_step IH hcR hc₇ hCR hC₁0 hC₃0 hy hs hsξ (hC₁ lower y s hy hs hsξ hξ3 hw2) + (src_le_of_le_xi hR hy hs hsξ hξ3 hw2) (hC₃ lower y s hy₃ hs) + (hyc y hyc' lower (r + 1) s hs hsξ) + hΛ hδ hK hdeep + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFourAsymp.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFourAsymp.lean new file mode 100644 index 000000000..984ed68bc --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFourAsymp.lean @@ -0,0 +1,390 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.Defs +public import LeanPool.IwaniecLinearSieve.PrimeSums.Error +import LeanPool.IwaniecLinearSieve.LinearSieve.Crude +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaEleven +import LeanPool.IwaniecLinearSieve.LinearSieve.TheoremFourAux +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds +import Mathlib.Tactic.Polynomial.Basic + +/-! +# Real-analysis facts for large `y` in [I71, Theorem 4] + +With `L = log y`, `ℓ = log log 3y`, `Λ = log log y`, `ξ = ξ(y) = L / ℓ^{11/5}` and +`w = y^{1/ξ}` (so `log w = ℓ^{11/5}` and `pntE w = exp (-κ ℓ^{11/10})`): + +* `eventually_delta_mul_le`: `δ(s₀, y) (1 + C ξ² pntE w) ≤ 1 + Λ² / (8 L²)` ([I71, (4.6)]); +* `eventually_mul_pntE_le`: `K ξ² L³ pntE w ≤ 1` ([I71, (4.2), (4.3)]); +* `eventually_crude`: the crude bound `2 (e X/(ξ-2))^{ξ-2}` for the depth sums at `w` + (with `X = log log w + C'`) times `L⁴` is below the Lemma 9 lower bound for `G(ξ/2)` and below + `δ(ξ/2, y)` times the Lemma 9 lower bound for `G(ξ)` ([I71, (4.4), (4.5), (4.9), (4.10)]). +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory Finset + +namespace IwaniecLinearSieve.TheoremFour + +/-! ### `L`, `ξ`, `w` in terms of `ℓ = log log 3y` -/ +theorem loglog_three_mul_pos {y : ℝ} (hy : 1 < y) : 0 < log (log (3 * y)) := + log_pos (one_lt_log_three_mul hy.le) + +theorem log_add_log_three {y : ℝ} (hy : 1 < y) : + log y + log 3 = exp (log (log (3 * y))) := by + rw [exp_log (by linarith [one_lt_log_three_mul hy.le]), log_mul (by norm_num) (by linarith)] + ring + +theorem xi_mul_rpow {y : ℝ} (hy : 1 < y) : + xi y * log (log (3 * y)) ^ (11 / 5 : ℝ) = log y := by + rw [xi, div_mul_cancel₀ _ (rpow_pos_of_pos (loglog_three_mul_pos hy) _).ne'] + +theorem pntE_rpow_one_div_xi {y : ℝ} (hy : 1 < y) : + pntE (y ^ (1 / xi y)) = exp (-pntκ * log (log (3 * y)) ^ (11 / 10 : ℝ)) := by + rw [pntE, log_rpow_one_div_xi hy, sqrt_eq_rpow, ← rpow_mul (loglog_three_mul_pos hy).le] + norm_num + +theorem xi_nonneg {y : ℝ} (hy : 1 < y) : 0 ≤ xi y := + div_nonneg (log_pos hy).le (rpow_nonneg (loglog_three_mul_pos hy).le _) + +theorem xi_le_log {y : ℝ} (hy : 1 < y) (hℓ : 1 ≤ log (log (3 * y))) : xi y ≤ log y := + div_le_self (log_pos hy).le (one_le_rpow hℓ (by norm_num)) + +/-! ### `L⁵ pntE(w) → 0` -/ +theorem tendsto_lin_sub_rpow : + Tendsto (fun ℓ : ℝ => 5 * ℓ - pntκ * ℓ ^ (11 / 10 : ℝ)) atTop atBot := by + have h := (tendsto_rpow_atTop (by norm_num : (0 : ℝ) < 1 / 10)).eventually + (eventually_ge_atTop (6 / pntκ)) + refine tendsto_atBot_mono' atTop ?_ tendsto_neg_atTop_atBot + filter_upwards [h, eventually_gt_atTop 0] with ℓ h hℓ + have hsplit : ℓ ^ (11 / 10 : ℝ) = ℓ * ℓ ^ (1 / 10 : ℝ) := by + rw [show (11 / 10 : ℝ) = 1 + 1 / 10 by norm_num, rpow_add hℓ, rpow_one] + have h6 : 6 ≤ pntκ * ℓ ^ (1 / 10 : ℝ) := by + rw [div_le_iff₀ pntκ_pos] at h; linarith + rw [hsplit] + nlinarith + +theorem tendsto_log_pow_pntE : + Tendsto (fun y : ℝ => log y ^ 5 * pntE (y ^ (1 / xi y))) atTop (𝓝 0) := by + have hT : Tendsto (fun y : ℝ => exp (5 * log (log (3 * y)) - + pntκ * log (log (3 * y)) ^ (11 / 10 : ℝ))) atTop (𝓝 0) := + tendsto_exp_atBot.comp (tendsto_lin_sub_rpow.comp tendsto_log_log_three_mul) + refine tendsto_of_tendsto_of_tendsto_of_le_of_le' tendsto_const_nhds hT ?_ ?_ + · filter_upwards [eventually_gt_atTop 1] with y hy + have := log_pos hy + have := pntE_pos (y ^ (1 / xi y)) + positivity + · filter_upwards [eventually_gt_atTop 1] with y hy + have hL := log_pos hy + have hLe : log y ≤ exp (log (log (3 * y))) := by + rw [← log_add_log_three hy]; linarith [log_pos (by norm_num : (1 : ℝ) < 3)] + rw [pntE_rpow_one_div_xi hy, sub_eq_add_neg, exp_add, ← neg_mul] + gcongr + calc log y ^ 5 ≤ exp (log (log (3 * y))) ^ 5 := by gcongr + _ = _ := by rw [← exp_nat_mul]; norm_num + +theorem eventually_one_le_loglog : ∀ᶠ y : ℝ in atTop, 1 ≤ log (log y) := + (tendsto_log_atTop.comp tendsto_log_atTop).eventually (eventually_ge_atTop 1) + +theorem eventually_mul_pntE_le (K : ℝ) : ∀ᶠ y : ℝ in atTop, + K * xi y ^ 2 * log y ^ 3 * pntE (y ^ (1 / xi y)) ≤ 1 := by + have hK : (0 : ℝ) < 1 / (|K| + 1) := by positivity + filter_upwards [tendsto_log_pow_pntE.eventually (eventually_le_nhds hK), + eventually_gt_atTop 1, tendsto_log_log_three_mul.eventually (eventually_ge_atTop 1)] + with y h1 hy hℓ + have hL := log_pos hy + have hξ0 := xi_nonneg hy + have hξL := xi_le_log hy hℓ + have hpE := pntE_pos (y ^ (1 / xi y)) + have hsq : xi y ^ 2 * log y ^ 3 ≤ log y ^ 5 := by + have : xi y ^ 2 ≤ log y ^ 2 := by gcongr + calc xi y ^ 2 * log y ^ 3 ≤ log y ^ 2 * log y ^ 3 := by gcongr + _ = log y ^ 5 := by ring + have h2 : |K| * (log y ^ 5 * pntE (y ^ (1 / xi y))) ≤ |K| * (1 / (|K| + 1)) := by gcongr + have h3 : |K| * (1 / (|K| + 1)) ≤ 1 := by + rw [mul_one_div, div_le_one (by positivity)]; linarith + calc K * xi y ^ 2 * log y ^ 3 * pntE (y ^ (1 / xi y)) + ≤ |K| * (xi y ^ 2 * log y ^ 3) * pntE (y ^ (1 / xi y)) := by + rw [mul_assoc K]; gcongr; exact le_abs_self K + _ ≤ |K| * log y ^ 5 * pntE (y ^ (1 / xi y)) := by gcongr + _ ≤ 1 := by rw [mul_assoc]; linarith + +/-- On `[0, 1]`, the exponential is at most `1 + 2v`. -/ +theorem exp_le_one_add_two_mul {v : ℝ} (hv0 : 0 ≤ v) (hv1 : v ≤ 1) : + exp v ≤ 1 + 2 * v := by + have h := (abs_le.1 (abs_exp_sub_one_sub_id_le + (by rw [abs_of_nonneg hv0]; exact hv1))).2 + nlinarith only [h, hv0, hv1] + +theorem eventually_delta_mul_le (C : ℝ) (hC : 0 ≤ C) : ∀ᶠ y : ℝ in atTop, + delta (exp 32) y * (1 + C * xi y ^ 2 * pntE (y ^ (1 / xi y))) ≤ + 1 + log (log y) ^ 2 / (8 * log y ^ 2) := by + set A : ℝ := 5 * exp 32 * (exp 32 ^ 2 * 32 ^ 5) with hA + have hA0 : 0 ≤ A := by positivity + have hsq := tendsto_pow_atTop (α := ℝ) (two_ne_zero) + filter_upwards [eventually_mul_pntE_le (2 * C), + tendsto_log_atTop.eventually (eventually_ge_atTop 1), + (hsq.comp tendsto_log_atTop).eventually (eventually_ge_atTop (A + 1)), + (hsq.comp (tendsto_log_atTop.comp tendsto_log_atTop)).eventually + (eventually_ge_atTop (8 * (2 * A + 1)))] with y hPNT hL1 hL2 hΛ + simp only [Function.comp] at hL2 hΛ + set L := log y + set b := C * xi y ^ 2 * pntE (y ^ (1 / xi y)) + have hL : 0 < L := by linarith only [hL1] + have hLsq : 0 < L ^ 2 := by positivity + have hpE := pntE_pos (y ^ (1 / xi y)) + have hb0 : 0 ≤ b := by positivity + -- The shared PNT estimate gives `b L³ ≤ 1/2`; `L ≥ 1` gives the needed `b L²` bound. + have hbL : b * L ^ 2 ≤ 1 / 2 := by + have hbL3 : b * L ^ 3 ≤ 1 / 2 := by + dsimp [b, L] + nlinarith only [hPNT] + calc b * L ^ 2 ≤ b * L ^ 3 := + mul_le_mul_of_nonneg_left (pow_le_pow_right₀ hL1 (by norm_num : 2 ≤ 3)) hb0 + _ ≤ 1 / 2 := hbL3 + -- `δ(s₀, y) ≤ exp (A / L²)` + have hδ : delta (exp 32) y ≤ exp (A / L ^ 2) := by + rw [delta, log_exp] + set x := exp 32 ^ 2 * 32 ^ 5 / L ^ 2 + have hx : 0 ≤ x := by positivity + rw [rpow_def_of_pos (by linarith only [hx])] + apply exp_le_exp.2 + have hlog := log_le_sub_one_of_pos (by linarith only [hx] : 0 < 1 + x) + calc log (1 + x) * (5 * exp 32) ≤ x * (5 * exp 32) := by + gcongr + linarith only [hlog] + _ = A / L ^ 2 := by rw [hA]; simp only [x]; ring + -- Combine the two errors in the exponent, then fit `2v` inside the target margin. + set v := A / L ^ 2 + b + have hv0 : 0 ≤ v := by positivity + have hvL : v * L ^ 2 ≤ A + 1 / 2 := by + calc v * L ^ 2 = A + b * L ^ 2 := by simp only [v]; field_simp + _ ≤ A + 1 / 2 := add_le_add le_rfl hbL + have hv1 : v ≤ 1 := by + have : v * L ^ 2 ≤ 1 * L ^ 2 := by linarith only [hvL, hL2] + exact le_of_mul_le_mul_right this hLsq + have h2v : 2 * v ≤ log (log y) ^ 2 / (8 * L ^ 2) := by + rw [le_div_iff₀ (by positivity)] + linarith only [hvL, hΛ] + calc delta (exp 32) y * (1 + b) ≤ exp (A / L ^ 2) * exp b := + mul_le_mul hδ (by simpa only [add_comm] using add_one_le_exp b) + (by linarith only [hb0]) (exp_pos _).le + _ = exp v := by rw [← exp_add] + _ ≤ 1 + 2 * v := exp_le_one_add_two_mul hv0 hv1 + _ ≤ _ := add_le_add le_rfl h2v + +/-! ### The crude bound against the Lemma 9 lower bounds -/ + +/-- `ξ log ξ - (ξ - 2) log (ξ - 2) ≤ 2 log ξ + 2`. -/ +theorem mul_log_sub_le {ξ : ℝ} (hξ : 2 < ξ) : + ξ * log ξ - (ξ - 2) * log (ξ - 2) ≤ 2 * log ξ + 2 := by + have hu : 0 < ξ - 2 := by linarith + have h := log_le_sub_one_of_pos (div_pos (by linarith : 0 < ξ) hu) + rw [log_div (by linarith) hu.ne'] at h + have h' : (ξ - 2) * (log ξ - log (ξ - 2)) ≤ (ξ - 2) * (ξ / (ξ - 2) - 1) := + mul_le_mul_of_nonneg_left h hu.le + have e : (ξ - 2) * (ξ / (ξ - 2) - 1) = 2 := by field_simp; ring + nlinarith + +/-- The exponent comparison for [I71, (4.4), (4.9)], after bounding the logarithms. -/ +theorem crude_half_exponent_le {c ℓ L ξ X : ℝ} (hℓ_large : 2 ≤ ℓ) (hxi_large : 8 * ℓ ≤ ξ) + (hlogL_upper : log L ≤ ℓ) (hlogX_nonneg : 0 ≤ log X) (hlogX_upper : log X ≤ log ℓ / 4) + (hlog_shift_lower : log (ξ / 2) ≤ log (ξ - 2)) (hlog_half_lower : ℓ / 2 ≤ log (ξ / 2)) + (hloglog_half_upper : log (log (ξ / 2)) ≤ log ℓ) + (herror_budget : 2 + c / 2 + 3 / 4 * log ℓ ≤ ℓ / 8) : + log 2 + (-((ξ - 2) * log (ξ - 2)) + (ξ - 2) * log X + (ξ - 2)) + 4 * log L ≤ + -(ξ / 2 * log (ξ / 2)) - ξ / 2 * log (log (ξ / 2)) - c * (ξ / 2) := by + have hxi_nonneg : 0 ≤ ξ := by linarith only [hℓ_large, hxi_large] + have hshifted_log := mul_le_mul_of_nonneg_left hlog_shift_lower + (by linarith only [hℓ_large, hxi_large] : 0 ≤ ξ - 2) + have hweighted_logX := mul_le_mul_of_nonneg_left hlogX_upper hxi_nonneg + have hhalf_log_gap := mul_le_mul_of_nonneg_left hlog_half_lower + (by linarith only [hℓ_large, hxi_large] : 0 ≤ ξ / 2 - 2) + have hweighted_loglog := mul_le_mul_of_nonneg_left hloglog_half_upper + (by linarith only [hxi_nonneg] : 0 ≤ ξ / 2) + have hweighted_budget := mul_le_mul_of_nonneg_left herror_budget hxi_nonneg + have hlinear_gap : ξ / 4 * (ℓ / 2) ≤ (ξ / 2 - 2) * (ℓ / 2) := + mul_le_mul_of_nonneg_right (by linarith only [hℓ_large, hxi_large]) + (by linarith only [hℓ_large]) + -- The decay from `log (ξ/2)` pays for the logarithmic error budget. + have hdecay : ξ * (ℓ / 8) ≤ (ξ / 2 - 2) * log (ξ / 2) := by + linarith only [hhalf_log_gap, hlinear_gap] + calc log 2 + (-((ξ - 2) * log (ξ - 2)) + (ξ - 2) * log X + (ξ - 2)) + 4 * log L + ≤ -(ξ / 2 * log (ξ / 2)) - ξ / 2 * log ℓ - c * (ξ / 2) := by + linarith only [hshifted_log, hweighted_logX, hweighted_budget, hdecay, + hlogX_nonneg, hlogL_upper, hxi_large, hℓ_large, log_two_lt_d9] + _ ≤ -(ξ / 2 * log (ξ / 2)) - ξ / 2 * log (log (ξ / 2)) - c * (ξ / 2) := by + linarith only [hweighted_loglog] + +/-- The exponent comparison for [I71, (4.5), (4.10)], using the lower bound on `log x`. -/ +theorem crude_full_exponent_le {c ℓ L ξ X x : ℝ} (hℓ_large : 2 ≤ ℓ) (hxi_large : 8 * ℓ ≤ ξ) + (hlogL_upper : log L ≤ ℓ) (hlogX_nonneg : 0 ≤ log X) (hlogX_upper : log X ≤ log ℓ / 4) + (hlogxi_upper : log ξ ≤ ℓ) (hloglogxi_upper : log (log ξ) ≤ log ℓ) + (hlogx_lower : 3 / 5 * log ℓ - 7 * log 2 ≤ log x) + (herror_budget : 2 + c + 18 * log 2 ≤ log ℓ / 4) : + log 2 + (-((ξ - 2) * log (ξ - 2)) + (ξ - 2) * log X + (ξ - 2)) + 4 * log L ≤ + log x * (5 * (ξ / 2)) + (-(ξ * log ξ) - ξ * log (log ξ) - c * ξ) := by + have hxi_nonneg : 0 ≤ ξ := by linarith only [hℓ_large, hxi_large] + have hweighted_logX := mul_le_mul_of_nonneg_left hlogX_upper hxi_nonneg + have hweighted_loglog := mul_le_mul_of_nonneg_left hloglogxi_upper hxi_nonneg + have hweighted_logx := mul_le_mul_of_nonneg_right hlogx_lower + (by linarith only [hxi_nonneg] : 0 ≤ 5 * (ξ / 2)) + have hweighted_budget := mul_le_mul_of_nonneg_left herror_budget hxi_nonneg + have hshift_loss := mul_log_sub_le (by linarith only [hℓ_large, hxi_large] : 2 < ξ) + have hlog_two_margin : 0 ≤ (ξ / 2 - 1) * log 2 := + mul_nonneg (by linarith only [hℓ_large, hxi_large]) (log_nonneg (by norm_num)) + -- The factor `x^(5ξ/2)` absorbs the shift loss and the remaining errors. + calc log 2 + (-((ξ - 2) * log (ξ - 2)) + (ξ - 2) * log X + (ξ - 2)) + 4 * log L + ≤ log x * (5 * (ξ / 2)) + (-(ξ * log ξ) - ξ * log ℓ - c * ξ) := by + linarith only [hweighted_logX, hweighted_logx, hweighted_budget, hshift_loss, + hlog_two_margin, hlogX_nonneg, hlogL_upper, hlogxi_upper, hxi_large, hℓ_large] + _ ≤ log x * (5 * (ξ / 2)) + (-(ξ * log ξ) - ξ * log (log ξ) - c * ξ) := by + linarith only [hweighted_loglog] + +/-- The comparisons [I71, (4.4), (4.5), (4.9), (4.10)] in the variable `ℓ = log log 3y`, with +`L = e^ℓ - log 3` and `ξ = L / ℓ^{11/5}`, under explicit "ℓ large" hypotheses. -/ +theorem crude_alg {c C' ℓ L ξ : ℝ} (hC' : 1 ≤ C') (hℓ : 2 ≤ ℓ) + (hL : L + log 3 = exp ℓ) (hξ : ξ * ℓ ^ (11 / 5 : ℝ) = L) (h2 : 2 * log 3 ≤ exp ℓ) + (h3 : 4 * ℓ ^ (11 / 5 : ℝ) ≤ exp (ℓ / 2)) (h4 : 11 / 5 * log ℓ + C' ≤ ℓ ^ (1 / 4 : ℝ)) + (h5 : 2 + c + 18 * log 2 ≤ log ℓ / 4) (h6 : 2 + c / 2 + 3 / 4 * log ℓ ≤ ℓ / 8) : + 0 < 11 / 5 * log ℓ + C' ∧ 2 * exp 1 * (11 / 5 * log ℓ + C') ≤ ξ - 2 ∧ + 2 * (exp 1 * (11 / 5 * log ℓ + C') / (ξ - 2)) ^ (ξ - 2) * L ^ 4 ≤ + exp (-(ξ / 2 * log (ξ / 2)) - ξ / 2 * log (log (ξ / 2)) - c * (ξ / 2)) ∧ + 2 * (exp 1 * (11 / 5 * log ℓ + C') / (ξ - 2)) ^ (ξ - 2) * L ^ 4 ≤ + (1 + (ξ / 2) ^ 2 * log (ξ / 2) ^ 5 / L ^ 2) ^ (5 * (ξ / 2)) * + exp (-(ξ * log ξ) - ξ * log (log ξ) - c * ξ) := by + set P := ℓ ^ (11 / 5 : ℝ) with hPdef + set X := 11 / 5 * log ℓ + C' + have hℓ0 : 0 < ℓ := by linarith only [hℓ] + have hlℓ : 0 < log ℓ := log_pos (by linarith only [hℓ]) + have hPℓ : ℓ ≤ P := self_le_rpow_of_one_le (by linarith only [hℓ]) (by norm_num) + have hP0 : 0 < P := by linarith only [hPℓ, hℓ] + have hl3 : 0 < log 3 := log_pos (by norm_num) + have hL0 : 0 < L := by linarith only [hL, h2, hl3] + have hLe : L ≤ exp ℓ := by linarith only [hL, hl3] + have hlogL : log L ≤ ℓ := by + calc log L ≤ log (exp ℓ) := log_le_log hL0 hLe + _ = ℓ := log_exp ℓ + have hξdef : ξ = L / P := by rw [← hξ]; field_simp + have hξ0 : 0 < ξ := by rw [hξdef]; exact div_pos hL0 hP0 + have hξL : ξ ≤ L := by rw [hξdef]; exact div_le_self hL0.le (by linarith only [hPℓ, hℓ]) + have hlogξ : log ξ ≤ ℓ := (log_le_log hξ0 hξL).trans hlogL + -- `ξ ≥ 2 e^{ℓ/2}` + have hE0 := exp_pos (ℓ / 2) + have he2 : exp ℓ = exp (ℓ / 2) * exp (ℓ / 2) := by rw [← exp_add]; ring_nf + have hξbig : 2 * exp (ℓ / 2) ≤ ξ := by + rw [hξdef, le_div_iff₀ hP0] + nlinarith only [hL, h2, he2, mul_le_mul_of_nonneg_left h3 hE0.le] + have hξlarge : 8 * ℓ ≤ ξ := by linarith only [hξbig, h3, hPℓ] + have hlogξ2 : ℓ / 2 ≤ log (ξ / 2) := by + calc ℓ / 2 = log (exp (ℓ / 2)) := (log_exp _).symm + _ ≤ log (ξ / 2) := log_le_log hE0 (by linarith only [hξbig]) + -- `X` + have hX1 : 1 ≤ X := by + dsimp [X]; linarith only [hlℓ, hC'] + have hX0 : 0 < X := by linarith only [hX1] + have hq : ℓ ^ (1 / 4 : ℝ) ≤ ℓ := rpow_le_self_of_one_le (by linarith only [hℓ]) (by norm_num) + have hXℓ : X ≤ ℓ := h4.trans hq + have hlogX0 : 0 ≤ log X := log_nonneg hX1 + have hlogX : log X ≤ log ℓ / 4 := by + have := log_le_log hX0 h4 + rw [log_rpow hℓ0] at this; linarith only [this] + have he : exp 1 < 2.72 := by have := exp_one_lt_d9; norm_num at this ⊢; linarith only [this] + have h2e : 2 * exp 1 * X ≤ ξ - 2 := by + have : exp 1 * X ≤ 2.72 * ℓ := mul_le_mul he.le hXℓ hX0.le (by norm_num) + linarith only [this, hξlarge, hℓ] + have hu0 : 0 < ξ - 2 := by linarith only [hξlarge, hℓ] + have hL4 : L ^ 4 = exp (4 * log L) := by + rw [show (4 : ℝ) * log L = log (L ^ 4) by rw [log_pow]; norm_num, exp_log (by positivity)] + have hcr : 2 * (exp 1 * X / (ξ - 2)) ^ (ξ - 2) * L ^ 4 = + exp (log 2 + (-((ξ - 2) * log (ξ - 2)) + (ξ - 2) * log X + (ξ - 2)) + 4 * log L) := by + rw [exp_add, exp_add, exp_log two_pos, ← hL4, ← exp_one_mul_div_rpow hX0 hu0] + -- common bounds + have hlam0 : 0 < log (ξ / 2) := by linarith only [hlogξ2, hℓ] + have hlogu : log (ξ / 2) ≤ log (ξ - 2) := + log_le_log (by positivity) (by linarith only [hξlarge, hℓ]) + have hlamξ : log (ξ / 2) ≤ log ξ := log_le_log (by positivity) (by linarith only [hξ0]) + have hlllam : log (log (ξ / 2)) ≤ log ℓ := log_le_log hlam0 (hlamξ.trans hlogξ) + refine ⟨hX0, h2e, ?_, ?_⟩ <;> rw [hcr] + · -- `s ≤ ξ/2`: (4.4), (4.9) + apply exp_le_exp.2 + exact crude_half_exponent_le hℓ hξlarge hlogL hlogX0 hlogX hlogu hlogξ2 hlllam h6 + · -- `s ≥ ξ/2`: (4.5), (4.10) + set x := (ξ / 2) ^ 2 * log (ξ / 2) ^ 5 / L ^ 2 with hx + have hx0 : 0 < x := by positivity + have h1 : exp (log x * (5 * (ξ / 2))) ≤ (1 + x) ^ (5 * (ξ / 2)) := by + rw [← rpow_def_of_pos hx0] + exact rpow_le_rpow hx0.le (by linarith only) (by positivity) + refine le_trans ?_ (mul_le_mul_of_nonneg_right h1 (exp_pos _).le) + rw [← exp_add] + apply exp_le_exp.2 + have hlogx : log x = 2 * log (ξ / 2) + 5 * log (log (ξ / 2)) - 2 * log L := by + rw [hx, log_div (by positivity) (by positivity), log_mul (by positivity) (by positivity), + log_pow, log_pow, log_pow] + push_cast; ring + have hlam : log (ξ / 2) = log L - log 2 - 11 / 5 * log ℓ := by + rw [hξdef, div_div, log_div hL0.ne' (by positivity), log_mul hP0.ne' (by norm_num), + hPdef, log_rpow hℓ0] + ring + have hlllam' : log ℓ - log 2 ≤ log (log (ξ / 2)) := by + rw [← log_div hℓ0.ne' (by norm_num)] + exact log_le_log (by positivity) hlogξ2 + have hlx : 3 / 5 * log ℓ - 7 * log 2 ≤ log x := by + rw [hlogx]; linarith only [hlam, hlllam'] + have hlξ0 : 0 < log ξ := log_pos (by linarith only [hℓ, hξlarge]) + exact crude_full_exponent_le hℓ hξlarge hlogL hlogX0 hlogX hlogξ + (log_le_log hlξ0 hlogξ) hlx h5 + +/-- The "ℓ large" hypotheses of `crude_alg` hold eventually. -/ +theorem eventually_crude_hyp (c C' : ℝ) : ∀ᶠ ℓ : ℝ in atTop, + 2 ≤ ℓ ∧ 2 * log 3 ≤ exp ℓ ∧ 4 * ℓ ^ (11 / 5 : ℝ) ≤ exp (ℓ / 2) ∧ + 11 / 5 * log ℓ + C' ≤ ℓ ^ (1 / 4 : ℝ) ∧ 2 + c + 18 * log 2 ≤ log ℓ / 4 ∧ + 2 + c / 2 + 3 / 4 * log ℓ ≤ ℓ / 8 := by + have hF3 := (tendsto_rpow_mul_exp_neg_mul_atTop_nhds_zero (11 / 5) (1 / 2) + (by norm_num)).eventually (eventually_le_nhds (by norm_num : (0 : ℝ) < 1 / 4)) + have hF4 := (isLittleO_log_rpow_atTop (by norm_num : (0 : ℝ) < 1 / 4)).bound + (by norm_num : (0 : ℝ) < 1 / 5) + have hF6 := isLittleO_log_id_atTop.bound (by norm_num : (0 : ℝ) < 1 / 16) + filter_upwards [eventually_ge_atTop 2, tendsto_exp_atTop.eventually + (eventually_ge_atTop (2 * log 3)), hF3, hF4, (tendsto_rpow_atTop + (by norm_num : (0 : ℝ) < 1 / 4)).eventually (eventually_ge_atTop (2 * C')), + tendsto_log_atTop.eventually (eventually_ge_atTop (4 * (2 + c + 18 * log 2))), hF6, + eventually_ge_atTop (16 * (2 + |c|))] with ℓ h1 h2 h3 h4 h4' h5 h6 h6' + have hℓ0 : 0 < ℓ := by linarith + have hlℓ : 0 ≤ log ℓ := log_nonneg (by linarith) + refine ⟨h1, h2, ?_, ?_, by linarith, ?_⟩ + · have := mul_le_mul_of_nonneg_right h3 (exp_pos (ℓ / 2)).le + rw [mul_assoc, ← exp_add, show -(1 / 2) * ℓ + ℓ / 2 = 0 by ring, exp_zero, mul_one] at this + linarith + · have hq := rpow_nonneg hℓ0.le (1 / 4 : ℝ) + rw [norm_of_nonneg hlℓ, norm_of_nonneg hq] at h4 + linarith + · rw [norm_of_nonneg hlℓ, id, norm_of_nonneg hℓ0.le] at h6 + have := le_abs_self c + have := abs_nonneg c + linarith + +theorem eventually_crude (c C' : ℝ) (hC' : 1 ≤ C') : ∀ᶠ y : ℝ in atTop, + 0 < log (log (y ^ (1 / xi y))) + C' ∧ + 2 * exp 1 * (log (log (y ^ (1 / xi y))) + C') ≤ xi y - 2 ∧ + 2 * (exp 1 * (log (log (y ^ (1 / xi y))) + C') / (xi y - 2)) ^ (xi y - 2) * log y ^ 4 ≤ + exp (-(xi y / 2 * log (xi y / 2)) - xi y / 2 * log (log (xi y / 2)) - c * (xi y / 2)) ∧ + 2 * (exp 1 * (log (log (y ^ (1 / xi y))) + C') / (xi y - 2)) ^ (xi y - 2) * log y ^ 4 ≤ + delta (xi y / 2) y * exp (-(xi y * log (xi y)) - xi y * log (log (xi y)) - c * xi y) := by + filter_upwards [tendsto_log_log_three_mul.eventually (eventually_crude_hyp c C'), + eventually_gt_atTop 1] with y h hy + obtain ⟨h1, h2, h3, h4, h5, h6⟩ := h + have hlw : log (log (y ^ (1 / xi y))) = 11 / 5 * log (log (log (3 * y))) := by + rw [log_rpow_one_div_xi hy, log_rpow (loglog_three_mul_pos hy)] + rw [hlw, delta] + exact crude_alg hC' h1 (log_add_log_three hy) (xi_mul_rpow hy) h2 h3 h4 h5 h6 + +end IwaniecLinearSieve.TheoremFour diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFourAux.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFourAux.lean new file mode 100644 index 000000000..1cf36d860 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFourAux.lean @@ -0,0 +1,264 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.LinearSieve.Defs +public import LeanPool.IwaniecLinearSieve.PrimeSums.Error +public import LeanPool.IwaniecLinearSieve.Rosser +import LeanPool.IwaniecLinearSieve.LinearSieve.Corollaries +import LeanPool.IwaniecLinearSieve.LinearSieve.LemmaEleven +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds +import Std.Tactic.BVDecide.Normalize.Bool + +/-! +# Auxiliary facts for [I71, Theorem 4] + +* the telescoping identity `∑_{a ≤ p < b} R(p)/p = R(a) - R(b)` (from `R_eq`), and the bound + for the depth-one source term of the upper sieve via `R_asymp`; +* monotonicity of `δ(s, y)` in `s`, and `δ(max s s₀, y) ≤ δ(s₀, y) δ(s, y)`; +* the inner level of the recursion: `(y/p)^{1/(t_p - 1)} = p`, the domain condition + `sMin (!lower) ≤ t_p - 1`, and `t_p - 1 ≤ ξ(y/p)` for `p ≥ y^{1/ξ(y)}`; +* the splitting of `fail lower (r+1) y z` at `w ≤ z`. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory Finset + +namespace IwaniecLinearSieve.TheoremFour + +/-! ### The depth-one source term -/ + +/-- Telescoping: `∑_{a ≤ p < b} R(p)/p = R(a) - R(b)` for `a ≤ b`. -/ +theorem sum_R_div_eq {a b : ℝ} (hab : a ≤ b) : + ∑ p ∈ (primesLT b).filter (fun p : ℕ => a ≤ p), R p / p = R a - R b := by + have h := sum_filter_add_sum_filter_not (primesLT b) (fun p : ℕ => a ≤ (p : ℝ)) + (fun p => R p / p) + have hs : (primesLT b).filter (fun p : ℕ => ¬ a ≤ (p : ℝ)) = primesLT a := by + ext p + simp only [mem_filter, mem_primesLT, not_le] + constructor + · rintro ⟨⟨hp, -⟩, h⟩; exact ⟨hp, h⟩ + · rintro ⟨hp, h⟩; exact ⟨⟨hp, h.trans_le hab⟩, h⟩ + rw [hs] at h + have ha := R_eq a + have hb := R_eq b + linarith + +/-- The depth-one source term of `fail false`: the primes `p < z` with `p³ ≥ y` (none for the +lower sieve). -/ +noncomputable def src (lower : Bool) (y z : ℝ) : ℝ := + if lower then 0 else ∑ p ∈ (primesLT z).filter (fun p : ℕ ↦ ¬ (p : ℝ) ^ 3 < y), R p / p + +theorem src_nonneg (lower : Bool) (y z : ℝ) : 0 ≤ src lower y z := by + unfold src + split_ifs + · exact le_rfl + · exact sum_nonneg fun p _ ↦ div_nonneg (R_nonneg _) p.cast_nonneg + +theorem fail_succ_eq (lower : Bool) (r : ℕ) (y z : ℝ) : + fail lower (r + 1) y z = + ∑ p ∈ rosserPrimes lower y z, fail (!lower) r (y / p) p / p + src lower y z := by + cases lower + · rw [fail_false_succ, src]; rfl + · rw [fail_true_succ, src, rosserPrimes_true]; simp + +/-- `¬ p³ < y ↔ y^{1/3} ≤ p`. -/ +theorem not_cube_lt_iff {y x : ℝ} (hy : 0 ≤ y) (hx : 0 ≤ x) : + ¬ x ^ 3 < y ↔ y ^ (1 / 3 : ℝ) ≤ x := by + rw [not_lt, one_div, rpow_inv_le_iff_of_pos hy hx (by norm_num)] + norm_cast + +/-- The source term for `z = y^{1/s}`: +`R(y^{1/3}) - R(y^{1/s}) ≤ cR (3 - s)⁺ / L + 6 C_R pntE(w) / L` for any `w ≥ 2` below `y^{1/s}` +and `y^{1/3}` (and `0` for the lower sieve). -/ +theorem src_le {cR CR : ℝ} (hR : ∀ z ≥ 2, |R z * log z - cR| ≤ CR * pntE z) {lower : Bool} + {y s w : ℝ} (hy : 1 < y) (hs : 1 ≤ s) (hw : 2 ≤ w) (hwz : w ≤ y ^ (1 / s)) + (hw3 : w ≤ y ^ (1 / 3 : ℝ)) : + src lower y (y ^ (1 / s)) ≤ + (if lower then 0 else cR * max (3 - s) 0 / log y) + 6 * CR * pntE w / log y := by + have hL : 0 < log y := log_pos hy + have hy0 : 0 < y := by linarith + have hCR : 0 ≤ CR := by + have h := (abs_nonneg _).trans (hR 2 le_rfl) + exact nonneg_of_mul_nonneg_left h (pntE_pos 2) + have hE : 0 ≤ 6 * CR * pntE w / log y := by have := pntE_pos w; positivity + cases lower + · simp only [src, Bool.false_eq_true, ite_false] + have hset : (primesLT (y ^ (1 / s))).filter (fun p : ℕ ↦ ¬ (p : ℝ) ^ 3 < y) = + (primesLT (y ^ (1 / s))).filter (fun p : ℕ ↦ y ^ (1 / 3 : ℝ) ≤ p) := + filter_congr fun p _ ↦ not_cube_lt_iff hy0.le p.cast_nonneg + rw [hset] + rcases le_total 3 s with h3 | h3 + · -- no primes + have : (primesLT (y ^ (1 / s))).filter (fun p : ℕ ↦ y ^ (1 / 3 : ℝ) ≤ p) = ∅ := by + refine eq_empty_of_forall_notMem fun p hp ↦ ?_ + rw [mem_filter, mem_primesLT] at hp + have := rpow_one_div_le_rpow_one_div hy.le (by norm_num) h3 + linarith [hp.1.2] + rw [this, sum_empty, max_eq_right (by linarith)] + simpa using hE + · rw [sum_R_div_eq (rpow_one_div_le_rpow_one_div hy.le (by linarith) h3), + max_eq_left (by linarith)] + have h1 := (abs_le.1 (hR _ (hw.trans hw3))).2 + have h2 := (abs_le.1 (hR _ (hw.trans hwz))).1 + rw [log_rpow_one_div hy0] at h1 h2 + have e1 : pntE (y ^ (1 / 3 : ℝ)) ≤ pntE w := pntE_le_pntE (by linarith) hw3 + have e2 : pntE (y ^ (1 / s)) ≤ pntE w := pntE_le_pntE (by linarith) hwz + have hR1 : R (y ^ (1 / 3 : ℝ)) ≤ 3 * (cR + CR * pntE w) / log y := by + rw [le_div_iff₀ hL] + nlinarith + have hR2 : s * (cR - CR * pntE w) / log y ≤ R (y ^ (1 / s)) := by + rw [div_le_iff₀ hL] + have : R (y ^ (1 / s)) * (log y / s) * s = R (y ^ (1 / s)) * log y := by + field_simp + have h2' : cR - CR * pntE w ≤ R (y ^ (1 / s)) * (log y / s) := by nlinarith + nlinarith [mul_le_mul_of_nonneg_left h2' (by linarith : (0 : ℝ) ≤ s)] + have : 3 * (cR + CR * pntE w) / log y - s * (cR - CR * pntE w) / log y ≤ + cR * (3 - s) / log y + 6 * CR * pntE w / log y := by + rw [← sub_div, ← add_div] + apply div_le_div_of_nonneg_right _ hL.le + have := pntE_pos w + nlinarith [mul_nonneg (mul_nonneg hCR this.le) (by linarith : (0 : ℝ) ≤ 3 - s)] + linarith + · simp only [src, ite_true] + simpa using hE + +/-! ### The compensation factor `δ` -/ +theorem one_le_delta {s : ℝ} (hs : 1 ≤ s) (y : ℝ) : 1 ≤ delta s y := by + rw [delta] + exact one_le_rpow (by linarith [lsx_nonneg (log y) hs]) (by linarith) + +theorem delta_le_delta {s s' : ℝ} (hs : 1 ≤ s) (hss' : s ≤ s') (y : ℝ) : + delta s y ≤ delta s' y := by + have hl := log_nonneg hs + have hll : log s ≤ log s' := log_le_log (by linarith) hss' + have hx0 := lsx_nonneg (log y) hs + have hx : s ^ 2 * log s ^ 5 / log y ^ 2 ≤ s' ^ 2 * log s' ^ 5 / log y ^ 2 := by gcongr + rw [delta, delta] + calc (1 + s ^ 2 * log s ^ 5 / log y ^ 2) ^ (5 * s) + ≤ (1 + s' ^ 2 * log s' ^ 5 / log y ^ 2) ^ (5 * s) := + rpow_le_rpow (by linarith) (by linarith) (by linarith) + _ ≤ _ := rpow_le_rpow_of_exponent_le (by linarith) (by linarith) + +theorem delta_max_le {s a : ℝ} (hs : 1 ≤ s) (ha : 1 ≤ a) (y : ℝ) : + delta (max s a) y ≤ delta a y * delta s y := by + rcases le_total s a with h | h + · rw [max_eq_right h] + exact le_mul_of_one_le_right (by linarith [one_le_delta ha y]) (one_le_delta hs y) + · rw [max_eq_left h] + exact le_mul_of_one_le_left (by linarith [one_le_delta hs y]) (one_le_delta ha y) + +/-! ### The inner level of the recursion -/ + +/-- `(y/p)^{1/(t_p - 1)} = p` for `1 < p < y`, `t_p = log y / log p`. -/ +theorem rpow_inner_eq {y : ℝ} {p : ℕ} (hp : 1 < p) (hpy : (p : ℝ) < y) : + (y / p) ^ (1 / (log y / log p - 1)) = p := by + have hp0 : (0 : ℝ) < p := by positivity + have hy0 : 0 < y := hp0.trans hpy + have hlp : 0 < log (p : ℝ) := log_pos (by exact_mod_cast hp) + have ht : 0 < log y / log p - 1 := by + rw [sub_pos, one_lt_div hlp]; exact log_lt_log hp0 hpy + rw [rpow_def_of_pos (div_pos hy0 hp0), log_div_prime_eq hy0 hp, mul_one_div, + mul_div_cancel_right₀ _ ht.ne', exp_log hp0] + +/-- `p < y^{1/s} ⇒ s < t_p`. -/ +theorem lt_div_log_of_lt_rpow {y s : ℝ} {p : ℕ} (hy : 1 < y) (hs : 0 < s) (hp : 1 < p) + (hpz : (p : ℝ) < y ^ (1 / s)) : s < log y / log p := by + have hlp : 0 < log (p : ℝ) := log_pos (by exact_mod_cast hp) + have h := log_lt_log (by positivity) hpz + rw [log_rpow_one_div (by linarith)] at h + rw [lt_div_iff₀ hlp]; rw [lt_div_iff₀ hs] at h; linarith + +theorem prime_lt_of_mem_rosserPrimes {lower : Bool} {y s : ℝ} {p : ℕ} (hy : 1 < y) (hs : 1 ≤ s) + (hp : p ∈ rosserPrimes lower y (y ^ (1 / s))) : (p : ℝ) < y := by + have h := lt_of_mem_primesLT (rosserPrimes_subset hp) + calc (p : ℝ) < y ^ (1 / s) := h + _ ≤ y ^ (1 / (1 : ℝ)) := rpow_one_div_le_rpow_one_div hy.le one_pos hs + _ = y := by simp + +/-- The inner parameter `t_p - 1` lies in the domain of `!lower`. -/ +theorem sMin_le_inner {lower : Bool} {y s : ℝ} {p : ℕ} (hy : 1 < y) (hs : sMin lower ≤ s) + (hp : p ∈ rosserPrimes lower y (y ^ (1 / s))) : sMin (!lower) ≤ log y / log p - 1 := by + have hpP := prime_of_mem_primesLT (rosserPrimes_subset hp) + have hlp : 0 < log (p : ℝ) := log_pos (by exact_mod_cast hpP.one_lt) + cases lower + · -- `p³ < y` + have h3 := ((mem_rosserPrimes.1 hp).2.resolve_left (by simp)) + have h := log_lt_log (by have := hpP.pos; positivity) h3 + rw [log_pow] at h + have : 3 < log y / log p := by rw [lt_div_iff₀ hlp]; push_cast at h; linarith + simp only [Bool.not_false, sMin] + linarith + · have hs2 : (2 : ℝ) ≤ s := hs + have := lt_div_log_of_lt_rpow hy (by linarith) hpP.one_lt + (lt_of_mem_primesLT (rosserPrimes_subset hp)) + simp only [Bool.not_true, sMin] + linarith + +theorem one_lt_log_three_mul {x : ℝ} (hx : 1 ≤ x) : 1 < log (3 * x) := by + rw [lt_log_iff_exp_lt (by linarith)] + have := exp_one_lt_d9 + linarith + +/-- `log (y^{1/ξ(y)}) = (log log 3y)^{11/5}`. -/ +theorem log_rpow_one_div_xi {y : ℝ} (hy : 1 < y) : + log (y ^ (1 / xi y)) = log (log (3 * y)) ^ (11 / 5 : ℝ) := by + have hL : 0 < log y := log_pos hy + have hℓ : 0 < log (log (3 * y)) := log_pos (one_lt_log_three_mul hy.le) + have hP : 0 < log (log (3 * y)) ^ (11 / 5 : ℝ) := rpow_pos_of_pos hℓ _ + rw [log_rpow_one_div (by linarith), xi, div_div_cancel₀ hL.ne'] + +/-- For `y^{1/ξ(y)} ≤ p < y`, the inner parameter satisfies `t_p - 1 ≤ ξ(y/p)`. -/ +theorem inner_le_xi {y : ℝ} {p : ℕ} (hy : 1 < y) (hp : 1 < p) (hpy : (p : ℝ) < y) + (hw : y ^ (1 / xi y) ≤ p) : log y / log p - 1 ≤ xi (y / p) := by + have hp0 : (0 : ℝ) < p := by positivity + have hy0 : 0 < y := by linarith + have hlp : 0 < log (p : ℝ) := log_pos (by exact_mod_cast hp) + have hℓ : 0 < log (log (3 * y)) := log_pos (one_lt_log_three_mul hy.le) + have hyp1 : 1 < y / p := by rw [one_lt_div hp0]; exact hpy + have hℓ' : 0 < log (log (3 * (y / p))) := log_pos (one_lt_log_three_mul hyp1.le) + have hℓℓ' : log (log (3 * (y / p))) ≤ log (log (3 * y)) := by + refine log_le_log (log_pos (by linarith)) (log_le_log (by positivity) ?_) + gcongr + exact div_le_self hy0.le (by exact_mod_cast hp.le) + have hP' : 0 < log (log (3 * (y / p))) ^ (11 / 5 : ℝ) := rpow_pos_of_pos hℓ' _ + have hPP : log (log (3 * (y / p))) ^ (11 / 5 : ℝ) ≤ log (log (3 * y)) ^ (11 / 5 : ℝ) := + rpow_le_rpow hℓ'.le hℓℓ' (by norm_num) + -- `(log log 3y)^{11/5} ≤ log p` + have hw' : log (log (3 * y)) ^ (11 / 5 : ℝ) ≤ log p := by + rw [← log_rpow_one_div_xi hy] + exact log_le_log (rpow_pos_of_pos hy0 _) hw + have ht : 0 < log y / log p - 1 := by + rw [sub_pos, one_lt_div hlp]; exact log_lt_log hp0 hpy + rw [xi, log_div_prime_eq hy0 hp, le_div_iff₀ hP'] + calc (log y / log p - 1) * log (log (3 * (y / p))) ^ (11 / 5 : ℝ) + ≤ (log y / log p - 1) * log p := by + gcongr; exact hPP.trans hw' + _ = log p * (log y / log p - 1) := mul_comm _ _ + +/-! ### Splitting the prime sum -/ +theorem rosserPrimes_filter_lt {lower : Bool} {y z w : ℝ} (hwz : w ≤ z) : + (rosserPrimes lower y z).filter (fun p : ℕ ↦ ¬ w ≤ p) = rosserPrimes lower y w := by + ext p + simp only [mem_filter, mem_rosserPrimes, mem_primesLT, not_le] + constructor + · rintro ⟨⟨⟨hp, -⟩, h⟩, hw⟩; exact ⟨⟨hp, hw⟩, h⟩ + · rintro ⟨⟨hp, hw⟩, h⟩; exact ⟨⟨⟨hp, hw.trans_le hwz⟩, h⟩, hw⟩ + +/-- `fail lower (r+1) y z ≤ fail lower (r+1) y w + ∑_{w ≤ p} (inner terms) + source`. -/ +theorem fail_succ_le_split (lower : Bool) (r : ℕ) {y z w : ℝ} (hwz : w ≤ z) : + fail lower (r + 1) y z ≤ fail lower (r + 1) y w + + ∑ p ∈ (rosserPrimes lower y z).filter (fun p : ℕ ↦ w ≤ p), + fail (!lower) r (y / p) p / p + src lower y z := by + rw [fail_succ_eq, fail_succ_eq lower r y w, + ← sum_filter_add_sum_filter_not (rosserPrimes lower y z) (fun p : ℕ ↦ w ≤ (p : ℝ)), + rosserPrimes_filter_lt hwz] + linarith [src_nonneg lower y w] + +end IwaniecLinearSieve.TheoremFour diff --git a/LeanPool/IwaniecLinearSieve/PrimeSums.lean b/LeanPool/IwaniecLinearSieve/PrimeSums.lean new file mode 100644 index 000000000..e22f4b3a3 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/PrimeSums.lean @@ -0,0 +1,29 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.PrimeSums.Error +public import LeanPool.IwaniecLinearSieve.PrimeSums.Mertens +public import LeanPool.IwaniecLinearSieve.PrimeSums.Product +public import LeanPool.IwaniecLinearSieve.PrimeSums.SummationByParts +public import LeanPool.IwaniecLinearSieve.PrimeSums.Lemma13 +public import LeanPool.IwaniecLinearSieve.PrimeSums.NthPrime + +/-! +# Prime sums with de la Vallée Poussin error terms, from `StrongPNT` + +* `IwaniecLinearSieve.PrimeSums.Error`: the error term `pntE x = exp (-pntκ √(log x))` and + `theta_asymp : |θ x - x| ≤ C x pntE x` for `x ≥ 2`. +* `IwaniecLinearSieve.PrimeSums.Mertens`: `S x = ∑_{p ≤ x} 1/p` and `S_asymp`. +* `IwaniecLinearSieve.PrimeSums.Product`: `R_asymp`, `R_lower`, `R_upper`. +* `IwaniecLinearSieve.PrimeSums.SummationByParts`: an abstract summation by parts bound. +* `IwaniecLinearSieve.PrimeSums.Lemma13`: [I71, Lemma 13] (`lemma13_mono`, `lemma13_anti`) and + [I71, Lemma 14] (`lemma14`). +* `IwaniecLinearSieve.PrimeSums.NthPrime`: `nth_prime_le`. +-/ + +@[expose] public section diff --git a/LeanPool/IwaniecLinearSieve/PrimeSums/Error.lean b/LeanPool/IwaniecLinearSieve/PrimeSums/Error.lean new file mode 100644 index 000000000..325cc6c05 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/PrimeSums/Error.lean @@ -0,0 +1,213 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.StrongPNT +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds + +/-! +# The de la Vallée Poussin error term + +We fix once and for all a constant `pntκ > 0` and the error function +`pntE x = exp (-pntκ * √(log x))`, and deduce from `StrongPNT` that +`θ(x) = x + O(x · pntE x)` for `x ≥ 2`, with an explicit constant valid for all `x ≥ 2`. + +The constant `pntκ` is the minimum of the constant `c` of `StrongPNT` and `1 / 2`; the bound +`pntκ ≤ 1 / 2` lets `pntE x` dominate `x ^ (-1/2) * log x` and `1 / x`. +-/ + +@[expose] public section + +open IwaniecLinearSievePNT Real Filter Asymptotics Topology + +namespace IwaniecLinearSieve + +/-- The constant `c` in `StrongPNT`. -/ +noncomputable def pntc : ℝ := StrongPNT.choose + +theorem pntc_pos : 0 < pntc := StrongPNT.choose_spec.1 + +/-- The constant `κ` in the error term `exp (-κ √(log x))` used throughout. -/ +noncomputable def pntκ : ℝ := min pntc (1 / 2) + +theorem pntκ_pos : 0 < pntκ := lt_min pntc_pos (by norm_num) + +theorem pntκ_le_half : pntκ ≤ 1 / 2 := min_le_right _ _ + +theorem pntκ_le_pntc : pntκ ≤ pntc := min_le_left _ _ + +/-- The de la Vallée Poussin error term `exp (-κ √(log x))`. -/ +noncomputable def pntE (x : ℝ) : ℝ := exp (-pntκ * √(log x)) + +theorem pntE_pos (x : ℝ) : 0 < pntE x := exp_pos _ + +theorem pntE_nonneg (x : ℝ) : 0 ≤ pntE x := (pntE_pos x).le + +theorem pntE_le_one (x : ℝ) : pntE x ≤ 1 := by + rw [pntE, exp_le_one_iff, neg_mul] + exact neg_nonpos.2 (mul_nonneg pntκ_pos.le (sqrt_nonneg _)) + +theorem pntE_le_pntE {x y : ℝ} (hx : 0 < x) (hxy : x ≤ y) : pntE y ≤ pntE x := by + unfold pntE + apply exp_le_exp.2 + rw [neg_mul, neg_mul, neg_le_neg_iff] + exact mul_le_mul_of_nonneg_left (sqrt_le_sqrt (log_le_log hx hxy)) pntκ_pos.le + +theorem pntE_antitoneOn : AntitoneOn pntE (Set.Ioi 0) := + fun _ hx _ _ hxy ↦ pntE_le_pntE hx hxy + +theorem pntE_antitoneOn_Ici_one : AntitoneOn pntE (Set.Ici 1) := + pntE_antitoneOn.mono fun _ hx ↦ lt_of_lt_of_le one_pos (Set.mem_Ici.1 hx) + +theorem tendsto_pntE : Tendsto pntE atTop (𝓝 0) := by + have h : Tendsto (fun x ↦ -pntκ * √(log x)) atTop atBot := + (tendsto_sqrt_atTop.comp tendsto_log_atTop).const_mul_atTop_of_neg (neg_lt_zero.2 pntκ_pos) + exact tendsto_exp_atBot.comp h + +/-- `pntE` dominates `1 / x`. -/ +theorem inv_le_pntE {x : ℝ} (hx : 2 ≤ x) : x⁻¹ ≤ pntE x := by + have hx0 : 0 < x := by linarith + have hL : 1 / 4 ≤ log x := by + have := log_two_gt_d9 + have := log_le_log (by norm_num) hx + linarith + have hs : 1 / 2 ≤ √(log x) := by + exact (le_sqrt (by norm_num) (by linarith)).2 (by linarith) + rw [← exp_log (inv_pos.2 hx0), pntE, log_inv] + apply exp_le_exp.2 + have h1 : pntκ * √(log x) ≤ √(log x) * √(log x) := by + have := pntκ_le_half + have := sqrt_nonneg (log x) + nlinarith + rw [mul_self_sqrt (by linarith)] at h1 + linarith + +theorem one_div_mul_log_le_pntE {x : ℝ} (hx : 2 ≤ x) : 1 / (x * log x) ≤ 2 * pntE x := by + have hx0 : 0 < x := by linarith + have hL : 1 / 2 ≤ log x := by + have := log_two_gt_d9 + have := log_le_log (by norm_num) hx + linarith + calc 1 / (x * log x) = x⁻¹ * (log x)⁻¹ := by rw [one_div, mul_inv] + _ ≤ pntE x * 2 := by + refine mul_le_mul (inv_le_pntE hx) ?_ (inv_nonneg.2 (by linarith)) (pntE_nonneg _) + rw [inv_le_comm₀ (by linarith) (by norm_num)] + linarith + _ = 2 * pntE x := mul_comm _ _ + +/-- `pntE` dominates `x ^ (-1/2) * log x`. -/ +theorem sqrt_mul_log_le {x : ℝ} (hx : 1 ≤ x) : √x * log x ≤ 12 * x * pntE x := by + have hx0 : 0 < x := by linarith + set L := log x with hLdef + have hL : 0 ≤ L := log_nonneg hx + have hsx : √x = exp (L / 2) := by + rw [sqrt_eq_iff_mul_self_eq hx0.le (exp_pos _).le, ← exp_add, add_halves, hLdef, + exp_log hx0] + have hxL : x = exp (L / 2) * exp (L / 2) := by + rw [← exp_add, add_halves, hLdef, exp_log hx0] + clear_value L + -- `L ≤ 4 exp (L / 4)` and `κ √L ≤ (L + 1) / 4`. + have h1 : L ≤ 4 * exp (L / 4) := by linarith [add_one_le_exp (L / 4)] + have h2 : pntκ * √L ≤ L / 4 + 1 / 4 := by + have hκ := pntκ_le_half + have hs := sqrt_nonneg L + have hsq := mul_self_sqrt hL + nlinarith [sq_nonneg (√L - 1)] + have h3 : exp (pntκ * √L) ≤ 3 * exp (L / 4) := by + calc exp (pntκ * √L) ≤ exp (L / 4 + 1 / 4) := exp_le_exp.2 h2 + _ = exp (L / 4) * exp (1 / 4) := exp_add _ _ + _ ≤ exp (L / 4) * 3 := by + gcongr + calc exp (1 / 4 : ℝ) ≤ exp 1 := exp_le_exp.2 (by norm_num) + _ ≤ 3 := by have := exp_one_lt_d9; linarith + _ = 3 * exp (L / 4) := mul_comm _ _ + have h4 : L * exp (pntκ * √L) ≤ 12 * exp (L / 2) := by + calc L * exp (pntκ * √L) ≤ (4 * exp (L / 4)) * (3 * exp (L / 4)) := by + gcongr + _ = 12 * (exp (L / 4) * exp (L / 4)) := by ring + _ = 12 * exp (L / 2) := by rw [← exp_add]; ring_nf + have hE : pntE x * exp (pntκ * √L) = 1 := by + rw [pntE, ← exp_add, ← hLdef]; simp + have h5 : √x * (12 * exp (L / 2)) = 12 * x := by + rw [hsx, hxL]; ring + calc √x * L = √x * L * (pntE x * exp (pntκ * √L)) := by rw [hE, mul_one] + _ = √x * pntE x * (L * exp (pntκ * √L)) := by ring + _ ≤ √x * pntE x * (12 * exp (L / 2)) := by + gcongr + exact mul_nonneg (sqrt_nonneg _) (pntE_nonneg _) + _ = pntE x * (√x * (12 * exp (L / 2))) := by ring + _ = 12 * x * pntE x := by rw [h5]; ring + +theorem hasDerivAt_pntE {x : ℝ} (hx : 1 < x) : + HasDerivAt pntE (pntE x * (-pntκ * (x⁻¹ / (2 * √(log x))))) x := by + have hlog : HasDerivAt log x⁻¹ x := hasDerivAt_log (by linarith) + have h := ((hlog.sqrt (log_pos hx).ne').const_mul (-pntκ)).exp + exact h + +/-- The prime number theorem for `ψ` with the error term `pntE`, valid from some point on. -/ +theorem exists_abs_psi_sub_le : + ∃ C X : ℝ, 0 ≤ C ∧ ∀ x ≥ X, |Chebyshev.psi x - x| ≤ C * x * pntE x := by + obtain ⟨C, hC⟩ := isBigO_iff.1 StrongPNT.choose_spec.2 + obtain ⟨X, hX⟩ := eventually_atTop.1 hC + refine ⟨max C 0, max X 1, le_max_right _ _, fun x hx ↦ ?_⟩ + have hx1 : 1 ≤ x := (le_max_right _ _).trans hx + have hx0 : 0 < x := by linarith + have h := hX x ((le_max_left _ _).trans hx) + simp only [Pi.sub_apply, id, norm_eq_abs, norm_mul, abs_of_pos hx0, abs_exp] at h + have hexp : exp (-StrongPNT.choose * log x ^ ((1 : ℝ) / 2)) ≤ pntE x := by + rw [pntE, ← sqrt_eq_rpow] + apply exp_le_exp.2 + rw [neg_mul, neg_mul, neg_le_neg_iff] + exact mul_le_mul_of_nonneg_right pntκ_le_pntc (sqrt_nonneg _) + calc |Chebyshev.psi x - x| ≤ C * (x * exp (-StrongPNT.choose * log x ^ ((1 : ℝ) / 2))) := h + _ ≤ max C 0 * (x * exp (-StrongPNT.choose * log x ^ ((1 : ℝ) / 2))) := by + gcongr + exact le_max_left _ _ + _ ≤ max C 0 * (x * pntE x) := by gcongr + _ = max C 0 * x * pntE x := by ring + +/-- The prime number theorem for `θ`: `|θ x - x| ≤ C x exp (-κ √(log x))` for all `x ≥ 2`. -/ +theorem theta_asymp : ∃ C : ℝ, 0 ≤ C ∧ ∀ x ≥ 2, |Chebyshev.theta x - x| ≤ C * x * pntE x := by + obtain ⟨C, X, hC, hX⟩ := exists_abs_psi_sub_le + set X' := max X 2 + refine ⟨max (C + 24) (pntE X')⁻¹, (hC.trans (by linarith)).trans (le_max_left _ _), + fun x hx ↦ ?_⟩ + have hx0 : 0 < x := by linarith + have hE := pntE_pos x + rcases le_or_gt X' x with hxX | hxX + · -- large `x`: use the PNT for `ψ` and `ψ - θ = O(√x log x)`. + have h1 := hX x ((le_max_left _ _).trans hxX) + have h2 := Chebyshev.psi_sub_theta_le (x := x) (by linarith) + have h3 := Chebyshev.theta_le_psi x + have h4 := sqrt_mul_log_le (x := x) (by linarith) + calc |Chebyshev.theta x - x| + ≤ |Chebyshev.psi x - x| + (Chebyshev.psi x - Chebyshev.theta x) := by + have h5 := le_abs_self (Chebyshev.psi x - x) + have h6 := neg_abs_le (Chebyshev.psi x - x) + rw [abs_le]; constructor <;> linarith + _ ≤ C * x * pntE x + 2 * (12 * x * pntE x) := by linarith + _ = (C + 24) * x * pntE x := by ring + _ ≤ max (C + 24) (pntE X')⁻¹ * x * pntE x := by gcongr; exact le_max_left _ _ + · -- small `x`: `0 ≤ θ x ≤ log 4 * x ≤ 2 x` and `pntE x ≥ pntE X'`. + have h1 := Chebyshev.theta_nonneg x + have h2 := Chebyshev.theta_le_log4_mul_x hx0.le + have hlog4 : log 4 < 2 := by + rw [show (4 : ℝ) = 2 ^ 2 by norm_num, log_pow] + have := log_two_lt_d9 + push_cast + linarith + have h3 : |Chebyshev.theta x - x| ≤ x := by + rw [abs_le]; constructor <;> nlinarith + have h4 : pntE X' ≤ pntE x := pntE_le_pntE hx0 hxX.le + calc |Chebyshev.theta x - x| ≤ x := h3 + _ = (pntE X')⁻¹ * x * pntE X' := by have := (pntE_pos X').ne'; field_simp + _ ≤ (pntE X')⁻¹ * x * pntE x := + mul_le_mul_of_nonneg_left h4 (by have := pntE_pos X'; positivity) + _ ≤ max (C + 24) (pntE X')⁻¹ * x * pntE x := by gcongr; exact le_max_right _ _ + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/PrimeSums/Lemma13.lean b/LeanPool/IwaniecLinearSieve/PrimeSums/Lemma13.lean new file mode 100644 index 000000000..987b9b1a3 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/PrimeSums/Lemma13.lean @@ -0,0 +1,423 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.PrimeSums.Mertens +import LeanPool.IwaniecLinearSieve.PrimeSums.SummationByParts +import Mathlib.Algebra.Order.Star.Real + +/-! +# [I71, Lemma 13] and [I71, Lemma 14] + +For `b ≥ 0` monotone on `[B, A]`, `2 ≤ B ≤ A`, +`∑_{B ≤ p ≤ A} b(p)/p = ∫_B^A b(x) / (x log x) dx + O(b(A) exp(-κ √(log B)))`, +and the analogous statement with `b(B)` for `b` antitone. + +The proof is Iwaniec's: summation by parts against `S(n)` (in the abstract form +`abs_sum_sub_integral_le`) at the points `B, ⌊B⌋ + 1, …, ⌊A⌋, A`, using `S_asymp`. +-/ + +@[expose] public section + +open Real Finset MeasureTheory intervalIntegral + +namespace IwaniecLinearSieve + +/-! ### Elementary facts about `log ∘ log` -/ +theorem continuousOn_inv_mul_log {u v : ℝ} (hu : 1 < u) : + ContinuousOn (fun x ↦ (x * log x)⁻¹) (Set.Icc u v) := by + have hpos : ∀ x ∈ Set.Icc u v, 1 < x := fun x hx ↦ by linarith [hx.1] + refine ContinuousOn.inv₀ (ContinuousOn.mul continuousOn_id ?_) fun x hx ↦ ?_ + · exact continuousOn_log.mono fun x hx ↦ by + simp only [Set.mem_compl_iff, Set.mem_singleton_iff]; linarith [hpos x hx] + · have := hpos x hx + have := log_pos this + positivity + +theorem integral_inv_mul_log {u v : ℝ} (hu : 1 < u) (huv : u ≤ v) : + ∫ x in u..v, (x * log x)⁻¹ = log (log v) - log (log u) := by + have hpos : ∀ x ∈ Set.uIcc u v, 1 < x := fun x hx ↦ by + rw [Set.uIcc_of_le huv] at hx; linarith [hx.1] + refine integral_eq_sub_of_hasDerivAt (f := fun x ↦ log (log x)) (fun x hx ↦ ?_) ?_ + · have hx := hpos x hx + have h := (hasDerivAt_log (by linarith : x ≠ 0)).log (log_pos hx).ne' + convert h using 1 + rw [mul_inv, div_eq_mul_inv] + · refine ContinuousOn.intervalIntegrable ?_ + rw [Set.uIcc_of_le huv] + exact continuousOn_inv_mul_log hu + +theorem log_log_sub_log_log_le {u v : ℝ} (hu : 1 < u) (huv : u ≤ v) : + log (log v) - log (log u) ≤ (v - u) / (u * log u) := by + have hu0 : 0 < u := by linarith + have hlu : 0 < log u := log_pos hu + have hlv : 0 < log v := log_pos (by linarith) + have h1 : log (log v) - log (log u) ≤ log v / log u - 1 := by + rw [← log_div hlv.ne' hlu.ne'] + exact log_le_sub_one_of_pos (div_pos hlv hlu) + have h2 : log v - log u ≤ v / u - 1 := by + rw [← log_div (by linarith) hu0.ne'] + exact log_le_sub_one_of_pos (div_pos (by linarith) hu0) + calc log (log v) - log (log u) ≤ log v / log u - 1 := h1 + _ = (log v - log u) / log u := by field_simp + _ ≤ (v / u - 1) / log u := by gcongr + _ = (v - u) / (u * log u) := by field_simp + +/-! ### The partition `B, ⌊B⌋ + 1, …, ⌊A⌋, A` of `[B, A]` -/ + +/-- The points `B = a 0 ≤ ⌊B⌋ + 1 ≤ ⋯ ≤ ⌊A⌋ ≤ A = a (⌊A⌋ - ⌊B⌋ + 1)`. -/ +noncomputable def clampPt (B A : ℝ) (j : ℕ) : ℝ := max B (min ((⌊B⌋₊ + j : ℕ) : ℝ) A) + +theorem clampPt_mono (B A : ℝ) : Monotone (clampPt B A) := fun i j hij ↦ by + unfold clampPt + gcongr + +theorem clampPt_zero {B A : ℝ} (hB : 0 ≤ B) : clampPt B A 0 = B := by + unfold clampPt + exact max_eq_left ((min_le_left _ _).trans (by simpa using Nat.floor_le hB)) + +theorem clampPt_last {B A : ℝ} (hBA : B ≤ A) : + clampPt B A (⌊A⌋₊ - ⌊B⌋₊ + 1) = A := by + unfold clampPt + have h : ⌊B⌋₊ + (⌊A⌋₊ - ⌊B⌋₊ + 1) = ⌊A⌋₊ + 1 := by + have := Nat.floor_le_floor (a := B) hBA; omega + rw [h, min_eq_right (by push_cast; exact (Nat.lt_floor_add_one A).le), max_eq_right hBA] + +theorem le_clampPt (B A : ℝ) (j : ℕ) : B ≤ clampPt B A j := le_max_left _ _ + +theorem clampPt_le {B A : ℝ} (hBA : B ≤ A) (j : ℕ) : clampPt B A j ≤ A := + max_le hBA (min_le_right _ _) + +theorem clampPt_succ_le (B A : ℝ) (j : ℕ) : clampPt B A (j + 1) ≤ clampPt B A j + 1 := by + unfold clampPt + push_cast + simp only [max_def, min_def] + split_ifs <;> linarith + +theorem clampPt_eq {B A : ℝ} {j : ℕ} (hj : 1 ≤ j) + (hjA : ((⌊B⌋₊ + j : ℕ) : ℝ) ≤ A) : clampPt B A j = ((⌊B⌋₊ + j : ℕ) : ℝ) := by + unfold clampPt + rw [min_eq_left hjA, max_eq_right] + have := Nat.lt_floor_add_one B + have : (1 : ℝ) ≤ j := by exact_mod_cast hj + push_cast + linarith + +theorem floor_clampPt {B A : ℝ} (hB : 0 ≤ B) (hBA : B ≤ A) (j : ℕ) : + ⌊clampPt B A j⌋₊ = min (⌊B⌋₊ + j) ⌊A⌋₊ := by + unfold clampPt + set k := ⌊B⌋₊ + j with hk + rcases le_or_gt (k : ℝ) A with hkA | hkA + · rw [min_eq_left hkA, min_eq_left (Nat.le_floor hkA)] + rcases le_or_gt B (k : ℝ) with hBk | hBk + · rw [max_eq_right hBk, Nat.floor_natCast] + · rw [max_eq_left hBk.le] + have : k ≤ ⌊B⌋₊ := Nat.le_floor hBk.le + omega + · rw [min_eq_right hkA.le, max_eq_right hBA, min_eq_right] + exact (Nat.cast_lt (α := ℝ)).1 ((Nat.floor_le (hB.trans hBA)).trans_lt hkA) |>.le + +/-- `S x` only depends on `⌊x⌋₊`. -/ +theorem S_eq_S_floor (x : ℝ) : S x = S (⌊x⌋₊ : ℝ) := by + rw [S_eq_sum, S_eq_sum, Nat.floor_natCast] + +theorem S_succ_sub (k : ℕ) : + S ((k + 1 : ℕ) : ℝ) - S (k : ℝ) = if (k + 1).Prime then ((k + 1 : ℕ) : ℝ)⁻¹ else 0 := by + rw [S_eq_sum, S_eq_sum, Nat.floor_natCast, Nat.floor_natCast, sum_range_succ] + ring + +/-- The primes `p` with `B < p ≤ A`. -/ +noncomputable def primesIoc (B A : ℝ) : Finset ℕ := {p ∈ Ioc ⌊B⌋₊ ⌊A⌋₊ | p.Prime} + +/-- The primes `p` with `B ≤ p ≤ A`. -/ +noncomputable def primesIcc (B A : ℝ) : Finset ℕ := {p ∈ Icc ⌈B⌉₊ ⌊A⌋₊ | p.Prime} + +/-- The primes `p` with `B < p < A`. -/ +noncomputable def primesIoo (B A : ℝ) : Finset ℕ := {p ∈ Ioo ⌊B⌋₊ ⌈A⌉₊ | p.Prime} + +theorem le_floor_iff_of_prime {p : ℕ} (hp : p.Prime) {A : ℝ} : p ≤ ⌊A⌋₊ ↔ (p : ℝ) ≤ A := by + rcases le_or_gt 0 A with hA | hA + · exact Nat.le_floor_iff hA + · rw [Nat.floor_of_nonpos hA.le] + have : (0 : ℝ) < p := by exact_mod_cast hp.pos + constructor <;> intro h + · exact absurd h (by have := hp.pos; omega) + · linarith + +theorem floor_lt_iff_of_prime {p : ℕ} (hp : p.Prime) {B : ℝ} : ⌊B⌋₊ < p ↔ B < p := by + rcases le_or_gt 0 B with hB | hB + · exact Nat.floor_lt hB + · rw [Nat.floor_of_nonpos hB.le] + have : (0 : ℝ) < p := by exact_mod_cast hp.pos + exact ⟨fun _ ↦ by linarith, fun _ ↦ hp.pos⟩ + +theorem mem_primesIoc {B A : ℝ} {p : ℕ} : p ∈ primesIoc B A ↔ p.Prime ∧ B < p ∧ (p : ℝ) ≤ A := by + simp only [primesIoc, mem_filter, mem_Ioc] + constructor + · rintro ⟨⟨h1, h2⟩, hp⟩ + exact ⟨hp, (floor_lt_iff_of_prime hp).1 h1, (le_floor_iff_of_prime hp).1 h2⟩ + · rintro ⟨hp, h1, h2⟩ + exact ⟨⟨(floor_lt_iff_of_prime hp).2 h1, (le_floor_iff_of_prime hp).2 h2⟩, hp⟩ + +theorem mem_primesIcc {B A : ℝ} {p : ℕ} : + p ∈ primesIcc B A ↔ p.Prime ∧ B ≤ p ∧ (p : ℝ) ≤ A := by + simp only [primesIcc, mem_filter, mem_Icc, Nat.ceil_le] + constructor + · rintro ⟨⟨h1, h2⟩, hp⟩ + exact ⟨hp, h1, (le_floor_iff_of_prime hp).1 h2⟩ + · rintro ⟨hp, h1, h2⟩ + exact ⟨⟨h1, (le_floor_iff_of_prime hp).2 h2⟩, hp⟩ + +theorem mem_primesIoo {B A : ℝ} {p : ℕ} : p ∈ primesIoo B A ↔ p.Prime ∧ B < p ∧ (p : ℝ) < A := by + simp only [primesIoo, mem_filter, mem_Ioo, Nat.lt_ceil] + constructor + · rintro ⟨⟨h1, h2⟩, hp⟩ + exact ⟨hp, (floor_lt_iff_of_prime hp).1 h1, h2⟩ + · rintro ⟨hp, h1, h2⟩ + exact ⟨⟨(floor_lt_iff_of_prime hp).2 h1, h2⟩, hp⟩ + +/-- Summation by parts identity: the Stieltjes sum against `S` over the partition `clampPt` +is the sum over primes in `(B, A]`. -/ +theorem sum_clampPt_eq (b : ℝ → ℝ) {B A : ℝ} (hB : 0 ≤ B) (hBA : B ≤ A) : + ∑ j ∈ range (⌊A⌋₊ - ⌊B⌋₊ + 1), + b (clampPt B A (j + 1)) * (S (clampPt B A (j + 1)) - S (clampPt B A j)) = + ∑ p ∈ primesIoc B A, b p / p := by + have hmN : ⌊B⌋₊ ≤ ⌊A⌋₊ := Nat.floor_le_floor hBA + have hS : ∀ j, S (clampPt B A j) = S ((min (⌊B⌋₊ + j) ⌊A⌋₊ : ℕ) : ℝ) := fun j ↦ by + rw [S_eq_S_floor, floor_clampPt hB hBA] + rw [sum_range_succ, hS, hS, show min (⌊B⌋₊ + (⌊A⌋₊ - ⌊B⌋₊ + 1)) ⌊A⌋₊ = ⌊A⌋₊ by omega, + show min (⌊B⌋₊ + (⌊A⌋₊ - ⌊B⌋₊)) ⌊A⌋₊ = ⌊A⌋₊ by omega, sub_self, mul_zero, add_zero, + primesIoc, sum_filter, ← Finset.Ico_add_one_add_one_eq_Ioc, sum_Ico_eq_sum_range, + show ⌊A⌋₊ + 1 - (⌊B⌋₊ + 1) = ⌊A⌋₊ - ⌊B⌋₊ by omega] + refine sum_congr rfl fun j hj ↦ ?_ + have hj : j < ⌊A⌋₊ - ⌊B⌋₊ := mem_range.1 hj + have hc : clampPt B A (j + 1) = ((⌊B⌋₊ + (j + 1) : ℕ) : ℝ) := by + refine clampPt_eq (by omega) ?_ + exact (Nat.le_floor_iff (hB.trans hBA)).1 (by omega) + rw [hS, hS, min_eq_left (by omega), min_eq_left (by omega), hc, + show ⌊B⌋₊ + (j + 1) = ⌊B⌋₊ + j + 1 by ring, S_succ_sub, + show ⌊B⌋₊ + 1 + j = ⌊B⌋₊ + j + 1 by ring] + split_ifs <;> simp [div_eq_mul_inv] + +theorem S_asymp_nonneg : ∃ c₅ C : ℝ, 0 ≤ C ∧ ∀ x ≥ 2, |S x - log (log x) - c₅| ≤ C * pntE x := by + obtain ⟨c₅, C, hC⟩ := S_asymp + refine ⟨c₅, C, ?_, hC⟩ + exact nonneg_of_mul_nonneg_left ((abs_nonneg _).trans (hC 2 le_rfl)) (pntE_pos 2) + +/-! ### Lemma 13 -/ + +/-- [I71, Lemma 13] for the primes in `(B, A]`. -/ +theorem lemma13_Ioc : ∃ C, 0 ≤ C ∧ ∀ (b : ℝ → ℝ) (A B : ℝ), 2 ≤ B → B ≤ A → + MonotoneOn b (Set.Icc B A) → (∀ x ∈ Set.Icc B A, 0 ≤ b x) → + |∑ p ∈ primesIoc B A, b p / p - ∫ x in B..A, b x / (x * log x)| ≤ C * b A * pntE B := by + obtain ⟨c₅, C, hC0, hC⟩ := S_asymp_nonneg + refine ⟨2 + 2 * C, by linarith, fun b A B hB hBA hb hb0 ↦ ?_⟩ + set n := ⌊A⌋₊ - ⌊B⌋₊ + 1 + have h0 : clampPt B A 0 = B := clampPt_zero (by linarith) + have hn : clampPt B A n = A := clampPt_last hBA + have h2 : ∀ j, 2 ≤ clampPt B A j := fun j ↦ hB.trans (le_clampPt B A j) + have hE : ∀ j, pntE (clampPt B A j) ≤ pntE B := fun j ↦ + pntE_le_pntE (by linarith) (le_clampPt B A j) + have hFf : ∀ j < n, ∫ x in clampPt B A j..clampPt B A (j + 1), (x * log x)⁻¹ = + (log (log (clampPt B A (j + 1))) + c₅) - (log (log (clampPt B A j)) + c₅) := by + intro j _ + rw [integral_inv_mul_log (by linarith [h2 j]) (clampPt_mono B A (Nat.le_succ j))] + ring + have hδ : ∀ j < n, (log (log (clampPt B A (j + 1))) + c₅) - (log (log (clampPt B A j)) + c₅) ≤ + 2 * pntE B := by + intro j _ + have hj := h2 j + have hlog : 0 < log (clampPt B A j) := log_pos (by linarith) + calc _ = log (log (clampPt B A (j + 1))) - log (log (clampPt B A j)) := by ring + _ ≤ (clampPt B A (j + 1) - clampPt B A j) / (clampPt B A j * log (clampPt B A j)) := + log_log_sub_log_log_le (by linarith) (clampPt_mono B A (Nat.le_succ j)) + _ ≤ 1 / (clampPt B A j * log (clampPt B A j)) := by + gcongr + linarith [clampPt_succ_le B A j] + _ ≤ 2 * pntE (clampPt B A j) := one_div_mul_log_le_pntE hj + _ ≤ 2 * pntE B := by linarith [hE j] + have hε : ∀ j ≤ n, |S (clampPt B A j) - (log (log (clampPt B A j)) + c₅)| ≤ C * pntE B := by + intro j _ + rw [← sub_sub] + exact (hC _ (h2 j)).trans (mul_le_mul_of_nonneg_left (hE j) hC0) + have key := abs_sum_sub_integral_le (n := n) (a := clampPt B A) (clampPt_mono B A) + (b := b) (f := fun x ↦ (x * log x)⁻¹) (F := fun x ↦ log (log x) + c₅) + (g := fun j ↦ S (clampPt B A j)) (by linarith [pntE_pos B]) (by rw [h0, hn]; exact hb) + (by rw [h0]; exact hb0 B ⟨le_rfl, hBA⟩) + (by + rw [h0, hn] + intro x hx + have : 0 < log x := log_pos (by linarith [hx.1]) + have : 0 < x := by linarith [hx.1] + positivity) + (by rw [h0, hn]; exact continuousOn_inv_mul_log (by linarith)) hFf hδ hε + rw [h0, hn, sum_clampPt_eq b (by linarith) hBA] at key + simp_rw [div_eq_mul_inv (b _)] + calc _ ≤ (2 * pntE B + 2 * (C * pntE B)) * b A := key + _ = (2 + 2 * C) * b A * pntE B := by ring + +theorem sum_of_forall_cast_eq {t : Finset ℕ} {v : ℝ} (h : ∀ p ∈ t, (p : ℝ) = v) (φ : ℝ → ℝ) + (hφ : 0 ≤ φ v) : 0 ≤ ∑ p ∈ t, φ p ∧ ∑ p ∈ t, φ p ≤ φ v := by + have hcard : t.card ≤ 1 := card_le_one.2 fun a ha b hb ↦ by + exact_mod_cast (h a ha).trans (h b hb).symm + have hcard' : (t.card : ℝ) ≤ 1 := by exact_mod_cast hcard + rw [sum_congr rfl fun p hp ↦ by rw [h p hp], sum_const, nsmul_eq_mul] + exact ⟨by positivity, by nlinarith⟩ + +/-- [I71, Lemma 13], increasing case, for any set of primes between those in `(B, A)` and +those in `[B, A]`. -/ +theorem lemma13_mono_of_subset : ∃ C, 0 ≤ C ∧ ∀ (b : ℝ → ℝ) (A B : ℝ) (s : Finset ℕ), 2 ≤ B → + B ≤ A → MonotoneOn b (Set.Icc B A) → (∀ x ∈ Set.Icc B A, 0 ≤ b x) → + (∀ p ∈ s, p.Prime ∧ B ≤ p ∧ (p : ℝ) ≤ A) → (∀ p : ℕ, p.Prime → B < p → (p : ℝ) < A → p ∈ s) → + |∑ p ∈ s, b p / p - ∫ x in B..A, b x / (x * log x)| ≤ C * b A * pntE B := by + obtain ⟨C, hC0, hC⟩ := lemma13_Ioc + refine ⟨C + 1, by linarith, fun b A B s hB hBA hb hb0 hs1 hs2 ↦ ?_⟩ + have hB0 : 0 < B := by linarith + have hbA : 0 ≤ b A := hb0 A ⟨hBA, le_rfl⟩ + have hbB : 0 ≤ b B := hb0 B ⟨le_rfl, hBA⟩ + have hbBA : b B ≤ b A := hb ⟨le_rfl, hBA⟩ ⟨hBA, le_rfl⟩ hBA + have h1 := sum_of_forall_cast_eq (t := s \ primesIoc B A) (v := B) (fun p hp ↦ by + rw [Finset.mem_sdiff, mem_primesIoc] at hp + obtain ⟨hp1, hp2⟩ := hp + obtain ⟨hpp, hBp, hpA⟩ := hs1 p hp1 + exact le_antisymm (not_lt.1 fun h ↦ hp2 ⟨hpp, h, hpA⟩) hBp) + (fun x ↦ b x / x) (div_nonneg hbB hB0.le) + have h2 := sum_of_forall_cast_eq (t := primesIoc B A \ s) (v := A) (fun p hp ↦ by + rw [Finset.mem_sdiff, mem_primesIoc] at hp + obtain ⟨⟨hpp, hBp, hpA⟩, hp2⟩ := hp + exact le_antisymm hpA (not_lt.1 fun h ↦ hp2 (hs2 p hpp hBp h))) + (fun x ↦ b x / x) (div_nonneg hbA (by linarith)) + have h3 : b B / B ≤ b A * pntE B := by + calc b B / B ≤ b A / B := by gcongr + _ = b A * B⁻¹ := div_eq_mul_inv _ _ + _ ≤ b A * pntE B := mul_le_mul_of_nonneg_left (inv_le_pntE hB) hbA + have h4 : b A / A ≤ b A * pntE B := by + calc b A / A ≤ b A / B := by gcongr + _ = b A * B⁻¹ := div_eq_mul_inv _ _ + _ ≤ b A * pntE B := mul_le_mul_of_nonneg_left (inv_le_pntE hB) hbA + have hdiff := sum_sdiff_sub_sum_sdiff (s₁ := primesIoc B A) (s₂ := s) (f := fun p : ℕ ↦ b p / p) + have hI := hC b A B hB hBA hb hb0 + rw [abs_le] at hI ⊢ + constructor <;> nlinarith [pntE_pos B] + +/-- [I71, Lemma 13]: for `b ≥ 0` increasing on `[B, A]`, `2 ≤ B ≤ A`, +`|∑_{B ≤ p ≤ A} b(p)/p - ∫_B^A b(x)/(x log x) dx| ≤ C b(A) exp(-κ √(log B))`. -/ +theorem lemma13_mono : ∃ C, ∀ (b : ℝ → ℝ) (A B : ℝ), 2 ≤ B → B ≤ A → + MonotoneOn b (Set.Icc B A) → (∀ x ∈ Set.Icc B A, 0 ≤ b x) → + |∑ p ∈ primesIcc B A, b p / p - ∫ x in B..A, b x / (x * log x)| ≤ C * b A * pntE B := by + obtain ⟨C, -, hC⟩ := lemma13_mono_of_subset + exact ⟨C, fun b A B hB hBA hb hb0 ↦ hC b A B _ hB hBA hb hb0 (fun p hp ↦ mem_primesIcc.1 hp) + fun p hp h1 h2 ↦ mem_primesIcc.2 ⟨hp, h1.le, h2.le⟩⟩ + +theorem intervalIntegrable_div_mul_log {b : ℝ → ℝ} {A B : ℝ} (hB : 1 < B) (hBA : B ≤ A) + (hb : MonotoneOn b (Set.Icc B A) ∨ AntitoneOn b (Set.Icc B A)) : + IntervalIntegrable (fun x ↦ b x / (x * log x)) volume B A := by + simp_rw [div_eq_mul_inv (b _)] + have hc := continuousOn_inv_mul_log (v := A) hB + rw [← Set.uIcc_of_le hBA] at hc hb + rcases hb with hb | hb + · exact hb.intervalIntegrable.mul_continuousOn hc + · exact hb.intervalIntegrable.mul_continuousOn hc + +/-- [I71, Lemma 13], decreasing case, for any set of primes between those in `(B, A)` and +those in `[B, A]`. -/ +theorem lemma13_anti_of_subset : ∃ C, 0 ≤ C ∧ ∀ (b : ℝ → ℝ) (A B : ℝ) (s : Finset ℕ), 2 ≤ B → + B ≤ A → AntitoneOn b (Set.Icc B A) → (∀ x ∈ Set.Icc B A, 0 ≤ b x) → + (∀ p ∈ s, p.Prime ∧ B ≤ p ∧ (p : ℝ) ≤ A) → (∀ p : ℕ, p.Prime → B < p → (p : ℝ) < A → p ∈ s) → + |∑ p ∈ s, b p / p - ∫ x in B..A, b x / (x * log x)| ≤ C * b B * pntE B := by + obtain ⟨C, hC0, hC⟩ := lemma13_mono_of_subset + refine ⟨2 * C, by linarith, fun b A B s hB hBA hb hb0 hs1 hs2 ↦ ?_⟩ + set c := b B + have hc : 0 ≤ c := hb0 B ⟨le_rfl, hBA⟩ + have hbA : 0 ≤ b A := hb0 A ⟨hBA, le_rfl⟩ + have hbA' : b A ≤ c := hb ⟨le_rfl, hBA⟩ ⟨hBA, le_rfl⟩ hBA + have hb' : MonotoneOn (fun x ↦ c - b x) (Set.Icc B A) := fun x hx y hy hxy ↦ by + simp only; linarith [hb hx hy hxy] + have hb'0 : ∀ x ∈ Set.Icc B A, 0 ≤ c - b x := fun x hx ↦ by + simp only [c]; linarith [hb ⟨le_rfl, hBA⟩ hx hx.1] + have e1 := hC (fun _ ↦ c) A B s hB hBA (fun _ _ _ _ _ ↦ le_rfl) (fun _ _ ↦ hc) hs1 hs2 + have e2 := hC (fun x ↦ c - b x) A B s hB hBA hb' hb'0 hs1 hs2 + have hsum : ∑ p ∈ s, b p / p = ∑ p ∈ s, c / p - ∑ p ∈ s, (c - b p) / p := by + rw [← sum_sub_distrib]; exact sum_congr rfl fun p _ ↦ by ring + have hint : ∫ x in B..A, b x / (x * log x) = + (∫ x in B..A, c / (x * log x)) - ∫ x in B..A, (c - b x) / (x * log x) := by + rw [← integral_sub (intervalIntegrable_div_mul_log (by linarith) hBA + (Or.inl fun _ _ _ _ _ ↦ le_rfl)) (intervalIntegrable_div_mul_log (by linarith) hBA + (Or.inl hb'))] + exact integral_congr fun x _ ↦ by ring + rw [hsum, hint] + have h5 : 0 ≤ C * b A * pntE B := mul_nonneg (mul_nonneg hC0 hbA) (pntE_pos B).le + rw [abs_le] at e1 e2 ⊢ + constructor <;> linarith + +/-- [I71, Lemma 13], decreasing case: for `b ≥ 0` decreasing on `[B, A]`, `2 ≤ B ≤ A`, +`|∑_{B ≤ p ≤ A} b(p)/p - ∫_B^A b(x)/(x log x) dx| ≤ C b(B) exp(-κ √(log B))`. -/ +theorem lemma13_anti : ∃ C, ∀ (b : ℝ → ℝ) (A B : ℝ), 2 ≤ B → B ≤ A → + AntitoneOn b (Set.Icc B A) → (∀ x ∈ Set.Icc B A, 0 ≤ b x) → + |∑ p ∈ primesIcc B A, b p / p - ∫ x in B..A, b x / (x * log x)| ≤ C * b B * pntE B := by + obtain ⟨C, -, hC⟩ := lemma13_anti_of_subset + exact ⟨C, fun b A B hB hBA hb hb0 ↦ hC b A B _ hB hBA hb hb0 (fun p hp ↦ mem_primesIcc.1 hp) + fun p hp h1 h2 ↦ mem_primesIcc.2 ⟨hp, h1.le, h2.le⟩⟩ + +/-! ### Lemma 14 -/ +theorem integral_inv_log_div_mul_log {u v : ℝ} (hu : 1 < u) (huv : u ≤ v) : + ∫ x in u..v, (log x)⁻¹ / (x * log x) = 1 / log u - 1 / log v := by + have hpos : ∀ x ∈ Set.uIcc u v, 1 < x := fun x hx ↦ by + rw [Set.uIcc_of_le huv] at hx; linarith [hx.1] + have hderiv : ∀ x ∈ Set.uIcc u v, + HasDerivAt (fun x ↦ -(log x)⁻¹) ((log x)⁻¹ / (x * log x)) x := fun x hx ↦ by + have hx := hpos x hx + have hl := (log_pos hx).ne' + convert ((hasDerivAt_log (by linarith : x ≠ 0)).inv hl).neg using 1 + field_simp + have hint : IntervalIntegrable (fun x ↦ (log x)⁻¹ / (x * log x)) volume u v := by + have hc := continuousOn_inv_mul_log (v := v) hu + have hl : ContinuousOn (fun x ↦ (log x)⁻¹) (Set.Icc u v) := + ContinuousOn.inv₀ (continuousOn_log.mono fun x hx ↦ by + simp only [Set.mem_compl_iff, Set.mem_singleton_iff]; linarith [hx.1]) + fun x hx ↦ (log_pos (by linarith [hx.1])).ne' + simp_rw [div_eq_mul_inv ((log _)⁻¹)] + exact (hl.mul hc).intervalIntegrable_of_Icc huv + rw [integral_eq_sub_of_hasDerivAt hderiv hint] + ring + +/-- [I71, Lemma 14]: `∑_{B < p < A} 1/(p log p) = 1/log B - 1/log A + O(exp(-κ √(log B)))`, +for any set of primes between those in `(B, A)` and those in `[B, A]`. -/ +theorem lemma14_of_subset : ∃ C, ∀ (A B : ℝ) (s : Finset ℕ), 2 ≤ B → B ≤ A → + (∀ p ∈ s, p.Prime ∧ B ≤ p ∧ (p : ℝ) ≤ A) → (∀ p : ℕ, p.Prime → B < p → (p : ℝ) < A → p ∈ s) → + |∑ p ∈ s, 1 / (p * log p) - (1 / log B - 1 / log A)| ≤ C * pntE B := by + obtain ⟨C, hC0, hC⟩ := lemma13_anti_of_subset + refine ⟨2 * C, fun A B s hB hBA hs1 hs2 ↦ ?_⟩ + have hlogB : 1 / 2 ≤ log B := half_le_log hB + have hb : AntitoneOn (fun x ↦ (log x)⁻¹) (Set.Icc B A) := fun x hx y hy hxy ↦ by + have hx0 : 0 < log x := log_pos (by linarith [hx.1]) + exact inv_anti₀ hx0 (log_le_log (by linarith [hx.1]) hxy) + have hb0 : ∀ x ∈ Set.Icc B A, 0 ≤ (log x)⁻¹ := fun x hx ↦ + inv_nonneg.2 (log_nonneg (by linarith [hx.1])) + have h := hC _ A B s hB hBA hb hb0 hs1 hs2 + rw [integral_inv_log_div_mul_log (by linarith) hBA] at h + have hsum : ∑ p ∈ s, (log (p : ℝ))⁻¹ / p = ∑ p ∈ s, 1 / (p * log p) := + sum_congr rfl fun p _ ↦ by ring + rw [hsum] at h + refine h.trans ?_ + have hinv : (log B)⁻¹ ≤ 2 := by + rw [inv_le_comm₀ (by linarith) (by norm_num)]; linarith + have := pntE_pos B + calc C * (log B)⁻¹ * pntE B ≤ C * 2 * pntE B := by gcongr + _ = 2 * C * pntE B := by ring + +/-- [I71, Lemma 14]: `∑_{B < p < A} 1/(p log p) = 1/log B - 1/log A + O(exp(-κ √(log B)))`. -/ +theorem lemma14 : ∃ C, ∀ A B : ℝ, 2 ≤ B → B ≤ A → + |∑ p ∈ primesIoo B A, 1 / (p * log p) - (1 / log B - 1 / log A)| ≤ C * pntE B := by + obtain ⟨C, hC⟩ := lemma14_of_subset + exact ⟨C, fun A B hB hBA ↦ hC A B _ hB hBA + (fun p hp ↦ by + obtain ⟨h1, h2, h3⟩ := mem_primesIoo.1 hp + exact ⟨h1, h2.le, h3.le⟩) + fun p hp h1 h2 ↦ mem_primesIoo.2 ⟨hp, h1, h2⟩⟩ + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/PrimeSums/Mertens.lean b/LeanPool/IwaniecLinearSieve/PrimeSums/Mertens.lean new file mode 100644 index 000000000..b0dce2ebd --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/PrimeSums/Mertens.lean @@ -0,0 +1,263 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.PrimeSums.Error +public import LeanPool.IwaniecLinearSieve.Definitions +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds + +/-! +# Mertens' second theorem with the de la Vallée Poussin error term + +`S x = ∑_{p ≤ x} 1/p = log (log x) + c₅ + O(pntE x)`, by partial summation against `θ`. +-/ + +@[expose] public section + +open Real Filter Topology MeasureTheory Finset intervalIntegral +open scoped Chebyshev + +namespace IwaniecLinearSieve + +/-- If `|T y - T x| ≤ g x` whenever `a ≤ x ≤ y` and `g → 0`, then `T` has a limit `c` with +`|T x - c| ≤ g x` for `x ≥ a`. -/ +theorem exists_abs_sub_le_of_cauchy {T g : ℝ → ℝ} {a : ℝ} + (h : ∀ x y, a ≤ x → x ≤ y → |T y - T x| ≤ g x) (hg : Tendsto g atTop (𝓝 0)) : + ∃ c, ∀ x ≥ a, |T x - c| ≤ g x := by + set u : ℕ → ℝ := fun n ↦ T (a + n) + have hu : CauchySeq u := by + rw [Metric.cauchySeq_iff'] + intro ε hε + obtain ⟨X, hX⟩ := eventually_atTop.1 (hg.eventually (eventually_lt_nhds hε)) + obtain ⟨N, hN⟩ := exists_nat_ge (X - a) + refine ⟨N, fun n hn ↦ ?_⟩ + rw [Real.dist_eq] + have hNn : (N : ℝ) ≤ n := by exact_mod_cast hn + calc |u n - u N| ≤ g (a + N) := h _ _ (by simp) (by linarith) + _ < ε := hX _ (by linarith) + obtain ⟨c, hc⟩ := cauchySeq_tendsto_of_complete hu + refine ⟨c, fun x hx ↦ ?_⟩ + have h1 : Tendsto (fun n : ℕ ↦ |u n - T x|) atTop (𝓝 |c - T x|) := (hc.sub_const _).abs + have h2 : ∀ᶠ n : ℕ in atTop, |u n - T x| ≤ g x := by + obtain ⟨N, hN⟩ := exists_nat_ge (x - a) + filter_upwards [eventually_ge_atTop N] with n hn + have hNn : (N : ℝ) ≤ n := by exact_mod_cast hn + exact h x (a + n) hx (by linarith) + rw [abs_sub_comm] + exact le_of_tendsto h1 h2 + +/-- `S x = ∑_{p ≤ x} 1/p`. -/ +noncomputable def S (x : ℝ) : ℝ := ∑ p ∈ primesLT (⌊x⌋₊ + 1), (p : ℝ)⁻¹ + +theorem S_eq_sum (x : ℝ) : + S x = ∑ k ∈ range (⌊x⌋₊ + 1), if k.Prime then (k : ℝ)⁻¹ else 0 := by + rw [S, primesLT, show ⌈(⌊x⌋₊ : ℝ) + 1⌉₊ = ⌊x⌋₊ + 1 by exact_mod_cast Nat.ceil_natCast _, + Nat.primesBelow, sum_filter] + +/-- The weight `log p` at primes `p`, and `0` elsewhere. -/ +noncomputable def logPrime (k : ℕ) : ℝ := if k.Prime then log k else 0 + +theorem sum_logPrime_eq_theta (t : ℝ) : + ∑ k ∈ Icc 0 ⌊t⌋₊, logPrime k = Chebyshev.theta t := by + rw [Chebyshev.theta_eq_sum_Icc, sum_filter] + rfl + +theorem S_sub_S {x y : ℝ} (hxy : x ≤ y) : + S y - S x = ∑ k ∈ Ioc ⌊x⌋₊ ⌊y⌋₊, ((k : ℝ) * log k)⁻¹ * logPrime k := by + rw [S_eq_sum, S_eq_sum, ← sum_Ico_eq_sub _ (by gcongr), Finset.Ico_add_one_add_one_eq_Ioc] + refine sum_congr rfl fun k _ ↦ ?_ + unfold logPrime + split_ifs with hk + · have : 0 < log k := log_pos (by exact_mod_cast hk.one_lt) + field_simp + · simp + +theorem hasDerivAt_inv_mul_log {t : ℝ} (ht : 1 < t) : + HasDerivAt (fun t ↦ (t * log t)⁻¹) (-((log t + 1) / (t * log t) ^ 2)) t := by + have h0 : t ≠ 0 := by linarith + have h1 : HasDerivAt (fun t ↦ t * log t) (1 * log t + t * t⁻¹) t := + (hasDerivAt_id t).mul (hasDerivAt_log h0) + convert h1.inv (mul_ne_zero h0 (log_pos ht).ne') using 1 + rw [mul_inv_cancel₀ h0] + ring + +theorem hasDerivAt_log_log_sub_inv_log {t : ℝ} (ht : 1 < t) : + HasDerivAt (fun t ↦ log (log t) - (log t)⁻¹) ((log t + 1) / (t * log t) ^ 2 * t) t := by + have h0 : t ≠ 0 := by linarith + have hl : log t ≠ 0 := (log_pos ht).ne' + convert ((hasDerivAt_log h0).log hl).sub ((hasDerivAt_log h0).inv hl) using 1 + field_simp + ring + +theorem continuousOn_log_add_one_div {x y : ℝ} (hx : 1 < x) : + ContinuousOn (fun t ↦ (log t + 1) / (t * log t) ^ 2) (Set.Icc x y) := by + have hlog : ContinuousOn log (Set.Icc x y) := + continuousOn_log.mono fun t ht ↦ by + simp only [Set.mem_compl_iff, Set.mem_singleton_iff]; linarith [ht.1] + refine ContinuousOn.div (by fun_prop) (by fun_prop) fun t ht ↦ ?_ + have : 1 < t := by linarith [ht.1] + have := log_pos this + positivity + +/-- Partial summation: the variation of `S x - log (log x)` in terms of `θ x - x`. -/ +theorem S_sub_loglog_eq {x y : ℝ} (hx : 2 ≤ x) (hxy : x ≤ y) : + (S y - log (log y)) - (S x - log (log x)) = + (y * log y)⁻¹ * (θ y - y) - (x * log x)⁻¹ * (θ x - x) + + ∫ t in x..y, (log t + 1) / (t * log t) ^ 2 * (θ t - t) := by + have hpos : ∀ t ∈ Set.Icc x y, 1 < t := fun t ht ↦ by linarith [ht.1] + have hderiv : ∀ t ∈ Set.Icc x y, + HasDerivAt (fun t ↦ (t * log t)⁻¹) (-((log t + 1) / (t * log t) ^ 2)) t := + fun t ht ↦ hasDerivAt_inv_mul_log (hpos t ht) + have hcont := continuousOn_log_add_one_div (y := y) (show 1 < x by linarith) + have hint : IntegrableOn (deriv fun t ↦ (t * log t)⁻¹) (Set.Icc x y) := + hcont.neg.integrableOn_Icc.congr_fun (fun t ht ↦ ((hderiv t ht).deriv).symm) + measurableSet_Icc + have habel := sum_mul_eq_sub_sub_integral_mul logPrime (f := fun t ↦ (t * log t)⁻¹) + (by linarith) hxy (fun t ht ↦ (hderiv t ht).differentiableAt) hint + rw [← S_sub_S hxy] at habel + simp only [sum_logPrime_eq_theta] at habel + rw [setIntegral_congr_fun measurableSet_Ioc + (g := fun t ↦ -((log t + 1) / (t * log t) ^ 2) * θ t) + (fun t ht ↦ by rw [(hderiv t (Set.Ioc_subset_Icc_self ht)).deriv]), + ← intervalIntegral.integral_of_le hxy] at habel + have hcont' : ContinuousOn (fun t ↦ (log t + 1) / (t * log t) ^ 2) (Set.uIcc x y) := by + rwa [Set.uIcc_of_le hxy] + have hθ : IntervalIntegrable θ volume x y := Chebyshev.theta_mono.intervalIntegrable + have hi1 := hθ.continuousOn_mul hcont' + have hi2 : IntervalIntegrable (fun t ↦ (log t + 1) / (t * log t) ^ 2 * t) volume x y := + (continuousOn_id.mono (Set.subset_univ _)).intervalIntegrable.continuousOn_mul hcont' + have hsplit : ∫ t in x..y, (log t + 1) / (t * log t) ^ 2 * (θ t - t) = + (∫ t in x..y, (log t + 1) / (t * log t) ^ 2 * θ t) - + ∫ t in x..y, (log t + 1) / (t * log t) ^ 2 * t := by + rw [← integral_sub hi1 hi2] + congr 1 + ext t + ring + have hneg : ∫ t in x..y, -((log t + 1) / (t * log t) ^ 2) * θ t = + -∫ t in x..y, (log t + 1) / (t * log t) ^ 2 * θ t := by + rw [← intervalIntegral.integral_neg] + congr 1 + ext t + ring + have hftc : ∫ t in x..y, (log t + 1) / (t * log t) ^ 2 * t = + (log (log y) - (log y)⁻¹) - (log (log x) - (log x)⁻¹) := + integral_eq_sub_of_hasDerivAt + (fun t ht ↦ hasDerivAt_log_log_sub_inv_log (hpos t (by rwa [Set.uIcc_of_le hxy] at ht))) + hi2 + have hy0 : y ≠ 0 := by linarith + have hx0 : x ≠ 0 := by linarith + have hfy : (y * log y)⁻¹ * y = (log y)⁻¹ := by field_simp + have hfx : (x * log x)⁻¹ * x = (log x)⁻¹ := by field_simp + rw [hneg] at habel + rw [hsplit, hftc] + linear_combination habel - hfx + hfy + +theorem half_le_log {t : ℝ} (ht : 2 ≤ t) : 1 / 2 ≤ log t := by + have := log_two_gt_d9 + have := log_le_log (by norm_num) ht + linarith + +theorem continuousOn_deriv_pntE {x y : ℝ} (hx : 1 < x) : + ContinuousOn (fun t ↦ pntE t * (-pntκ * (t⁻¹ / (2 * √(log t))))) (Set.Icc x y) := by + have hpos : ∀ t ∈ Set.Icc x y, 1 < t := fun t ht ↦ by linarith [ht.1] + have hlog : ContinuousOn log (Set.Icc x y) := + continuousOn_log.mono fun t ht ↦ by + simp only [Set.mem_compl_iff, Set.mem_singleton_iff]; linarith [hpos t ht] + unfold pntE + refine ContinuousOn.mul (by fun_prop) (ContinuousOn.mul (by fun_prop) ?_) + refine ContinuousOn.div (continuousOn_inv₀.mono fun t ht ↦ ?_) (by fun_prop) fun t ht ↦ ?_ + · simp only [Set.mem_compl_iff, Set.mem_singleton_iff]; linarith [hpos t ht] + · have := sqrt_pos.2 (log_pos (hpos t ht)) + positivity + +/-- The integrand in `S_sub_loglog_eq` is dominated by a multiple of `-pntE'`. -/ +theorem abs_integrand_le {C t : ℝ} (hC : 0 ≤ C) (ht : 2 ≤ t) + (hθ : |θ t - t| ≤ C * t * pntE t) : + |(log t + 1) / (t * log t) ^ 2 * (θ t - t)| ≤ + -(12 * C / pntκ) * (pntE t * (-pntκ * (t⁻¹ / (2 * √(log t))))) := by + have ht0 : 0 < t := by linarith + have hL := half_le_log ht + have hL0 : 0 < log t := by linarith + have hs : 1 / 2 ≤ √(log t) := (le_sqrt (by norm_num) hL0.le).2 (by linarith) + have hs0 : 0 < √(log t) := by linarith + have hss := mul_self_sqrt hL0.le + have hE := pntE_pos t + have hκ := pntκ_pos + have key : (log t + 1) * √(log t) ≤ 6 * log t ^ 2 := by nlinarith + calc |(log t + 1) / (t * log t) ^ 2 * (θ t - t)| + = (log t + 1) / (t * log t) ^ 2 * |θ t - t| := by + rw [abs_mul, abs_of_nonneg (by positivity)] + _ ≤ (log t + 1) / (t * log t) ^ 2 * (C * t * pntE t) := by gcongr + _ = C * pntE t * ((log t + 1) / (t * log t ^ 2)) := by field_simp + _ ≤ C * pntE t * (6 / (t * √(log t))) := by + refine mul_le_mul_of_nonneg_left ?_ (by positivity) + rw [div_le_div_iff₀ (by positivity) (by positivity)] + nlinarith + _ = -(12 * C / pntκ) * (pntE t * (-pntκ * (t⁻¹ / (2 * √(log t))))) := by + field_simp + ring + +theorem exists_abs_S_sub_loglog_sub_le : + ∃ K, 0 ≤ K ∧ ∀ x y, 2 ≤ x → x ≤ y → + |(S y - log (log y)) - (S x - log (log x))| ≤ K * pntE x := by + obtain ⟨C, hC0, hC⟩ := theta_asymp + have hκ := pntκ_pos + refine ⟨4 * C + 12 * C / pntκ, by positivity, fun x y hx hxy ↦ ?_⟩ + rw [S_sub_loglog_eq hx hxy] + have hy : 2 ≤ y := hx.trans hxy + have hbd : ∀ t, x ≤ t → |(t * log t)⁻¹ * (θ t - t)| ≤ 2 * C * pntE x := by + intro t hxt + have ht : 2 ≤ t := hx.trans hxt + have ht0 : 0 < t := by linarith + have hL := half_le_log ht + have hE := pntE_pos t + calc |(t * log t)⁻¹ * (θ t - t)| = (t * log t)⁻¹ * |θ t - t| := by + rw [abs_mul, abs_of_pos (inv_pos.2 (by positivity))] + _ ≤ (t * log t)⁻¹ * (C * t * pntE t) := by gcongr; exact hC t ht + _ = C * pntE t / log t := by field_simp + _ ≤ 2 * C * pntE t := by + rw [div_le_iff₀ (by linarith)] + nlinarith [mul_nonneg hC0 hE.le] + _ ≤ 2 * C * pntE x := by gcongr; exact pntE_le_pntE (by linarith) hxt + have hderivE : ∀ t ∈ Set.uIcc x y, + HasDerivAt pntE (pntE t * (-pntκ * (t⁻¹ / (2 * √(log t))))) t := fun t ht ↦ + hasDerivAt_pntE (by rw [Set.uIcc_of_le hxy] at ht; linarith [ht.1]) + have hcontE := continuousOn_deriv_pntE (y := y) (show 1 < x by linarith) + rw [← Set.uIcc_of_le hxy] at hcontE + have hintE := hcontE.intervalIntegrable (μ := volume) + have hftc : ∫ t in x..y, -(12 * C / pntκ) * (pntE t * (-pntκ * (t⁻¹ / (2 * √(log t))))) = + 12 * C / pntκ * (pntE x - pntE y) := by + rw [intervalIntegral.integral_const_mul, integral_eq_sub_of_hasDerivAt hderivE hintE] + ring + have hint : |∫ t in x..y, (log t + 1) / (t * log t) ^ 2 * (θ t - t)| ≤ + 12 * C / pntκ * pntE x := by + rw [← norm_eq_abs] + refine (norm_integral_le_of_norm_le hxy (ae_of_all _ fun t ht ↦ ?_) + (hintE.const_mul (-(12 * C / pntκ)))).trans ?_ + · rw [norm_eq_abs] + have ht2 : 2 ≤ t := by linarith [ht.1] + exact abs_integrand_le hC0 ht2 (hC t ht2) + · rw [hftc] + have := pntE_pos y + have : 0 ≤ 12 * C / pntκ := by positivity + nlinarith + have h1 := hbd y hxy + have h2 := hbd x le_rfl + calc _ ≤ |(y * log y)⁻¹ * (θ y - y)| + |(x * log x)⁻¹ * (θ x - x)| + + |∫ t in x..y, (log t + 1) / (t * log t) ^ 2 * (θ t - t)| := + (abs_add_le _ _).trans (add_le_add_left (abs_sub _ _) _) + _ ≤ (4 * C + 12 * C / pntκ) * pntE x := by linarith + +/-- Mertens' second theorem with the de la Vallée Poussin error term. -/ +theorem S_asymp : ∃ c₅ C : ℝ, ∀ x ≥ 2, |S x - log (log x) - c₅| ≤ C * pntE x := by + obtain ⟨K, -, hK⟩ := exists_abs_S_sub_loglog_sub_le + obtain ⟨c, hc⟩ := exists_abs_sub_le_of_cauchy (T := fun x ↦ S x - log (log x)) + (g := fun x ↦ K * pntE x) (a := 2) hK (by simpa using tendsto_pntE.const_mul K) + exact ⟨c, K, hc⟩ + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/PrimeSums/NthPrime.lean b/LeanPool/IwaniecLinearSieve/PrimeSums/NthPrime.lean new file mode 100644 index 000000000..5b092e1d6 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/PrimeSums/NthPrime.lean @@ -0,0 +1,86 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import Mathlib.Analysis.SpecialFunctions.Log.Basic +public import Mathlib.Data.Nat.Nth +import LeanPool.IwaniecLinearSieve.PrimeSums.Error +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds + +/-! +# The `r`-th prime is `O(r log r)` + +From `θ(x) ≥ x / 2` for large `x` (a consequence of `theta_asymp`) and `θ(x) ≤ π(x) log x`. +-/ + +@[expose] public section + +open Real Filter Topology + +namespace IwaniecLinearSieve + +theorem log_le_div_eight {K : ℝ} (hK : 256 ≤ K) : log K ≤ K / 8 := by + have hK0 : 0 < K := by linarith + have hs : 16 ≤ √K := (le_sqrt (by norm_num) hK0.le).2 (by linarith) + have h1 : log K = 2 * log √K := by rw [log_sqrt hK0.le]; ring + have h2 := log_le_sub_one_of_pos (sqrt_pos.2 hK0) + have h3 := sq_sqrt hK0.le + nlinarith + +/-- The `r`-th prime `p_r = Nat.nth Nat.Prime (r - 1)` satisfies `p_r ≤ C r log r`. -/ +theorem nth_prime_le : ∃ C, ∀ r : ℕ, 2 ≤ r → (Nat.nth Nat.Prime (r - 1) : ℝ) ≤ C * r * log r := by + obtain ⟨Cθ, -, hθ⟩ := theta_asymp + obtain ⟨X, hX⟩ := eventually_atTop.1 + ((by simpa using tendsto_pntE.const_mul Cθ : + Tendsto (fun x ↦ Cθ * pntE x) atTop (𝓝 0)).eventually (eventually_lt_nhds one_half_pos)) + set K := max X 256 + have hK : 256 ≤ K := le_max_right _ _ + refine ⟨K, fun r hr ↦ ?_⟩ + have hr' : (2 : ℝ) ≤ r := by exact_mod_cast hr + have hlogr : 1 / 2 ≤ log r := by + have := log_two_gt_d9 + have := log_le_log (by norm_num) hr' + linarith + set x := K * r * log r with hx + have hxK : K ≤ x := by + rw [hx, mul_assoc] + refine le_mul_of_one_le_right (by linarith) ?_ + nlinarith + have hx2 : 2 ≤ x := by linarith + have hx0 : 0 < x := by linarith + -- `θ x ≥ x / 2` + have hθx : x / 2 ≤ Chebyshev.theta x := by + have h1 := hθ x hx2 + have h2 := hX x ((le_max_left _ _).trans hxK) + rw [abs_le] at h1 + nlinarith + -- `log x ≤ K / 8 + 2 log r` + have hlogx : log x ≤ K / 8 + 2 * log r := by + have hlr0 : 0 < log r := by linarith + rw [hx, log_mul (by positivity) hlr0.ne', log_mul (by positivity) (by positivity)] + have h1 := log_le_div_eight hK + have h2 := log_le_sub_one_of_pos hlr0 + linarith + have hlogx0 : 0 < log x := log_pos (by linarith) + -- hence `π x ≥ x / (2 log x) ≥ r` + have hπ : (r : ℝ) ≤ Nat.primeCounting ⌊x⌋₊ := by + have h1 := Chebyshev.theta_le_pi_mul_log' x + have h2 : (r : ℝ) * (2 * log x) ≤ x := by + rw [hx] + have : 2 * log x ≤ K * log r := by nlinarith + nlinarith + nlinarith + have hcount : r - 1 < Nat.count Nat.Prime (⌊x⌋₊ + 1) := by + have : r ≤ Nat.primeCounting ⌊x⌋₊ := by exact_mod_cast hπ + simp only [Nat.primeCounting, Nat.primeCounting'] at this + omega + have hnth := Nat.nth_lt_of_lt_count hcount + calc (Nat.nth Nat.Prime (r - 1) : ℝ) ≤ ⌊x⌋₊ := by exact_mod_cast Nat.lt_succ_iff.1 hnth + _ ≤ x := Nat.floor_le hx0.le + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/PrimeSums/Product.lean b/LeanPool/IwaniecLinearSieve/PrimeSums/Product.lean new file mode 100644 index 000000000..b359526d5 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/PrimeSums/Product.lean @@ -0,0 +1,241 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.PrimeSums.Mertens +public import LeanPool.IwaniecLinearSieve.Basic +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Tactic.Polynomial.Basic + +/-! +# Mertens' product theorem with the de la Vallée Poussin error term + +`R z = ∏_{p < z} (1 - 1/p) = c_R / log z + O(pntE z / log z)`. +-/ + +@[expose] public section + +open Real Filter Topology Finset + +namespace IwaniecLinearSieve + +theorem one_sub_inv_pos {p : ℕ} (hp : p.Prime) : 0 < 1 - (p : ℝ)⁻¹ := by + have : (1 : ℝ) < p := by exact_mod_cast hp.one_lt + rw [sub_pos] + exact inv_lt_one_of_one_lt₀ this + +theorem one_sub_inv_le_one (p : ℕ) : 1 - (p : ℝ)⁻¹ ≤ 1 := by + have : (0 : ℝ) ≤ (p : ℝ)⁻¹ := by positivity + linarith + +theorem primesLT_mono {z w : ℝ} (hzw : z ≤ w) : primesLT z ⊆ primesLT w := fun p hp ↦ by + rw [mem_primesLT] at hp ⊢ + exact ⟨hp.1, hp.2.trans_le hzw⟩ + +theorem R_eq_mul_prod_sdiff {z w : ℝ} (hzw : z ≤ w) : + R w = R z * ∏ p ∈ primesLT w \ primesLT z, (1 - (p : ℝ)⁻¹) := by + rw [R, R, mul_comm, prod_sdiff (primesLT_mono hzw)] + +theorem R_antitone : Antitone R := fun z w hzw ↦ by + rw [R_eq_mul_prod_sdiff hzw] + refine mul_le_of_le_one_right (R_pos z).le (prod_le_one₀ (fun p hp ↦ ?_) fun p _ ↦ + one_sub_inv_le_one p) + exact (one_sub_inv_pos (mem_primesLT.1 (Finset.mem_sdiff.1 hp).1).1).le + +/-- `∑_{p < z} 1/p`. -/ +noncomputable def SLT (z : ℝ) : ℝ := ∑ p ∈ primesLT z, (p : ℝ)⁻¹ + +/-- `S` counts primes `p ≤ z` and `SLT` primes `p < z`; they differ by at most `1 / z`. -/ +theorem S_sub_SLT {z : ℝ} (hz : 0 < z) : 0 ≤ S z - SLT z ∧ S z - SLT z ≤ z⁻¹ := by + have hS : S z = ∑ p ∈ Nat.primesBelow (⌊z⌋₊ + 1), (p : ℝ)⁻¹ := by + rw [S, primesLT, show ⌈(⌊z⌋₊ : ℝ) + 1⌉₊ = ⌊z⌋₊ + 1 by exact_mod_cast Nat.ceil_natCast _] + have hsub : primesLT z ⊆ Nat.primesBelow (⌊z⌋₊ + 1) := fun p hp ↦ by + rw [primesLT, Nat.mem_primesBelow] at hp + rw [Nat.mem_primesBelow] + exact ⟨hp.1.trans_le (Nat.ceil_le_floor_add_one z), hp.2⟩ + rw [hS, SLT, ← sum_sdiff hsub, add_sub_cancel_right] + refine ⟨sum_nonneg fun p _ ↦ by positivity, ?_⟩ + have hmem : ∀ p ∈ Nat.primesBelow (⌊z⌋₊ + 1) \ primesLT z, (p : ℝ) = z ∧ p = ⌊z⌋₊ := by + intro p hp + rw [Finset.mem_sdiff, Nat.mem_primesBelow, primesLT, Nat.mem_primesBelow] at hp + have h1 : p ≤ ⌊z⌋₊ := Nat.lt_succ_iff.1 hp.1.1 + have h2 : ⌈z⌉₊ ≤ p := by + by_contra h + exact hp.2 ⟨Nat.lt_of_not_le h, hp.1.2⟩ + have h3 : z ≤ p := Nat.ceil_le.1 h2 + have h4 : (p : ℝ) ≤ z := (Nat.le_floor_iff hz.le).1 h1 + exact ⟨le_antisymm h4 h3, le_antisymm h1 (Nat.floor_le_of_le h3)⟩ + have hcard : (Nat.primesBelow (⌊z⌋₊ + 1) \ primesLT z).card ≤ 1 := + card_le_one.2 fun a ha b hb ↦ (hmem a ha).2.trans (hmem b hb).2.symm + calc ∑ p ∈ Nat.primesBelow (⌊z⌋₊ + 1) \ primesLT z, (p : ℝ)⁻¹ + = ∑ p ∈ Nat.primesBelow (⌊z⌋₊ + 1) \ primesLT z, z⁻¹ := + sum_congr rfl fun p hp ↦ by rw [(hmem p hp).1] + _ = (Nat.primesBelow (⌊z⌋₊ + 1) \ primesLT z).card * z⁻¹ := by rw [sum_const, nsmul_eq_mul] + _ ≤ 1 * z⁻¹ := by gcongr; exact_mod_cast hcard + _ = z⁻¹ := one_mul _ + +/-- `0 ≤ -log (1 - 1/p) - 1/p ≤ 1/(p-1) - 1/p`. -/ +theorem abs_log_one_sub_inv_add_inv_le {p : ℝ} (hp : 2 ≤ p) : + |log (1 - p⁻¹) + p⁻¹| ≤ (p - 1)⁻¹ - p⁻¹ := by + have hp0 : 0 < p := by linarith + have hq : 0 < 1 - p⁻¹ := by + rw [sub_pos]; exact inv_lt_one_of_one_lt₀ (by linarith) + have h1 : log (1 - p⁻¹) ≤ -p⁻¹ := by linarith [log_le_sub_one_of_pos hq] + have h2 : -((1 - p⁻¹)⁻¹ - 1) ≤ log (1 - p⁻¹) := by + have := log_le_sub_one_of_pos (inv_pos.2 hq) + rw [log_inv] at this + linarith + have h3 : (1 - p⁻¹)⁻¹ - 1 = (p - 1)⁻¹ := by + have : p - 1 ≠ 0 := by linarith + field_simp + ring + rw [abs_of_nonpos (by linarith)] + linarith + +theorem sum_Ico_inv_sub_inv {m M : ℕ} (hmM : m ≤ M) : + ∑ n ∈ Ico m M, (((n : ℝ) - 1)⁻¹ - (n : ℝ)⁻¹) = ((m : ℝ) - 1)⁻¹ - ((M : ℝ) - 1)⁻¹ := by + induction M, hmM using Nat.le_induction with + | base => simp + | succ M hmM ih => + rw [sum_Ico_succ_top hmM, ih] + push_cast + ring + +/-- The tail of `∑_p (-log (1 - 1/p) - 1/p)` is at most `2 / z`. -/ +theorem abs_sum_log_one_sub_inv_add_inv_le {z w : ℝ} (hz : 2 ≤ z) (hzw : z ≤ w) : + |∑ p ∈ primesLT w \ primesLT z, (log (1 - (p : ℝ)⁻¹) + (p : ℝ)⁻¹)| ≤ 2 * z⁻¹ := by + have hz1 : (2 : ℝ) ≤ ⌈z⌉₊ := hz.trans (Nat.le_ceil z) + have hw1 : (2 : ℝ) ≤ ⌈w⌉₊ := hz1.trans (by exact_mod_cast Nat.ceil_mono hzw) + have hsub : primesLT w \ primesLT z ⊆ Ico ⌈z⌉₊ ⌈w⌉₊ := fun p hp ↦ by + rw [Finset.mem_sdiff, primesLT, primesLT, Nat.mem_primesBelow, Nat.mem_primesBelow] at hp + rw [Finset.mem_Ico] + exact ⟨not_lt.1 fun h ↦ hp.2 ⟨h, hp.1.2⟩, hp.1.1⟩ + have hnn : ∀ n ∈ Ico ⌈z⌉₊ ⌈w⌉₊, 0 ≤ ((n : ℝ) - 1)⁻¹ - (n : ℝ)⁻¹ := fun n hn ↦ by + have : (2 : ℝ) ≤ n := hz1.trans (by exact_mod_cast (Finset.mem_Ico.1 hn).1) + rw [sub_nonneg] + exact inv_anti₀ (by linarith) (by linarith) + calc |∑ p ∈ primesLT w \ primesLT z, (log (1 - (p : ℝ)⁻¹) + (p : ℝ)⁻¹)| + ≤ ∑ p ∈ primesLT w \ primesLT z, |log (1 - (p : ℝ)⁻¹) + (p : ℝ)⁻¹| := abs_sum_le_sum_abs _ _ + _ ≤ ∑ p ∈ primesLT w \ primesLT z, (((p : ℝ) - 1)⁻¹ - (p : ℝ)⁻¹) := by + refine sum_le_sum fun p hp ↦ abs_log_one_sub_inv_add_inv_le ?_ + exact hz1.trans (by exact_mod_cast (Finset.mem_Ico.1 (hsub hp)).1) + _ ≤ ∑ n ∈ Ico ⌈z⌉₊ ⌈w⌉₊, (((n : ℝ) - 1)⁻¹ - (n : ℝ)⁻¹) := + sum_le_sum_of_subset_of_nonneg hsub fun n hn _ ↦ hnn n hn + _ = ((⌈z⌉₊ : ℝ) - 1)⁻¹ - ((⌈w⌉₊ : ℝ) - 1)⁻¹ := sum_Ico_inv_sub_inv (Nat.ceil_mono hzw) + _ ≤ (z - 1)⁻¹ := by + have : 0 ≤ ((⌈w⌉₊ : ℝ) - 1)⁻¹ := inv_nonneg.2 (by linarith) + have : ((⌈z⌉₊ : ℝ) - 1)⁻¹ ≤ (z - 1)⁻¹ := + inv_anti₀ (by linarith) (by linarith [Nat.le_ceil z]) + linarith + _ ≤ 2 * z⁻¹ := by + rw [← div_eq_mul_inv, inv_eq_one_div, div_le_div_iff₀ (by linarith) (by linarith)] + linarith + +theorem log_R_eq (z : ℝ) : log (R z) = ∑ p ∈ primesLT z, log (1 - (p : ℝ)⁻¹) := + log_prod fun _ hp ↦ (one_sub_inv_pos (mem_primesLT.1 hp).1).ne' + +theorem abs_exp_sub_one_le_mul_exp (d : ℝ) : |exp d - 1| ≤ |d| * exp |d| := by + rcases le_total 0 d with hd | hd + · rw [abs_of_nonneg hd, abs_of_nonneg (by linarith [add_one_le_exp d])] + have h1 := add_one_le_exp (-d) + have h2 : exp d * exp (-d) = 1 := by rw [← exp_add]; simp + nlinarith [exp_pos d] + · rw [abs_of_nonpos hd, abs_of_nonpos (by linarith [exp_le_one_iff.2 hd])] + have h1 := add_one_le_exp d + have h2 : 1 ≤ exp (-d) := one_le_exp_iff.2 (by linarith) + nlinarith + +theorem exists_abs_log_R_add_loglog_sub_le : + ∃ K, 0 ≤ K ∧ ∀ z w, 2 ≤ z → z ≤ w → + |(log (R w) + log (log w)) - (log (R z) + log (log z))| ≤ K * pntE z := by + obtain ⟨c₅, C, hC⟩ := S_asymp + have hC0 : 0 ≤ C := by + have h := (abs_nonneg _).trans (hC 2 le_rfl) + exact nonneg_of_mul_nonneg_left h (pntE_pos 2) + refine ⟨2 * C + 4, by positivity, fun z w hz hzw ↦ ?_⟩ + have hw : 2 ≤ w := hz.trans hzw + set D := primesLT w \ primesLT z + have hR : log (R w) - log (R z) = ∑ p ∈ D, log (1 - (p : ℝ)⁻¹) := by + rw [R_eq_mul_prod_sdiff hzw, log_mul (R_pos z).ne', log_prod] + · ring + · exact fun p hp ↦ (one_sub_inv_pos (mem_primesLT.1 (Finset.mem_sdiff.1 hp).1).1).ne' + · exact (prod_pos fun p hp ↦ + one_sub_inv_pos (mem_primesLT.1 (Finset.mem_sdiff.1 hp).1).1).ne' + have hS : SLT w - SLT z = ∑ p ∈ D, (p : ℝ)⁻¹ := by + rw [SLT, SLT, ← sum_sdiff (primesLT_mono hzw)] + ring + have h1 := abs_sum_log_one_sub_inv_add_inv_le hz hzw + rw [sum_add_distrib, ← hR, ← hS] at h1 + have h2 := S_sub_SLT (z := z) (by linarith) + have h3 := S_sub_SLT (z := w) (by linarith) + have h4 := hC z hz + have h5 := hC w hw + have hE : pntE w ≤ pntE z := pntE_le_pntE (by linarith) hzw + have hiz := inv_le_pntE hz + have hiw : w⁻¹ ≤ z⁻¹ := inv_anti₀ (by linarith) hzw + rw [abs_le] at h1 h4 h5 ⊢ + constructor <;> nlinarith + +/-- Mertens' product theorem with the de la Vallée Poussin error term. -/ +theorem R_asymp : ∃ cR > 0, ∃ C, ∀ z ≥ 2, |R z * log z - cR| ≤ C * pntE z := by + obtain ⟨K, hK0, hK⟩ := exists_abs_log_R_add_loglog_sub_le + obtain ⟨L, hL⟩ := exists_abs_sub_le_of_cauchy (T := fun z ↦ log (R z) + log (log z)) + (g := fun z ↦ K * pntE z) (a := 2) hK (by simpa using tendsto_pntE.const_mul K) + refine ⟨exp L, exp_pos L, exp L * (K * exp K), fun z hz ↦ ?_⟩ + have hlog : 0 < log z := log_pos (by linarith) + have hRz : R z * log z = exp (log (R z) + log (log z)) := by + rw [exp_add, exp_log (R_pos z), exp_log hlog] + have hd := hL z hz + have hdK : |log (R z) + log (log z) - L| ≤ K := by + have := pntE_le_one z + nlinarith + rw [hRz, show exp (log (R z) + log (log z)) - exp L = + exp L * (exp (log (R z) + log (log z) - L) - 1) by rw [mul_sub, ← exp_add]; ring_nf, + abs_mul, abs_of_pos (exp_pos L)] + calc exp L * |exp (log (R z) + log (log z) - L) - 1| + ≤ exp L * (|log (R z) + log (log z) - L| * exp |log (R z) + log (log z) - L|) := by + gcongr; exact abs_exp_sub_one_le_mul_exp _ + _ ≤ exp L * ((K * pntE z) * exp K) := by + have := pntE_pos z + gcongr + _ = exp L * (K * exp K) * pntE z := by ring + +/-- Lower bound `R z ≫ 1 / log z`. -/ +theorem R_lower : ∃ c > 0, ∀ z ≥ 2, c / log z ≤ R z := by + obtain ⟨cR, hcR, C, hC⟩ := R_asymp + obtain ⟨Z, hZ⟩ := eventually_atTop.1 + ((by simpa using tendsto_pntE.const_mul C : Tendsto (fun z ↦ C * pntE z) atTop (𝓝 0)).eventually + (eventually_lt_nhds (half_pos hcR))) + set Z' := max Z 2 + have hlog2 : 0 < log 2 := log_pos one_lt_two + refine ⟨min (cR / 2) (R Z' * log 2), lt_min (half_pos hcR) (mul_pos (R_pos _) hlog2), + fun z hz ↦ ?_⟩ + have hlog : 0 < log z := log_pos (by linarith) + rw [div_le_iff₀ hlog] + rcases le_or_gt Z' z with hzZ | hzZ + · have h1 := hC z hz + have h2 := hZ z ((le_max_left _ _).trans hzZ) + rw [abs_le] at h1 + exact (min_le_left _ _).trans (by linarith) + · refine (min_le_right _ _).trans ?_ + exact mul_le_mul (R_antitone hzZ.le) (log_le_log (by norm_num) hz) hlog2.le (R_pos z).le + +/-- Upper bound `R z ≪ 1 / log z`. -/ +theorem R_upper : ∃ C > 0, ∀ z ≥ 2, R z ≤ C / log z := by + obtain ⟨cR, hcR, C, hC⟩ := R_asymp + refine ⟨cR + |C|, by positivity, fun z hz ↦ ?_⟩ + have hlog : 0 < log z := log_pos (by linarith) + rw [le_div_iff₀ hlog] + have h1 := hC z hz + have h2 : C * pntE z ≤ |C| := + (le_abs_self _).trans (by + rw [abs_mul, abs_of_pos (pntE_pos z)] + exact mul_le_of_le_one_right (abs_nonneg _) (pntE_le_one z)) + rw [abs_le] at h1 + linarith + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/PrimeSums/SummationByParts.lean b/LeanPool/IwaniecLinearSieve/PrimeSums/SummationByParts.lean new file mode 100644 index 000000000..4e7e53c5b --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/PrimeSums/SummationByParts.lean @@ -0,0 +1,139 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic +import Mathlib.Algebra.Order.Star.Real +import Mathlib.NumberTheory.Chebyshev +import Mathlib.Tactic.Polynomial.Basic + +/-! +# Comparing a Stieltjes-type sum with an integral + +An abstract form of the summation by parts in [I71, Lemma 13]: if `g` is a cumulative counting +function that is within `ε` of `F` at the points `a 0 ≤ a 1 ≤ ⋯ ≤ a n`, with `F' = f ≥ 0` and +increments `F (a (j+1)) - F (a j) ≤ δ`, then for `b ≥ 0` monotone +`∑_j b (a (j+1)) (g (j+1) - g j) = ∫ b f + O((δ + 2ε) b (a n))`. +-/ + +@[expose] public section + +open Finset MeasureTheory intervalIntegral + +namespace IwaniecLinearSieve + +/-- Abel summation bound: if `β` is nonnegative and monotone and `|e j| ≤ ε`, then +`|∑_{j simpa using hβ0 + | succ m ih => + obtain ⟨h0, h1, h2⟩ := ih (by omega) + have hm' : β m ≤ β (m + 1) := hβ m (by omega) + refine ⟨by linarith, by linarith, ?_⟩ + rw [sum_range_succ] + have h3 : |(β (m + 1) - β m) * e m| ≤ (β (m + 1) - β m) * ε := by + rw [abs_mul, abs_of_nonneg (by linarith)] + exact mul_le_mul_of_nonneg_left (he m (by omega)) (by linarith) + calc |∑ j ∈ range m, β (j + 1) * (e (j + 1) - e j) + β (m + 1) * (e (m + 1) - e m) - + β (m + 1) * e (m + 1) + β 0 * e 0| + = |(∑ j ∈ range m, β (j + 1) * (e (j + 1) - e j) - β m * e m + β 0 * e 0) - + (β (m + 1) - β m) * e m| := by ring_nf + _ ≤ |∑ j ∈ range m, β (j + 1) * (e (j + 1) - e j) - β m * e m + β 0 * e 0| + + |(β (m + 1) - β m) * e m| := abs_sub _ _ + _ ≤ ε * (β m - β 0) + (β (m + 1) - β m) * ε := add_le_add h2 h3 + _ = ε * (β (m + 1) - β 0) := by ring + obtain ⟨h0, h1, h2⟩ := key n le_rfl + have hn : |β n * e n| ≤ β n * ε := by + rw [abs_mul, abs_of_nonneg h0]; exact mul_le_mul_of_nonneg_left (he n le_rfl) h0 + have hz : |β 0 * e 0| ≤ β 0 * ε := by + rw [abs_mul, abs_of_nonneg hβ0]; exact mul_le_mul_of_nonneg_left (he 0 (by omega)) hβ0 + rw [abs_le] at h2 hn hz ⊢ + constructor <;> nlinarith + +/-- Abstract form of [I71, Lemma 13]. The points `a 0 ≤ ⋯ ≤ a n` partition `[a 0, a n]`; +`g j` is a cumulative counting function at `a j`, within `ε` of `F (a j)`, where `F' = f ≥ 0` +and `F` increases by at most `δ` on each piece. Then for `b ≥ 0` monotone, +`∑_j b (a (j+1)) (g (j+1) - g j)` is within `(δ + 2ε) b (a n)` of `∫ b f`. -/ +theorem abs_sum_sub_integral_le {n : ℕ} {a : ℕ → ℝ} (ha : Monotone a) {b f F : ℝ → ℝ} + {g : ℕ → ℝ} {δ ε : ℝ} (hδ0 : 0 ≤ δ) + (hb : MonotoneOn b (Set.Icc (a 0) (a n))) (hb0 : 0 ≤ b (a 0)) + (hf : ∀ x ∈ Set.Icc (a 0) (a n), 0 ≤ f x) (hfc : ContinuousOn f (Set.Icc (a 0) (a n))) + (hFf : ∀ j < n, ∫ x in a j..a (j + 1), f x = F (a (j + 1)) - F (a j)) + (hδ : ∀ j < n, F (a (j + 1)) - F (a j) ≤ δ) + (hε : ∀ j ≤ n, |g j - F (a j)| ≤ ε) : + |∑ j ∈ range n, b (a (j + 1)) * (g (j + 1) - g j) - ∫ x in a 0..a n, b x * f x| ≤ + (δ + 2 * ε) * b (a n) := by + have hmem : ∀ j ≤ n, a j ∈ Set.Icc (a 0) (a n) := fun j hj ↦ ⟨ha (Nat.zero_le j), ha hj⟩ + have hsub : ∀ j < n, Set.Icc (a j) (a (j + 1)) ⊆ Set.Icc (a 0) (a n) := fun j hj x hx ↦ + ⟨(hmem j hj.le).1.trans hx.1, hx.2.trans (hmem (j + 1) hj).2⟩ + have hle : ∀ j, a j ≤ a (j + 1) := fun j ↦ ha (Nat.le_succ j) + have hβ : ∀ j < n, b (a j) ≤ b (a (j + 1)) := fun j hj ↦ + hb (hmem j hj.le) (hmem (j + 1) hj) (hle j) + have hint : ∀ j < n, IntervalIntegrable (fun x ↦ b x * f x) volume (a j) (a (j + 1)) := by + intro j hj + have h1 := hsub j hj + rw [← Set.uIcc_of_le (hle j)] at h1 + exact (hb.mono h1).intervalIntegrable.mul_continuousOn (hfc.mono h1) + have hintf : ∀ j < n, IntervalIntegrable f volume (a j) (a (j + 1)) := by + intro j hj + have h1 := hsub j hj + rw [← Set.uIcc_of_le (hle j)] at h1 + exact (hfc.mono h1).intervalIntegrable + -- the increments `I j = F (a (j+1)) - F (a j)` are nonnegative + have hI : ∀ j < n, 0 ≤ F (a (j + 1)) - F (a j) := fun j hj ↦ by + rw [← hFf j hj] + exact intervalIntegral.integral_nonneg (hle j) fun x hx ↦ hf x (hsub j hj hx) + -- each piece of the integral lies between `b (a j) I j` and `b (a (j+1)) I j` + have hpiece : ∀ j < n, b (a j) * (F (a (j + 1)) - F (a j)) ≤ ∫ x in a j..a (j + 1), b x * f x ∧ + ∫ x in a j..a (j + 1), b x * f x ≤ b (a (j + 1)) * (F (a (j + 1)) - F (a j)) := by + intro j hj + rw [← hFf j hj, ← intervalIntegral.integral_const_mul, ← intervalIntegral.integral_const_mul] + constructor + · refine intervalIntegral.integral_mono_on (hle j) ((hintf j hj).const_mul _) (hint j hj) + fun x hx ↦ mul_le_mul_of_nonneg_right ?_ (hf x (hsub j hj hx)) + exact hb (hmem j hj.le) (hsub j hj hx) hx.1 + · refine intervalIntegral.integral_mono_on (hle j) (hint j hj) ((hintf j hj).const_mul _) + fun x hx ↦ mul_le_mul_of_nonneg_right ?_ (hf x (hsub j hj hx)) + exact hb (hsub j hj hx) (hmem (j + 1) hj) hx.2 + rw [← intervalIntegral.sum_integral_adjacent_intervals hint] + -- split the sum into a main part and an error part + have hsplit : ∑ j ∈ range n, b (a (j + 1)) * (g (j + 1) - g j) - + ∑ j ∈ range n, ∫ x in a j..a (j + 1), b x * f x = + ∑ j ∈ range n, (b (a (j + 1)) * (F (a (j + 1)) - F (a j)) - + ∫ x in a j..a (j + 1), b x * f x) + + ∑ j ∈ range n, b (a (j + 1)) * ((g (j + 1) - F (a (j + 1))) - (g j - F (a j))) := by + rw [← sum_sub_distrib, ← sum_add_distrib] + refine sum_congr rfl fun j _ ↦ ?_ + ring + rw [hsplit] + have hmain0 : 0 ≤ ∑ j ∈ range n, (b (a (j + 1)) * (F (a (j + 1)) - F (a j)) - + ∫ x in a j..a (j + 1), b x * f x) := + sum_nonneg fun j hj ↦ sub_nonneg.2 (hpiece j (mem_range.1 hj)).2 + have hmain : ∑ j ∈ range n, (b (a (j + 1)) * (F (a (j + 1)) - F (a j)) - + ∫ x in a j..a (j + 1), b x * f x) ≤ δ * b (a n) := by + calc _ ≤ ∑ j ∈ range n, (b (a (j + 1)) - b (a j)) * δ := by + refine sum_le_sum fun j hj ↦ ?_ + have hj := mem_range.1 hj + have h1 := (hpiece j hj).1 + have h2 : (b (a (j + 1)) - b (a j)) * (F (a (j + 1)) - F (a j)) ≤ + (b (a (j + 1)) - b (a j)) * δ := + mul_le_mul_of_nonneg_left (hδ j hj) (sub_nonneg.2 (hβ j hj)) + linarith + _ = (b (a n) - b (a 0)) * δ := by rw [← sum_mul, sum_range_sub (fun j ↦ b (a j))] + _ ≤ δ * b (a n) := by nlinarith + have herr := abs_sum_mul_sub_le (β := fun j ↦ b (a j)) (e := fun j ↦ g j - F (a j)) hβ hb0 hε + rw [abs_le] at herr ⊢ + constructor <;> linarith + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/Rosser.lean b/LeanPool/IwaniecLinearSieve/Rosser.lean new file mode 100644 index 000000000..8acf0fd6b --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Rosser.lean @@ -0,0 +1,517 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Basic +public import Mathlib.NumberTheory.ArithmeticFunction.Moebius +import Mathlib.Algebra.Order.Ring.Star +import Mathlib.Data.Int.Star +import Mathlib.NumberTheory.Chebyshev +import Mathlib.Tactic.Polynomial.Basic +import Std.Tactic.BVDecide.Normalize.Bool + +/-! +# Rosser's linear sieve, combinatorial part ([I71, §2], `k = 1`) + +* `rosserSet lower y z`: the supports `D⁻` (`lower = true`) and `D⁺` (`lower = false`) of + Rosser's `β = 2` sieve, defined recursively by + `D^± (y, z) = {1} ∪ ⋃_{p < z} p · D^∓ (y / p, p)`, where `D⁺` only admits `p³ < y`. +* `rosserSieve_le_siftIndicator_le`: the sieve property + `∑_{d ∈ D⁻, d ∣ m} μ(d) ≤ [(m, P(z)) = 1] ≤ ∑_{d ∈ D⁺, d ∣ m} μ(d)`, from Buchstab's identity. +* `rosserMain lower y z = ∑_{d ∈ D^±} μ(d)/d` and the depth-truncated deficits `fail`, with + `R(z) - rosserMain true y z = fail true r y z` and + `rosserMain false y z - R(z) = fail false r y z` for `r > π(z)` (`fail_eq_of_card_lt`); + `R(z) = 1 - ∑_{p < z} R(p)/p` is `R_eq`. +* `card_rosserSet`, `card_filter_rosserSet_succ`: the counting recursions ([I71, Lemma 17]). +-/ + +@[expose] public section + +open Finset ArithmeticFunction +open scoped ArithmeticFunction.Moebius + +namespace IwaniecLinearSieve + +section primesLT + +variable {z : ℝ} {p : ℕ} + +theorem lt_ceil_of_mem_primesLT (hp : p ∈ primesLT z) : p < ⌈z⌉₊ := + Nat.lt_of_mem_primesBelow hp + +theorem prime_of_mem_primesLT (hp : p ∈ primesLT z) : p.Prime := + (mem_primesLT.1 hp).1 + +theorem lt_of_mem_primesLT (hp : p ∈ primesLT z) : (p : ℝ) < z := + (mem_primesLT.1 hp).2 + +theorem primesLT_natCast_subset (hp : p ∈ primesLT z) : primesLT p ⊆ primesLT z := by + intro q hq + rw [mem_primesLT] at hq ⊢ + exact ⟨hq.1, hq.2.trans (lt_of_mem_primesLT hp)⟩ + +theorem notMem_primesLT_self : p ∉ primesLT p := by + simp [mem_primesLT] + +theorem primesLT_natCast_ssubset (hp : p ∈ primesLT z) : primesLT p ⊂ primesLT z := + ssubset_of_subset_of_ne (primesLT_natCast_subset hp) fun h ↦ + notMem_primesLT_self (h ▸ hp) + +/-- For `p < z` prime, the primes below `z` that are smaller than `p` are the primes below `p`. -/ +theorem filter_lt_primesLT (hp : p ∈ primesLT z) : + (primesLT z).filter (· < p) = primesLT p := by + ext q + simp only [mem_filter, mem_primesLT, Nat.cast_lt] + constructor + · rintro ⟨⟨hq, -⟩, hqp⟩ + exact ⟨hq, hqp⟩ + · rintro ⟨hq, hqp⟩ + exact ⟨⟨hq, (Nat.cast_lt.2 hqp).trans (lt_of_mem_primesLT hp)⟩, hqp⟩ + +/-- Strong induction on `⌈z⌉₊`, descending from `z` to the primes below `z`. -/ +theorem primesLT_induction {P : ℝ → Prop} (h : ∀ z, (∀ p ∈ primesLT z, P p) → P z) (z : ℝ) : + P z := by + suffices ∀ n : ℕ, ∀ z : ℝ, ⌈z⌉₊ = n → P z from this _ z rfl + intro n + induction n using Nat.strong_induction_on with + | _ n ih => + rintro z rfl + exact h z fun p hp ↦ ih p (by simpa using lt_ceil_of_mem_primesLT hp) p (by simp) + +/-- [I71, (2.11)] with `k = 1`: `R(z) = 1 - ∑_{p < z} R(p) / p`. -/ +theorem R_eq (z : ℝ) : R z = 1 - ∑ p ∈ primesLT z, R p / p := by + rw [R, prod_one_sub_ordered] + congr 1 + refine sum_congr rfl fun p hp ↦ ?_ + rw [filter_lt_primesLT hp, R, div_eq_inv_mul] + +end primesLT + +/-! ### The sets `D^±` -/ + +/-- The primes `p < z` admitted at the top level of `rosserSet lower y z`: all of them for the +lower-bound sieve, and those with `p³ < y` for the upper-bound sieve. -/ +noncomputable def rosserPrimes (lower : Bool) (y z : ℝ) : Finset ℕ := + (primesLT z).filter fun p ↦ lower = true ∨ (p : ℝ) ^ 3 < y + +/-- Rosser's sieve support (`β = 2`, [I71, §2]): `rosserSet true y z` is `D⁻` and +`rosserSet false y z` is `D⁺`. Equivalently `d = p₁ ⋯ p_l` with `z > p₁ > ⋯ > p_l` prime and +`p₁ ⋯ p_m p_m² < y` for every `m ≤ l` which is even (for `D⁻`) or odd (for `D⁺`). -/ +noncomputable def rosserSet (lower : Bool) (y z : ℝ) : Finset ℕ := + insert 1 ((rosserPrimes lower y z).attach.biUnion fun p ↦ + (rosserSet (!lower) (y / p.1) p.1).image (p.1 * ·)) +termination_by ⌈z⌉₊ +decreasing_by + rw [Nat.ceil_natCast] + exact lt_ceil_of_mem_primesLT (mem_filter.1 p.2).1 + +variable {lower : Bool} {y z : ℝ} {p d : ℕ} + +theorem mem_rosserPrimes : + p ∈ rosserPrimes lower y z ↔ p ∈ primesLT z ∧ (lower = true ∨ (p : ℝ) ^ 3 < y) := + mem_filter + +@[simp] theorem rosserPrimes_true : rosserPrimes true y z = primesLT z := by + simp [rosserPrimes] + +theorem rosserPrimes_false : + rosserPrimes false y z = (primesLT z).filter fun p : ℕ ↦ (p : ℝ) ^ 3 < y := by + simp [rosserPrimes] + +theorem rosserPrimes_subset : rosserPrimes lower y z ⊆ primesLT z := + filter_subset _ _ + +theorem rosserSet_eq (lower : Bool) (y z : ℝ) : + rosserSet lower y z = insert 1 ((rosserPrimes lower y z).biUnion fun p ↦ + (rosserSet (!lower) (y / p) p).image (p * ·)) := by + rw [rosserSet] + ext d + simp + +theorem one_mem_rosserSet : 1 ∈ rosserSet lower y z := by + rw [rosserSet_eq] + exact mem_insert_self _ _ + +theorem mem_rosserSet : d ∈ rosserSet lower y z ↔ + d = 1 ∨ ∃ p ∈ rosserPrimes lower y z, ∃ e ∈ rosserSet (!lower) (y / p) p, d = p * e := by + rw [rosserSet_eq] + simp [eq_comm (a := d)] + +/-- Elements of `rosserSet lower y z` are squarefree products of primes below `z`. -/ +theorem squarefree_and_primeFactors_subset (hd : d ∈ rosserSet lower y z) : + Squarefree d ∧ d.primeFactors ⊆ primesLT z := by + induction z using primesLT_induction generalizing lower y d with + | h z ih => + rcases mem_rosserSet.1 hd with rfl | ⟨p, hp, e, he, rfl⟩ + · simp + have hpz := rosserPrimes_subset hp + have hpp := prime_of_mem_primesLT hpz + obtain ⟨hse, hpe⟩ := ih p hpz he + have hne : ¬ p ∣ e := fun h ↦ + notMem_primesLT_self (hpe (Nat.mem_primeFactors.2 ⟨hpp, h, hse.ne_zero⟩)) + refine ⟨Nat.squarefree_mul_iff.2 ⟨(Nat.Prime.coprime_iff_not_dvd hpp).2 hne, + hpp.squarefree, hse⟩, ?_⟩ + rw [Nat.primeFactors_mul hpp.ne_zero hse.ne_zero, hpp.primeFactors] + exact union_subset (singleton_subset_iff.2 hpz) (hpe.trans (primesLT_natCast_subset hpz)) + +theorem squarefree_of_mem_rosserSet (hd : d ∈ rosserSet lower y z) : Squarefree d := + (squarefree_and_primeFactors_subset hd).1 + +theorem primeFactors_subset_of_mem_rosserSet (hd : d ∈ rosserSet lower y z) : + d.primeFactors ⊆ primesLT z := + (squarefree_and_primeFactors_subset hd).2 + +theorem pos_of_mem_rosserSet (hd : d ∈ rosserSet lower y z) : 0 < d := + Nat.pos_of_ne_zero (squarefree_of_mem_rosserSet hd).ne_zero + +/-- Elements of `rosserSet` are squarefree divisors of `primorialLT z`. -/ +theorem dvd_primorialLT_of_mem_rosserSet (hd : d ∈ rosserSet lower y z) : + d ∣ primorialLT z := by + rw [← Nat.prod_primeFactors_of_squarefree (squarefree_of_mem_rosserSet hd)] + exact prod_dvd_prod_of_subset _ _ _ (primeFactors_subset_of_mem_rosserSet hd) + +theorem lt_of_prime_dvd_of_mem_rosserSet {q : ℕ} (hq : q.Prime) (hd : d ∈ rosserSet lower y z) + (hqd : q ∣ d) : (q : ℝ) < z := + lt_of_mem_primesLT <| primeFactors_subset_of_mem_rosserSet hd <| + Nat.mem_primeFactors.2 ⟨hq, hqd, (pos_of_mem_rosserSet hd).ne'⟩ + +theorem not_dvd_of_mem_rosserSet (hp : p.Prime) (hd : d ∈ rosserSet lower y p) : ¬ p ∣ d := + fun h ↦ (lt_irrefl _) (lt_of_prime_dvd_of_mem_rosserSet hp hd h) + +theorem coprime_of_mem_rosserSet (hp : p.Prime) (hd : d ∈ rosserSet lower y p) : + p.Coprime d := + (Nat.Prime.coprime_iff_not_dvd hp).2 (not_dvd_of_mem_rosserSet hp hd) + + +theorem pairwiseDisjoint_rosserSet_image (lower : Bool) (y z : ℝ) : + (rosserPrimes lower y z : Set ℕ).PairwiseDisjoint fun p ↦ + (rosserSet (!lower) (y / p) p).image (p * ·) := by + intro p hp q hq hpq + simp only [Function.onFun] + rw [disjoint_left] + simp only [mem_image, not_exists, not_and] + rintro _ ⟨d, hd, rfl⟩ e he hde + have hp' := prime_of_mem_primesLT (rosserPrimes_subset hp) + have hq' := prime_of_mem_primesLT (rosserPrimes_subset hq) + have key : ∀ {p q d e : ℕ}, p.Prime → q.Prime → p ≠ q → e ∈ rosserSet (!lower) (y / q) q → + q * e = p * d → (p : ℝ) < q := by + intro p q d e hp hq hpq he h + have : p ∣ q * e := h ▸ dvd_mul_right p d + rcases (Nat.Prime.dvd_mul hp).1 this with h' | h' + · exact absurd ((Nat.prime_dvd_prime_iff_eq hp hq).1 h') hpq + · exact lt_of_prime_dvd_of_mem_rosserSet hp he h' + exact lt_asymm (key hp' hq' hpq he hde) (key hq' hp' (Ne.symm hpq) hd hde.symm) + +theorem one_notMem_biUnion_rosserSet (lower : Bool) (y z : ℝ) : + 1 ∉ (rosserPrimes lower y z).biUnion fun p ↦ + (rosserSet (!lower) (y / p) p).image (p * ·) := by + simp only [mem_biUnion, mem_image, not_exists, not_and] + intro p hp d _ h + exact (prime_of_mem_primesLT (rosserPrimes_subset hp)).one_lt.ne' + (Nat.eq_one_of_mul_eq_one_right h) + +/-- Sums over `rosserSet` unfold along the recursion. -/ +theorem sum_rosserSet {M : Type*} [AddCommMonoid M] (f : ℕ → M) (lower : Bool) (y z : ℝ) : + ∑ d ∈ rosserSet lower y z, f d = + f 1 + ∑ p ∈ rosserPrimes lower y z, ∑ d ∈ rosserSet (!lower) (y / p) p, f (p * d) := by + rw [rosserSet_eq, sum_insert (one_notMem_biUnion_rosserSet lower y z), + sum_biUnion (pairwiseDisjoint_rosserSet_image lower y z)] + congr 1 + refine sum_congr rfl fun p hp ↦ ?_ + rw [sum_image] + intro a _ b _ h + exact Nat.eq_of_mul_eq_mul_left (prime_of_mem_primesLT (rosserPrimes_subset hp)).pos h + +/-- The size of the sieve support satisfies the same recursion as the set. -/ +theorem card_rosserSet (lower : Bool) (y z : ℝ) : + #(rosserSet lower y z) = 1 + ∑ p ∈ rosserPrimes lower y z, #(rosserSet (!lower) (y / p) p) := by + simpa using sum_rosserSet (fun _ ↦ (1 : ℕ)) lower y z + +theorem card_primeFactors_mul_of_mem_rosserSet (hp : p.Prime) + (hd : d ∈ rosserSet lower y p) : #(p * d).primeFactors = #d.primeFactors + 1 := by + rw [Nat.primeFactors_mul hp.ne_zero (pos_of_mem_rosserSet hd).ne', hp.primeFactors, + singleton_union, card_insert_of_notMem] + exact fun h ↦ not_dvd_of_mem_rosserSet hp hd (Nat.dvd_of_mem_primeFactors h) + +/-- The elements of `rosserSet` with at most `0` prime factors. -/ +theorem card_filter_rosserSet_zero (lower : Bool) (y z : ℝ) : + #((rosserSet lower y z).filter fun d ↦ #d.primeFactors ≤ 0) = 1 := by + rw [card_eq_one] + refine ⟨1, ?_⟩ + ext d + simp only [mem_filter, nonpos_iff_eq_zero, card_eq_zero, Nat.primeFactors_eq_empty, + mem_singleton] + constructor + · rintro ⟨hd, h0 | h1⟩ + · exact absurd h0 (pos_of_mem_rosserSet hd).ne' + · exact h1 + · rintro rfl + exact ⟨one_mem_rosserSet, Or.inr rfl⟩ + +/-- Depth-truncated counts ([I71, Lemma 17]): the elements of `rosserSet` with at most `n + 1` +prime factors. -/ +theorem card_filter_rosserSet_succ (n : ℕ) (lower : Bool) (y z : ℝ) : + #((rosserSet lower y z).filter fun d ↦ #d.primeFactors ≤ n + 1) = + 1 + ∑ p ∈ rosserPrimes lower y z, + #((rosserSet (!lower) (y / p) p).filter fun d ↦ #d.primeFactors ≤ n) := by + simp only [card_filter] + rw [sum_rosserSet] + simp only [Nat.primeFactors_one, card_empty, zero_le, ite_true] + congr 1 + refine sum_congr rfl fun p hp ↦ sum_congr rfl fun d hd ↦ ?_ + rw [card_primeFactors_mul_of_mem_rosserSet (prime_of_mem_primesLT (rosserPrimes_subset hp)) hd] + simp + +/-! ### Main terms -/ + +/-- `∑_{d ∈ D^±} μ(d) / d`. -/ +noncomputable def rosserMain (lower : Bool) (y z : ℝ) : ℝ := + ∑ d ∈ rosserSet lower y z, (μ d : ℝ) / d + +theorem moebius_mul_of_mem_rosserSet (hp : p.Prime) (hd : d ∈ rosserSet lower y p) : + μ (p * d) = -μ d := by + rw [isMultiplicative_moebius.map_mul_of_coprime (coprime_of_mem_rosserSet hp hd), + moebius_apply_prime hp, neg_one_mul] + +theorem rosserMain_eq (lower : Bool) (y z : ℝ) : + rosserMain lower y z = 1 - ∑ p ∈ rosserPrimes lower y z, rosserMain (!lower) (y / p) p / p := by + rw [rosserMain, sum_rosserSet, sub_eq_add_neg, ← sum_neg_distrib] + simp only [moebius_apply_one, Int.cast_one, Nat.cast_one, div_one] + congr 1 + refine sum_congr rfl fun p hp ↦ ?_ + have hp' := prime_of_mem_primesLT (rosserPrimes_subset hp) + rw [rosserMain, sum_div, ← sum_neg_distrib] + refine sum_congr rfl fun d hd ↦ ?_ + rw [moebius_mul_of_mem_rosserSet hp' hd] + push_cast + field_simp + + +/-! ### The sieve property -/ + +/-- `1` if no prime `p < z` divides `m`, and `0` otherwise. -/ +noncomputable def siftIndicator (z : ℝ) (m : ℕ) : ℤ := + if ∀ p ∈ primesLT z, ¬ p ∣ m then 1 else 0 + +theorem siftIndicator_nonneg (z : ℝ) (m : ℕ) : 0 ≤ siftIndicator z m := by + unfold siftIndicator + split_ifs <;> norm_num + +/-- Buchstab's identity for the indicator: `[(m, P(z)) = 1] = 1 - ∑_{p < z, p ∣ m} [(m, P(p)) = 1]`, +i.e. [I71, (2.3)] for a single integer. -/ +theorem siftIndicator_eq (z : ℝ) (m : ℕ) : + siftIndicator z m = 1 - ∑ p ∈ (primesLT z).filter (· ∣ m), siftIndicator p m := by + set F := (primesLT z).filter (· ∣ m) + rcases F.eq_empty_or_nonempty with hF | hF + · rw [hF, sum_empty, sub_zero, siftIndicator, ite_eq_left] + intro p hp hpm + have : p ∈ F := mem_filter.2 ⟨hp, hpm⟩ + simp [hF] at this + set p₀ := F.min' hF + have hp₀ : p₀ ∈ F := F.min'_mem hF + have hsum : ∑ p ∈ F, siftIndicator p m = ∑ p ∈ F, if p = p₀ then 1 else 0 := by + refine sum_congr rfl fun p hp ↦ ?_ + rw [siftIndicator] + have hpz := (mem_filter.1 hp).1 + congr 1 + apply propext + constructor + · intro h + refine le_antisymm ?_ (F.min'_le p hp) + by_contra hlt + exact h p₀ (mem_primesLT.2 ⟨prime_of_mem_primesLT (mem_filter.1 hp₀).1, + by exact_mod_cast not_le.1 hlt⟩) (mem_filter.1 hp₀).2 + · rintro rfl q hq hqm + have hqF : q ∈ F := mem_filter.2 ⟨primesLT_natCast_subset hpz hq, hqm⟩ + exact absurd (F.min'_le q hqF) (not_le.2 (by exact_mod_cast lt_of_mem_primesLT hq)) + rw [hsum, sum_ite_eq' F p₀, ite_eq_left hp₀, siftIndicator, ite_eq_right] + · norm_num + · push Not + exact ⟨p₀, (mem_filter.1 hp₀).1, (mem_filter.1 hp₀).2⟩ + +/-- For `m ∣ P(z)`, the indicator is `[m = 1]`. -/ +theorem siftIndicator_of_dvd_primorialLT {m : ℕ} (hm : m ∣ primorialLT z) : + siftIndicator z m = if m = 1 then 1 else 0 := by + rw [siftIndicator] + congr 1 + apply propext + constructor + · intro h + by_contra hm1 + obtain ⟨q, hq, hqm⟩ := Nat.exists_prime_and_dvd hm1 + have hqP : q ∣ primorialLT z := hqm.trans hm + obtain ⟨p, hp, hqp⟩ := (Prime.dvd_finsetProd_iff hq.prime _).1 hqP + rw [(Nat.prime_dvd_prime_iff_eq hq (prime_of_mem_primesLT hp)).1 hqp] at hqm + exact h p hp hqm + · rintro rfl p hp h + exact (prime_of_mem_primesLT hp).one_lt.ne' (Nat.dvd_one.1 h) + + +/-- `∑_{d ∈ D^±, d ∣ m} μ(d)`. -/ +noncomputable def rosserSieve (lower : Bool) (y z : ℝ) (m : ℕ) : ℤ := + ∑ d ∈ (rosserSet lower y z).filter (· ∣ m), μ d + +theorem rosserSieve_eq (lower : Bool) (y z : ℝ) (m : ℕ) : + rosserSieve lower y z m = + 1 - ∑ p ∈ (rosserPrimes lower y z).filter (· ∣ m), rosserSieve (!lower) (y / p) p m := by + rw [rosserSieve, sum_filter, sum_rosserSet, sum_filter, sub_eq_add_neg, ← sum_neg_distrib] + simp only [one_dvd, ite_true, moebius_apply_one] + congr 1 + refine sum_congr rfl fun p hp ↦ ?_ + have hp' := prime_of_mem_primesLT (rosserPrimes_subset hp) + split_ifs with hpm + · rw [rosserSieve, sum_filter, ← sum_neg_distrib] + refine sum_congr rfl fun d hd ↦ ?_ + have key : p * d ∣ m ↔ d ∣ m := + ⟨fun h ↦ (dvd_mul_left d p).trans h, + fun h ↦ Nat.Coprime.mul_dvd_of_dvd_of_dvd (coprime_of_mem_rosserSet hp' hd) hpm h⟩ + simp only [key, moebius_mul_of_mem_rosserSet hp' hd] + split_ifs <;> simp + · refine sum_eq_zero fun d _ ↦ ?_ + rw [ite_eq_right] + exact fun h ↦ hpm ((dvd_mul_right p d).trans h) + + +/-- The sieve property of Rosser's weights, for every `m`: +`∑_{d ∈ D⁻, d ∣ m} μ(d) ≤ [(m, P(z)) = 1] ≤ ∑_{d ∈ D⁺, d ∣ m} μ(d)`. -/ +theorem rosserSieve_le_siftIndicator_le (y z : ℝ) (m : ℕ) : + rosserSieve true y z m ≤ siftIndicator z m ∧ siftIndicator z m ≤ rosserSieve false y z m := by + induction z using primesLT_induction generalizing y with + | h z ih => + constructor + · rw [rosserSieve_eq, siftIndicator_eq, rosserPrimes_true] + refine sub_le_sub_left (sum_le_sum fun p hp ↦ ?_) _ + exact (ih p (mem_filter.1 hp).1 (y / p)).2 + · rw [rosserSieve_eq, siftIndicator_eq] + refine sub_le_sub_left ?_ _ + calc ∑ p ∈ (rosserPrimes false y z).filter (· ∣ m), rosserSieve (!false) (y / p) p m + ≤ ∑ p ∈ (rosserPrimes false y z).filter (· ∣ m), siftIndicator p m := + sum_le_sum fun p hp ↦ + (ih p (rosserPrimes_subset (mem_filter.1 hp).1) (y / p)).1 + _ ≤ ∑ p ∈ (primesLT z).filter (· ∣ m), siftIndicator p m := + sum_le_sum_of_subset_of_nonneg (filter_subset_filter _ rosserPrimes_subset) + fun p _ _ ↦ siftIndicator_nonneg p m + +/-- Lower-bound sieve property: `∑_{d ∈ D⁻, d ∣ m} μ(d) ≤ [no prime p < z divides m]`. -/ +theorem sum_moebius_rosserSet_true_le (y z : ℝ) (m : ℕ) : + ∑ d ∈ (rosserSet true y z).filter (· ∣ m), μ d ≤ + if ∀ p ∈ primesLT z, ¬ p ∣ m then 1 else 0 := + (rosserSieve_le_siftIndicator_le y z m).1 + +/-- Upper-bound sieve property: `[no prime p < z divides m] ≤ ∑_{d ∈ D⁺, d ∣ m} μ(d)`. -/ +theorem le_sum_moebius_rosserSet_false (y z : ℝ) (m : ℕ) : + (if ∀ p ∈ primesLT z, ¬ p ∣ m then 1 else 0) ≤ + ∑ d ∈ (rosserSet false y z).filter (· ∣ m), μ d := + (rosserSieve_le_siftIndicator_le y z m).2 + +/-- The sieve property for divisors of `P(z)`: +`∑_{d ∈ D⁻, d ∣ m} μ(d) ≤ [m = 1] ≤ ∑_{d ∈ D⁺, d ∣ m} μ(d)`. -/ +theorem rosserSieve_of_dvd_primorialLT (y : ℝ) {m : ℕ} (hm : m ∣ primorialLT z) : + ∑ d ∈ (rosserSet true y z).filter (· ∣ m), μ d ≤ (if m = 1 then 1 else 0) ∧ + (if m = 1 then 1 else 0) ≤ ∑ d ∈ (rosserSet false y z).filter (· ∣ m), μ d := by + rw [← siftIndicator_of_dvd_primorialLT hm] + exact rosserSieve_le_siftIndicator_le y z m + +/-! ### The deficits `R(z) - ∑_{D⁻} μ(d)/d` and `∑_{D⁺} μ(d)/d - R(z)` -/ + +/-- Depth-truncated deficits ([I71, (2.9), (2.10)] with `k = 1`): `fail true r y z` and +`fail false r y z` are `R(z) - ∑_{d ∈ D⁻} μ(d)/d` and `∑_{d ∈ D⁺} μ(d)/d - R(z)` computed to +depth `r`. -/ +noncomputable def fail : Bool → ℕ → ℝ → ℝ → ℝ + | _, 0, _, _ => 0 + | true, r + 1, y, z => ∑ p ∈ primesLT z, fail false r (y / p) p / p + | false, r + 1, y, z => ∑ p ∈ rosserPrimes false y z, fail true r (y / p) p / p + + ∑ p ∈ (primesLT z).filter (fun p : ℕ ↦ ¬ (p : ℝ) ^ 3 < y), R p / p + +@[simp] theorem fail_zero (lower : Bool) (y z : ℝ) : fail lower 0 y z = 0 := by + cases lower <;> rfl + +theorem fail_true_succ (r : ℕ) (y z : ℝ) : + fail true (r + 1) y z = ∑ p ∈ primesLT z, fail false r (y / p) p / p := rfl + +theorem fail_false_succ (r : ℕ) (y z : ℝ) : + fail false (r + 1) y z = ∑ p ∈ rosserPrimes false y z, fail true r (y / p) p / p + + ∑ p ∈ (primesLT z).filter (fun p : ℕ ↦ ¬ (p : ℝ) ^ 3 < y), R p / p := rfl + +theorem fail_nonneg (lower : Bool) (r : ℕ) (y z : ℝ) : 0 ≤ fail lower r y z := by + induction r generalizing lower y z with + | zero => simp + | succ r ih => + cases lower + · rw [fail_false_succ] + exact add_nonneg (sum_nonneg fun p _ ↦ div_nonneg (ih _ _ _) p.cast_nonneg) + (sum_nonneg fun p _ ↦ div_nonneg (R_nonneg _) p.cast_nonneg) + · rw [fail_true_succ] + exact sum_nonneg fun p _ ↦ div_nonneg (ih _ _ _) p.cast_nonneg + +theorem fail_le_fail_succ (lower : Bool) (r : ℕ) (y z : ℝ) : + fail lower r y z ≤ fail lower (r + 1) y z := by + induction r generalizing lower y z with + | zero => simpa using fail_nonneg lower 1 y z + | succ r ih => + cases lower + · rw [fail_false_succ, fail_false_succ] + gcongr with p + exact ih _ _ _ + · rw [fail_true_succ, fail_true_succ] + gcongr with p + exact ih _ _ _ + +theorem fail_mono (lower : Bool) (y z : ℝ) : Monotone fun r ↦ fail lower r y z := + monotone_nat_of_le_succ fun r ↦ fail_le_fail_succ lower r y z + +/-- Once `r` exceeds the possible depth of the recursion, `fail` computes the deficits exactly +([I71, Lemma 2]). -/ +theorem fail_eq_of_card_lt {r : ℕ} (hr : #(primesLT z) < r) (y : ℝ) : + fail true r y z = R z - rosserMain true y z ∧ + fail false r y z = rosserMain false y z - R z := by + induction r generalizing y z with + | zero => simp at hr + | succ r ih => + have ih' : ∀ p ∈ primesLT z, ∀ y, fail true r y p = R p - rosserMain true y p ∧ + fail false r y p = rosserMain false y p - R p := fun p hp y ↦ + ih ((card_lt_card (primesLT_natCast_ssubset hp)).trans_le (Nat.lt_succ_iff.1 hr)) y + constructor + · rw [fail_true_succ, rosserMain_eq, R_eq z, rosserPrimes_true] + simp only [Bool.not_true] + rw [sub_sub_sub_cancel_left, ← sum_sub_distrib] + refine sum_congr rfl fun p hp ↦ ?_ + rw [(ih' p hp _).2, sub_div] + · rw [fail_false_succ, rosserMain_eq, R_eq z, rosserPrimes_false, + ← sum_filter_add_sum_filter_not (primesLT z) (fun p : ℕ ↦ (p : ℝ) ^ 3 < y) + (fun p ↦ R p / p)] + simp only [Bool.not_false, ← rosserPrimes_false] + have : ∑ p ∈ rosserPrimes false y z, fail true r (y / p) p / p = + ∑ p ∈ rosserPrimes false y z, R p / p - + ∑ p ∈ rosserPrimes false y z, rosserMain true (y / p) p / p := by + rw [← sum_sub_distrib] + refine sum_congr rfl fun p hp ↦ ?_ + rw [(ih' p (rosserPrimes_subset hp) _).1, sub_div] + rw [this] + ring + +/-- `∑_{d ∈ D⁻} μ(d)/d = R(z) - fail true r y z` for `r` large. -/ +theorem rosserMain_true_eq {r : ℕ} (hr : #(primesLT z) < r) (y : ℝ) : + rosserMain true y z = R z - fail true r y z := by + rw [(fail_eq_of_card_lt hr y).1] + ring + +/-- `∑_{d ∈ D⁺} μ(d)/d = R(z) + fail false r y z` for `r` large. -/ +theorem rosserMain_false_eq {r : ℕ} (hr : #(primesLT z) < r) (y : ℝ) : + rosserMain false y z = R z + fail false r y z := by + rw [(fail_eq_of_card_lt hr y).2] + ring + +theorem rosserMain_true_le_R (y z : ℝ) : rosserMain true y z ≤ R z := by + rw [rosserMain_true_eq (Nat.lt_succ_self _) y] + linarith [fail_nonneg true (#(primesLT z) + 1) y z] + +theorem R_le_rosserMain_false (y z : ℝ) : R z ≤ rosserMain false y z := by + rw [rosserMain_false_eq (Nat.lt_succ_self _) y] + linarith [fail_nonneg false (#(primesLT z) + 1) y z] + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/SieveFunctions.lean b/LeanPool/IwaniecLinearSieve/SieveFunctions.lean new file mode 100644 index 000000000..3c90dec8a --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveFunctions.lean @@ -0,0 +1,29 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.SieveFunctions.Defs +public import LeanPool.IwaniecLinearSieve.SieveFunctions.Bounds +public import LeanPool.IwaniecLinearSieve.SieveFunctions.Series +public import LeanPool.IwaniecLinearSieve.SieveFunctions.LemmaFive +import Mathlib.NumberTheory.Chebyshev + +/-! +# The sieve functions of [I71, §3] + +* `IwaniecLinearSieve.g`: Iwaniec's `g_n` (3.1)–(3.3), with `g_two_eq`, `g_two_of_four_le`, + `g_odd_eq_integral`, `g_odd_of_le_three`, `g_even_eq_integral`, `continuous_g`, `g_nonneg`, + `g_pos`, `g_antitone`, `g_eq_zero_of_le`. +* Lemma 3: `psi_le_psi_two`. Lemma 4: `g_odd_le'` (3.4), `g_even_le` (3.5), with constants + `gLead` (`a`) and `gRatio` (`A`), `gRatio_lt : gRatio < 0.72`. +* Corollary: `fSieve` (`f`), `FSieve` (`F`), `fr`; `continuous_fSieve`, `fSieve_pos`, + `fSieve_le`, `fSieve_eq_integral` (3.6), `FSieve_eq_integral`, `FSieve_of_le_three` (3.7), ... +* Lemma 5: `fSieve_eq_on_Icc'` (3.9), `fSieve_two` (3.10), `fSieve_eq_on_Icc`, + `one_sub_fSieve_div_ge`. +-/ + +@[expose] public section diff --git a/LeanPool/IwaniecLinearSieve/SieveFunctions/Bounds.lean b/LeanPool/IwaniecLinearSieve/SieveFunctions/Bounds.lean new file mode 100644 index 000000000..a4ef49e79 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveFunctions/Bounds.lean @@ -0,0 +1,332 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Definitions +public import Mathlib.Analysis.Calculus.Deriv.Basic +public import Mathlib.Analysis.LocallyConvex.AbsConvexOpen +import LeanPool.IwaniecLinearSieve.SieveFunctions.Defs +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds +import Mathlib.Analysis.SpecialFunctions.Integrals.Basic +import Mathlib.NumberTheory.Chebyshev +import Mathlib.Tactic.Polynomial.Basic + +/-! +# Lemmas 3 and 4 of [I71, §3] + +* Lemma 3: `ψ(s) = s⁻¹ e^{s-3} (1 + 3 log (3/(s-1)))` satisfies `ψ(s) ≤ ψ(2)` on `[2, 4]`. +* Lemma 4: with `a = sup_{2 ≤ s ≤ 4} g₂(s) s⁻¹ eˢ` (`gLead`) and + `A = (e/3) ψ(2) = (1 + 3 log 3)/6 < 0.72` (`gRatio`), + `g_{2n+1}(s) ≤ a (e/3) A^{n-1} s e^{-s}` for `s ≥ 1`, `n ≥ 1` (3.4), and + `g_{2n+2}(s) ≤ a Aⁿ s e^{-s}` for `s ≥ 2`, `n ≥ 0` (3.5). +-/ + +@[expose] public section + +open Real Set MeasureTheory intervalIntegral + +namespace IwaniecLinearSieve + +/-! ### Numerical facts -/ +theorem log_three_sub_log_two_lt : log 3 - log 2 < 5 / 12 := by + have h1 := log_three_lt_d9 + have h2 := log_two_gt_d9 + norm_num at h1 h2 ⊢ + linarith + +theorem one_lt_log_three : 1 < log 3 := by + have := log_three_gt_d9; norm_num at this ⊢; linarith + +theorem exp_one_sq_lt : exp 1 ^ 2 < 2 + 6 * log 3 := by + have h1 := exp_one_lt_d9 + have h0 := exp_pos 1 + have h3 := one_lt_log_three + norm_num at h1 + nlinarith + +/-- `s e^{-s}` is decreasing for `s ≥ 1`. -/ +theorem mul_exp_neg_le_of_one_le {u v : ℝ} (hu : 1 ≤ u) (huv : u ≤ v) : + v * exp (-v) ≤ u * exp (-u) := by + have h1 : v ≤ u * exp (v - u) := by + have := add_one_le_exp (v - u) + nlinarith + have h2 : exp (-u) = exp (v - u) * exp (-v) := by rw [← exp_add]; ring_nf + rw [h2] + have := exp_pos (-v) + nlinarith + +/-! ### Lemma 3 -/ + +/-- Iwaniec's `ψ(s) = s⁻¹ e^{s-3} (1 + 3 log (3/(s-1)))` [I71, Lemma 3]. -/ +noncomputable def psi (s : ℝ) : ℝ := s⁻¹ * exp (s - 3) * (1 + 3 * log (3 / (s - 1))) + +theorem psi_two : psi 2 = (1 + 3 * log 3) / (2 * exp 1) := by + have : exp ((2 : ℝ) - 3) = (exp 1)⁻¹ := by rw [← exp_neg]; norm_num + rw [psi, this]; norm_num; field_simp + +/-- The key inequality behind Lemma 3: `(x-1)(1 + 3 log (3/(x-1))) ≤ 3x/(x-1)` on `(2, 4)`. -/ +theorem psi_deriv_aux {x : ℝ} (hx : 2 < x) : + (x - 1) * (1 + 3 * log (3 / (x - 1))) ≤ 3 * x / (x - 1) := by + set y := x - 1 with hy + have hy0 : 0 < y := by linarith + have hx' : x = y + 1 := by ring + rw [hx'] + have hlog : log (2 / y) ≤ 2 / y - 1 := log_le_sub_one_of_pos (by positivity) + rw [log_div (by norm_num) hy0.ne'] at hlog + have hL : 1 + 3 * log (3 / y) ≤ -3 / 4 + 6 / y := by + rw [log_div (by norm_num) hy0.ne'] + have : 6 / y = 3 * (2 / y) := by ring + linarith [log_three_sub_log_two_lt] + have h6 : y * (6 / y) = 6 := by field_simp + have : y * (1 + 3 * log (3 / y)) ≤ -3 / 4 * y + 6 := by + have := mul_le_mul_of_nonneg_left hL hy0.le + rw [mul_add y (-3 / 4), h6] at this; linarith + rw [le_div_iff₀ hy0] + nlinarith [sq_nonneg (y - 2)] + +theorem hasDerivAt_psi {x : ℝ} (hx : 1 < x) : + HasDerivAt psi + (exp (x - 3) * ((x - 1) * (1 + 3 * log (3 / (x - 1))) - 3 * x / (x - 1)) / + x ^ 2) x := by + have hx0 : x ≠ 0 := by positivity + have hx1 : x - 1 ≠ 0 := by linarith + have h3 : (3 : ℝ) / (x - 1) ≠ 0 := div_ne_zero (by norm_num) hx1 + have h := (((hasDerivAt_id' x).inv hx0).mul ((hasDerivAt_id' x).sub_const 3).exp).mul + ((((hasDerivAt_const x (3 : ℝ)).div ((hasDerivAt_id' x).sub_const 1) hx1).log h3).const_mul + 3 |>.const_add 1) + convert h using 1 + · funext s; simp [psi] + · simp only [Pi.div_apply, Pi.inv_apply, Pi.mul_apply] + field_simp + ring + +/-- [I71, Lemma 3]: `ψ(s) ≤ ψ(2)` for `2 ≤ s ≤ 4`. -/ +theorem psi_le_psi_two {s : ℝ} (hs : s ∈ Icc (2 : ℝ) 4) : psi s ≤ psi 2 := by + have hanti : AntitoneOn psi (Icc 2 4) := by + refine antitoneOn_of_hasDerivWithinAt_nonpos (convex_Icc 2 4) + (f' := fun x => exp (x - 3) * ((x - 1) * (1 + 3 * log (3 / (x - 1))) - 3 * x / (x - 1)) / + x ^ 2) ?_ ?_ ?_ + · intro x hx + exact (hasDerivAt_psi (by linarith [hx.1])).continuousAt.continuousWithinAt + · intro x hx + rw [interior_Icc] at hx + exact (hasDerivAt_psi (by linarith [hx.1])).hasDerivWithinAt + · intro x hx + rw [interior_Icc] at hx + have hx1 : 0 < x - 1 := by linarith [hx.1] + refine div_nonpos_of_nonpos_of_nonneg + (mul_nonpos_of_nonneg_of_nonpos (exp_pos _).le (sub_nonpos.2 (psi_deriv_aux hx.1))) + (by positivity) + exact hanti ⟨le_rfl, by norm_num⟩ hs hs.1 + +/-! ### Lemma 4 -/ + +/-- Iwaniec's constant `a = sup_{2 ≤ s ≤ 4} g₂(s) s⁻¹ eˢ` [I71, Lemma 4]. -/ +noncomputable def gLead : ℝ := sSup ((fun s => g 2 s * s⁻¹ * exp s) '' Icc 2 4) + +/-- Iwaniec's constant `A = (e/3) ψ(2) = (1 + 3 log 3)/6` [I71, Lemma 4]. -/ +noncomputable def gRatio : ℝ := (1 + 3 * log 3) / 6 + +theorem gRatio_eq : gRatio = exp 1 / 3 * psi 2 := by + rw [psi_two, gRatio]; field_simp; ring + +theorem gRatio_lt : gRatio < 0.72 := by + have := log_three_lt_d9 + rw [gRatio]; norm_num at this ⊢; linarith + +theorem gRatio_pos : 0 < gRatio := by + rw [gRatio]; have := one_lt_log_three; positivity + +theorem gRatio_lt_one : gRatio < 1 := gRatio_lt.trans (by norm_num) + +theorem bddAbove_gLead : BddAbove ((fun s => g 2 s * s⁻¹ * exp s) '' Icc 2 4) := + isCompact_Icc.bddAbove_image <| + (((continuous_g 2).continuousOn.mul (continuousOn_inv₀.mono fun x hx => by + simp only [mem_compl_iff, mem_singleton_iff]; linarith [hx.1])).mul + continuous_exp.continuousOn) + +theorem le_gLead {s : ℝ} (hs : s ∈ Icc (2 : ℝ) 4) : g 2 s * s⁻¹ * exp s ≤ gLead := + le_csSup bddAbove_gLead (mem_image_of_mem _ hs) + +theorem gLead_nonneg : 0 ≤ gLead := by + refine le_trans ?_ (le_gLead (s := 2) ⟨le_rfl, by norm_num⟩) + have := g_nonneg 2 2 + positivity + +/-- If `h(u) ≤ C u e^{-u}` for `u ≥ s - 1`, then `∫_s^b h(t-1)/(t-1) dt ≤ C e^{1-s}`. -/ +theorem integral_shift_le {h : ℝ → ℝ} (hh : Continuous h) {C s b : ℝ} (hC : 0 ≤ C) + (hs : 2 ≤ s) (hsb : s ≤ b) (hb : ∀ u, s - 1 ≤ u → h u ≤ C * u * exp (-u)) : + ∫ t in s..b, h (t - 1) / (t - 1) ≤ C * exp (1 - s) := by + have hint1 : IntervalIntegrable (fun t => h (t - 1) / (t - 1)) volume s b := by + refine ContinuousOn.intervalIntegrable ?_ + rw [uIcc_of_le hsb] + exact (hh.comp (continuous_sub_right 1)).continuousOn.div + (continuous_sub_right 1).continuousOn fun t ht => by linarith [ht.1] + have hcont : Continuous fun t : ℝ => C * exp (1 - t) := + continuous_const.mul (continuous_exp.comp (continuous_const.sub continuous_id)) + calc ∫ t in s..b, h (t - 1) / (t - 1) ≤ ∫ t in s..b, C * exp (1 - t) := by + refine integral_mono_on hsb hint1 (hcont.intervalIntegrable _ _) fun t ht => ?_ + have ht1 : 0 < t - 1 := by linarith [ht.1] + rw [div_le_iff₀ ht1] + have := hb (t - 1) (by linarith [ht.1]) + have e : exp (-(t - 1)) = exp (1 - t) := by ring_nf + rw [e] at this; linarith + _ = C * exp (1 - s) - C * exp (1 - b) := by + rw [integral_eq_sub_of_hasDerivAt (f := fun t => -(C * exp (1 - t))) (fun t _ => ?_) + (hcont.intervalIntegrable _ _)] + · ring + · have := (((hasDerivAt_id' t).const_sub 1).exp.const_mul C).neg + convert this using 1; ring + _ ≤ C * exp (1 - s) := by + have := mul_nonneg hC (exp_pos (1 - b)).le + linarith + +/-- The inductive step of [I71, Lemma 4] in uniform form. -/ +theorem g_add_three_le {n : ℕ} {C s : ℝ} (hC : 0 ≤ C) (hs : gLower (n + 3) ≤ s) + (hb : ∀ u, s - 1 ≤ u → g (n + 2) u ≤ C * u * exp (-u)) : g (n + 3) s ≤ C * exp (1 - s) := by + rcases le_or_gt s ((n : ℝ) + 5) with hsb | hsb + · rw [g_add_three_eq n hs] + exact integral_shift_le (continuous_g _) hC ((two_le_gLower _).trans hs) hsb hb + · rw [g_eq_zero_of_le (n + 3) (by push_cast; linarith)] + positivity + +theorem gLower_two_mul_add_three (n : ℕ) : gLower (2 * n + 3) = 3 := + gLower_odd (not_even_two_mul_add_three n) + +theorem gLower_two_mul_add_four (n : ℕ) : gLower (2 * n + 1 + 3) = 2 := + gLower_even (by rw [show 2 * n + 1 + 3 = 2 * n + 4 by ring]; exact even_two_mul_add_four n) + +/-- For `2 ≤ s ≤ 4`: `g_{2n+4}(s) = g_{2n+4}(4) + g_{2n+3}(3) log (3/(s-1))` +(proof of [I71, Lemma 4]). -/ +theorem g_even_eq_on_Icc (n : ℕ) {s : ℝ} (hs : s ∈ Icc (2 : ℝ) 4) : + g (2 * n + 4) s = g (2 * n + 4) 4 + g (2 * n + 3) 3 * log (3 / (s - 1)) := by + rw [show 2 * n + 4 = 2 * n + 1 + 3 by ring] + have h := g_add_three_sub (2 * n + 1) (u := s) (v := 4) + (by rw [gLower_two_mul_add_four]; exact hs.1) (by rw [gLower_two_mul_add_four]; norm_num) + have hc : ∫ t in s..4, shiftKernel (g (2 * n + 1 + 2)) t = + ∫ t in s..4, g (2 * n + 3) 3 * (1 / (t - 1)) := by + refine integral_congr fun t ht => ?_ + rw [uIcc_of_le hs.2] at ht + rw [shiftKernel_of_two_le _ (by linarith [ht.1, hs.1]), show 2 * n + 1 + 2 = 2 * n + 3 by ring, + g_eq_of_le_gLower _ (s := t - 1) (by rw [gLower_two_mul_add_three]; linarith [ht.2]), + gLower_two_mul_add_three, mul_one_div] + have hs1 : 0 < s - 1 := by linarith [hs.1] + rw [hc, intervalIntegral.integral_const_mul, + integral_comp_sub_right (fun x => 1 / x), integral_one_div_of_pos hs1 (by norm_num)] at h + norm_num at h + linarith + +private theorem g_odd_le_of_even (n : ℕ) + (H : ∀ s, 2 ≤ s → g (2 * n + 2) s ≤ gLead * gRatio ^ n * s * exp (-s)) {s : ℝ} (hs : 1 ≤ s) : + g (2 * n + 3) s ≤ gLead * (exp 1 / 3) * gRatio ^ n * s * exp (-s) := by + have hC : 0 ≤ gLead * gRatio ^ n := mul_nonneg gLead_nonneg (pow_nonneg gRatio_pos.le _) + have h3 : ∀ s, 3 ≤ s → g (2 * n + 3) s ≤ gLead * gRatio ^ n * exp (1 - s) := fun s hs => + g_add_three_le hC (by rw [gLower_two_mul_add_three]; exact hs) + fun u hu => H u (by linarith) + have key : ∀ s, 3 ≤ s → gLead * gRatio ^ n * exp (1 - s) ≤ + gLead * (exp 1 / 3) * gRatio ^ n * s * exp (-s) := fun s hs => by + have e : exp (1 - s) = exp 1 * exp (-s) := by rw [← exp_add]; ring_nf + rw [e] + have := mul_nonneg (mul_nonneg (mul_nonneg hC (exp_pos (-s)).le) (exp_pos 1).le) + (sub_nonneg.2 hs) + nlinarith + rcases le_total 3 s with hs3 | hs3 + · exact (h3 s hs3).trans (key s hs3) + · have e : g (2 * n + 3) s = g (2 * n + 3) 3 := by + have := g_eq_of_le_gLower (2 * n + 3) (s := s) (by rw [gLower_two_mul_add_three]; exact hs3) + rwa [gLower_two_mul_add_three] at this + rw [e] + refine (h3 3 le_rfl).trans ((key 3 le_rfl).trans ?_) + have := mul_exp_neg_le_of_one_le hs hs3 + have h0 : 0 ≤ gLead * (exp 1 / 3) * gRatio ^ n := by + have := exp_pos 1; have := gLead_nonneg; have := gRatio_pos; positivity + have := mul_le_mul_of_nonneg_left this h0 + linarith + +private theorem g_even_le_of_odd (n : ℕ) + (H : ∀ s, 1 ≤ s → g (2 * n + 3) s ≤ gLead * (exp 1 / 3) * gRatio ^ n * s * exp (-s)) + {s : ℝ} (hs : 2 ≤ s) : g (2 * n + 4) s ≤ gLead * gRatio ^ (n + 1) * s * exp (-s) := by + have hC : 0 ≤ gLead * (exp 1 / 3) * gRatio ^ n := by + have := exp_pos 1; have := gLead_nonneg; have := gRatio_pos; positivity + have h4 : ∀ s, 2 ≤ s → g (2 * n + 4) s ≤ gLead * (exp 1 / 3) * gRatio ^ n * exp (1 - s) := + fun s hs => by + rw [show 2 * n + 4 = 2 * n + 1 + 3 by ring] + exact g_add_three_le hC (by rw [gLower_two_mul_add_four]; exact hs) + fun u hu => by rw [show 2 * n + 1 + 2 = 2 * n + 3 by ring]; exact H u (by linarith) + have hA := gRatio_pos + have he := exp_one_sq_lt + rcases le_total 4 s with hs4 | hs4 + · refine (h4 s hs).trans ?_ + have e : exp (1 - s) = exp 1 * exp (-s) := by rw [← exp_add]; ring_nf + rw [e, pow_succ] + have h1 : exp 1 ^ 2 / 3 ≤ gRatio * s := by + rw [gRatio]; nlinarith + have h0 : 0 ≤ gLead * gRatio ^ n * exp (-s) := + mul_nonneg (mul_nonneg gLead_nonneg (pow_nonneg hA.le _)) (exp_pos _).le + have := mul_le_mul_of_nonneg_left h1 h0 + nlinarith + · rw [g_even_eq_on_Icc n ⟨hs, hs4⟩] + have hg4 := h4 4 (by norm_num) + have hg3 := H 3 (by norm_num) + have hlog : 0 ≤ log (3 / (s - 1)) := + log_nonneg (by rw [le_div_iff₀ (by linarith)]; linarith) + have hpsi := psi_le_psi_two ⟨hs, hs4⟩ + have hpsi' : psi s * s * exp (-s) = exp (-3) * (1 + 3 * log (3 / (s - 1))) := by + rw [psi] + have : exp (s - 3) * exp (-s) = exp (-3) := by rw [← exp_add]; ring_nf + rw [← this] + field_simp + have e4 : exp (1 - 4) = exp (-3) := by ring_nf + have hsum : g (2 * n + 4) 4 + g (2 * n + 3) 3 * log (3 / (s - 1)) ≤ + gLead * (exp 1 / 3) * gRatio ^ n * (psi s * s * exp (-s)) := by + rw [hpsi'] + rw [e4] at hg4 + have := mul_le_mul_of_nonneg_right hg3 hlog + nlinarith + have hs0 : 0 ≤ s * exp (-s) := by positivity + have := mul_le_mul_of_nonneg_left (mul_le_mul_of_nonneg_right hpsi hs0) hC + calc _ ≤ gLead * (exp 1 / 3) * gRatio ^ n * (psi 2 * (s * exp (-s))) := by + refine hsum.trans (le_of_eq_of_le ?_ this); ring + _ = gLead * gRatio ^ (n + 1) * s * exp (-s) := by rw [pow_succ, gRatio_eq]; ring + +/-- (3.5) of [I71, Lemma 4]: `g_{2n+2}(s) ≤ a Aⁿ s e^{-s}` for `s ≥ 2`, `n ≥ 0`. -/ +theorem g_even_le (n : ℕ) {s : ℝ} (hs : 2 ≤ s) : + g (2 * n + 2) s ≤ gLead * gRatio ^ n * s * exp (-s) := by + induction n generalizing s with + | zero => + simp only [mul_zero, zero_add, pow_zero, mul_one] + rcases le_total s 4 with hs4 | hs4 + · have := le_gLead ⟨hs, hs4⟩ + have hs0 : 0 < s := by linarith + have e : g 2 s = g 2 s * s⁻¹ * exp s * (s * exp (-s)) := by + rw [exp_neg]; field_simp + rw [e] + exact (mul_le_mul_of_nonneg_right this (by positivity : (0 : ℝ) ≤ s * exp (-s))).trans_eq + (by ring) + · rw [g_two_of_four_le hs4] + have := gLead_nonneg + have : 0 ≤ s := by linarith + positivity + | succ n ih => + rw [show 2 * (n + 1) + 2 = 2 * n + 4 by ring] + exact g_even_le_of_odd n (fun s hs => g_odd_le_of_even n (fun s hs => ih hs) hs) hs + +/-- (3.4) of [I71, Lemma 4] (with `n` shifted by one): +`g_{2n+3}(s) ≤ a (e/3) Aⁿ s e^{-s}` for `s ≥ 1`. -/ +theorem g_odd_le (n : ℕ) {s : ℝ} (hs : 1 ≤ s) : + g (2 * n + 3) s ≤ gLead * (exp 1 / 3) * gRatio ^ n * s * exp (-s) := + g_odd_le_of_even n (fun _ hs => g_even_le n hs) hs + +/-- (3.4) of [I71, Lemma 4]: `g_{2n+1}(s) ≤ a (e/3) A^{n-1} s e^{-s}` for `s ≥ 1`, `n ≥ 1`. -/ +theorem g_odd_le' {n : ℕ} (hn : 1 ≤ n) {s : ℝ} (hs : 1 ≤ s) : + g (2 * n + 1) s ≤ gLead * (exp 1 / 3) * gRatio ^ (n - 1) * s * exp (-s) := by + obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := ⟨n - 1, by omega⟩ + rw [show 2 * (m + 1) + 1 = 2 * m + 3 by ring, Nat.add_sub_cancel] + exact g_odd_le m hs + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/SieveFunctions/Defs.lean b/LeanPool/IwaniecLinearSieve/SieveFunctions/Defs.lean new file mode 100644 index 000000000..333ab76d4 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveFunctions/Defs.lean @@ -0,0 +1,319 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Definitions +import Mathlib.Algebra.Order.Star.Real +import Mathlib.NumberTheory.Chebyshev + +/-! +# The functions `g_n` of [I71, §3] + +Iwaniec's functions `g_n` (`n ≥ 2`) of [I71, (3.1)–(3.3)], defined on all of `ℝ` in +`IwaniecLinearSieve.Definitions`, are: + +* `g 2 s = 3 log (3 / (s - 1)) + s - 4` for `2 ≤ s ≤ 4` and `g 2 s = 0` for `s ≥ 4`; +* `g (2n+1) s = ∫_s^∞ g (2n) (t-1) / (t-1) dt` for `s ≥ 3` and `g (2n+1) s = g (2n+1) 3` for + `s ≤ 3`; +* `g (2n+2) s = ∫_s^∞ g (2n+1) (t-1) / (t-1) dt` for `s ≥ 2`. + +Outside the domains of [I71] the argument is clamped (`g 2` and the even functions are constant +on `s ≤ 2`, the odd functions on `s ≤ 3`), and `g 0 = g 1 = 0`. With these conventions every +`g i` is continuous, nonnegative and antitone on all of `ℝ`, and `g i s = 0` for `s ≥ i + 2`. +-/ + +@[expose] public section + +open Real Set MeasureTheory intervalIntegral + +namespace IwaniecLinearSieve + +theorem g_zero (s : ℝ) : g 0 s = 0 := rfl + +theorem g_one (s : ℝ) : g 1 s = 0 := rfl + +theorem g_two_def (s : ℝ) : g 2 s = gTwoFormula (max 2 (min s 4)) := rfl + +theorem g_add_three (n : ℕ) (s : ℝ) : + g (n + 3) s = ∫ t in max s (gLower (n + 3))..((n : ℝ) + 5), shiftKernel (g (n + 2)) t := rfl + +theorem gLower_le_three (i : ℕ) : gLower i ≤ 3 := by + unfold gLower; split_ifs <;> norm_num + +theorem two_le_gLower (i : ℕ) : 2 ≤ gLower i := by + unfold gLower; split_ifs <;> norm_num + +theorem gLower_even {i : ℕ} (hi : Even i) : gLower i = 2 := by simp [gLower, hi] + +theorem gLower_odd {i : ℕ} (hi : ¬ Even i) : gLower i = 3 := by simp [gLower, hi] + +theorem shiftKernel_of_two_le (h : ℝ → ℝ) {t : ℝ} (ht : 2 ≤ t) : + shiftKernel h t = h (t - 1) / (t - 1) := by + rw [shiftKernel, max_eq_left (by linarith)] + +theorem continuous_shiftKernel {h : ℝ → ℝ} (hh : Continuous h) : Continuous (shiftKernel h) := + (hh.comp (continuous_sub_right 1)).div ((continuous_sub_right 1).max continuous_const) + fun _ => (lt_of_lt_of_le one_pos (le_max_right _ _)).ne' + +theorem shiftKernel_nonneg {h : ℝ → ℝ} (hh : ∀ s, 0 ≤ h s) (t : ℝ) : 0 ≤ shiftKernel h t := + div_nonneg (hh _) (le_trans zero_le_one (le_max_right _ _)) + +theorem continuous_integral_left {k : ℝ → ℝ} (hk : Continuous k) (b : ℝ) : + Continuous fun u => ∫ t in u..b, k t := by + have : (fun u => ∫ t in u..b, k t) = fun u => -∫ t in b..u, k t := by + funext u; exact integral_symm _ _ + rw [this] + exact (continuous_primitive (fun _ _ => hk.intervalIntegrable _ _) b).neg + +/-! ### `g₂` -/ +theorem gTwoFormula_four : gTwoFormula 4 = 0 := by norm_num [gTwoFormula] + +theorem gTwoFormula_continuousOn : ContinuousOn gTwoFormula (Icc 2 4) := by + unfold gTwoFormula + refine ContinuousOn.sub (ContinuousOn.add (continuousOn_const.mul ?_) continuousOn_id) + continuousOn_const + refine ContinuousOn.log (continuousOn_const.div (continuousOn_id.sub continuousOn_const) ?_) ?_ + · intro x hx; have := hx.1; linarith + · intro x hx; have := hx.1; exact div_ne_zero (by norm_num) (by linarith) + +/-- `gTwoFormula u - gTwoFormula v ≥ 0` for `2 ≤ u ≤ v ≤ 4`, with strictness when `u < v`. -/ +theorem gTwoFormula_sub_ge {u v : ℝ} (hu : 2 ≤ u) (huv : u ≤ v) (hv : v ≤ 4) : + (v - u) * (4 - v) / (v - 1) ≤ gTwoFormula u - gTwoFormula v ∧ + (u < v → 0 < gTwoFormula u - gTwoFormula v) := by + have hu1 : 0 < u - 1 := by linarith + have hv1 : 0 < v - 1 := by linarith + have hlog : gTwoFormula u - gTwoFormula v = 3 * (-log ((u - 1) / (v - 1))) - (v - u) := by + simp only [gTwoFormula] + rw [log_div (by norm_num) hu1.ne', log_div (by norm_num) hv1.ne', + log_div hu1.ne' hv1.ne'] + ring + have key : 1 - (u - 1) / (v - 1) ≤ -log ((u - 1) / (v - 1)) := by + linarith [log_le_sub_one_of_pos (div_pos hu1 hv1), log_inv ((u - 1) / (v - 1)), + show ((u - 1) / (v - 1))⁻¹ = (v - 1) / (u - 1) from inv_div _ _] + have h1 : 1 - (u - 1) / (v - 1) = (v - u) / (v - 1) := by field_simp; ring + refine ⟨?_, fun huv' => ?_⟩ + · rw [hlog] + have : (v - u) * (4 - v) / (v - 1) = 3 * ((v - u) / (v - 1)) - (v - u) := by + field_simp; ring + rw [this]; linarith + · rw [hlog] + have hne : (u - 1) / (v - 1) ≠ 1 := by + rw [Ne, div_eq_one_iff_eq hv1.ne']; linarith + have key' : 1 - (u - 1) / (v - 1) < -log ((u - 1) / (v - 1)) := by + have := log_lt_sub_one_of_pos (div_pos hu1 hv1) hne + linarith + have : (v - u) ≤ 3 * ((v - u) / (v - 1)) := by + rw [mul_div_assoc', le_div_iff₀ hv1]; nlinarith + linarith + +theorem gTwoFormula_nonneg {u : ℝ} (hu : 2 ≤ u) (hu4 : u ≤ 4) : 0 ≤ gTwoFormula u := by + have := (gTwoFormula_sub_ge hu hu4 le_rfl).1 + rw [gTwoFormula_four] at this + simpa using this + +theorem gTwoFormula_pos {u : ℝ} (hu : 2 ≤ u) (hu4 : u < 4) : 0 < gTwoFormula u := by + have := (gTwoFormula_sub_ge hu hu4.le le_rfl).2 hu4 + rwa [gTwoFormula_four, sub_zero] at this + +/-! ### Basic properties of `g` -/ + +/-- [I71, (3.1)] on `[2, 4]`. -/ +theorem g_two_eq {s : ℝ} (hs : s ∈ Icc (2 : ℝ) 4) : g 2 s = 3 * log (3 / (s - 1)) + s - 4 := by + rw [g_two_def, min_eq_left hs.2, max_eq_right hs.1]; rfl + +/-- [I71, (3.1)] for `s ≥ 4`. -/ +theorem g_two_of_four_le {s : ℝ} (hs : 4 ≤ s) : g 2 s = 0 := by + rw [g_two_def, min_eq_right hs, max_eq_right (by norm_num), gTwoFormula_four] + +theorem g_eq_of_le_gLower (i : ℕ) {s : ℝ} (hs : s ≤ gLower i) : g i s = g i (gLower i) := by + match i with + | 0 => rfl + | 1 => rfl + | 2 => + have h2 : gLower 2 = 2 := gLower_even even_two + rw [h2] at hs ⊢ + rw [g_two_def, g_two_def, min_eq_left (hs.trans (by norm_num)), max_eq_left hs] + norm_num + | n + 3 => rw [g_add_three, g_add_three, max_eq_right hs, max_self] + +theorem g_add_three_eq (n : ℕ) {s : ℝ} (hs : gLower (n + 3) ≤ s) : + g (n + 3) s = ∫ t in s..((n : ℝ) + 5), g (n + 2) (t - 1) / (t - 1) := by + rw [g_add_three, max_eq_left hs] + refine integral_congr fun t ht => shiftKernel_of_two_le _ ?_ + have := two_le_gLower (n + 3) + rcases le_total s ((n : ℝ) + 5) with h | h + · rw [uIcc_of_le h] at ht; linarith [ht.1] + · rw [uIcc_of_ge h] at ht; linarith [ht.1, n.cast_nonneg (α := ℝ)] + +theorem continuous_g : ∀ i, Continuous (g i) + | 0 => continuous_const + | 1 => continuous_const + | 2 => by + have : g 2 = gTwoFormula ∘ fun s => max 2 (min s 4) := rfl + rw [this] + exact gTwoFormula_continuousOn.comp_continuous + (continuous_const.max (continuous_id.min continuous_const)) + fun s => ⟨le_max_left _ _, max_le (by norm_num) (min_le_right _ _)⟩ + | n + 3 => by + have : g (n + 3) = (fun u => ∫ t in u..((n : ℝ) + 5), shiftKernel (g (n + 2)) t) ∘ + fun s => max s (gLower (n + 3)) := rfl + rw [this] + exact (continuous_integral_left (continuous_shiftKernel (continuous_g (n + 2))) _).comp + (continuous_id.max continuous_const) + +/-- `g i s = 0` for `s ≥ i + 2` ([I71], remark after (3.3)). -/ +theorem g_eq_zero_of_le : ∀ (i : ℕ) {s : ℝ}, (i : ℝ) + 2 ≤ s → g i s = 0 + | 0, _, _ => rfl + | 1, _, _ => rfl + | 2, _, hs => g_two_of_four_le (by norm_num at hs ⊢; linarith) + | n + 3, s, hs => by + push_cast at hs + have hc : gLower (n + 3) ≤ s := (gLower_le_three _).trans (by linarith [n.cast_nonneg (α := ℝ)]) + rw [g_add_three, max_eq_left hc, integral_congr (g := fun _ => (0 : ℝ)), + intervalIntegral.integral_zero] + intro t ht + rw [uIcc_of_ge (by linarith)] at ht + simp only [shiftKernel] + rw [g_eq_zero_of_le (n + 2) (by push_cast; linarith [ht.1]), zero_div] + +theorem g_nonneg : ∀ (i : ℕ) (s : ℝ), 0 ≤ g i s + | 0, _ => le_rfl + | 1, _ => le_rfl + | 2, _ => gTwoFormula_nonneg (le_max_left _ _) (max_le (by norm_num) (min_le_right _ _)) + | n + 3, s => by + rcases le_or_gt ((n : ℝ) + 5) s with hs | hs + · rw [g_eq_zero_of_le (n + 3) (by push_cast; linarith)] + · rw [g_add_three] + exact integral_nonneg + (max_le hs.le (by linarith [gLower_le_three (n + 3), n.cast_nonneg (α := ℝ)])) + fun t _ => shiftKernel_nonneg (g_nonneg (n + 2)) t + +/-- `g i s > 0` for `i ≥ 2` and `s < i + 2`. -/ +theorem g_pos : ∀ (i : ℕ), 2 ≤ i → ∀ {s : ℝ}, s < i + 2 → 0 < g i s + | 0, h, _, _ => by omega + | 1, h, _, _ => by omega + | 2, _, s, hs => by + norm_num at hs + exact gTwoFormula_pos (le_max_left _ _) (max_lt (by norm_num) ((min_le_left _ _).trans_lt hs)) + | n + 3, _, s, hs => by + push_cast at hs + rw [g_add_three] + have hc := gLower_le_three (n + 3) + have hn := n.cast_nonneg (α := ℝ) + refine intervalIntegral_pos_of_pos_on + ((continuous_shiftKernel (continuous_g _)).intervalIntegrable _ _) (fun t ht => ?_) + (max_lt (by linarith) (by linarith)) + have ht1 : max s (gLower (n + 3)) < t := ht.1 + have ht2 : t < (n : ℝ) + 5 := ht.2 + have h3 : 2 ≤ t := by linarith [le_max_right s (gLower (n + 3)), two_le_gLower (n + 3)] + rw [shiftKernel_of_two_le _ h3] + exact div_pos (g_pos (n + 2) (by omega) (by push_cast; linarith)) (by linarith) + +theorem g_antitone : ∀ i, Antitone (g i) + | 0 => antitone_const + | 1 => antitone_const + | 2 => fun u v huv => by + rw [g_two_def, g_two_def] + have h := (gTwoFormula_sub_ge (le_max_left 2 (min u 4)) + (max_le_max le_rfl (min_le_min huv le_rfl)) (max_le (by norm_num) (min_le_right v 4))).1 + have h1 : 0 ≤ max 2 (min v 4) - max 2 (min u 4) := + sub_nonneg.2 (max_le_max le_rfl (min_le_min huv le_rfl)) + have h2 : 0 ≤ 4 - max 2 (min v 4) := sub_nonneg.2 (max_le (by norm_num) (min_le_right v 4)) + have h3 : 0 ≤ max 2 (min v 4) - 1 := by linarith [le_max_left 2 (min v 4)] + linarith [div_nonneg (mul_nonneg h1 h2) h3] + | n + 3 => fun u v huv => by + rw [g_add_three, g_add_three] + have hk := continuous_shiftKernel (continuous_g (n + 2)) + rw [← integral_add_adjacent_intervals (hk.intervalIntegrable (max u (gLower (n + 3))) + (max v (gLower (n + 3)))) (hk.intervalIntegrable _ _)] + have : 0 ≤ ∫ t in max u (gLower (n + 3))..max v (gLower (n + 3)), shiftKernel (g (n + 2)) t := + integral_nonneg (max_le_max huv le_rfl) fun t _ => shiftKernel_nonneg (g_nonneg (n + 2)) t + linarith + +/-- Differences of `g (n + 3)` are integrals of the kernel. -/ +theorem g_add_three_sub (n : ℕ) {u v : ℝ} (hu : gLower (n + 3) ≤ u) (hv : gLower (n + 3) ≤ v) : + g (n + 3) u - g (n + 3) v = ∫ t in u..v, shiftKernel (g (n + 2)) t := by + have hk := continuous_shiftKernel (continuous_g (n + 2)) + rw [g_add_three, g_add_three, max_eq_left hu, max_eq_left hv, + ← integral_add_adjacent_intervals (hk.intervalIntegrable u v) (hk.intervalIntegrable v _)] + ring + +/-! ### Improper integrals -/ + +/-- If `h` is integrable on `(s, b]` and vanishes on `[b, ∞)`, then it is integrable on `(s, ∞)` +and its integral there is `∫_s^b h`. -/ +theorem integral_Ioi_eq_of_eq_zero {h : ℝ → ℝ} {s b : ℝ} (hsb : s ≤ b) + (hint : IntegrableOn h (Ioc s b)) (hz : ∀ t, b ≤ t → h t = 0) : + IntegrableOn h (Ioi s) ∧ ∫ t in Ioi s, h t = ∫ t in s..b, h t := by + have hI : IntegrableOn h (Ioi b) := + integrableOn_zero.congr_fun (fun t ht => (hz t (le_of_lt ht)).symm) measurableSet_Ioi + have hI' : IntegrableOn h (Ioi s) := by + rw [← Ioc_union_Ioi_eq_Ioi hsb]; exact hint.union hI + refine ⟨hI', ?_⟩ + have := integral_Ioi_sub_Ioi hI' hsb + rwa [setIntegral_eq_zero_of_forall_eq_zero (t := Ioi b) (fun t ht => hz t (le_of_lt ht)), + sub_zero] at this + +theorem g_add_three_eq_Ioi (n : ℕ) {s : ℝ} (hs : gLower (n + 3) ≤ s) : + IntegrableOn (fun t => g (n + 2) (t - 1) / (t - 1)) (Ioi s) ∧ + g (n + 3) s = ∫ t in Ioi s, g (n + 2) (t - 1) / (t - 1) := by + have h2 := two_le_gLower (n + 3) + have hz : ∀ t, (n : ℝ) + 5 ≤ t → g (n + 2) (t - 1) / (t - 1) = 0 := fun t ht => by + rw [g_eq_zero_of_le (n + 2) (by push_cast; linarith), zero_div] + rcases le_or_gt s ((n : ℝ) + 5) with hsb | hsb + · have hcont : ContinuousOn (fun t => g (n + 2) (t - 1) / (t - 1)) (Icc s ((n : ℝ) + 5)) := + (continuous_shiftKernel (continuous_g (n + 2))).continuousOn.congr + fun t ht => (shiftKernel_of_two_le _ (by linarith [ht.1])).symm + obtain ⟨hI, hEq⟩ := integral_Ioi_eq_of_eq_zero hsb + ((hcont.integrableOn_Icc).mono_set Ioc_subset_Icc_self) hz + exact ⟨hI, by rw [hEq, g_add_three_eq n hs]⟩ + · obtain ⟨hI, hEq⟩ := integral_Ioi_eq_of_eq_zero le_rfl (by simp) fun t ht => hz t (by linarith) + refine ⟨hI, ?_⟩ + rw [hEq, integral_same, g_eq_zero_of_le (n + 3) (by push_cast; linarith)] + +/-! ### The identities (3.2), (3.3) in the form of [I71] -/ +theorem not_even_two_mul_add_three (m : ℕ) : ¬ Even (2 * m + 3) := by + rw [Nat.not_even_iff_odd]; exact ⟨m + 1, by ring⟩ + +theorem even_two_mul_add_four (m : ℕ) : Even (2 * m + 4) := ⟨m + 2, by ring⟩ + +/-- [I71, (3.2)], first line: `g_{2n+1}(s) = ∫_s^∞ g_{2n}(t-1)/(t-1) dt` for `s ≥ 3`. -/ +theorem g_odd_eq_integral {n : ℕ} (hn : 1 ≤ n) {s : ℝ} (hs : 3 ≤ s) : + IntegrableOn (fun t => g (2 * n) (t - 1) / (t - 1)) (Ioi s) ∧ + g (2 * n + 1) s = ∫ t in Ioi s, g (2 * n) (t - 1) / (t - 1) := by + obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := ⟨n - 1, by omega⟩ + have e1 : 2 * (m + 1) + 1 = 2 * m + 3 := by ring + have e2 : 2 * (m + 1) = 2 * m + 2 := by ring + rw [e1, e2] + exact g_add_three_eq_Ioi (2 * m) (by rw [gLower_odd (not_even_two_mul_add_three m)]; exact hs) + +/-- [I71, (3.2)], second line: `g_{2n+1}(s) = g_{2n+1}(3)` for `s ≤ 3`. -/ +theorem g_odd_of_le_three (n : ℕ) {s : ℝ} (hs : s ≤ 3) : g (2 * n + 1) s = g (2 * n + 1) 3 := by + rcases n with _ | m + · rfl + · have e1 : 2 * (m + 1) + 1 = 2 * m + 3 := by ring + rw [e1] + have h := gLower_odd (not_even_two_mul_add_three m) + rw [g_eq_of_le_gLower _ (h ▸ hs), h] + +/-- [I71, (3.3)]: `g_{2n+2}(s) = ∫_s^∞ g_{2n+1}(t-1)/(t-1) dt` for `s ≥ 2`. -/ +theorem g_even_eq_integral {n : ℕ} (hn : 1 ≤ n) {s : ℝ} (hs : 2 ≤ s) : + IntegrableOn (fun t => g (2 * n + 1) (t - 1) / (t - 1)) (Ioi s) ∧ + g (2 * n + 2) s = ∫ t in Ioi s, g (2 * n + 1) (t - 1) / (t - 1) := by + obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := ⟨n - 1, by omega⟩ + have e1 : 2 * (m + 1) + 2 = (2 * m + 1) + 3 := by ring + have e2 : 2 * (m + 1) + 1 = (2 * m + 1) + 2 := by ring + rw [e1, e2] + refine g_add_three_eq_Ioi (2 * m + 1) ?_ + rw [show 2 * m + 1 + 3 = 2 * m + 4 by ring, gLower_even (even_two_mul_add_four m)]; exact hs + +/-- Even `g` are constant on `s ≤ 2`. -/ +theorem g_even_of_le_two (n : ℕ) {s : ℝ} (hs : s ≤ 2) : g (2 * n + 2) s = g (2 * n + 2) 2 := by + have h : gLower (2 * n + 2) = 2 := gLower_even ⟨n + 1, by ring⟩ + rw [g_eq_of_le_gLower _ (h ▸ hs), h] + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/SieveFunctions/LemmaFive.lean b/LeanPool/IwaniecLinearSieve/SieveFunctions/LemmaFive.lean new file mode 100644 index 000000000..fb9b93926 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveFunctions/LemmaFive.lean @@ -0,0 +1,328 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.SieveFunctions.Series +import LeanPool.IwaniecLinearSieve.SieveFunctions.Defs +import Mathlib.Algebra.Order.Star.Real +import Mathlib.NumberTheory.Chebyshev +import Mathlib.Tactic.Polynomial.Basic + +/-! +# `f(2) = 2` ([I71, Lemma 5], the part we need) + +We prove (3.9), `f(s) = f(4) + (F(3) + 3) log (3/(s-1)) + s - 4` on `[2, 4]`, and `f(2) = 2`, +following Iwaniec: `M = f + F` satisfies `M'(s) = -M(s-1)/(s-1)` for `s > 3` once it is extended +to `[2, 3]` by `M(s) = 3 + F(3) - s + f(s)` (`MSieve`). Then +`Q(s) = (s-1) M(s) - ∫_{s-1}^s M` has derivative `0` on `(3, 4) ∪ (4, ∞)`, so it is constant on +`[3, ∞)`, and it tends to `0` because `M(s) = O(s e^{-s})`. Evaluating `Q(3) = 0` gives +`f(4) + (F(3) + 3) log 3 = 4`, i.e. `f(s) = s - (F(3) + 3) log (s - 1)` on `[2, 4]`. + +The value `F(3) = 2e^γ - 3` is not needed; only `F(3) ≥ 0` is used for the final inequality +`1 - f(s)/s ≥ 3 log (s - 1) / s` on `[2, 4]`. The rest of Lemma 5 (`F(3) = 2e^γ - 3` via Buchstab's +function) is in `IwaniecLinearSieve.EulerGamma.LemmaFive`. +-/ + +@[expose] public section + +open Real Set MeasureTheory intervalIntegral Filter Topology + +namespace IwaniecLinearSieve + +/-! ### (3.9) -/ + +/-- [I71, (3.9)]: `f(s) = f(4) + (F(3) + 3) log (3/(s-1)) + s - 4` for `2 ≤ s ≤ 4`. -/ +theorem fSieve_eq_on_Icc' {s : ℝ} (hs : s ∈ Icc (2 : ℝ) 4) : + fSieve s = fSieve 4 + (FSieve 3 + 3) * log (3 / (s - 1)) + s - 4 := by + have hs' := (summable_g_even s).tsum_eq_zero_add + have h4 := (summable_g_even 4).tsum_eq_zero_add + have e : ∀ n : ℕ, g (2 * (n + 1) + 2) s = + g (2 * (n + 1) + 2) 4 + g (2 * n + 3) 3 * log (3 / (s - 1)) := fun n => by + rw [show 2 * (n + 1) + 2 = 2 * n + 4 by ring]; exact g_even_eq_on_Icc n hs + have hsum4 : Summable fun n : ℕ => g (2 * (n + 1) + 2) 4 := + (summable_nat_add_iff (f := fun n : ℕ => g (2 * n + 2) 4) 1).mpr (summable_g_even 4) + rw [tsum_congr e, Summable.tsum_add hsum4 ((summable_g_odd 3).mul_right _), tsum_mul_right] + at hs' + rw [fSieve, fSieve, hs', h4, FSieve] + simp only [mul_zero, zero_add] + rw [g_two_eq hs, g_two_of_four_le le_rfl] + ring + +/-! ### Derivatives -/ + +/-- Derivative of `u ↦ ∫_u^∞ k`. -/ +theorem hasDerivAt_integral_Ioi {k : ℝ → ℝ} {a s : ℝ} (hint : IntegrableOn k (Ioi a)) + (hc : ContinuousOn k (Ioi a)) (has : a < s) : + HasDerivAt (fun u => ∫ t in Ioi u, k t) (-k s) s := by + have hd : HasDerivAt (fun u => (∫ t in Ioi a, k t) - ∫ t in a..u, k t) (-k s) s := by + refine (integral_hasDerivAt_right ?_ (hc.stronglyMeasurableAtFilter isOpen_Ioi s has) + (hc.continuousAt (Ioi_mem_nhds has))).const_sub _ + exact (intervalIntegrable_iff_integrableOn_Ioc_of_le has.le).2 + (hint.mono_set Ioc_subset_Ioi_self) + refine hd.congr_of_eventuallyEq ?_ + filter_upwards [Ioi_mem_nhds has] with u hu + have := integral_Ioi_sub_Ioi hint (le_of_lt hu) + linarith + +theorem continuousOn_shift {h : ℝ → ℝ} (hh : Continuous h) : + ContinuousOn (fun t => h (t - 1) / (t - 1)) (Ioi 1) := + (hh.comp (continuous_sub_right 1)).continuousOn.div (continuous_sub_right 1).continuousOn + fun t ht => by have : (1 : ℝ) < t := ht; linarith + +/-- `F'(s) = -f(s-1)/(s-1)` for `s > 3`. -/ +theorem hasDerivAt_FSieve {s : ℝ} (hs : 3 < s) : + HasDerivAt FSieve (-(fSieve (s - 1) / (s - 1))) s := by + have hd := hasDerivAt_integral_Ioi (integrableOn_fSieve_shift le_rfl) + ((continuousOn_shift continuous_fSieve).mono (Ioi_subset_Ioi (by norm_num))) hs + refine hd.congr_of_eventuallyEq ?_ + filter_upwards [Ioi_mem_nhds hs] with u hu + exact FSieve_eq_integral (le_of_lt hu) + +/-- `f'(s) = -F(s-1)/(s-1)` for `s > 4`. -/ +theorem hasDerivAt_fSieve_of_four_lt {s : ℝ} (hs : 4 < s) : + HasDerivAt fSieve (-(FSieve (s - 1) / (s - 1))) s := by + have hd := hasDerivAt_integral_Ioi (integrableOn_FSieve_shift le_rfl) + ((continuousOn_shift continuous_FSieve).mono (Ioi_subset_Ioi (by norm_num))) (by linarith) + refine hd.congr_of_eventuallyEq ?_ + filter_upwards [Ioi_mem_nhds hs] with u hu + have hu' : (4 : ℝ) < u := hu + rw [fSieve_eq_integral (by linarith), g_two_of_four_le hu'.le, add_zero] + +/-- `f'(s) = 1 - (F(3) + 3)/(s-1)` for `2 < s < 4`. -/ +theorem hasDerivAt_fSieve_of_lt_four {s : ℝ} (hs2 : 2 < s) (hs4 : s < 4) : + HasDerivAt fSieve (1 - (FSieve 3 + 3) / (s - 1)) s := by + have hne : s - 1 ≠ 0 := by linarith + have hd : HasDerivAt + (fun u => fSieve 4 + (FSieve 3 + 3) * (log 3 - log (u - 1)) + u - 4) + (1 - (FSieve 3 + 3) / (s - 1)) s := by + have := ((((((hasDerivAt_id' s).sub_const 1).log hne).const_sub (log 3)).const_mul + (FSieve 3 + 3)).const_add (fSieve 4)).add (hasDerivAt_id' s) |>.sub_const 4 + convert this using 1 + field_simp + ring + refine hd.congr_of_eventuallyEq ?_ + filter_upwards [Ioo_mem_nhds hs2 hs4] with u hu + rw [fSieve_eq_on_Icc' ⟨hu.1.le, hu.2.le⟩, log_div (by norm_num) (by linarith [hu.1])] + +/-! ### Iwaniec's `M` -/ + +/-- Iwaniec's `M(s)`: `f(s) + F(s)` for `s ≥ 3`, extended by `M(s) = 3 + F(3) - s + f(s)` for +`s ≤ 3` (which is `-s M'(s+1)` on `[2, 3]`). -/ +noncomputable def MSieve (s : ℝ) : ℝ := fSieve s + FSieve s + max (3 - s) 0 + +theorem MSieve_of_three_le {s : ℝ} (hs : 3 ≤ s) : MSieve s = fSieve s + FSieve s := by + rw [MSieve, max_eq_right (by linarith), add_zero] + +theorem MSieve_of_le_three {s : ℝ} (hs : s ≤ 3) : MSieve s = 3 + FSieve 3 - s + fSieve s := by + rw [MSieve, max_eq_left (by linarith), FSieve_of_le_three hs]; ring + +theorem continuous_MSieve : Continuous MSieve := + (continuous_fSieve.add continuous_FSieve).add ((continuous_const.sub continuous_id).max + continuous_const) + +theorem MSieve_nonneg (s : ℝ) : 0 ≤ MSieve s := by + have := fSieve_nonneg s; have := FSieve_nonneg s; have := le_max_right (3 - s) 0 + rw [MSieve]; linarith + +theorem MSieve_antitone : Antitone MSieve := fun u v h => by + have := fSieve_antitone h; have := FSieve_antitone h + have : max (3 - v) 0 ≤ max (3 - u) 0 := max_le_max (by linarith) le_rfl + rw [MSieve, MSieve]; linarith + +/-- `Σ_{k ≥ 2} g_k(s) = M(s)` for `s ≥ 3`. -/ +theorem hasSum_g_MSieve {s : ℝ} (hs : 3 ≤ s) : HasSum (fun k : ℕ => g (k + 2) s) (MSieve s) := by + rw [MSieve_of_three_le hs]; exact hasSum_g s + +/-- `f_r(s) < M(s)` (first step of [I71, Lemma 7]). -/ +theorem fr_lt_MSieve (r : ℕ) (s : ℝ) : fr r s < MSieve s := by + have hf := fSieve_pos s; have hF := FSieve_pos s; have := le_max_right (3 - s) 0 + unfold fr MSieve; split_ifs <;> linarith + +/-- `M(s) = O(s e^{-s})`: `M(s) ≤ C s e^{-s}` for `s ≥ 3`. -/ +theorem MSieve_le {s : ℝ} (hs : 3 ≤ s) : + MSieve s ≤ (gLead * (1 - gRatio)⁻¹ + gLead * (exp 1 / 3) * (1 - gRatio)⁻¹) * s * exp (-s) := by + rw [MSieve_of_three_le hs] + have := fSieve_le (by linarith : (2 : ℝ) ≤ s) + have := FSieve_le (by linarith : (1 : ℝ) ≤ s) + linarith + +/-- The derivative of `M` for `s > 3`, `s ≠ 4`: `(s - 1) M'(s) = -M(s - 1)`. -/ +theorem hasDerivAt_MSieve {s : ℝ} (hs3 : 3 < s) (hs4 : s ≠ 4) : + HasDerivAt MSieve (-(MSieve (s - 1) / (s - 1))) s := by + have hne : s - 1 ≠ 0 := by linarith + have hev : MSieve =ᶠ[𝓝 s] fun u => fSieve u + FSieve u := by + filter_upwards [Ioi_mem_nhds hs3] with u hu + exact MSieve_of_three_le (le_of_lt hu) + rcases lt_or_gt_of_ne hs4 with h4 | h4 + · have hd := (hasDerivAt_fSieve_of_lt_four (by linarith) h4).add (hasDerivAt_FSieve hs3) + refine (hd.congr_of_eventuallyEq hev).congr_deriv ?_ + rw [MSieve_of_le_three (by linarith)] + field_simp + ring + · have hd := (hasDerivAt_fSieve_of_four_lt h4).add (hasDerivAt_FSieve hs3) + refine (hd.congr_of_eventuallyEq hev).congr_deriv ?_ + rw [MSieve_of_three_le (by linarith)] + field_simp + ring + +/-! ### The conserved quantity -/ + +/-- `Q(s) = (s - 1) M(s) - ∫_{s-1}^s M`. -/ +noncomputable def lemma5Q (s : ℝ) : ℝ := (s - 1) * MSieve s - ∫ x in (s - 1)..s, MSieve x + +theorem lemma5Q_eq (s : ℝ) : lemma5Q s = + (s - 1) * MSieve s - ((∫ x in (0 : ℝ)..s, MSieve x) - ∫ x in (0 : ℝ)..(s - 1), MSieve x) := by + rw [lemma5Q, integral_interval_sub_left (continuous_MSieve.intervalIntegrable _ _) + (continuous_MSieve.intervalIntegrable _ _)] + +theorem continuous_lemma5Q : Continuous lemma5Q := by + have hP : Continuous fun u => ∫ x in (0 : ℝ)..u, MSieve x := + continuous_primitive (fun _ _ => continuous_MSieve.intervalIntegrable _ _) 0 + rw [funext lemma5Q_eq] + exact ((continuous_id.sub continuous_const).mul continuous_MSieve).sub + (hP.sub (hP.comp (continuous_id.sub continuous_const))) + +theorem hasDerivAt_lemma5Q {s : ℝ} (hs3 : 3 < s) (hs4 : s ≠ 4) : HasDerivAt lemma5Q 0 s := by + have hM := hasDerivAt_MSieve hs3 hs4 + have hP : ∀ u, HasDerivAt (fun u => ∫ x in (0 : ℝ)..u, MSieve x) (MSieve u) u := fun u => + (continuous_MSieve.integral_hasStrictDerivAt 0 u).hasDerivAt + have hP1 : HasDerivAt (fun u => ∫ x in (0 : ℝ)..(u - 1), MSieve x) (MSieve (s - 1)) s := + HasDerivAt.comp_sub_const s 1 (hP (s - 1)) + have hd := (((hasDerivAt_id' s).sub_const 1).mul hM).sub ((hP s).sub hP1) + rw [funext lemma5Q_eq] + refine hd.congr_deriv ?_ + have hne : s - 1 ≠ 0 := by linarith + field_simp + ring + +theorem lemma5Q_eq_of_deriv {a b : ℝ} (hab : a ≤ b) (hd : ∀ x ∈ Ioo a b, HasDerivAt lemma5Q 0 x) : + lemma5Q b = lemma5Q a := by + rcases eq_or_lt_of_le hab with h | h + · rw [h] + · obtain ⟨c, _, hc⟩ := exists_hasDerivAt_eq_slope lemma5Q (fun _ => (0 : ℝ)) h + continuous_lemma5Q.continuousOn hd + have hba : b - a ≠ 0 := by linarith + rw [eq_div_iff hba, zero_mul] at hc + linarith + +theorem lemma5Q_const {b : ℝ} (hb : 3 ≤ b) : lemma5Q b = lemma5Q 3 := by + rcases le_total b 4 with h4 | h4 + · exact lemma5Q_eq_of_deriv hb fun x hx => hasDerivAt_lemma5Q hx.1 (by linarith [hx.2]) + · rw [lemma5Q_eq_of_deriv h4 fun x hx => hasDerivAt_lemma5Q (by linarith [hx.1]) + (by linarith [hx.1]), + lemma5Q_eq_of_deriv (by norm_num) fun x hx => hasDerivAt_lemma5Q hx.1 (by linarith [hx.2])] + +theorem abs_lemma5Q_le {b : ℝ} (hb : 4 ≤ b) : + |lemma5Q b| ≤ ((gLead * (1 - gRatio)⁻¹ + gLead * (exp 1 / 3) * (1 - gRatio)⁻¹) * exp 1) * + (b ^ 2 * exp (-b)) := by + set C := gLead * (1 - gRatio)⁻¹ + gLead * (exp 1 / 3) * (1 - gRatio)⁻¹ + have hM1 : MSieve (b - 1) ≤ C * (b - 1) * exp (-(b - 1)) := MSieve_le (s := b - 1) (by linarith) + have hMb : MSieve b ≤ MSieve (b - 1) := MSieve_antitone (by linarith) + have hI0 : 0 ≤ ∫ x in (b - 1)..b, MSieve x := + integral_nonneg (by linarith) fun x _ => MSieve_nonneg x + have hI1 : ∫ x in (b - 1)..b, MSieve x ≤ MSieve (b - 1) := by + have := integral_mono_on (μ := volume) (by linarith : b - 1 ≤ b) + (continuous_MSieve.intervalIntegrable _ _) + (intervalIntegrable_const (c := MSieve (b - 1))) fun x hx => MSieve_antitone hx.1 + simpa using this + have hQ : |lemma5Q b| ≤ b * MSieve (b - 1) := by + rw [lemma5Q, abs_le] + have := MSieve_nonneg b + constructor <;> nlinarith + have he : exp (-(b - 1)) = exp 1 * exp (-b) := by rw [← exp_add]; ring_nf + rw [he] at hM1 + refine hQ.trans ?_ + have := mul_le_mul_of_nonneg_left hM1 (by linarith : (0 : ℝ) ≤ b) + have hb' : 0 ≤ C * exp 1 * exp (-b) * b := by + have : 0 ≤ C := by + have := gLead_nonneg; have := gRatio_lt_one; have := exp_pos 1 + have : 0 ≤ (1 - gRatio)⁻¹ := inv_nonneg.2 (by linarith) + positivity + have := exp_pos 1; have := exp_pos (-b); positivity + nlinarith + +theorem lemma5Q_three : lemma5Q 3 = 0 := by + set C := (gLead * (1 - gRatio)⁻¹ + gLead * (exp 1 / 3) * (1 - gRatio)⁻¹) * exp 1 + have hlim : Tendsto lemma5Q atTop (𝓝 0) := by + refine squeeze_zero_norm' ?_ (by + simpa using (tendsto_pow_mul_exp_neg_atTop_nhds_zero 2).const_mul C) + filter_upwards [eventually_ge_atTop 4] with b hb + rw [norm_eq_abs]; exact abs_lemma5Q_le hb + have hconst : Tendsto lemma5Q atTop (𝓝 (lemma5Q 3)) := by + refine tendsto_const_nhds.congr' ?_ + filter_upwards [eventually_ge_atTop 3] with b hb + exact (lemma5Q_const hb).symm + exact tendsto_nhds_unique hconst hlim + +/-! ### `f(2) = 2` -/ + +/-- `∫_2^3 M = F(3) - 1 + f(4) + (F(3) + 3)(2 log (3/2) - log 3 + 1)`. -/ +theorem integral_MSieve_two_three : + ∫ x in (2 : ℝ)..3, MSieve x = FSieve 3 - 1 + fSieve 4 + + (FSieve 3 + 3) * (2 * (log 3 - log 2) - log 3 + 1) := by + set K := FSieve 3 + 3 + set c := FSieve 3 - 1 + fSieve 4 + have hcongr : + ∫ x in (2 : ℝ)..3, MSieve x = ∫ x in (2 : ℝ)..3, (c + K * (log 3 - log (x - 1))) := by + refine integral_congr fun x hx => ?_ + rw [uIcc_of_le (by norm_num)] at hx + rw [MSieve_of_le_three hx.2, fSieve_eq_on_Icc' ⟨hx.1, by linarith [hx.2]⟩, + log_div (by norm_num) (by linarith [hx.1])] + ring + rw [hcongr, integral_eq_sub_of_hasDerivAt + (f := fun x => c * x + K * ((x - 1) * (log 3 - log (x - 1)) + x))] + · norm_num + ring + · intro x hx + rw [uIcc_of_le (by norm_num)] at hx + have hne : x - 1 ≠ 0 := by linarith [hx.1] + have := ((hasDerivAt_id' x).const_mul c).add + (((((hasDerivAt_id' x).sub_const 1).mul + ((((hasDerivAt_id' x).sub_const 1).log hne).const_sub (log 3))).add + (hasDerivAt_id' x)).const_mul K) + convert this using 1 + field_simp + ring + · refine ContinuousOn.intervalIntegrable ?_ + refine continuousOn_const.add (continuousOn_const.mul (continuousOn_const.sub ?_)) + refine ((continuous_sub_right 1).continuousOn).log fun x hx => ?_ + rw [uIcc_of_le (by norm_num)] at hx + linarith [hx.1] + +/-- The key identity `f(4) + (F(3) + 3) log 3 = 4`. -/ +theorem fSieve_four_add : fSieve 4 + (FSieve 3 + 3) * log 3 = 4 := by + have h := lemma5Q_three + rw [lemma5Q, show (3 : ℝ) - 1 = 2 by norm_num, integral_MSieve_two_three, + MSieve_of_three_le le_rfl, fSieve_eq_on_Icc' ⟨by norm_num, by norm_num⟩, + show (3 : ℝ) / (3 - 1) = 3 / 2 by norm_num, log_div (by norm_num) (by norm_num)] at h + linarith + +/-- [I71, Lemma 5] in the form we need: `f(s) = s - (F(3) + 3) log (s - 1)` for `2 ≤ s ≤ 4` +(Iwaniec: `F(3) + 3 = 2e^γ`). -/ +theorem fSieve_eq_on_Icc {s : ℝ} (hs : s ∈ Icc (2 : ℝ) 4) : + fSieve s = s - (FSieve 3 + 3) * log (s - 1) := by + rw [fSieve_eq_on_Icc' hs, log_div (by norm_num) (by linarith [hs.1])] + linarith [fSieve_four_add] + +/-- [I71, (3.10)]: `f(2) = 2`. -/ +theorem fSieve_two : fSieve 2 = 2 := by + rw [fSieve_eq_on_Icc ⟨le_rfl, by norm_num⟩]; norm_num + +/-- The consequence of Lemma 5 used for the sieve: `1 - f(s)/s ≥ 3 log (s - 1) / s` on `[2, 4]`. -/ +theorem le_one_sub_fSieve_div {s : ℝ} (hs : s ∈ Icc (2 : ℝ) 4) : + 3 * log (s - 1) / s ≤ 1 - fSieve s / s := by + have hs0 : 0 < s := by linarith [hs.1] + have hlog : 0 ≤ log (s - 1) := log_nonneg (by linarith [hs.1]) + have hF := FSieve_nonneg 3 + rw [fSieve_eq_on_Icc hs, div_le_iff₀ hs0, sub_mul, div_mul_cancel₀ _ hs0.ne'] + nlinarith + +/-- `le_one_sub_fSieve_div` in the form used by the linear-sieve modules. -/ +theorem one_sub_fSieve_div_ge : ∀ s ∈ Icc (2 : ℝ) 4, 1 - fSieve s / s ≥ 3 * Real.log (s - 1) / s := + fun _ hs => le_one_sub_fSieve_div hs + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/SieveFunctions/Series.lean b/LeanPool/IwaniecLinearSieve/SieveFunctions/Series.lean new file mode 100644 index 000000000..eace69efe --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveFunctions/Series.lean @@ -0,0 +1,249 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.SieveFunctions.Bounds +import LeanPool.IwaniecLinearSieve.SieveFunctions.Defs +import Mathlib.MeasureTheory.Integral.ExpDecay +import Mathlib.NumberTheory.Chebyshev +import Mathlib.Tactic.Polynomial.Basic + +/-! +# The functions `f` and `F` of [I71, §3] + +`f(s) = Σ_{i ≥ 1} g_{2i}(s)` (`fSieve`) and `F(s) = Σ_{i ≥ 1} g_{2i+1}(s)` (`FSieve`), defined in +`IwaniecLinearSieve.Definitions`. This module proves the +Corollary to Lemma 4 of [I71]: convergence (with geometric majorants), continuity, positivity, +`f, F = O(s e^{-s})`, and the integral equations (3.6), (3.7). + +Since the `g_i` are clamped (see `IwaniecLinearSieve.SieveFunctions.Defs`), the series converge +for all real `s`; `f` is constant on `s ≤ 2` and `F` on `s ≤ 3`. +-/ + +@[expose] public section + +open Real Set MeasureTheory intervalIntegral Filter Topology + +namespace IwaniecLinearSieve + +/-- `f_r = f` for even `r` and `F` for odd `r` ([I71], before Lemma 7). -/ +noncomputable def fr (r : ℕ) (s : ℝ) : ℝ := if Even r then fSieve s else FSieve s + +/-! ### Clamping and uniform bounds -/ +theorem g_odd_of_le_three' (n : ℕ) {s : ℝ} (hs : s ≤ 3) : g (2 * n + 3) s = g (2 * n + 3) 3 := by + have := g_eq_of_le_gLower (2 * n + 3) (s := s) (by rw [gLower_two_mul_add_three]; exact hs) + rwa [gLower_two_mul_add_three] at this + +theorem g_even_le_at_two (n : ℕ) (s : ℝ) : g (2 * n + 2) s ≤ g (2 * n + 2) 2 := by + rcases le_total 2 s with h | h + · exact g_antitone _ h + · rw [g_even_of_le_two n h] + +theorem g_odd_le_at_three (n : ℕ) (s : ℝ) : g (2 * n + 3) s ≤ g (2 * n + 3) 3 := by + rcases le_total 3 s with h | h + · exact g_antitone _ h + · rw [g_odd_of_le_three' n h] + +theorem g_even_le_uniform (n : ℕ) (s : ℝ) : + g (2 * n + 2) s ≤ gLead * 2 * exp (-2) * gRatio ^ n := + (g_even_le_at_two n s).trans ((g_even_le n le_rfl).trans_eq (by ring)) + +theorem g_odd_le_uniform (n : ℕ) (s : ℝ) : + g (2 * n + 3) s ≤ gLead * (exp 1 / 3) * 3 * exp (-3) * gRatio ^ n := + (g_odd_le_at_three n s).trans ((g_odd_le n (by norm_num)).trans_eq (by ring)) + +theorem summable_geom_gRatio (c : ℝ) : Summable fun n : ℕ => c * gRatio ^ n := + (summable_geometric_of_lt_one gRatio_pos.le gRatio_lt_one).mul_left c + +theorem summable_g_even (s : ℝ) : Summable fun n : ℕ => g (2 * n + 2) s := + Summable.of_nonneg_of_le (fun _ => g_nonneg _ _) (fun n => g_even_le_uniform n s) + (summable_geom_gRatio _) + +theorem summable_g_odd (s : ℝ) : Summable fun n : ℕ => g (2 * n + 3) s := + Summable.of_nonneg_of_le (fun _ => g_nonneg _ _) (fun n => g_odd_le_uniform n s) + (summable_geom_gRatio _) + +/-! ### Basic properties of `f` and `F` -/ +theorem continuous_fSieve : Continuous fSieve := + continuous_tsum (fun _ => continuous_g _) (summable_geom_gRatio _) fun n s => by + rw [norm_of_nonneg (g_nonneg _ _)]; exact g_even_le_uniform n s + +theorem continuous_FSieve : Continuous FSieve := + continuous_tsum (fun _ => continuous_g _) (summable_geom_gRatio _) fun n s => by + rw [norm_of_nonneg (g_nonneg _ _)]; exact g_odd_le_uniform n s + +theorem fSieve_nonneg (s : ℝ) : 0 ≤ fSieve s := tsum_nonneg fun _ => g_nonneg _ _ + +theorem FSieve_nonneg (s : ℝ) : 0 ≤ FSieve s := tsum_nonneg fun _ => g_nonneg _ _ + +theorem fSieve_pos (s : ℝ) : 0 < fSieve s := by + set n := ⌈s⌉₊ + have h : 0 < g (2 * n + 2) s := + g_pos _ (by omega) (by push_cast; linarith [Nat.le_ceil s, (Nat.cast_nonneg n : (0 : ℝ) ≤ n)]) + exact h.trans_le ((summable_g_even s).le_tsum n fun _ _ => g_nonneg _ _) + +theorem FSieve_pos (s : ℝ) : 0 < FSieve s := by + set n := ⌈s⌉₊ + have h : 0 < g (2 * n + 3) s := + g_pos _ (by omega) (by push_cast; linarith [Nat.le_ceil s, (Nat.cast_nonneg n : (0 : ℝ) ≤ n)]) + exact h.trans_le ((summable_g_odd s).le_tsum n fun _ _ => g_nonneg _ _) + +theorem fSieve_antitone : Antitone fSieve := fun _ _ h => + Summable.tsum_le_tsum (fun _ => g_antitone _ h) (summable_g_even _) (summable_g_even _) + +theorem FSieve_antitone : Antitone FSieve := fun _ _ h => + Summable.tsum_le_tsum (fun _ => g_antitone _ h) (summable_g_odd _) (summable_g_odd _) + +theorem fSieve_of_le_two {s : ℝ} (hs : s ≤ 2) : fSieve s = fSieve 2 := + tsum_congr fun n => g_even_of_le_two n hs + +/-- [I71, (3.7)], second line: `F(s) = F(3)` for `s ≤ 3`. -/ +theorem FSieve_of_le_three {s : ℝ} (hs : s ≤ 3) : FSieve s = FSieve 3 := + tsum_congr fun n => g_odd_of_le_three' n hs + +/-- `f(s) ≤ a (1 - A)⁻¹ s e^{-s}` for `s ≥ 2`. -/ +theorem fSieve_le {s : ℝ} (hs : 2 ≤ s) : fSieve s ≤ gLead * (1 - gRatio)⁻¹ * s * exp (-s) := + calc fSieve s ≤ ∑' n : ℕ, gLead * s * exp (-s) * gRatio ^ n := + Summable.tsum_le_tsum (fun n => (g_even_le n hs).trans_eq (by ring)) (summable_g_even s) + (summable_geom_gRatio _) + _ = _ := by rw [tsum_mul_left, tsum_geometric_of_lt_one gRatio_pos.le gRatio_lt_one]; ring + +/-- `F(s) ≤ a (e/3) (1 - A)⁻¹ s e^{-s}` for `s ≥ 1`. -/ +theorem FSieve_le {s : ℝ} (hs : 1 ≤ s) : + FSieve s ≤ gLead * (exp 1 / 3) * (1 - gRatio)⁻¹ * s * exp (-s) := + calc FSieve s ≤ ∑' n : ℕ, gLead * (exp 1 / 3) * s * exp (-s) * gRatio ^ n := + Summable.tsum_le_tsum (fun n => (g_odd_le n hs).trans_eq (by ring)) (summable_g_odd s) + (summable_geom_gRatio _) + _ = _ := by rw [tsum_mul_left, tsum_geometric_of_lt_one gRatio_pos.le gRatio_lt_one]; ring + +theorem fSieve_isBigO : fSieve =O[atTop] fun s => s * exp (-s) := by + refine Asymptotics.IsBigO.of_bound (gLead * (1 - gRatio)⁻¹) ?_ + filter_upwards [eventually_ge_atTop 2] with s hs + rw [norm_of_nonneg (fSieve_nonneg s), norm_of_nonneg (by positivity)] + exact (fSieve_le hs).trans_eq (by ring) + +theorem FSieve_isBigO : FSieve =O[atTop] fun s => s * exp (-s) := by + refine Asymptotics.IsBigO.of_bound (gLead * (exp 1 / 3) * (1 - gRatio)⁻¹) ?_ + filter_upwards [eventually_ge_atTop 2] with s hs + rw [norm_of_nonneg (FSieve_nonneg s), norm_of_nonneg (by positivity)] + exact (FSieve_le (by linarith)).trans_eq (by ring) + +theorem g_even_le_fSieve (n : ℕ) (s : ℝ) : g (2 * n + 2) s ≤ fSieve s := + (summable_g_even s).le_tsum n fun _ _ => g_nonneg _ _ + +theorem g_odd_le_FSieve (n : ℕ) (s : ℝ) : g (2 * n + 3) s ≤ FSieve s := + (summable_g_odd s).le_tsum n fun _ _ => g_nonneg _ _ + +/-- Partial sums of the series for `f` are at most `f`. -/ +theorem sum_g_even_le_fSieve (N : ℕ) (s : ℝ) : + ∑ n ∈ Finset.range N, g (2 * n + 2) s ≤ fSieve s := + (summable_g_even s).sum_le_tsum _ fun _ _ => g_nonneg _ _ + +/-- Partial sums of the series for `F` are at most `F`. -/ +theorem sum_g_odd_le_FSieve (N : ℕ) (s : ℝ) : + ∑ n ∈ Finset.range N, g (2 * n + 3) s ≤ FSieve s := + (summable_g_odd s).sum_le_tsum _ fun _ _ => g_nonneg _ _ + +theorem hasSum_g_fSieve (s : ℝ) : HasSum (fun n : ℕ => g (2 * n + 2) s) (fSieve s) := + (summable_g_even s).hasSum + +theorem hasSum_g_FSieve (s : ℝ) : HasSum (fun n : ℕ => g (2 * n + 3) s) (FSieve s) := + (summable_g_odd s).hasSum + +/-- `Σ_{k ≥ 2} g_k(s) = f(s) + F(s)`. -/ +theorem hasSum_g (s : ℝ) : HasSum (fun k : ℕ => g (k + 2) s) (fSieve s + FSieve s) := + HasSum.even_add_odd (hasSum_g_fSieve s) (by simpa [add_assoc] using hasSum_g_FSieve s) + +theorem fr_of_even {r : ℕ} (hr : Even r) : fr r = fSieve := funext fun _ => by simp [fr, hr] + +theorem fr_of_odd {r : ℕ} (hr : ¬ Even r) : fr r = FSieve := funext fun _ => by simp [fr, hr] + +/-! ### The integral equations (3.6), (3.7) -/ +theorem shift_div_le {h : ℝ → ℝ} {C t : ℝ} (ht : 1 < t) + (hb : h (t - 1) ≤ C * (t - 1) * exp (-(t - 1))) : + h (t - 1) / (t - 1) ≤ C * exp 1 * exp (-t) := by + have ht1 : 0 < t - 1 := by linarith + rw [div_le_iff₀ ht1] + have e : exp (-(t - 1)) = exp 1 * exp (-t) := by rw [← exp_add]; ring_nf + rw [e] at hb; linarith + +/-- An exponentially decaying `h` gives an integrable kernel `h(t-1)/(t-1)` on `(s, ∞)`. -/ +theorem integrableOn_shift {h : ℝ → ℝ} (hh : Continuous h) {C s : ℝ} (hs : 2 ≤ s) + (hnn : ∀ u, 0 ≤ h u) (hb : ∀ u, s - 1 ≤ u → h u ≤ C * u * exp (-u)) : + IntegrableOn (fun t => h (t - 1) / (t - 1)) (Ioi s) := by + refine Integrable.mono' ((exp_neg_integrableOn_Ioi s one_pos).const_mul (C * exp 1)) ?_ ?_ + · refine ContinuousOn.aestronglyMeasurable ?_ measurableSet_Ioi + exact (hh.comp (continuous_sub_right 1)).continuousOn.div + (continuous_sub_right 1).continuousOn fun t ht => by + have : s < t := ht; linarith + · filter_upwards [ae_restrict_mem measurableSet_Ioi] with t ht + have ht' : s < t := ht + rw [norm_of_nonneg (div_nonneg (hnn _) (by linarith))] + have := shift_div_le (C := C) (by linarith) (hb (t - 1) (by linarith)) + simpa using this + +/-- Interchange of `Σ` and `∫_s^∞` for nonnegative kernels. -/ +theorem tsum_integral_Ioi_shift {φ : ℕ → ℝ → ℝ} {s : ℝ} (hs : 2 ≤ s) + (hnn : ∀ n x, 0 ≤ φ n x) (hint : ∀ n, IntegrableOn (fun t => φ n (t - 1) / (t - 1)) (Ioi s)) + (hsum : Summable fun n => ∫ t in Ioi s, φ n (t - 1) / (t - 1)) : + ∑' n, ∫ t in Ioi s, φ n (t - 1) / (t - 1) = ∫ t in Ioi s, (∑' n, φ n (t - 1)) / (t - 1) := by + rw [integral_tsum_of_summable_integral_norm hint] + · congr 1; funext t; exact tsum_div_const + · refine hsum.congr fun n => setIntegral_congr_fun measurableSet_Ioi fun t ht => ?_ + have : s < t := ht + exact (norm_of_nonneg (div_nonneg (hnn _ _) (by linarith))).symm + +theorem integrableOn_FSieve_shift {s : ℝ} (hs : 2 ≤ s) : + IntegrableOn (fun t => FSieve (t - 1) / (t - 1)) (Ioi s) := + integrableOn_shift (C := gLead * (exp 1 / 3) * (1 - gRatio)⁻¹) continuous_FSieve hs + FSieve_nonneg fun u hu => + (FSieve_le (by linarith)).trans_eq (by ring) + +theorem integrableOn_fSieve_shift {s : ℝ} (hs : 3 ≤ s) : + IntegrableOn (fun t => fSieve (t - 1) / (t - 1)) (Ioi s) := + integrableOn_shift (C := gLead * (1 - gRatio)⁻¹) continuous_fSieve (by linarith) + fSieve_nonneg fun u hu => + (fSieve_le (by linarith)).trans_eq (by ring) + +theorem g_even_add_four_eq_Ioi (n : ℕ) {s : ℝ} (hs : 2 ≤ s) : + IntegrableOn (fun t => g (2 * n + 3) (t - 1) / (t - 1)) (Ioi s) ∧ + g (2 * n + 4) s = ∫ t in Ioi s, g (2 * n + 3) (t - 1) / (t - 1) := by + have := g_add_three_eq_Ioi (2 * n + 1) (s := s) (by rw [gLower_two_mul_add_four]; exact hs) + rwa [show 2 * n + 1 + 3 = 2 * n + 4 by ring, show 2 * n + 1 + 2 = 2 * n + 3 by ring] at this + +theorem g_odd_add_three_eq_Ioi (n : ℕ) {s : ℝ} (hs : 3 ≤ s) : + IntegrableOn (fun t => g (2 * n + 2) (t - 1) / (t - 1)) (Ioi s) ∧ + g (2 * n + 3) s = ∫ t in Ioi s, g (2 * n + 2) (t - 1) / (t - 1) := + g_add_three_eq_Ioi (2 * n) (by rw [gLower_two_mul_add_three]; exact hs) + +/-- [I71, (3.6)]: `f(s) = ∫_s^∞ F(t-1)/(t-1) dt + g₂(s)` for `s ≥ 2`. -/ +theorem fSieve_eq_integral {s : ℝ} (hs : 2 ≤ s) : + fSieve s = (∫ t in Ioi s, FSieve (t - 1) / (t - 1)) + g 2 s := by + have e : ∀ n : ℕ, g (2 * (n + 1) + 2) s = ∫ t in Ioi s, g (2 * n + 3) (t - 1) / (t - 1) := + fun n => by rw [show 2 * (n + 1) + 2 = 2 * n + 4 by ring]; exact (g_even_add_four_eq_Ioi n hs).2 + have hsum : Summable fun n : ℕ => g (2 * (n + 1) + 2) s := + (summable_nat_add_iff (f := fun n : ℕ => g (2 * n + 2) s) 1).mpr (summable_g_even s) + have hsum' : Summable fun n : ℕ => ∫ t in Ioi s, g (2 * n + 3) (t - 1) / (t - 1) := + hsum.congr e + have hT := tsum_integral_Ioi_shift (φ := fun n => g (2 * n + 3)) hs (fun _ _ => g_nonneg _ _) + (fun n => (g_even_add_four_eq_Ioi n hs).1) hsum' + have h0 := (summable_g_even s).tsum_eq_zero_add + rw [tsum_congr e, hT] at h0 + rw [fSieve, h0, add_comm] + rfl + +/-- [I71, (3.7)], first line: `F(s) = ∫_s^∞ f(t-1)/(t-1) dt` for `s ≥ 3`. -/ +theorem FSieve_eq_integral {s : ℝ} (hs : 3 ≤ s) : + FSieve s = ∫ t in Ioi s, fSieve (t - 1) / (t - 1) := by + have e : ∀ n : ℕ, g (2 * n + 3) s = ∫ t in Ioi s, g (2 * n + 2) (t - 1) / (t - 1) := + fun n => (g_odd_add_three_eq_Ioi n hs).2 + rw [FSieve, tsum_congr e, tsum_integral_Ioi_shift (φ := fun n => g (2 * n + 2)) (by linarith) + (fun _ _ => g_nonneg _ _) + (fun n => (g_odd_add_three_eq_Ioi n hs).1) ((summable_g_odd s).congr e)] + rfl + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/SieveMajorants/Defs.lean b/LeanPool/IwaniecLinearSieve/SieveMajorants/Defs.lean new file mode 100644 index 000000000..fa7d732fb --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveMajorants/Defs.lean @@ -0,0 +1,359 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Definitions +public import Mathlib.Analysis.Calculus.Deriv.Basic +public import Mathlib.Analysis.LocallyConvex.AbsConvexOpen +import LeanPool.IwaniecLinearSieve.SieveMajorants.Delay +import Mathlib.Algebra.Ring.IsFormallyReal +import Mathlib.NumberTheory.Chebyshev + +/-! +# Iwaniec's functions `𝔐`, `𝔚` ([I71, §3, Definition]) + +* `𝔚(s) = 1/(s-1) - log(s-1)` on `[2, 3]`, `𝔚'(s) = s/(s-1)² 𝔚(s-1)` for `s > 3`; +* `𝔐(s) = 2 + 1/(s-1) - log(s-1)` on `[2, 3]`, `𝔐'(s) = -s/(s-1)² 𝔐(s-1)` for `s > 3`. + +Both are defined on all of `ℝ` (`𝔐` in `IwaniecLinearSieve.Definitions`) and are continuous; to +the left of `2` they are constant +(`𝔚 = 1`, `𝔐 = 3`). We prove the integral equations (3.11) and (3.12) of [I71]. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory + +namespace IwaniecLinearSieve + +/-- Iwaniec's `𝔚` [I71, §3, Definition]. -/ +noncomputable def bigW : ℝ → ℝ := Delay.sol delayKer initW + +theorem delayKer_of_ge {x : ℝ} (hx : 3 ≤ x) : delayKer x = x / (x - 1) ^ 2 := by + simp [delayKer, max_eq_left hx] + +theorem continuous_delayKer : Continuous delayKer := by + unfold delayKer + refine (continuous_id.max continuous_const).div + (((continuous_id.max continuous_const).sub continuous_const).pow 2) fun x => ?_ + have : (3 : ℝ) ≤ max x 3 := le_max_right _ _ + have : (0 : ℝ) < max x 3 - 1 := by linarith + positivity + +theorem continuous_initW : Continuous initW := by + unfold initW + have h1 : Continuous fun s : ℝ => max s 2 - 1 := + (continuous_id.max continuous_const).sub continuous_const + have hne : ∀ s : ℝ, max s 2 - 1 ≠ 0 := fun s => by + have : (2 : ℝ) ≤ max s 2 := le_max_right _ _ + linarith + exact (continuous_const.div h1 hne).sub (h1.log hne) + +theorem initW_of_le {s : ℝ} (hs : s ≤ 2) : initW s = 1 := by + simp [initW, max_eq_right hs] + norm_num + +theorem initW_of_ge {s : ℝ} (hs : 2 ≤ s) : initW s = 1 / (s - 1) - log (s - 1) := by + simp [initW, max_eq_left hs] + +theorem continuous_bigW : Continuous bigW := + Delay.continuous_sol continuous_delayKer continuous_initW + +theorem continuous_initM : Continuous fun s => 2 + initW s := + continuous_const.add continuous_initW + +theorem continuous_bigM : Continuous bigM := + Delay.continuous_sol continuous_delayKer.neg continuous_initM + +theorem bigW_of_le_three {s : ℝ} (hs : s ≤ 3) : bigW s = initW s := + Delay.sol_of_le hs + +theorem bigM_of_le_three {s : ℝ} (hs : s ≤ 3) : bigM s = 2 + initW s := + Delay.sol_of_le hs + +theorem bigW_of_le_two {s : ℝ} (hs : s ≤ 2) : bigW s = 1 := by + rw [bigW_of_le_three (by linarith), initW_of_le hs] + +theorem bigM_of_le_two {s : ℝ} (hs : s ≤ 2) : bigM s = 3 := by + rw [bigM_of_le_three (by linarith), initW_of_le hs]; norm_num + +theorem bigW_eq {s : ℝ} (hs : 2 ≤ s) (hs' : s ≤ 3) : bigW s = 1 / (s - 1) - log (s - 1) := by + rw [bigW_of_le_three hs', initW_of_ge hs] + +theorem bigM_eq {s : ℝ} (hs : 2 ≤ s) (hs' : s ≤ 3) : + bigM s = 2 + 1 / (s - 1) - log (s - 1) := by + rw [bigM_of_le_three hs', initW_of_ge hs]; ring + +theorem bigW_two : bigW 2 = 1 := bigW_of_le_two le_rfl + +theorem bigM_two : bigM 2 = 3 := bigM_of_le_two le_rfl + +theorem bigW_three : bigW 3 = 1 / 2 - log 2 := by + rw [bigW_eq (by norm_num) le_rfl]; norm_num + +theorem bigM_three : bigM 3 = 5 / 2 - log 2 := by + rw [bigM_eq (by norm_num) le_rfl]; norm_num + +/-- The derivative of `1/(x-1) - log(x-1)` is `-x/(x-1)²`. -/ +theorem hasDerivAt_initForm {x : ℝ} (hx : 1 < x) : + HasDerivAt (fun x => 1 / (x - 1) - log (x - 1)) (-(x / (x - 1) ^ 2)) x := by + have h0 : x - 1 ≠ 0 := by linarith + have h1 : HasDerivAt (fun x : ℝ => x - 1) 1 x := (hasDerivAt_id x).sub_const 1 + have := (h1.inv h0).sub (h1.log h0) + convert this using 1 + · ext y; simp [one_div] + · field_simp; ring + +theorem bigW_eq_integral {s : ℝ} (hs : 3 ≤ s) : + bigW s = bigW 3 + ∫ x in (3 : ℝ)..s, x / (x - 1) ^ 2 * bigW (x - 1) := by + rw [bigW, Delay.sol_of_ge hs, ← bigW, bigW_of_le_three le_rfl] + congr 1 + refine intervalIntegral.integral_congr fun x hx => ?_ + rw [uIcc_of_le hs] at hx + simp only [delayKer_of_ge hx.1, bigW] + +theorem bigM_eq_integral {s : ℝ} (hs : 3 ≤ s) : + bigM s = bigM 3 - ∫ x in (3 : ℝ)..s, x / (x - 1) ^ 2 * bigM (x - 1) := by + rw [bigM, Delay.sol_of_ge hs, ← bigM, bigM_of_le_three le_rfl, sub_eq_add_neg, + ← intervalIntegral.integral_neg] + congr 1 + refine intervalIntegral.integral_congr fun x hx => ?_ + rw [uIcc_of_le hs] at hx + simp only [delayKer_of_ge hx.1, bigM, neg_mul] + +theorem hasDerivAt_bigW {s : ℝ} (hs : 3 < s) : + HasDerivAt bigW (s / (s - 1) ^ 2 * bigW (s - 1)) s := by + have := Delay.hasDerivAt_sol continuous_delayKer continuous_initW hs + rwa [delayKer_of_ge hs.le] at this + +theorem hasDerivAt_bigM {s : ℝ} (hs : 3 < s) : + HasDerivAt bigM (-(s / (s - 1) ^ 2 * bigM (s - 1))) s := by + have := Delay.hasDerivAt_sol continuous_delayKer.neg + continuous_initM hs + rwa [Pi.neg_apply, delayKer_of_ge hs.le, neg_mul] at this + +theorem hasDerivWithinAt_bigW_Ici {s : ℝ} (hs : 3 ≤ s) : + HasDerivWithinAt bigW (s / (s - 1) ^ 2 * bigW (s - 1)) (Ici s) s := by + have := Delay.hasDerivWithinAt_sol_Ici continuous_delayKer continuous_initW hs + rwa [delayKer_of_ge hs] at this + +theorem hasDerivWithinAt_bigM_Ici {s : ℝ} (hs : 3 ≤ s) : + HasDerivWithinAt bigM (-(s / (s - 1) ^ 2 * bigM (s - 1))) (Ici s) s := by + have := Delay.hasDerivWithinAt_sol_Ici continuous_delayKer.neg + continuous_initM hs + rwa [Pi.neg_apply, delayKer_of_ge hs, neg_mul] at this + +/-! ### Auxiliary calculus -/ + +/-- `t ↦ ∫_{t-1}^t F` has derivative `F t - F (t - 1)`. -/ +theorem hasDerivAt_integral_unit {F : ℝ → ℝ} (hF : Continuous F) (t : ℝ) : + HasDerivAt (fun t => ∫ x in (t - 1)..t, F x) (F t - F (t - 1)) t := by + have hI : ∀ a b : ℝ, IntervalIntegrable F volume a b := fun a b => hF.intervalIntegrable a b + have heq : (fun t => ∫ x in (t - 1)..t, F x) = + fun t => (∫ x in (0 : ℝ)..t, F x) - ∫ x in (0 : ℝ)..(t - 1), F x := by + ext t + rw [intervalIntegral.integral_interval_sub_left (hI 0 t) (hI 0 (t - 1))] + rw [heq] + have h1 := (hF.integral_hasStrictDerivAt 0 t).hasDerivAt + have h2 := ((hF.integral_hasStrictDerivAt 0 (t - 1)).hasDerivAt).comp t + ((hasDerivAt_id t).sub_const 1) + convert h1.sub h2 using 1 + · funext x; simp [Function.comp_def] + · ring + +/-- A function continuous on `[a, ∞)` with zero derivative on `(a, ∞)` is constant there. -/ +theorem eq_of_hasDerivAt_zero {g : ℝ → ℝ} {a : ℝ} (hg : ContinuousOn g (Ici a)) + (hd : ∀ x, a < x → HasDerivAt g 0 x) {s : ℝ} (hs : a ≤ s) : g s = g a := by + rcases hs.eq_or_lt with rfl | hs + · rfl + obtain ⟨c, hc, hc'⟩ := exists_hasDerivAt_eq_slope g (fun _ => (0 : ℝ)) hs + (hg.mono Icc_subset_Ici_self) fun x hx => hd x hx.1 + have : s - a ≠ 0 := by linarith + field_simp at hc' + linarith + +/-! ### (3.11) -/ + +/-- The integrand of (3.11), made continuous on `ℝ`. -/ +noncomputable def wIntegrand (x : ℝ) : ℝ := bigW x / max x 1 ^ 2 + +theorem continuous_wIntegrand : Continuous wIntegrand := by + unfold wIntegrand + refine continuous_bigW.div ((continuous_id.max continuous_const).pow 2) fun x => ?_ + have : (1 : ℝ) ≤ max x 1 := le_max_right _ _ + positivity + +theorem wIntegrand_of_ge {x : ℝ} (hx : 1 ≤ x) : wIntegrand x = bigW x / x ^ 2 := by + simp [wIntegrand, max_eq_left hx] + +theorem integral_wIntegrand_two_three : + ∫ x in (2 : ℝ)..3, wIntegrand x = (1 + log 2) / 3 - 1 / 2 := by + have hcongr : ∫ x in (2 : ℝ)..3, wIntegrand x = + ∫ x in (2 : ℝ)..3, (1 / (x - 1) - log (x - 1)) / x ^ 2 := by + refine intervalIntegral.integral_congr fun x hx => ?_ + rw [uIcc_of_le (by norm_num)] at hx + rw [wIntegrand_of_ge (by linarith [hx.1]), bigW_eq hx.1 hx.2] + rw [hcongr] + have hderiv : ∀ x ∈ uIcc (2 : ℝ) 3, HasDerivAt (fun x => (1 + log (x - 1)) / x) + ((1 / (x - 1) - log (x - 1)) / x ^ 2) x := by + intro x hx + rw [uIcc_of_le (by norm_num)] at hx + have hx1 : x - 1 ≠ 0 := by linarith [hx.1] + have hx0 : x ≠ 0 := by linarith [hx.1] + have h1 : HasDerivAt (fun x : ℝ => x - 1) 1 x := (hasDerivAt_id x).sub_const 1 + have := ((h1.log hx1).const_add 1).div (hasDerivAt_id x) hx0 + refine this.congr_deriv ?_ + simp only [id] + field_simp + ring + have hcont : ContinuousOn (fun x : ℝ => (1 / (x - 1) - log (x - 1)) / x ^ 2) (uIcc 2 3) := by + rw [uIcc_of_le (by norm_num)] + intro x hx + have hx1 : x - 1 ≠ 0 := by linarith [hx.1] + have hx0 : x ^ 2 ≠ 0 := pow_ne_zero 2 (by linarith [hx.1]) + exact (((continuousAt_const.div (continuousAt_id.sub continuousAt_const) hx1).sub + ((continuousAt_id.sub continuousAt_const).log hx1)).div + (continuousAt_id.pow 2) hx0).continuousWithinAt + rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hderiv (hcont.intervalIntegrable)] + norm_num + +/-- [I71, (3.11)]: `𝔚(s) = -s ∫_{s-1}^s 𝔚(x)/x² dx` for `s ≥ 3`. -/ +theorem bigW_eq_neg_mul_integral {s : ℝ} (hs : 3 ≤ s) : + bigW s = -s * ∫ x in (s - 1)..s, bigW x / x ^ 2 := by + set g : ℝ → ℝ := fun t => bigW t / t + ∫ x in (t - 1)..t, wIntegrand x + have hgc : ContinuousOn g (Ici 3) := by + refine ContinuousOn.add ?_ ?_ + · exact continuous_bigW.continuousOn.div continuousOn_id fun x hx => by + linarith [hx.out] + · exact fun t _ => (hasDerivAt_integral_unit continuous_wIntegrand t).continuousAt + |>.continuousWithinAt + have hgd : ∀ t, 3 < t → HasDerivAt g 0 t := by + intro t ht + have ht0 : t ≠ 0 := by linarith + have ht1 : t - 1 ≠ 0 := by linarith + have := ((hasDerivAt_bigW ht).div (hasDerivAt_id t) ht0).add + (hasDerivAt_integral_unit continuous_wIntegrand t) + refine this.congr_deriv ?_ + rw [wIntegrand_of_ge (by linarith), wIntegrand_of_ge (by linarith)] + simp only [id] + field_simp + ring + have h3 : g 3 = 0 := by + simp only [g] + norm_num + rw [integral_wIntegrand_two_three, bigW_three] + ring + have hgs : g s = 0 := (eq_of_hasDerivAt_zero hgc hgd hs).trans h3 + have hint : ∫ x in (s - 1)..s, wIntegrand x = ∫ x in (s - 1)..s, bigW x / x ^ 2 := by + refine intervalIntegral.integral_congr fun x hx => ?_ + rw [uIcc_of_le (by linarith)] at hx + exact wIntegrand_of_ge (by linarith [hx.1]) + simp only [g, hint] at hgs + have hs0 : s ≠ 0 := by linarith + field_simp at hgs + linarith + +/-! ### (3.12) -/ + +/-- The integrand of (3.12), made continuous on `ℝ`. -/ +noncomputable def mIntegrand (x : ℝ) : ℝ := (1 - 1 / (2 * max x 1 ^ 2)) * bigM x + +theorem continuous_mIntegrand : Continuous mIntegrand := by + unfold mIntegrand + refine (continuous_const.sub (continuous_const.div + (continuous_const.mul ((continuous_id.max continuous_const).pow 2)) fun x => ?_)).mul + continuous_bigM + exact mul_ne_zero two_ne_zero (pow_ne_zero 2 (lt_of_lt_of_le one_pos (le_max_right _ _)).ne') + +theorem mIntegrand_of_ge {x : ℝ} (hx : 1 ≤ x) : + mIntegrand x = (1 - 1 / (2 * x ^ 2)) * bigM x := by + simp [mIntegrand, max_eq_left hx] + +theorem integral_mIntegrand_two_three : + ∫ x in (2 : ℝ)..3, mIntegrand x = 7 / 2 * (5 / 2 - log 2) / 3 := by + have hcongr : ∫ x in (2 : ℝ)..3, mIntegrand x = + ∫ x in (2 : ℝ)..3, (1 - 1 / (2 * x ^ 2)) * (2 + (1 / (x - 1) - log (x - 1))) := by + refine intervalIntegral.integral_congr fun x hx => ?_ + rw [uIcc_of_le (by norm_num)] at hx + rw [mIntegrand_of_ge (by linarith [hx.1]), bigM_eq hx.1 hx.2] + ring + rw [hcongr] + have hderiv : ∀ x ∈ uIcc (2 : ℝ) 3, HasDerivAt + (fun x => ((x - 1) ^ 2 - 1 / 2) * (2 + (1 / (x - 1) - log (x - 1))) / x + x + + 1 / (2 * (x - 1))) + ((1 - 1 / (2 * x ^ 2)) * (2 + (1 / (x - 1) - log (x - 1)))) x := by + intro x hx + rw [uIcc_of_le (by norm_num)] at hx + have hx1 : x - 1 ≠ 0 := by linarith [hx.1] + have hx0 : x ≠ 0 := by linarith [hx.1] + have h1 : HasDerivAt (fun x : ℝ => x - 1) 1 x := (hasDerivAt_id x).sub_const 1 + have hr : HasDerivAt (fun x : ℝ => (x - 1) ^ 2 - 1 / 2) (2 * (x - 1)) x := by + convert (h1.pow 2).sub_const (1 / 2) using 1; ring + have hm := (hasDerivAt_initForm (x := x) (by linarith [hx.1])).const_add 2 + have hq : HasDerivAt (fun x : ℝ => 2 * (x - 1)) 2 x := by + convert h1.const_mul 2 using 1; ring + have := (((hr.mul hm).div (hasDerivAt_id x) hx0).add (hasDerivAt_id x)).add + ((hasDerivAt_const x (1 : ℝ)).div hq (by positivity)) + refine this.congr_deriv ?_ + simp only [id, Pi.mul_apply] + field_simp + ring + have hcont : ContinuousOn + (fun x : ℝ => (1 - 1 / (2 * x ^ 2)) * (2 + (1 / (x - 1) - log (x - 1)))) (uIcc 2 3) := by + rw [uIcc_of_le (by norm_num)] + intro x hx + have hx1 : x - 1 ≠ 0 := by linarith [hx.1] + have hx0 : 2 * x ^ 2 ≠ 0 := by have : x ≠ 0 := by linarith [hx.1] + positivity + exact ((continuousAt_const.sub (continuousAt_const.div + (continuousAt_const.mul (continuousAt_id.pow 2)) hx0)).mul + (continuousAt_const.add ((continuousAt_const.div (continuousAt_id.sub continuousAt_const) + hx1).sub ((continuousAt_id.sub continuousAt_const).log hx1)))).continuousWithinAt + rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hderiv (hcont.intervalIntegrable)] + norm_num + ring + +/-- [I71, (3.12)]: `((s-1)² - 1/2) 𝔐(s) / s = ∫_{s-1}^s (1 - 1/(2x²)) 𝔐(x) dx` for `s ≥ 3`. -/ +theorem bigM_integral_identity {s : ℝ} (hs : 3 ≤ s) : + ((s - 1) ^ 2 - 1 / 2) * bigM s / s = ∫ x in (s - 1)..s, (1 - 1 / (2 * x ^ 2)) * bigM x := by + set g : ℝ → ℝ := fun t => ((t - 1) ^ 2 - 1 / 2) * bigM t / t - ∫ x in (t - 1)..t, mIntegrand x + have hgc : ContinuousOn g (Ici 3) := by + refine ContinuousOn.sub ?_ ?_ + · refine ContinuousOn.div ?_ continuousOn_id fun x hx => by linarith [hx.out] + exact (((continuous_id.sub continuous_const).pow 2).sub continuous_const).continuousOn.mul + continuous_bigM.continuousOn + · exact fun t _ => (hasDerivAt_integral_unit continuous_mIntegrand t).continuousAt + |>.continuousWithinAt + have hgd : ∀ t, 3 < t → HasDerivAt g 0 t := by + intro t ht + have ht0 : t ≠ 0 := by linarith + have ht1 : t - 1 ≠ 0 := by linarith + have h1 : HasDerivAt (fun x : ℝ => x - 1) 1 t := (hasDerivAt_id t).sub_const 1 + have hr : HasDerivAt (fun x : ℝ => (x - 1) ^ 2 - 1 / 2) (2 * (t - 1)) t := by + convert (h1.pow 2).sub_const (1 / 2) using 1; ring + have := ((hr.mul (hasDerivAt_bigM ht)).div (hasDerivAt_id t) ht0).sub + (hasDerivAt_integral_unit continuous_mIntegrand t) + refine this.congr_deriv ?_ + rw [mIntegrand_of_ge (by linarith), mIntegrand_of_ge (by linarith)] + simp only [id, Pi.mul_apply] + field_simp + ring + have h3 : g 3 = 0 := by + simp only [g] + norm_num + rw [integral_mIntegrand_two_three, bigM_three] + ring + have hgs : g s = 0 := (eq_of_hasDerivAt_zero hgc hgd hs).trans h3 + have hint : ∫ x in (s - 1)..s, mIntegrand x = + ∫ x in (s - 1)..s, (1 - 1 / (2 * x ^ 2)) * bigM x := by + refine intervalIntegral.integral_congr fun x hx => ?_ + rw [uIcc_of_le (by linarith)] at hx + exact mIntegrand_of_ge (by linarith [hx.1]) + simp only [g, hint] at hgs + linarith + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/SieveMajorants/Delay.lean b/LeanPool/IwaniecLinearSieve/SieveMajorants/Delay.lean new file mode 100644 index 000000000..d4cc5d6ab --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveMajorants/Delay.lean @@ -0,0 +1,189 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Definitions +public import Mathlib.Analysis.Calculus.Deriv.Basic +public import Mathlib.Analysis.LocallyConvex.AbsConvexOpen +import Mathlib.NumberTheory.Chebyshev + +/-! +# Linear delay equations with unit delay + +For continuous `k y₀ : ℝ → ℝ`, `y = Delay.sol k y₀` (defined in `IwaniecLinearSieve.Definitions`) +is the continuous function with + +* `y s = y₀ s` for `s ≤ 3`, +* `y s = y₀ 3 + ∫ x in 3..s, k x * y (x - 1)` for `s ≥ 3`, + +so that `y' s = k s * y (s - 1)` for `s > 3`. This is the shape of the equations defining +Iwaniec's functions `𝔐`, `𝔚` in [I71, §3]. + +We also record a "first crossing" principle used for the comparison arguments of [I71, §3]. +-/ + +@[expose] public section + +open Set Filter Topology MeasureTheory + +namespace IwaniecLinearSieve + +namespace Delay + +variable {k y₀ : ℝ → ℝ} + +theorem step_of_le {y : ℝ → ℝ} {s : ℝ} (hs : s ≤ 3) : step k y₀ y s = y₀ s := by + simp [step, min_eq_left hs, max_eq_right hs] + +theorem step_of_ge {y : ℝ → ℝ} {s : ℝ} (hs : 3 ≤ s) : + step k y₀ y s = y₀ 3 + ∫ x in (3 : ℝ)..s, k x * y (x - 1) := by + simp [step, min_eq_right hs, max_eq_left hs] + +/-- `step` only looks one unit back. -/ +theorem step_congr {y y' : ℝ → ℝ} {m : ℝ} (h : ∀ x ≤ m, y x = y' x) {s : ℝ} (hs : s ≤ m + 1) : + step k y₀ y s = step k y₀ y' s := by + rcases le_total s 3 with h3 | h3 + · rw [step_of_le h3, step_of_le h3] + · rw [step_of_ge h3, step_of_ge h3] + congr 1 + refine intervalIntegral.integral_congr fun x hx => ?_ + rw [uIcc_of_le h3] at hx + rw [h (x - 1) (by linarith [hx.2])] + +theorem iter_succ_eq (n : ℕ) {s : ℝ} (hs : s ≤ n + 3) : + iter k y₀ (n + 1) s = iter k y₀ n s := by + induction n generalizing s with + | zero => + simp only [Nat.cast_zero, zero_add] at hs + exact step_of_le hs + | succ n ih => + change step k y₀ (iter k y₀ (n + 1)) s = step k y₀ (iter k y₀ n) s + refine step_congr (m := n + 3) (fun x hx => ih hx) ?_ + push_cast at hs + linarith + +theorem iter_add_eq (n j : ℕ) {s : ℝ} (hs : s ≤ n + 3) : + iter k y₀ (n + j) s = iter k y₀ n s := by + induction j with + | zero => rfl + | succ j ih => + rw [← add_assoc, iter_succ_eq _ (by push_cast; linarith), ih] + +theorem iter_eq_of_le {m n : ℕ} (hmn : m ≤ n) {s : ℝ} (hs : s ≤ m + 3) : + iter k y₀ n s = iter k y₀ m s := by + obtain ⟨j, rfl⟩ := Nat.exists_eq_add_of_le hmn + exact iter_add_eq m j hs + +theorem sol_eq_iter {n : ℕ} {s : ℝ} (hs : s ≤ n + 3) : sol k y₀ s = iter k y₀ n s := by + unfold sol + rcases le_total n ⌈s⌉₊ with h | h + · exact iter_eq_of_le h hs + · exact (iter_eq_of_le h (by linarith [Nat.le_ceil s])).symm + +/-- `sol` is a fixed point of `step`. -/ +theorem sol_eq_step (s : ℝ) : sol k y₀ s = step k y₀ (sol k y₀) s := by + set n := ⌈s⌉₊ + have hn : s ≤ n := Nat.le_ceil s + rw [sol_eq_iter (n := n + 1) (by push_cast; linarith)] + change step k y₀ (iter k y₀ n) s = _ + exact step_congr (m := n + 3) (fun x hx => (sol_eq_iter hx).symm) (by linarith) + +theorem sol_of_le {s : ℝ} (hs : s ≤ 3) : sol k y₀ s = y₀ s := by + rw [sol_eq_step, step_of_le hs] + +theorem sol_of_ge {s : ℝ} (hs : 3 ≤ s) : + sol k y₀ s = y₀ 3 + ∫ x in (3 : ℝ)..s, k x * sol k y₀ (x - 1) := by + rw [sol_eq_step, step_of_ge hs] + +theorem continuous_step (hk : Continuous k) (hy₀ : Continuous y₀) {y : ℝ → ℝ} + (hy : Continuous y) : Continuous (step k y₀ y) := by + have hF : Continuous fun x => k x * y (x - 1) := hk.mul (hy.comp (continuous_sub_right 1)) + have hP : Continuous fun b => ∫ x in (3 : ℝ)..b, k x * y (x - 1) := + intervalIntegral.continuous_primitive (fun a b => hF.intervalIntegrable a b) 3 + exact (hy₀.comp (continuous_id.min continuous_const)).add + (hP.comp (continuous_id.max continuous_const)) + +theorem continuous_iter (hk : Continuous k) (hy₀ : Continuous y₀) (n : ℕ) : + Continuous (iter k y₀ n) := by + induction n with + | zero => exact hy₀ + | succ n ih => exact continuous_step hk hy₀ ih + +theorem continuous_sol (hk : Continuous k) (hy₀ : Continuous y₀) : Continuous (sol k y₀) := by + rw [continuous_iff_continuousAt] + intro s + set n := ⌈s⌉₊ + have hn : s ≤ n := Nat.le_ceil s + have hev : iter k y₀ n =ᶠ[𝓝 s] sol k y₀ := by + filter_upwards [Iio_mem_nhds (show s < n + 3 by linarith)] with x hx + exact (sol_eq_iter hx.le).symm + exact ((continuous_iter hk hy₀ n).continuousAt).congr hev + +/-- For `s ≥ 3`, `sol` agrees with `y₀ 3 + ∫_3^s k x y(x-1) dx`, a function with derivative +`k s * y (s - 1)` everywhere. -/ +theorem hasDerivAt_primitive (hk : Continuous k) (hy₀ : Continuous y₀) (s : ℝ) : + HasDerivAt (fun t => y₀ 3 + ∫ x in (3 : ℝ)..t, k x * sol k y₀ (x - 1)) + (k s * sol k y₀ (s - 1)) s := by + have hF : Continuous fun x => k x * sol k y₀ (x - 1) := + hk.mul ((continuous_sol hk hy₀).comp (continuous_sub_right 1)) + exact ((hF.integral_hasStrictDerivAt 3 s).hasDerivAt).const_add _ + +theorem hasDerivAt_sol (hk : Continuous k) (hy₀ : Continuous y₀) {s : ℝ} (hs : 3 < s) : + HasDerivAt (sol k y₀) (k s * sol k y₀ (s - 1)) s := by + refine (hasDerivAt_primitive hk hy₀ s).congr_of_eventuallyEq ?_ + filter_upwards [Ioi_mem_nhds hs] with x hx + exact sol_of_ge hx.out.le + +theorem hasDerivWithinAt_sol_Ici (hk : Continuous k) (hy₀ : Continuous y₀) {s : ℝ} + (hs : 3 ≤ s) : HasDerivWithinAt (sol k y₀) (k s * sol k y₀ (s - 1)) (Ici s) s := by + refine (hasDerivAt_primitive hk hy₀ s).hasDerivWithinAt.congr (fun x hx => ?_) ?_ + · exact sol_of_ge (hs.trans hx) + · exact sol_of_ge hs + +end Delay + +/-- First-crossing principle. If `f` is continuous on `[a, ∞)`, nonnegative on `[a₀, a]`, +positive at `a`, and `f s > 0` whenever `s > a` and `f ≥ 0` on `[a₀, s]`, `f > 0` on `[a, s)`, +then `f > 0` on `[a, ∞)`. -/ +theorem pos_of_first_crossing {f : ℝ → ℝ} {a₀ a : ℝ} (hf : ContinuousOn f (Ici a)) + (hinit : ∀ x ∈ Icc a₀ a, 0 ≤ f x) (ha : 0 < f a) + (hstep : ∀ s > a, (∀ x ∈ Icc a₀ s, 0 ≤ f x) → (∀ x ∈ Ico a s, 0 < f x) → 0 < f s) : + ∀ s, a ≤ s → 0 < f s := by + by_contra hcon + push Not at hcon + set B := Ici a ∩ f ⁻¹' Iic 0 with hB + have hBne : B.Nonempty := by + obtain ⟨s, hs, hfs⟩ := hcon + exact ⟨s, hs, hfs⟩ + have hBc : IsClosed B := hf.preimage_isClosed_of_isClosed isClosed_Ici isClosed_Iic + have hBb : BddBelow B := ⟨a, fun x hx => hx.1⟩ + set t := sInf B + have htB : t ∈ B := hBc.csInf_mem hBne hBb + have hat : a ≤ t := htB.1 + have hft : f t ≤ 0 := htB.2 + have hat' : a < t := lt_of_le_of_ne hat fun h => by rw [← h] at hft; linarith + have hpos : ∀ x ∈ Ico a t, 0 < f x := by + intro x hx + by_contra hx' + push Not at hx' + have : t ≤ x := csInf_le hBb ⟨hx.1, hx'⟩ + exact absurd hx.2 (not_lt.2 this) + have hnn : ∀ x ∈ Icc a t, 0 ≤ f x := by + have hcl : closure (Ico a t) = Icc a t := closure_Ico hat'.ne + have hcont : ContinuousOn f (closure (Ico a t)) := by + rw [hcl]; exact hf.mono Icc_subset_Ici_self + have := le_on_closure (f := fun _ => (0 : ℝ)) (g := f) (fun x hx => (hpos x hx).le) + continuousOn_const hcont + rwa [hcl] at this + have hall : ∀ x ∈ Icc a₀ t, 0 ≤ f x := by + intro x hx + rcases le_total x a with hxa | hxa + · exact hinit x ⟨hx.1, hxa⟩ + · exact hnn x ⟨hxa, hx.2⟩ + linarith [hstep t hat' hall hpos] + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/SieveMajorants/Lemmas.lean b/LeanPool/IwaniecLinearSieve/SieveMajorants/Lemmas.lean new file mode 100644 index 000000000..3d9a83b4b --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveMajorants/Lemmas.lean @@ -0,0 +1,576 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.SieveMajorants.Majorants +import LeanPool.IwaniecLinearSieve.SieveMajorants.Delay +import LeanPool.IwaniecLinearSieve.SieveMajorants.Properties +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.ExponentialBounds +import Mathlib.NumberTheory.Chebyshev +import Mathlib.Tactic.Polynomial.Basic + +/-! +# [I71, Lemmas 8, 9 (lower bound), 10] + +* Lemma 8: `𝔐(s-1) < 4 s² 𝔐(s)` for `s ≥ 3`. +* Lemma 10: `log t 𝔐(t) < 2 t/(t-1)² 𝔐(t-1)` for `t ≥ 2`; hence `𝔐(t) t log t / 𝔐(t-1) < 9/2` + for `t ≥ 3`, and the Corollary `G_{r+1}(t) (t-1)² log t / (G_r(t-1) t) < 4` for `t ≥ 2`. +* Lemma 9 (lower bound): `G_r(s) ≥ exp(-s log s - s log log s - c s)` for `s ≥ 3`. + +[I71] proves Lemma 10 assuming that `𝔐(t-1)/𝔐(t)` is increasing; we instead use a first +crossing argument for the inequality itself (cf. [Opera de Cribro, Lemma 11.7]). For Lemma 9 we +compare `𝔐` with the explicit subsolution `exp(-(s log s + s log log s + 2s))` of (3.12), +instead of quoting the asymptotics of Hua's book. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory + +namespace IwaniecLinearSieve + +/-! ### Lemma 8 -/ + +/-- From (3.12): `𝔐(s - 1/2) ≤ 2(s-1)²/s 𝔐(s)` for `s ≥ 3`. -/ +theorem bigM_sub_half_le {s : ℝ} (hs : 3 ≤ s) : + bigM (s - 1 / 2) ≤ 2 * (s - 1) ^ 2 / s * bigM s := by + have hs0 : 0 < s := by linarith + have hy : 0 < (s - 1) ^ 2 := by nlinarith + have hs1 : s - 1 ≠ 0 := by linarith + have hwc := continuousOn_weight_mul continuous_bigM (a := s - 1) (b := s) (by linarith) + have hI : ∀ a b, s - 1 ≤ a → a ≤ b → b ≤ s → + IntervalIntegrable (fun x => (1 - 1 / (2 * x ^ 2)) * bigM x) volume a b := + fun a b ha hab hb => (hwc.mono (Icc_subset_Icc ha hb)).intervalIntegrable_of_Icc hab + have hsplit := intervalIntegral.integral_add_adjacent_intervals + (hI (s - 1) (s - 1 / 2) le_rfl (by linarith) (by linarith)) + (hI (s - 1 / 2) s (by linarith) (by linarith) le_rfl) + have h2 : 0 ≤ ∫ x in (s - 1 / 2)..s, (1 - 1 / (2 * x ^ 2)) * bigM x := + intervalIntegral.integral_nonneg (by linarith) fun x hx => + (mul_pos (weight_mem (by linarith [hx.1])).1 (bigM_pos x)).le + have h1 : ∫ _ in (s - 1)..(s - 1 / 2), (1 - 1 / (2 * (s - 1) ^ 2)) * bigM (s - 1 / 2) ≤ + ∫ x in (s - 1)..(s - 1 / 2), (1 - 1 / (2 * x ^ 2)) * bigM x := by + refine intervalIntegral.integral_mono_on (by linarith) intervalIntegrable_const + (hI _ _ le_rfl (by linarith) (by linarith)) fun x hx => ?_ + have hw : 1 - 1 / (2 * (s - 1) ^ 2) ≤ 1 - 1 / (2 * x ^ 2) := by + have : 1 / (2 * x ^ 2) ≤ 1 / (2 * (s - 1) ^ 2) := + one_div_le_one_div_of_le (by positivity) (by nlinarith [hx.1]) + linarith + exact mul_le_mul hw (bigM_antitone hx.2) (bigM_pos _).le + (weight_mem (by linarith [hx.1])).1.le + rw [intervalIntegral.integral_const, smul_eq_mul] at h1 + have key := bigM_integral_identity hs + rw [← hsplit] at key + have : (s - 1 / 2 - (s - 1)) * ((1 - 1 / (2 * (s - 1) ^ 2)) * bigM (s - 1 / 2)) ≤ + ((s - 1) ^ 2 - 1 / 2) * bigM s / s := by linarith + have e1 : (s - 1 / 2 - (s - 1)) * ((1 - 1 / (2 * (s - 1) ^ 2)) * bigM (s - 1 / 2)) = + ((s - 1) ^ 2 - 1 / 2) * bigM (s - 1 / 2) / (2 * (s - 1) ^ 2) := by + field_simp; ring + rw [e1, div_le_div_iff₀ (by positivity) hs0] at this + have hr : 0 < (s - 1) ^ 2 - 1 / 2 := by nlinarith + rw [div_mul_eq_mul_div, le_div_iff₀ hs0] + nlinarith + +/-- [I71, Lemma 8]: `𝔐(s-1) < 4 s² 𝔐(s)` for `s ≥ 3`. -/ +theorem bigM_sub_one_lt {s : ℝ} (hs : 3 ≤ s) : bigM (s - 1) < 4 * s ^ 2 * bigM s := by + have hs0 : 0 < s := by linarith + have hB := bigM_sub_half_le hs + have hMs := bigM_pos s + rcases le_total s (7 / 2) with h | h + · have h1 : bigM (s - 1) ≤ 3 := bigM_le_three _ + have h2 : bigM 3 ≤ bigM (s - 1 / 2) := bigM_antitone (by linarith) + rw [bigM_three] at h2 + have h3 : 2 * (s - 1) ^ 2 / s ≤ s ^ 2 := by + rw [div_le_iff₀ hs0]; nlinarith + have := mul_le_mul_of_nonneg_right h3 hMs.le + nlinarith [log_two_lt_d9] + · have hA := bigM_sub_half_le (s := s - 1 / 2) (by linarith) + rw [show s - 1 / 2 - 1 / 2 = s - 1 by ring] at hA + have h3 : 2 * (s - 1 / 2 - 1) ^ 2 / (s - 1 / 2) < 2 * s := by + rw [div_lt_iff₀ (by linarith)]; nlinarith + have h4 : 2 * (s - 1) ^ 2 / s < 2 * s := by + rw [div_lt_iff₀ hs0]; nlinarith + have h5 : 0 < 2 * (s - 1) ^ 2 / s := div_pos (by nlinarith) hs0 + calc bigM (s - 1) ≤ 2 * (s - 1 / 2 - 1) ^ 2 / (s - 1 / 2) * bigM (s - 1 / 2) := hA + _ ≤ 2 * (s - 1 / 2 - 1) ^ 2 / (s - 1 / 2) * (2 * (s - 1) ^ 2 / s * bigM s) := + mul_le_mul_of_nonneg_left hB (div_nonneg (by positivity) (by linarith)) + _ < 2 * s * (2 * s * bigM s) := by + apply mul_lt_mul' h3.le (mul_lt_mul_of_pos_right h4 hMs) (by positivity) (by linarith) + _ = 4 * s ^ 2 * bigM s := by ring + +/-- [I71, Lemma 8] in ratio form. -/ +theorem bigM_sub_one_div_lt {s : ℝ} (hs : 3 ≤ s) : bigM (s - 1) / bigM s < 4 * s ^ 2 := by + rw [div_lt_iff₀ (bigM_pos s)]; exact bigM_sub_one_lt hs + +/-! ### Lemma 10 -/ + +/-- `∫_{a}^{a+1} exp(-λ(x - a)) dx = (1 - exp(-λ))/λ`. -/ +theorem integral_exp_neg_mul_unit (a : ℝ) {l : ℝ} (hl : l ≠ 0) : + ∫ x in a..(a + 1), exp (-(l * (x - a))) = (1 - exp (-l)) / l := by + have hderiv : ∀ x ∈ uIcc a (a + 1), HasDerivAt (fun x => -exp (-(l * (x - a))) / l) + (exp (-(l * (x - a)))) x := by + intro x _ + have h := ((((hasDerivAt_id' x).sub_const a).const_mul l).neg).exp.neg.div_const l + refine h.congr_deriv ?_ + simp only [Pi.neg_apply] + field_simp + rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hderiv + ((by fun_prop : Continuous fun x => exp (-(l * (x - a)))).intervalIntegrable _ _)] + simp only [add_sub_cancel_left, mul_one, sub_self, mul_zero, neg_zero, exp_zero] + ring + +theorem log_four_lt : log 4 < 1.3863 := by + rw [show (4 : ℝ) = 2 ^ 2 by norm_num, log_pow] + have := log_two_lt_d9 + push_cast + linarith + +/-- The numerical comparison in the main range of Lemma 10. With `q² = t - 1`, the +logarithmic bound makes the integrated exponential estimate smaller than `2t/(t-1)²`. -/ +theorem log_mul_ratio_lt {t q L : ℝ} (ht0 : 0 < t) (hq1 : 1 < q) + (hq2 : q ^ 2 = t - 1) (hL : 1 < L) (hLt : log t ≤ L + 1 / (t - 1)) : + log t * (t / ((t - 1) ^ 2 - 1 / 2) * ((1 - q⁻¹) / (L / 2))) < + 2 * (t / (t - 1) ^ 2) := by + have hq0 : 0 < q := by linarith only [hq1] + have hq4 : 0 < q ^ 4 - 1 / 2 := by + linarith only [one_lt_pow₀ hq1 (by decide : 4 ≠ 0)] + have hL0 : 0 < L := by linarith only [hL] + have hD : 0 < L * q * (q ^ 4 - 1 / 2) := by positivity + have hy : (t - 1) ^ 2 = q ^ 4 := by rw [← hq2]; ring + have e1 : log t * (t / ((t - 1) ^ 2 - 1 / 2) * ((1 - q⁻¹) / (L / 2))) = + t * (2 * (log t * (q - 1)) / (L * q * (q ^ 4 - 1 / 2))) := by + rw [hy] + field_simp + have e2 : 2 * (t / (t - 1) ^ 2) = t * (2 / q ^ 4) := by + rw [hy]; ring + rw [e1, e2] + refine mul_lt_mul_of_pos_left ?_ ht0 + rw [div_lt_div_iff₀ hD (by positivity)] + -- `log t (q-1) q⁴ < L q (q⁴ - 1/2)` using `log t ≤ L + 1/q²` + have hLt' : log t ≤ L + 1 / q ^ 2 := by rwa [hq2] + have h1 := mul_le_mul_of_nonneg_right hLt' + (show 0 ≤ (q - 1) * q ^ 4 by have : 0 ≤ q - 1 := by linarith + positivity) + have h2 : (L + 1 / q ^ 2) * ((q - 1) * q ^ 4) = L * (q - 1) * q ^ 4 + (q - 1) * q ^ 2 := by + field_simp + have h3 : L * (q - 1) * q ^ 4 + (q - 1) * q ^ 2 < L * q * (q ^ 4 - 1 / 2) := by + have hA : 0 < q ^ 4 - q / 2 := by + have hcube := mul_lt_mul_of_pos_right (one_lt_pow₀ hq1 (by decide : 3 ≠ 0)) hq0 + nlinarith only [hcube, hq0] + have hB' : 0 < q ^ 2 * q * (q - 1) + q * (q - 1 / 2) := by + have : 0 < q - 1 := by linarith + have : 0 < q - 1 / 2 := by linarith + positivity + nlinarith [mul_lt_mul_of_pos_right hL hA] + nlinarith + +/-- The inequality behind [I71, Lemma 10]: `log t · 𝔐(t) < 2 t/(t-1)² · 𝔐(t-1)` for +`t ≥ 2`. -/ +theorem log_mul_bigM_lt {t : ℝ} (ht : 2 ≤ t) : + log t * bigM t < 2 * (t / (t - 1) ^ 2) * bigM (t - 1) := by + refine sub_pos.1 <| pos_of_first_crossing + (f := fun t => 2 * (t / (t - 1) ^ 2) * bigM (t - 1) - log t * bigM t) (a₀ := 2) (a := 2) + ?_ ?_ ?_ ?_ t ht + · refine ContinuousOn.sub (ContinuousOn.mul (continuousOn_const.mul + (continuousOn_id.div ((continuousOn_id.sub continuousOn_const).pow 2) fun x hx => ?_)) + (continuous_bigM.comp (continuous_sub_right 1)).continuousOn) + ((continuousOn_log.mono fun x hx => ?_).mul continuous_bigM.continuousOn) + · have : 0 < x - 1 := by linarith [hx.out] + positivity + · simp only [mem_compl_iff, mem_singleton_iff]; linarith [hx.out] + · intro x hx + obtain rfl : x = 2 := le_antisymm hx.2 hx.1 + rw [show (2 : ℝ) - 1 = 1 by norm_num, bigM_of_le_two (by norm_num), bigM_two] + linarith [log_two_lt_d9] + · rw [show (2 : ℝ) - 1 = 1 by norm_num, bigM_of_le_two (by norm_num), bigM_two] + linarith [log_two_lt_d9] + intro t ht _ hpos + show 0 < 2 * (t / (t - 1) ^ 2) * bigM (t - 1) - log t * bigM t + rw [sub_pos] + have ht0 : 0 < t := by linarith + have hB := bigM_pos (t - 1) + have hlog0 : 0 ≤ log t := log_nonneg (by linarith) + rcases le_total t 3 with h3 | h3 + · -- explicit range `2 < t ≤ 3` + rw [bigM_of_le_two (show t - 1 ≤ 2 by linarith)] + have hl : log t < 1.3863 := (log_le_log ht0 (by linarith)).trans_lt log_four_lt + have hk : 3 / 4 ≤ t / (t - 1) ^ 2 := by + rw [le_div_iff₀ (by have : 0 < t - 1 := by linarith + positivity)] + nlinarith + have := bigM_le_three t + nlinarith + rcases le_total t 4 with h4 | h4 + · -- crude range `3 ≤ t ≤ 4`, from `𝔐(t) ≤ t/((t-1)² - 1/2) 𝔐(t-1)` + have hl : log t < 1.3863 := (log_le_log ht0 h4).trans_lt log_four_lt + have hR := bigM_le_ratio h3 + have hy : 4 ≤ (t - 1) ^ 2 := by nlinarith + have hr : 0 < (t - 1) ^ 2 - 1 / 2 := by linarith + have key : log t * (t / ((t - 1) ^ 2 - 1 / 2)) < 2 * (t / (t - 1) ^ 2) := by + rw [mul_div_assoc', mul_div_assoc', div_lt_div_iff₀ hr (by linarith)] + have : 1 < (2 - log t) * (t - 1) ^ 2 := by nlinarith + nlinarith [mul_lt_mul_of_pos_left this ht0] + calc log t * bigM t ≤ log t * (t / ((t - 1) ^ 2 - 1 / 2) * bigM (t - 1)) := + mul_le_mul_of_nonneg_left hR hlog0 + _ = log t * (t / ((t - 1) ^ 2 - 1 / 2)) * bigM (t - 1) := by ring + _ < 2 * (t / (t - 1) ^ 2) * bigM (t - 1) := mul_lt_mul_of_pos_right key hB + -- main range `t > 4` + set L₁ := log (t - 1) with hL₁ + set l := L₁ / 2 with hl + have hL₁1 : 1 < L₁ := by + rw [hL₁, lt_log_iff_exp_lt (by linarith)] + linarith [exp_one_lt_d9] + have hl0 : 0 < l := by linarith + -- `𝔐(x) ≤ 𝔐(t-1) exp(-l(x - (t-1)))` on `[t-1, t]` + have hanti : AntitoneOn (fun x => bigM x * exp (l * x)) (Icc (t - 1) t) := by + have hd : ∀ x, 3 < x → HasDerivAt (fun x => bigM x * exp (l * x)) + (-(x / (x - 1) ^ 2 * bigM (x - 1)) * exp (l * x) + bigM x * (exp (l * x) * l)) x := + fun x hx => (hasDerivAt_bigM hx).mul (((hasDerivAt_id x).const_mul l).exp.congr_deriv + (by simp)) + refine antitoneOn_of_deriv_nonpos (convex_Icc _ _) + (continuous_bigM.mul (continuous_const.mul continuous_id).rexp).continuousOn + (fun x hx => ?_) (fun x hx => ?_) <;> rw [interior_Icc] at hx + · exact (hd x (by linarith [hx.1])).differentiableAt.differentiableWithinAt + · rw [(hd x (by linarith [hx.1])).deriv] + have hfx := hpos x ⟨by linarith [hx.1], hx.2⟩ + have hlx : L₁ ≤ log x := log_le_log (by linarith) hx.1.le + have hMx := bigM_pos x + have : l * bigM x < x / (x - 1) ^ 2 * bigM (x - 1) := by nlinarith + have he := exp_pos (l * x) + nlinarith + have hbound : ∀ x ∈ Icc (t - 1) t, + (1 - 1 / (2 * x ^ 2)) * bigM x ≤ bigM (t - 1) * exp (-(l * (x - (t - 1)))) := by + intro x hx + have h := hanti ⟨le_rfl, by linarith⟩ hx hx.1 + simp only at h + have hw := weight_mem (x := x) (by linarith [hx.1]) + have hMx := bigM_pos x + have e : bigM (t - 1) * exp (-(l * (x - (t - 1)))) = + bigM (t - 1) * exp (l * (t - 1)) / exp (l * x) := by + rw [div_eq_mul_inv, ← exp_neg, mul_assoc, ← exp_add]; ring_nf + rw [e, le_div_iff₀ (exp_pos _)] + calc (1 - 1 / (2 * x ^ 2)) * bigM x * exp (l * x) ≤ 1 * bigM x * exp (l * x) := by + gcongr; exact hw.2 + _ ≤ _ := by rw [one_mul]; exact h + have hint : ((t - 1) ^ 2 - 1 / 2) * bigM t / t ≤ bigM (t - 1) * ((1 - exp (-l)) / l) := by + rw [bigM_integral_identity h3, ← integral_exp_neg_mul_unit (t - 1) hl0.ne', + sub_add_cancel, ← intervalIntegral.integral_const_mul] + refine intervalIntegral.integral_mono_on (by linarith) + ((continuousOn_weight_mul continuous_bigM (by linarith)).intervalIntegrable_of_Icc + (by linarith)) ((by fun_prop : Continuous fun x => + bigM (t - 1) * exp (-(l * (x - (t - 1))))).intervalIntegrable _ _) hbound + -- the numerical inequality, with `q = exp l = √(t-1)` + set q := exp l with hq + have hq2 : q ^ 2 = t - 1 := by + rw [hq, sq, ← exp_add, show l + l = L₁ by rw [hl]; ring, hL₁, exp_log (by linarith)] + have hq1 : 1 < q := one_lt_exp_iff.2 hl0 + have hel : exp (-l) = q⁻¹ := by rw [exp_neg] + have hLt : log t ≤ L₁ + 1 / (t - 1) := by + have := log_le_sub_one_of_pos (div_pos ht0 (by linarith : (0 : ℝ) < t - 1)) + rw [log_div (by linarith) (by linarith)] at this + have : t - 1 ≠ 0 := by linarith + have e : t / (t - 1) - 1 = 1 / (t - 1) := by field_simp; ring + linarith + rw [hel] at hint + have hr : 0 < (t - 1) ^ 2 - 1 / 2 := by nlinarith + have hMt : bigM t ≤ t / ((t - 1) ^ 2 - 1 / 2) * (bigM (t - 1) * ((1 - q⁻¹) / l)) := by + rw [div_mul_eq_mul_div, le_div_iff₀ hr] + rw [div_le_iff₀ ht0] at hint + linarith + have key := log_mul_ratio_lt ht0 hq1 hq2 hL₁1 hLt + calc log t * bigM t ≤ log t * (t / ((t - 1) ^ 2 - 1 / 2) * (bigM (t - 1) * ((1 - q⁻¹) / l))) := + mul_le_mul_of_nonneg_left hMt hlog0 + _ = log t * (t / ((t - 1) ^ 2 - 1 / 2) * ((1 - q⁻¹) / l)) * bigM (t - 1) := by ring + _ < 2 * (t / (t - 1) ^ 2) * bigM (t - 1) := mul_lt_mul_of_pos_right key hB + +/-- [I71, Lemma 10]: `𝔐(t) t log t / 𝔐(t-1) < 9/2` for `t ≥ 3` (so it is `O(1)`). -/ +theorem bigM_mul_log_div_lt {t : ℝ} (ht : 3 ≤ t) : + bigM t * t * log t / bigM (t - 1) < 9 / 2 := by + have h := log_mul_bigM_lt (t := t) (by linarith) + have hB := bigM_pos (t - 1) + have ht0 : 0 < t := by linarith + have hy : 0 < (t - 1) ^ 2 := by nlinarith + rw [div_lt_iff₀ hB] + have h' : log t * bigM t * t ≤ 2 * (t / (t - 1) ^ 2) * bigM (t - 1) * t := + mul_le_mul_of_nonneg_right h.le ht0.le + have hk : 2 * (t / (t - 1) ^ 2) * t ≤ 9 / 2 := by + rw [mul_div_assoc', div_mul_eq_mul_div, div_le_iff₀ hy]; nlinarith + nlinarith + +/-- Corollary to [I71, Lemma 10]: `G_{r+1}(t) (t-1)² log t / (G_r(t-1) t) < 4` for `t ≥ 2` +(and all `r`; [I71] states it for `t > (5 + (-1)^r)/2`). -/ +theorem majG_succ_mul_log_div_lt (r : ℕ) {t : ℝ} (ht : 2 ≤ t) : + majG (r + 1) t * (t - 1) ^ 2 * log t / (majG r (t - 1) * t) < 4 := by + have h := log_mul_bigM_lt ht + have ht0 : 0 < t := by linarith + have hy : 0 < (t - 1) ^ 2 := by nlinarith + have hlog : 0 ≤ log t := log_nonneg (by linarith) + have hG := majG_mem (r + 1) t + have hG' := majG_mem r (t - 1) + have hGpos := majG_pos r (t - 1) + rw [div_lt_iff₀ (mul_pos hGpos ht0)] + have h1 : majG (r + 1) t * (t - 1) ^ 2 * log t ≤ 2 * bigM t / 3 * (t - 1) ^ 2 * log t := + mul_le_mul_of_nonneg_right (mul_le_mul_of_nonneg_right hG.2 hy.le) hlog + have h2 : log t * bigM t * (t - 1) ^ 2 < 2 * t * bigM (t - 1) := by + have ht1 : t - 1 ≠ 0 := by linarith + have := mul_lt_mul_of_pos_right h hy + rwa [show 2 * (t / (t - 1) ^ 2) * bigM (t - 1) * (t - 1) ^ 2 = 2 * t * bigM (t - 1) by + field_simp] at this + nlinarith + +/-! ### Lemma 9 (lower bound) -/ + +/-- The comparison function `exp(-(s log s + s log log s + 2 s))` for [I71, Lemma 9]. -/ +noncomputable def lemma9Fun (s : ℝ) : ℝ := exp (-(s * log s + s * log (log s) + 2 * s)) + +theorem continuousOn_lemma9Fun : ContinuousOn lemma9Fun (Ici 3) := by + unfold lemma9Fun + have hlog : ContinuousOn log (Ici 3) := continuousOn_log.mono fun x hx => by + simp only [mem_compl_iff, mem_singleton_iff]; linarith [hx.out] + have hloglog : ContinuousOn (fun x => log (log x)) (Ici 3) := + ContinuousOn.log hlog fun x hx => (log_pos (by linarith [hx.out])).ne' + exact ((((continuousOn_id.mul hlog).add (continuousOn_id.mul hloglog)).add + (continuousOn_const.mul continuousOn_id)).neg).rexp + +theorem one_le_log_of_three_le {x : ℝ} (hx : 3 ≤ x) : 1 ≤ log x := by + rw [le_log_iff_exp_le (by linarith)] + linarith [exp_one_lt_d9] + +theorem lemma9Fun_le_one {x : ℝ} (hx : 3 ≤ x) : lemma9Fun x ≤ 1 := by + unfold lemma9Fun + rw [exp_le_one_iff, neg_nonpos] + have h1 := log_nonneg (one_le_log_of_three_le hx) + have h2 := log_nonneg (show 1 ≤ x by linarith) + have : 0 ≤ x := by linarith + positivity + +/-- Convexity estimate: `φ(s) - φ(x) ≥ λ (s - x)` for `3 ≤ s - 1 ≤ x ≤ s`, where +`φ(s) = s log s + s log log s + 2s` and `λ = log(s-1) + log log(s-1) + 3`. -/ +theorem lemma9_phi_sub {s x : ℝ} (hs : 4 ≤ s) (hx : s - 1 ≤ x) (hxs : x ≤ s) : + (log (s - 1) + log (log (s - 1)) + 3) * (s - x) ≤ + (s * log s + s * log (log s) + 2 * s) - (x * log x + x * log (log x) + 2 * x) := by + have hx0 : 0 < x := by linarith + have hs0 : 0 < s := by linarith + -- `s log s - x log x ≥ (s - x)(1 + log x)` + have h1 : (s - x) * (1 + log x) ≤ s * log s - x * log x := by + have := log_le_sub_one_of_pos (div_pos hx0 hs0) + rw [log_div hx0.ne' hs0.ne'] at this + have e : s * (x / s - 1) = x - s := by field_simp + nlinarith + have h2 : log (s - 1) ≤ log x := log_le_log (by linarith) hx + have hl1 : 1 ≤ log (s - 1) := one_le_log_of_three_le (by linarith) + have h3 : log (log (s - 1)) ≤ log (log x) := log_le_log (by linarith) h2 + have h4 : log (log x) ≤ log (log s) := log_le_log (by linarith) (log_le_log hx0 hxs) + have h5 : 0 ≤ log (log (s - 1)) := log_nonneg hl1 + have hsx : 0 ≤ s - x := by linarith + nlinarith [mul_le_mul_of_nonneg_left h2 hsx, mul_le_mul_of_nonneg_left h3 hsx, + mul_le_mul_of_nonneg_left h4 hs0.le] + +/-- On `[s-1, s]`, convexity of the exponent gives an exponential lower bound for the +weighted comparison function in (3.12). -/ +theorem lemma9Fun_weighted_exp_le {s x : ℝ} (hs : 4 ≤ s) (hx : s - 1 ≤ x) (hxs : x ≤ s) : + let l := log (s - 1) + log (log (s - 1)) + 3 + (1 - 1 / (2 * (s - 1) ^ 2)) * (lemma9Fun s * exp l) * + exp (-(l * (x - (s - 1)))) ≤ (1 - 1 / (2 * x ^ 2)) * lemma9Fun x := by + dsimp only + set l := log (s - 1) + log (log (s - 1)) + 3 + have hweight : 1 - 1 / (2 * (s - 1) ^ 2) ≤ 1 - 1 / (2 * x ^ 2) := by + have hrecip : 1 / (2 * x ^ 2) ≤ 1 / (2 * (s - 1) ^ 2) := + one_div_le_one_div_of_le (by nlinarith only [hs]) (by nlinarith only [hs, hx]) + linarith only [hrecip] + have hexp : lemma9Fun s * exp l * exp (-(l * (x - (s - 1)))) ≤ lemma9Fun x := by + unfold lemma9Fun + rw [← exp_add, ← exp_add, exp_le_exp] + have hconvex := lemma9_phi_sub hs hx hxs + dsimp only [l] + linarith only [hconvex] + rw [mul_assoc] + exact mul_le_mul hweight hexp (by unfold lemma9Fun; positivity) + (weight_mem (by linarith only [hs, hx])).1.le + +/-- The exponential lower bound, integrated and multiplied by the factor in (3.12), +has coefficient at least one. The key estimate is `l (s-1)² ≤ s (exp l - 1)`. -/ +theorem lemma9_integral_factor_ge_one {s : ℝ} (hs : 4 ≤ s) : + let l := log (s - 1) + log (log (s - 1)) + 3 + 1 ≤ (1 - 1 / (2 * (s - 1) ^ 2)) * (exp l * ((1 - exp (-l)) / l)) * + (s / ((s - 1) ^ 2 - 1 / 2)) := by + dsimp only + set L := log (s - 1) with hL + set l := L + log L + 3 with hl + set w₀ := 1 - 1 / (2 * (s - 1) ^ 2) with hw₀ + have hL1 : 1 ≤ L := one_le_log_of_three_le (by linarith) + have hlogL : log L ≤ L - 1 := log_le_sub_one_of_pos (by linarith) + have hlogL0 : 0 ≤ log L := log_nonneg hL1 + have hl0 : 0 < l := by linarith only [hL1, hlogL0, hl] + have hr : 0 < (s - 1) ^ 2 - 1 / 2 := by nlinarith only [hs] + -- The numerical inequality `l (s-1)² ≤ s (exp l - 1)`. + have hel : exp l = (s - 1) * L * exp 3 := by + rw [hl, exp_add, exp_add, hL, exp_log (by linarith), exp_log (by linarith)] + have he3 : 20 ≤ exp 3 := by + have : exp 3 = exp 1 ^ 3 := by rw [← exp_nat_mul]; norm_num + rw [this] + have h := pow_le_pow_left₀ (by norm_num) exp_one_gt_d9.le 3 + norm_num at h + linarith + have hexp_gain : l * (s - 1) ^ 2 ≤ s * (exp l - 1) := by + rw [hel] + have hy : 3 ≤ s - 1 := by linarith + have h0 : 0 ≤ (s - 1) * L := by positivity + have : 20 * ((s - 1) * L) ≤ (s - 1) * L * exp 3 := by + nlinarith [mul_le_mul_of_nonneg_left he3 h0] + nlinarith [mul_le_mul_of_nonneg_left hL1 (by nlinarith : (0 : ℝ) ≤ (s - 1) ^ 2)] + have hexp_cancel : exp l * (1 - exp (-l)) = exp l - 1 := by + rw [mul_sub, mul_one, ← exp_add]; simp + have hweight_cancel : w₀ / ((s - 1) ^ 2 - 1 / 2) = 1 / (s - 1) ^ 2 := by + have : s - 1 ≠ 0 := by linarith + rw [hw₀, div_eq_div_iff hr.ne' (by positivity)] + field_simp + have hfactor : w₀ * (exp l * ((1 - exp (-l)) / l)) * (s / ((s - 1) ^ 2 - 1 / 2)) = + s * (exp l - 1) / (l * (s - 1) ^ 2) := by + rw [← hexp_cancel] + calc w₀ * (exp l * ((1 - exp (-l)) / l)) * (s / ((s - 1) ^ 2 - 1 / 2)) + = w₀ / ((s - 1) ^ 2 - 1 / 2) * (s * (exp l * (1 - exp (-l))) / l) := by ring + _ = _ := by rw [hweight_cancel]; field_simp + rw [hfactor, le_div_iff₀ (mul_pos hl0 (by nlinarith)), one_mul] + exact hexp_gain + +/-- `lemma9Fun` is a subsolution of (3.12) for `s ≥ 4`. -/ +theorem lemma9Fun_le_integral {s : ℝ} (hs : 4 ≤ s) : + lemma9Fun s ≤ s / ((s - 1) ^ 2 - 1 / 2) * + ∫ x in (s - 1)..s, (1 - 1 / (2 * x ^ 2)) * lemma9Fun x := by + set l := log (s - 1) + log (log (s - 1)) + 3 + set w₀ := 1 - 1 / (2 * (s - 1) ^ 2) + have hL1 : 1 ≤ log (s - 1) := one_le_log_of_three_le (by linarith only [hs]) + have hl0 : 0 < l := by + dsimp only [l] + linarith only [hL1, log_nonneg hL1] + have hr : 0 < (s - 1) ^ 2 - 1 / 2 := by nlinarith only [hs] + -- Integrate the pointwise exponential lower bound over `[s-1, s]`. + have hint : w₀ * (lemma9Fun s * exp l) * ((1 - exp (-l)) / l) ≤ + ∫ x in (s - 1)..s, (1 - 1 / (2 * x ^ 2)) * lemma9Fun x := by + have hexp := integral_exp_neg_mul_unit (s - 1) hl0.ne' + rw [sub_add_cancel] at hexp + rw [← hexp, ← intervalIntegral.integral_const_mul] + refine intervalIntegral.integral_mono_on (by linarith only) + ((by fun_prop : Continuous fun x => + w₀ * (lemma9Fun s * exp l) * exp (-(l * (x - (s - 1))))).intervalIntegrable _ _) + ?_ (fun x hx => lemma9Fun_weighted_exp_le hs hx.1 hx.2) + refine ContinuousOn.intervalIntegrable_of_Icc (by linarith only) ?_ + refine ContinuousOn.mul (continuousOn_const.sub (continuousOn_const.div + (continuousOn_const.mul (continuousOn_id.pow 2)) fun x hx => ?_)) + (continuousOn_lemma9Fun.mono fun x hx => by + simp only [mem_Ici]; linarith only [hs, hx.1]) + have : 0 < x := by linarith only [hs, hx.1] + positivity + -- The integrated exponential has a large enough coefficient to recover `lemma9Fun s`. + have hF : 0 < lemma9Fun s := exp_pos _ + calc + lemma9Fun s ≤ lemma9Fun s * (w₀ * (exp l * ((1 - exp (-l)) / l)) * + (s / ((s - 1) ^ 2 - 1 / 2))) := + le_mul_of_one_le_right hF.le (lemma9_integral_factor_ge_one hs) + _ = s / ((s - 1) ^ 2 - 1 / 2) * + (w₀ * (lemma9Fun s * exp l) * ((1 - exp (-l)) / l)) := by ring + _ ≤ _ := mul_le_mul_of_nonneg_left hint (div_nonneg (by linarith only [hs]) hr.le) + +/-- Comparison of `𝔐` with the subsolution `lemma9Fun`: `𝔐(s) > (𝔐(4)/2) lemma9Fun(s)` for +`s ≥ 3`. -/ +theorem bigM_gt_lemma9Fun {s : ℝ} (hs : 3 ≤ s) : bigM 4 / 2 * lemma9Fun s < bigM s := by + set κ := bigM 4 / 2 with hκ + have hM4 := bigM_pos 4 + have hinit : ∀ x ∈ Icc (3 : ℝ) 4, 0 < bigM x - κ * lemma9Fun x := by + intro x hx + have h1 := lemma9Fun_le_one hx.1 + have h2 : bigM 4 ≤ bigM x := bigM_antitone hx.2 + have h3 : κ * lemma9Fun x ≤ κ := by + have : 0 ≤ κ := by positivity + nlinarith + linarith + rcases le_total s 4 with h4 | h4 + · exact sub_pos.1 (hinit s ⟨hs, h4⟩) + refine sub_pos.1 <| pos_of_first_crossing (f := fun s => bigM s - κ * lemma9Fun s) (a₀ := 3) + (a := 4) (continuous_bigM.continuousOn.sub (continuousOn_const.mul + (continuousOn_lemma9Fun.mono fun x hx => by simp only [mem_Ici] at hx ⊢; linarith))) + (fun x hx => (hinit x hx).le) (hinit 4 ⟨by norm_num, le_rfl⟩) ?_ s h4 + intro t ht hall hpos + show 0 < bigM t - κ * lemma9Fun t + have hpos' : ∀ x ∈ Ioo (t - 1) t, 0 < bigM x - κ * lemma9Fun x := by + intro x hx + rcases le_total x 4 with h | h + · exact hinit x ⟨by linarith [hx.1], h⟩ + · exact hpos x ⟨h, hx.2⟩ + have ht0 : 0 < t := by linarith + have hr : 0 < (t - 1) ^ 2 - 1 / 2 := by nlinarith + have hcw : ContinuousOn (fun x => (1 - 1 / (2 * x ^ 2)) * (κ * lemma9Fun x)) (Icc (t - 1) t) := by + refine ContinuousOn.mul (continuousOn_const.sub (continuousOn_const.div + (continuousOn_const.mul (continuousOn_id.pow 2)) fun x hx => ?_)) + (continuousOn_const.mul (continuousOn_lemma9Fun.mono fun x hx => by + simp only [mem_Ici]; linarith [hx.1])) + have : 0 < x := by linarith [hx.1] + positivity + have hlt : ∫ x in (t - 1)..t, (1 - 1 / (2 * x ^ 2)) * (κ * lemma9Fun x) < + ∫ x in (t - 1)..t, (1 - 1 / (2 * x ^ 2)) * bigM x := by + refine intervalIntegral.integral_lt_integral_of_continuousOn_of_le_of_exists_lt + (by linarith) hcw (continuousOn_weight_mul continuous_bigM (by linarith)) ?_ ?_ + · intro x hx + have hw := (weight_mem (x := x) (by linarith [hx.1])).1 + rcases hx.2.lt_or_eq with h | rfl + · exact mul_le_mul_of_nonneg_left (sub_pos.1 (hpos' x ⟨hx.1, h⟩)).le hw.le + · exact mul_le_mul_of_nonneg_left (sub_nonneg.1 (hall x ⟨by linarith, le_rfl⟩)) hw.le + · refine ⟨t - 1 / 2, ⟨by linarith, by linarith⟩, ?_⟩ + exact mul_lt_mul_of_pos_left (sub_pos.1 (hpos' _ ⟨by linarith, by linarith⟩)) + (weight_mem (by linarith)).1 + rw [← bigM_integral_identity (by linarith), intervalIntegral.integral_congr + (g := fun x => κ * ((1 - 1 / (2 * x ^ 2)) * lemma9Fun x)) (fun x _ => by simp only; ring), + intervalIntegral.integral_const_mul] at hlt + have hsub := lemma9Fun_le_integral ht.le + have hκ0 : 0 < κ := by positivity + have h1 : κ * lemma9Fun t ≤ + t / ((t - 1) ^ 2 - 1 / 2) * (κ * ∫ x in (t - 1)..t, (1 - 1 / (2 * x ^ 2)) * lemma9Fun x) := by + calc κ * lemma9Fun t ≤ κ * (t / ((t - 1) ^ 2 - 1 / 2) * + ∫ x in (t - 1)..t, (1 - 1 / (2 * x ^ 2)) * lemma9Fun x) := + mul_le_mul_of_nonneg_left hsub hκ0.le + _ = _ := by ring + have h2 := mul_lt_mul_of_pos_left hlt (div_pos ht0 hr) + have e : t / ((t - 1) ^ 2 - 1 / 2) * (((t - 1) ^ 2 - 1 / 2) * bigM t / t) = bigM t := by + generalize (t - 1) ^ 2 - 1 / 2 = r at hr ⊢ + field_simp + rw [e] at h2 + linarith + +/-- [I71, Lemma 9], lower bound for `𝔐`: there is `κ > 0` with +`𝔐(s) ≥ κ exp(-(s log s + s log log s + 2 s))` for `s ≥ 3`. -/ +theorem bigM_ge_exp : ∃ κ > 0, ∀ s ≥ 3, + κ * exp (-(s * log s + s * log (log s) + 2 * s)) ≤ bigM s := + ⟨bigM 4 / 2, by linarith [bigM_pos 4], fun _ hs => (bigM_gt_lemma9Fun hs).le⟩ + +/-- [I71, Lemma 9], lower bound: there is `c` with +`G_r(s) ≥ exp(-s log s - s log log s - c s)` for all `r` and `s ≥ 3`. -/ +theorem majG_ge_exp : ∃ c : ℝ, ∀ (r : ℕ) (s : ℝ), 3 ≤ s → + exp (-(s * log s) - s * log (log s) - c * s) ≤ majG r s := by + obtain ⟨κ, hκ, hM⟩ := bigM_ge_exp + set K := |log (κ / 3)| / 3 with hK + have hK0 : 0 ≤ K := by positivity + refine ⟨2 + K, fun r s hs => ?_⟩ + have hG := (majG_mem r s).1 + have h1 := hM s hs + have hexp : exp (-(K * s)) ≤ κ / 3 := by + calc exp (-(K * s)) ≤ exp (log (κ / 3)) := by + rw [exp_le_exp] + have : -log (κ / 3) ≤ |log (κ / 3)| := neg_le_abs _ + nlinarith + _ = κ / 3 := exp_log (by positivity) + have e : exp (-(s * log s) - s * log (log s) - (2 + K) * s) = + exp (-(K * s)) * exp (-(s * log s + s * log (log s) + 2 * s)) := by + rw [← exp_add]; ring_nf + rw [e] + calc exp (-(K * s)) * exp (-(s * log s + s * log (log s) + 2 * s)) + ≤ κ / 3 * exp (-(s * log s + s * log (log s) + 2 * s)) := + mul_le_mul_of_nonneg_right hexp (exp_pos _).le + _ ≤ bigM s / 3 := by linarith + _ ≤ majG r s := hG + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/SieveMajorants/Majorants.lean b/LeanPool/IwaniecLinearSieve/SieveMajorants/Majorants.lean new file mode 100644 index 000000000..51a497398 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveMajorants/Majorants.lean @@ -0,0 +1,217 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.SieveMajorants.Defs +import LeanPool.IwaniecLinearSieve.SieveMajorants.Properties +import Mathlib.Algebra.Order.Star.Real +import Mathlib.NumberTheory.Chebyshev + +/-! +# The functions `𝔣`, `𝔉`, `G_r` ([I71, §3]) + +`𝔣 = (𝔐 + 𝔚)/2`, `𝔉 = (𝔐 - 𝔚)/2`; `G_r = 𝔣` for `r` even and `𝔉` for `r` odd. +We prove (3.13), (3.14), the Corollary to Lemma 6, and positivity, continuity and monotonicity. + +With our extension of `𝔐`, `𝔚` to `ℝ`, `𝔉 = 1` on `(-∞, 3]` (as in [I71], where `𝔉 = 1` on +`[1, 3]`), and `𝔣 = 2` on `(-∞, 2]`. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory + +namespace IwaniecLinearSieve + +/-- Iwaniec's `𝔣 = (𝔐 + 𝔚)/2`. -/ +noncomputable def majf (s : ℝ) : ℝ := (bigM s + bigW s) / 2 + +/-- Iwaniec's `𝔉 = (𝔐 - 𝔚)/2`. -/ +noncomputable def majF (s : ℝ) : ℝ := (bigM s - bigW s) / 2 + +/-- Iwaniec's `G_r`: `𝔣` for `r` even, `𝔉` for `r` odd. -/ +noncomputable def majG (r : ℕ) (s : ℝ) : ℝ := if Even r then majf s else majF s + +theorem majG_of_even {r : ℕ} (hr : Even r) : majG r = majf := by + ext s; simp [majG, hr] + +theorem majG_of_odd {r : ℕ} (hr : Odd r) : majG r = majF := by + ext s; simp [majG, Nat.not_even_iff_odd.2 hr] + +theorem continuous_majf : Continuous majf := + (continuous_bigM.add continuous_bigW).div_const 2 + +theorem continuous_majF : Continuous majF := + (continuous_bigM.sub continuous_bigW).div_const 2 + +theorem continuous_majG (r : ℕ) : Continuous (majG r) := by + rcases Nat.even_or_odd r with hr | hr + · rw [majG_of_even hr]; exact continuous_majf + · rw [majG_of_odd hr]; exact continuous_majF + +/-- `𝔉 = 1` for `s ≤ 3`. -/ +theorem majF_of_le_three {s : ℝ} (hs : s ≤ 3) : majF s = 1 := by + simp only [majF, bigM_of_le_three hs, bigW_of_le_three hs]; ring + +/-- `𝔣(s) = 1 + 1/(s-1) - log(s-1)` for `2 ≤ s ≤ 3`. -/ +theorem majf_eq {s : ℝ} (hs : 2 ≤ s) (hs' : s ≤ 3) : + majf s = 1 + 1 / (s - 1) - log (s - 1) := by + simp only [majf, bigM_eq hs hs', bigW_eq hs hs']; ring + +theorem majf_of_le_two {s : ℝ} (hs : s ≤ 2) : majf s = 2 := by + simp only [majf, bigM_of_le_two hs, bigW_of_le_two hs]; norm_num + +/-- Corollary to [I71, Lemma 6]: `𝔐/3 ≤ 𝔣 ≤ 2𝔐/3`. -/ +theorem majf_mem (s : ℝ) : bigM s / 3 ≤ majf s ∧ majf s ≤ 2 * bigM s / 3 := by + have := abs_le.1 (abs_bigW_le s) + unfold majf; constructor <;> linarith [this.1, this.2] + +/-- Corollary to [I71, Lemma 6]: `𝔐/3 ≤ 𝔉 ≤ 2𝔐/3`. -/ +theorem majF_mem (s : ℝ) : bigM s / 3 ≤ majF s ∧ majF s ≤ 2 * bigM s / 3 := by + have := abs_le.1 (abs_bigW_le s) + unfold majF; constructor <;> linarith [this.1, this.2] + +/-- Corollary to [I71, Lemma 6] for `G_r`. -/ +theorem majG_mem (r : ℕ) (s : ℝ) : bigM s / 3 ≤ majG r s ∧ majG r s ≤ 2 * bigM s / 3 := by + unfold majG; split_ifs + · exact majf_mem s + · exact majF_mem s + +theorem majG_le_two (r : ℕ) (s : ℝ) : majG r s ≤ 2 := by + linarith [(majG_mem r s).2, bigM_le_three s] + +theorem majG_pos (r : ℕ) (s : ℝ) : 0 < majG r s := + lt_of_lt_of_le (by linarith [bigM_pos s]) (majG_mem r s).1 + +theorem majf_pos (s : ℝ) : 0 < majf s := by + simpa [majG_of_even (⟨0, rfl⟩ : Even 0)] using majG_pos 0 s + +theorem majF_pos (s : ℝ) : 0 < majF s := by + simpa [majG_of_odd odd_one] using majG_pos 1 s + +/-! ### Derivatives -/ +theorem hasDerivAt_majF {s : ℝ} (hs : 3 < s) : + HasDerivAt majF (-(s / (s - 1) ^ 2 * majf (s - 1))) s := by + refine ((hasDerivAt_bigM hs).sub (hasDerivAt_bigW hs)).div_const 2 |>.congr_deriv ?_ + simp only [majf]; ring + +theorem hasDerivWithinAt_majf_Ici {s : ℝ} (hs : 3 ≤ s) : + HasDerivWithinAt majf (-(s / (s - 1) ^ 2 * majF (s - 1))) (Ici s) s := by + refine ((hasDerivWithinAt_bigM_Ici hs).add (hasDerivWithinAt_bigW_Ici hs)).div_const 2 + |>.congr_deriv ?_ + simp only [majF]; ring + +/-- `𝔣' (s) = -s/(s-1)² 𝔉(s-1)` for `s > 2`. -/ +theorem hasDerivAt_majf {s : ℝ} (hs : 2 < s) : + HasDerivAt majf (-(s / (s - 1) ^ 2 * majF (s - 1))) s := by + have hexp : ∀ x, 2 < x → x ≤ 4 → HasDerivAt (fun x => 1 + (1 / (x - 1) - log (x - 1))) + (-(x / (x - 1) ^ 2 * majF (x - 1))) x := by + intro x hx hx4 + rw [majF_of_le_three (by linarith), mul_one] + exact (hasDerivAt_initForm (by linarith)).const_add 1 + have heq : ∀ x, 2 ≤ x → x ≤ 3 → majf x = 1 + (1 / (x - 1) - log (x - 1)) := by + intro x hx hx3; rw [majf_eq hx hx3]; ring + rcases lt_trichotomy s 3 with h3 | rfl | h3 + · refine (hexp s hs (by linarith)).congr_of_eventuallyEq ?_ + filter_upwards [Ioo_mem_nhds hs h3] with x hx + exact heq x hx.1.le hx.2.le + · have hl : HasDerivWithinAt majf (-(3 / (3 - 1) ^ 2 * majF (3 - 1))) (Iic 3) 3 := by + refine (hexp 3 (by norm_num) (by norm_num)).hasDerivWithinAt.congr_of_eventuallyEq ?_ + (heq 3 (by norm_num) le_rfl) + filter_upwards [inter_mem_nhdsWithin (Iic 3) (Ioi_mem_nhds (show (2 : ℝ) < 3 by norm_num)), + self_mem_nhdsWithin] with x hx _ + exact heq x hx.2.out.le hx.1 + have := hl.union (hasDerivWithinAt_majf_Ici le_rfl) + rwa [Iic_union_Ici, hasDerivWithinAt_univ] at this + · refine ((hasDerivAt_bigM h3).add (hasDerivAt_bigW h3)).div_const 2 |>.congr_deriv ?_ + simp only [majF]; ring + +/-- The derivative of `G_{r+1}` is `-G_r(t-1) t/(t-1)²`, for `t > 3`, and for `t > 2` if `r` is +odd; i.e. for `t > (5 + (-1)^r)/2` as in [I71, proof of Lemma 11]. -/ +theorem hasDerivAt_majG_succ (r : ℕ) {t : ℝ} (ht : (5 + (-1) ^ r) / 2 < t) : + HasDerivAt (majG (r + 1)) (-(majG r (t - 1) * t / (t - 1) ^ 2)) t := by + rcases Nat.even_or_odd r with hr | hr + · rw [majG_of_odd hr.add_one, majG_of_even hr] + rw [hr.neg_one_pow] at ht + exact (hasDerivAt_majF (by linarith)).congr_deriv (by ring) + · rw [majG_of_even hr.add_one, majG_of_odd hr] + rw [hr.neg_one_pow] at ht + exact (hasDerivAt_majf (by linarith)).congr_deriv (by ring) + +/-! ### Monotonicity -/ +theorem majF_antitone : Antitone majF := by + refine antitone_of_antitoneOn_Iic_Ici (a := 3) ?_ ?_ + · intro s hs t ht _ + rw [majF_of_le_three hs, majF_of_le_three ht] + · refine antitoneOn_of_deriv_nonpos (convex_Ici 3) continuous_majF.continuousOn + (fun x hx => ?_) (fun x hx => ?_) <;> rw [interior_Ici] at hx + · exact (hasDerivAt_majF hx).differentiableAt.differentiableWithinAt + · rw [(hasDerivAt_majF hx).deriv] + have := mul_pos (kernel_pos (by linarith [hx.out] : (1 : ℝ) < x)) (majf_pos (x - 1)) + linarith + +theorem majf_antitone : Antitone majf := by + refine antitone_of_antitoneOn_Iic_Ici (a := 2) ?_ ?_ + · intro s hs t ht _ + rw [majf_of_le_two hs, majf_of_le_two ht] + · refine antitoneOn_of_deriv_nonpos (convex_Ici 2) continuous_majf.continuousOn + (fun x hx => ?_) (fun x hx => ?_) <;> rw [interior_Ici] at hx + · exact (hasDerivAt_majf hx).differentiableAt.differentiableWithinAt + · rw [(hasDerivAt_majf hx).deriv] + have := mul_pos (kernel_pos (by linarith [hx.out] : (1 : ℝ) < x)) (majF_pos (x - 1)) + linarith + +/-- [I71, Remark after Lemma 6]: `G_r` is decreasing. -/ +theorem majG_antitone (r : ℕ) : Antitone (majG r) := by + rcases Nat.even_or_odd r with hr | hr + · rw [majG_of_even hr]; exact majf_antitone + · rw [majG_of_odd hr]; exact majF_antitone + +/-! ### (3.13), (3.14) -/ +theorem tendsto_majG_atTop (r : ℕ) : Tendsto (majG r) atTop (𝓝 0) := by + have h : Tendsto (fun s => 2 * bigM s / 3) atTop (𝓝 0) := by + simpa using (tendsto_bigM_atTop.const_mul 2).div_const 3 + exact tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds h + (fun s => (majG_pos r s).le) fun s => (majG_mem r s).2 + +theorem tendsto_majf_atTop : Tendsto majf atTop (𝓝 0) := by + simpa [majG_of_even (⟨0, rfl⟩ : Even 0)] using tendsto_majG_atTop 0 + +theorem tendsto_majF_atTop : Tendsto majF atTop (𝓝 0) := by + simpa [majG_of_odd odd_one] using tendsto_majG_atTop 1 + +/-- [I71, (3.13)]: `𝔉(s) = ∫_s^∞ 𝔣(t-1) t/(t-1)² dt` for `s ≥ 3`. -/ +theorem majF_eq_integral {s : ℝ} (hs : 3 ≤ s) : + majF s = ∫ t in Ioi s, majf (t - 1) * t / (t - 1) ^ 2 := by + have := integral_Ioi_of_hasDerivAt_of_nonneg (g := fun t => -majF t) (l := 0) + (g' := fun t => majf (t - 1) * t / (t - 1) ^ 2) + continuous_majF.neg.continuousWithinAt + (fun t ht => (hasDerivAt_majF (hs.trans_lt ht)).neg.congr_deriv (by ring)) + (fun t ht => by + have h1 : 0 < t - 1 := by linarith [ht.out] + have := majf_pos (t - 1) + have : 0 < t := by linarith + positivity) + (by simpa using tendsto_majF_atTop.neg) + rw [this]; ring + +/-- [I71, (3.14)]: `𝔣(s) = ∫_s^∞ 𝔉(t-1) t/(t-1)² dt` for `s ≥ 2`. -/ +theorem majf_eq_integral {s : ℝ} (hs : 2 ≤ s) : + majf s = ∫ t in Ioi s, majF (t - 1) * t / (t - 1) ^ 2 := by + have := integral_Ioi_of_hasDerivAt_of_nonneg (g := fun t => -majf t) (l := 0) + (g' := fun t => majF (t - 1) * t / (t - 1) ^ 2) + continuous_majf.neg.continuousWithinAt + (fun t ht => (hasDerivAt_majf (hs.trans_lt ht)).neg.congr_deriv (by ring)) + (fun t ht => by + have h1 : 0 < t - 1 := by linarith [ht.out] + have := majF_pos (t - 1) + have : 0 < t := by linarith + positivity) + (by simpa using tendsto_majf_atTop.neg) + rw [this]; ring + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/SieveMajorants/Properties.lean b/LeanPool/IwaniecLinearSieve/SieveMajorants/Properties.lean new file mode 100644 index 000000000..d58a76b33 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/SieveMajorants/Properties.lean @@ -0,0 +1,275 @@ +/- +Copyright (c) 2026 Jason Davies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jason Davies +-/ + +module + +public import LeanPool.IwaniecLinearSieve.SieveMajorants.Defs +import LeanPool.IwaniecLinearSieve.SieveMajorants.Delay +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Algebra.Ring.IsFormallyReal +import Mathlib.Analysis.Complex.ExponentialBounds +import Mathlib.NumberTheory.Chebyshev + +/-! +# Basic properties of `𝔐`, `𝔚` ([I71, §3]) + +`0 < 𝔐`, `𝔐` antitone, `𝔐 = O(e^{-s})`, and [I71, Lemma 6] `|𝔚| ≤ 𝔐/3`. +-/ + +@[expose] public section + +open Real Set Filter Topology MeasureTheory + +namespace IwaniecLinearSieve + +/-- On `(-∞, 3]`, `-1/2 ≤ 𝔚 ≤ 1`. -/ +theorem initW_mem {s : ℝ} (hs : s ≤ 3) : -(1 / 2) ≤ initW s ∧ initW s ≤ 1 := by + unfold initW + set y := max s 2 - 1 with hy + have hy1 : 1 ≤ y := by have := le_max_right s 2; linarith + have hy2 : y ≤ 2 := by have : max s 2 ≤ 3 := max_le hs (by norm_num); linarith + have hlog0 : 0 ≤ log y := log_nonneg hy1 + have hlog1 : log y ≤ y - 1 := log_le_sub_one_of_pos (by linarith) + have h1 : 1 / y ≤ 1 := by rw [div_le_one (by linarith)]; exact hy1 + have h2 : 1 / 2 ≤ 1 / y := one_div_le_one_div_of_le (by linarith) hy2 + constructor <;> linarith + +theorem bigM_pos_of_le_three {s : ℝ} (hs : s ≤ 3) : 0 < bigM s := by + rw [bigM_of_le_three hs]; linarith [(initW_mem hs).1] + +theorem abs_bigW_le_of_le_three {s : ℝ} (hs : s ≤ 3) : |bigW s| ≤ bigM s / 3 := by + rw [bigW_of_le_three hs, bigM_of_le_three hs, abs_le] + obtain ⟨h1, h2⟩ := initW_mem hs + constructor <;> linarith + +/-- The weight `1 - 1/(2x²)` of (3.12) is in `(0, 1]` for `x ≥ 1`. -/ +theorem weight_mem {x : ℝ} (hx : 1 ≤ x) : 0 < 1 - 1 / (2 * x ^ 2) ∧ 1 - 1 / (2 * x ^ 2) ≤ 1 := by + have : 1 / (2 * x ^ 2) ≤ 1 / 2 := by + apply one_div_le_one_div_of_le (by norm_num) + nlinarith + have : 0 < 1 / (2 * x ^ 2) := by positivity + constructor <;> linarith + +theorem continuousOn_weight_mul {g : ℝ → ℝ} (hg : Continuous g) {a b : ℝ} (ha : 0 < a) : + ContinuousOn (fun x => (1 - 1 / (2 * x ^ 2)) * g x) (Icc a b) := by + refine ContinuousOn.mul ?_ hg.continuousOn + refine continuousOn_const.sub (continuousOn_const.div (continuousOn_const.mul + (continuousOn_id.pow 2)) fun x hx => ?_) + have : 0 < x := lt_of_lt_of_le ha hx.1 + positivity + +/-- `0 < 𝔐` [I71, after (3.12)]. -/ +theorem bigM_pos (s : ℝ) : 0 < bigM s := by + rcases le_total s 3 with hs | hs + · exact bigM_pos_of_le_three hs + refine pos_of_first_crossing (f := bigM) (a₀ := 3) (a := 3) continuous_bigM.continuousOn + (fun x hx => (bigM_pos_of_le_three hx.2).le) (bigM_pos_of_le_three le_rfl) ?_ s hs + intro t ht _ hpos + have hpos' : ∀ x, x < t → 0 < bigM x := fun x hx => by + rcases le_total x 3 with h | h + · exact bigM_pos_of_le_three h + · exact hpos x ⟨h, hx⟩ + have hI : 0 < ∫ x in (t - 1)..t, (1 - 1 / (2 * x ^ 2)) * bigM x := by + refine intervalIntegral.intervalIntegral_pos_of_pos_on ?_ (fun x hx => ?_) (by linarith) + · exact (continuousOn_weight_mul continuous_bigM (by linarith)).intervalIntegrable_of_Icc + (by linarith) + · exact mul_pos (weight_mem (by linarith [hx.1])).1 (hpos' x hx.2) + rw [← bigM_integral_identity ht.le] at hI + have hr : 0 < (t - 1) ^ 2 - 1 / 2 := by nlinarith + have ht0 : 0 < t := by linarith + by_contra h + push Not at h + have : ((t - 1) ^ 2 - 1 / 2) * bigM t / t ≤ 0 := + div_nonpos_of_nonpos_of_nonneg (mul_nonpos_of_nonneg_of_nonpos hr.le h) ht0.le + linarith + +/-- An antitone function on `(-∞, a]` and on `[a, ∞)` is antitone. -/ +theorem antitone_of_antitoneOn_Iic_Ici {f : ℝ → ℝ} {a : ℝ} (h₁ : AntitoneOn f (Iic a)) + (h₂ : AntitoneOn f (Ici a)) : Antitone f := by + intro s t hst + rcases le_total t a with hta | hta + · exact h₁ (hst.trans hta) hta hst + rcases le_total a s with has | has + · exact h₂ has hta hst + exact (h₂ (le_refl a) hta hta).trans (h₁ has (le_refl a) has) + +theorem antitoneOn_initW : AntitoneOn initW (Iic 3) := by + intro s _ t _ hst + unfold initW + have h1 : 1 ≤ max s 2 - 1 := by have := le_max_right s 2; linarith + have h2 : max s 2 ≤ max t 2 := max_le_max hst le_rfl + have h3 : log (max s 2 - 1) ≤ log (max t 2 - 1) := log_le_log (by linarith) (by linarith) + have h4 : 1 / (max t 2 - 1) ≤ 1 / (max s 2 - 1) := + one_div_le_one_div_of_le (by linarith) (by linarith) + linarith + +theorem continuousOn_kernel_mul {g : ℝ → ℝ} (hg : Continuous g) : + ContinuousOn (fun x => x / (x - 1) ^ 2 * g (x - 1)) (Ici 2) := by + refine ContinuousOn.mul (continuousOn_id.div ((continuousOn_id.sub continuousOn_const).pow 2) + fun x hx => ?_) (hg.comp (continuous_sub_right 1)).continuousOn + have : (2 : ℝ) ≤ x := hx + have : 0 < x - 1 := by linarith + positivity + +theorem intervalIntegrable_kernel_mul {g : ℝ → ℝ} (hg : Continuous g) {a b : ℝ} (ha : 2 ≤ a) + (hb : 2 ≤ b) : IntervalIntegrable (fun x => x / (x - 1) ^ 2 * g (x - 1)) volume a b := by + refine ((continuousOn_kernel_mul hg).mono fun x hx => ?_).intervalIntegrable + rcases le_total a b with h | h + · rw [uIcc_of_le h] at hx; exact ha.trans hx.1 + · rw [uIcc_of_ge h] at hx; exact hb.trans hx.1 + +theorem kernel_pos {x : ℝ} (hx : 1 < x) : 0 < x / (x - 1) ^ 2 := by + have : 0 < x - 1 := by linarith + positivity + +/-- `𝔐` is antitone (on all of `ℝ`). -/ +theorem bigM_antitone : Antitone bigM := by + refine antitone_of_antitoneOn_Iic_Ici (a := 3) ?_ ?_ + · intro s hs t ht hst + rw [bigM_of_le_three hs, bigM_of_le_three ht] + linarith [antitoneOn_initW hs ht hst] + · intro s hs t ht hst + have hs' : (3 : ℝ) ≤ s := hs + have ht' : (3 : ℝ) ≤ t := ht + rw [bigM_eq_integral hs', bigM_eq_integral ht', + ← intervalIntegral.integral_add_adjacent_intervals + (intervalIntegrable_kernel_mul continuous_bigM (by norm_num) (b := s) (by linarith)) + (intervalIntegrable_kernel_mul continuous_bigM (by linarith) (by linarith))] + have : 0 ≤ ∫ x in s..t, x / (x - 1) ^ 2 * bigM (x - 1) := + intervalIntegral.integral_nonneg hst fun x hx => + (mul_pos (kernel_pos (by linarith [hx.1])) (bigM_pos _)).le + linarith + +theorem bigM_le_three (s : ℝ) : bigM s ≤ 3 := by + rcases le_total s 2 with h | h + · rw [bigM_of_le_two h] + · exact (bigM_antitone h).trans_eq bigM_two + +/-- From (3.12) and monotonicity: `𝔐(s) ≤ s/((s-1)² - 1/2) 𝔐(s-1)` for `s ≥ 3`. -/ +theorem bigM_le_ratio {s : ℝ} (hs : 3 ≤ s) : + bigM s ≤ s / ((s - 1) ^ 2 - 1 / 2) * bigM (s - 1) := by + have hr : 0 < (s - 1) ^ 2 - 1 / 2 := by nlinarith + have hs0 : 0 < s := by linarith + have h := bigM_integral_identity hs + have hle : ∫ x in (s - 1)..s, (1 - 1 / (2 * x ^ 2)) * bigM x ≤ + ∫ _ in (s - 1)..s, bigM (s - 1) := by + refine intervalIntegral.integral_mono_on (by linarith) + ((continuousOn_weight_mul continuous_bigM (by linarith)).intervalIntegrable_of_Icc + (by linarith)) intervalIntegrable_const fun x hx => ?_ + obtain ⟨h0, h1⟩ := weight_mem (x := x) (by linarith [hx.1]) + calc (1 - 1 / (2 * x ^ 2)) * bigM x ≤ 1 * bigM x := + mul_le_mul_of_nonneg_right h1 (bigM_pos x).le + _ ≤ bigM (s - 1) := by rw [one_mul]; exact bigM_antitone hx.1 + rw [intervalIntegral.integral_const, ← h] at hle + simp only [sub_sub_cancel, smul_eq_mul, one_mul] at hle + rw [div_mul_eq_mul_div, le_div_iff₀ hr] + rw [div_le_iff₀ hs0] at hle + linarith + +/-- `𝔐(s) = O(e^{-s})`. -/ +theorem bigM_le_exp (s : ℝ) : bigM s ≤ 3 * exp 5 * exp (-s) := by + have base : ∀ s : ℝ, s ≤ 5 → bigM s ≤ 3 * exp 5 * exp (-s) := by + intro s hs + have : 1 ≤ exp 5 * exp (-s) := by + rw [← exp_add]; exact one_le_exp (by linarith) + nlinarith [bigM_le_three s] + have key : ∀ n : ℕ, ∀ s : ℝ, s ≤ n → bigM s ≤ 3 * exp 5 * exp (-s) := by + intro n + induction n with + | zero => intro s hs; exact base s (by simp at hs; linarith) + | succ n ih => + intro s hs + rcases le_total s 5 with h5 | h5 + · exact base s h5 + have h1 := bigM_le_ratio (s := s) (by linarith) + have h2 := ih (s - 1) (by push_cast at hs; linarith) + have hr : 0 < (s - 1) ^ 2 - 1 / 2 := by nlinarith + have hc : s / ((s - 1) ^ 2 - 1 / 2) ≤ exp (-1) := by + rw [div_le_iff₀ hr, exp_neg, ← div_eq_inv_mul, le_div_iff₀ (exp_pos 1)] + nlinarith [exp_one_lt_d9] + calc bigM s ≤ s / ((s - 1) ^ 2 - 1 / 2) * bigM (s - 1) := h1 + _ ≤ exp (-1) * (3 * exp 5 * exp (-(s - 1))) := + mul_le_mul hc h2 (bigM_pos _).le (exp_pos _).le + _ = 3 * exp 5 * exp (-s) := by + rw [show -s = -1 + -(s - 1) by ring, exp_add]; ring + exact key ⌈s⌉₊ s (Nat.le_ceil s) + +theorem tendsto_bigM_atTop : Tendsto bigM atTop (𝓝 0) := by + have h : Tendsto (fun s => 3 * exp 5 * exp (-s)) atTop (𝓝 0) := by + simpa using tendsto_exp_neg_atTop_nhds_zero.const_mul (3 * exp 5) + exact tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds h + (fun s => (bigM_pos s).le) bigM_le_exp + +theorem lemma6_aux {r x M : ℝ} (hr : r ≠ 0) (hx : x ≠ 0) : + 1 / (3 * r) * ((1 - 1 / (2 * x ^ 2)) * M) - M / 3 / x ^ 2 = + M * (x ^ 2 - 1 / 2 - r) / (3 * r * x ^ 2) := by + field_simp + +/-- [I71, Lemma 6], strict form for `s ≥ 3`: `|𝔚(s)| < 𝔐(s)/3`. -/ +theorem abs_bigW_lt {s : ℝ} (hs : 3 ≤ s) : |bigW s| < bigM s / 3 := by + refine sub_pos.1 <| pos_of_first_crossing (f := fun s => bigM s / 3 - |bigW s|) (a₀ := 2) + (a := 3) ((continuous_bigM.div_const 3).sub continuous_bigW.abs).continuousOn + (fun x hx => sub_nonneg.2 (abs_bigW_le_of_le_three hx.2)) ?_ ?_ s hs + · rw [bigM_three, bigW_three, abs_of_neg (by linarith [log_two_gt_d9])] + linarith [log_two_lt_d9] + intro t ht hall _ + have ht0 : 0 < t := by linarith + have hr : 0 < (t - 1) ^ 2 - 1 / 2 := by nlinarith + have hx0 : ∀ x ∈ Icc (t - 1) t, x ^ 2 ≠ 0 := fun x hx => + pow_ne_zero 2 (by linarith [hx.1]) + have hcW : ContinuousOn (fun x => |bigW x / x ^ 2|) (Icc (t - 1) t) := + (continuous_bigW.continuousOn.div (continuousOn_id.pow 2) hx0).abs + have hcM : ContinuousOn (fun x => bigM x / 3 / x ^ 2) (Icc (t - 1) t) := + (continuous_bigM.div_const 3).continuousOn.div (continuousOn_id.pow 2) hx0 + have hcM' : ContinuousOn (fun x => 1 / (3 * ((t - 1) ^ 2 - 1 / 2)) * + ((1 - 1 / (2 * x ^ 2)) * bigM x)) (Icc (t - 1) t) := + continuousOn_const.mul (continuousOn_weight_mul continuous_bigM (by linarith)) + have h1 : |bigW t| ≤ t * ∫ x in (t - 1)..t, |bigW x / x ^ 2| := by + rw [bigW_eq_neg_mul_integral ht.le, abs_mul, abs_neg, abs_of_pos ht0] + exact mul_le_mul_of_nonneg_left (intervalIntegral.abs_integral_le_integral_abs + (by linarith)) ht0.le + have h2 : ∫ x in (t - 1)..t, |bigW x / x ^ 2| ≤ ∫ x in (t - 1)..t, bigM x / 3 / x ^ 2 := by + refine intervalIntegral.integral_mono_on (by linarith) (hcW.intervalIntegrable_of_Icc + (by linarith)) (hcM.intervalIntegrable_of_Icc (by linarith)) fun x hx => ?_ + have hx2 : 0 < x ^ 2 := pow_pos (by linarith [hx.1]) 2 + rw [abs_div, abs_of_pos hx2] + have := hall x ⟨by linarith [hx.1], hx.2⟩ + exact div_le_div_of_nonneg_right (by linarith) hx2.le + have hpt : ∀ x, t - 1 < x → 0 < 1 / (3 * ((t - 1) ^ 2 - 1 / 2)) * + ((1 - 1 / (2 * x ^ 2)) * bigM x) - bigM x / 3 / x ^ 2 := by + intro x hx + have hx' : 0 < x := by linarith + rw [lemma6_aux hr.ne' hx'.ne'] + have : 0 < x ^ 2 - 1 / 2 - ((t - 1) ^ 2 - 1 / 2) := by nlinarith + have := bigM_pos x + positivity + have h3 : ∫ x in (t - 1)..t, bigM x / 3 / x ^ 2 < ∫ x in (t - 1)..t, + 1 / (3 * ((t - 1) ^ 2 - 1 / 2)) * ((1 - 1 / (2 * x ^ 2)) * bigM x) := by + refine intervalIntegral.integral_lt_integral_of_continuousOn_of_le_of_exists_lt + (by linarith) hcM hcM' (fun x hx => (sub_pos.1 (hpt x hx.1)).le) + ⟨t, ⟨by linarith, le_rfl⟩, sub_pos.1 (hpt t (by linarith))⟩ + rw [intervalIntegral.integral_const_mul, ← bigM_integral_identity ht.le] at h3 + have h4 : t * (1 / (3 * ((t - 1) ^ 2 - 1 / 2)) * (((t - 1) ^ 2 - 1 / 2) * bigM t / t)) = + bigM t / 3 := by + generalize (t - 1) ^ 2 - 1 / 2 = r at hr ⊢ + field_simp + have := mul_lt_mul_of_pos_left h3 ht0 + rw [h4] at this + have := mul_le_mul_of_nonneg_left h2 ht0.le + linarith + +/-- [I71, Lemma 6]: `|𝔚(s)| ≤ 𝔐(s)/3` (for all `s`; [I71] states it for `s ≥ 2`). -/ +theorem abs_bigW_le (s : ℝ) : |bigW s| ≤ bigM s / 3 := by + rcases le_total s 3 with hs | hs + · exact abs_bigW_le_of_le_three hs + · exact (abs_bigW_lt hs).le + +/-- `𝔚(s) = O(e^{-s})`. -/ +theorem abs_bigW_le_exp (s : ℝ) : |bigW s| ≤ exp 5 * exp (-s) := by + have := bigM_le_exp s + linarith [abs_bigW_le s] + +end IwaniecLinearSieve diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/Auxiliary.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/Auxiliary.lean new file mode 100644 index 000000000..96b87282c --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/Auxiliary.lean @@ -0,0 +1,86 @@ +/- +Copyright (c) 2024 Michael Stoll. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Michael Stoll +-/ +module + +public import Mathlib.Analysis.InnerProductSpace.Basic +public import Mathlib.Analysis.Calculus.Deriv.Basic +import Mathlib.Analysis.Complex.RealDeriv + +/-! +Adapted from PrimeNumberTheoremAnd revision +`127b50e33f6033e2147921167a117af96d9ba4ea`, via Jason Davies's +Iwaniec linear sieve snapshot `c8d01549d2ae640b36ec198c1f0f6495f1b036cf` +(both Apache-2.0). Blueprint-only machinery is omitted. + +### Auxiliary lemmas +-/ + +@[expose] public section + + +namespace Complex +-- see https://leanprover.zulipchat.com/#narrow/stream/217875-Is-there-code-for-X.3F/topic/Differentiability.20of.20the.20natural.20map.20.E2.84.9D.20.E2.86.92.20.E2.84.82/near/418095234 + +lemma hasDerivAt_ofReal (x : ℝ) : HasDerivAt ofReal 1 x := + HasDerivAt.ofReal_comp <| hasDerivAt_id x + +lemma deriv_ofReal (x : ℝ) : deriv ofReal x = 1 := + (hasDerivAt_ofReal x).deriv + +lemma differentiableAt_ofReal (x : ℝ) : DifferentiableAt ℝ ofReal x := + (hasDerivAt_ofReal x).differentiableAt + +end Complex + +lemma DifferentiableAt.comp_ofReal {e : ℂ → ℂ} {z : ℝ} (hf : DifferentiableAt ℂ e z) : + DifferentiableAt ℝ (fun x : ℝ ↦ e x) z := + hf.hasDerivAt.comp_ofReal.differentiableAt + +lemma deriv.comp_ofReal {e : ℂ → ℂ} {z : ℝ} (hf : DifferentiableAt ℂ e z) : + deriv (fun x : ℝ ↦ e x) z = deriv e z := + hf.hasDerivAt.comp_ofReal.deriv + +lemma Differentiable.comp_ofReal {e : ℂ → ℂ} (h : Differentiable ℂ e) : + Differentiable ℝ (fun x : ℝ ↦ e x) := + fun _ ↦ h.differentiableAt.comp_ofReal + +lemma DifferentiableAt.ofReal_comp {z : ℝ} {f : ℝ → ℝ} (hf : DifferentiableAt ℝ f z) : + DifferentiableAt ℝ (fun (y : ℝ) ↦ (f y : ℂ)) z := + hf.hasDerivAt.ofReal_comp.differentiableAt + +lemma Differentiable.ofReal_comp {f : ℝ → ℝ} (hf : Differentiable ℝ f) : + Differentiable ℝ (fun (y : ℝ) ↦ (f y : ℂ)) := + fun _ ↦ hf.differentiableAt.ofReal_comp + +open Complex ContinuousLinearMap in +lemma HasDerivAt.of_hasDerivAt_ofReal_comp {z : ℝ} {f : ℝ → ℝ} {u : ℂ} + (hf : HasDerivAt (fun y ↦ (f y : ℂ)) u z) : + ∃ u' : ℝ, u = u' ∧ HasDerivAt f u' z := by + lift u to ℝ + · have H := (imCLM.hasFDerivAt.comp z hf.hasFDerivAt).hasDerivAt.deriv + simp only [Function.comp_def, imCLM_apply, ofReal_im, deriv_const] at H + rwa [eq_comm, comp_apply, imCLM_apply, toSpanSingleton_apply_one] at H + refine ⟨u, rfl, ?_⟩ + convert! (reCLM.hasFDerivAt.comp z hf.hasFDerivAt).hasDerivAt + rw [comp_apply, toSpanSingleton_apply_one, reCLM_apply, ofReal_re] + +lemma DifferentiableAt.ofReal_comp_iff {z : ℝ} {f : ℝ → ℝ} : + DifferentiableAt ℝ (fun (y : ℝ) ↦ (f y : ℂ)) z ↔ DifferentiableAt ℝ f z := by + refine ⟨fun H ↦ ?_, ofReal_comp⟩ + obtain ⟨u, _, hu₂⟩ := H.hasDerivAt.of_hasDerivAt_ofReal_comp + exact HasDerivAt.differentiableAt hu₂ + +lemma Differentiable.ofReal_comp_iff {f : ℝ → ℝ} : + Differentiable ℝ (fun (y : ℝ) ↦ (f y : ℂ)) ↔ Differentiable ℝ f := + forall_congr' fun _ ↦ DifferentiableAt.ofReal_comp_iff + +lemma deriv.ofReal_comp {z : ℝ} {f : ℝ → ℝ} : + deriv (fun (y : ℝ) ↦ (f y : ℂ)) z = deriv f z := by + by_cases hf : DifferentiableAt ℝ f z + · exact hf.hasDerivAt.ofReal_comp.deriv + · have hf' := mt DifferentiableAt.ofReal_comp_iff.mp hf + rw [deriv_zero_of_not_differentiableAt hf, deriv_zero_of_not_differentiableAt hf', + Complex.ofReal_zero] diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/EulerMaclaurin.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/EulerMaclaurin.lean new file mode 100644 index 000000000..7441c65f2 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/EulerMaclaurin.lean @@ -0,0 +1,108 @@ +/- +Copyright (c) 2026 PrimeNumberTheoremAnd contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: PrimeNumberTheoremAnd contributors +-/ + +module + +public import Mathlib.Analysis.Calculus.Deriv.Basic +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic +import Mathlib.NumberTheory.AbelSummation + +/-! We prove the 1st order Euler-Maclaurin formula by specialising Abel summation and manipulating +integrals. -/ + +/-! +Adapted from PrimeNumberTheoremAnd revision +`127b50e33f6033e2147921167a117af96d9ba4ea`, via Jason Davies's +Iwaniec linear sieve snapshot `c8d01549d2ae640b36ec198c1f0f6495f1b036cf` +(both Apache-2.0). Blueprint-only machinery is omitted. + +Supporting lemmas for Iwaniec's sieve and its prime-number-theorem input. +-/ + +@[expose] public section + +namespace IwaniecLinearSievePNT + + +open Finset Interval MeasureTheory + + +variable {𝕜 : Type*} [RCLike 𝕜] {f : ℝ → 𝕜} {a b : ℝ} + +/-- The 1st Bernoulli function. -/ +noncomputable def B1 (x : ℝ) : ℝ := x - ⌊x⌋₊ - 1 / 2 + +@[fun_prop] +lemma aestronglyMeasurable_B1 : AEStronglyMeasurable B1 := by + unfold B1 + fun_prop + +lemma abs_B1_le_half {x : ℝ} (hx : 0 ≤ x) : |B1 x| ≤ 1 / 2 := by + unfold B1 + refine abs_le.mpr ⟨?_, ?_⟩ + · grind [Nat.floor_le hx] + · grind [Nat.lt_succ_floor x] + +lemma integral_deriv_mul_add_const (c : 𝕜) (hab : a ≤ b) (h_int : IntervalIntegrable (deriv f) + volume a b) + (hf_diff : ∀ t ∈ Set.Icc a b, DifferentiableAt ℝ f t) : + ∫ t in a..b, (t + c) * deriv f t = (b + c) * f b - (a + c) * f a - ∫ t in a..b, f t := by + rw [← Set.uIcc_of_le hab] at hf_diff + have : ∀ t ∈ [[a, b]], HasDerivAt (fun (t : ℝ) ↦ t + c) 1 t := by + intro t ht + simp only [hasDerivAt_add_const_iff] + convert! ContinuousLinearMap.hasDerivAt (RCLike.ofRealCLM (K := 𝕜)) using 1 + simp + replace hf_diff := fun t ht ↦ (hf_diff t ht).hasDerivAt + rw [intervalIntegral.integral_mul_deriv_eq_deriv_mul this hf_diff (by simp) h_int] + simp + +lemma intervalIntegrable_deriv_mul_B1 (ha : 0 ≤ a) (hab : a ≤ b) (h_cont : ContinuousOn (deriv f) + [[a, b]]) : + IntervalIntegrable (fun t ↦ deriv f t * B1 t) volume a b := by + refine IntervalIntegrable.continuousOn_mul ?_ h_cont + rw [intervalIntegrable_iff'] + apply MeasureTheory.Measure.integrableOn_of_bounded (by simp) (by fun_prop) (M := 1 / 2) + filter_upwards [self_mem_ae_restrict (by measurability)] with x hx + rw [Set.uIcc_of_le hab, Set.mem_Icc] at hx + norm_cast + exact abs_B1_le_half (by linarith) + +lemma integral_deriv_mul_floor_add_one (ha : 0 ≤ a) (hab : a ≤ b) + (hf_diff : ∀ t ∈ Set.Icc a b, DifferentiableAt ℝ f t) (h_cont : ContinuousOn (deriv f) [[a, + b]]) : + ∫ t in a..b, deriv f t * (⌊t⌋₊ + 1) = (b + 1 / 2) * f b - (a + 1 / 2) * f a - (∫ t in a..b, f + t) - ∫ t in a..b, deriv f t * B1 t := by + calc + _ = ∫ t in a..b, (deriv f t * (t + 1 / 2) -deriv f t * B1 t) := by + congr + ext + simp only [B1] + push_cast + ring + _ = (∫ t in a..b, deriv f t * (t + 1 / 2)) - ∫ t in a..b, deriv f t * B1 t := by + exact intervalIntegral.integral_sub (ContinuousOn.intervalIntegrable (by fun_prop)) + (intervalIntegrable_deriv_mul_B1 ha hab h_cont) + _ = _ := by + conv => lhs; arg 1; arg 1; ext; rw [mul_comm] + rw [integral_deriv_mul_add_const _ hab h_cont.intervalIntegrable hf_diff] + +theorem sum_eq_integral_add_integral_deriv (ha : 0 ≤ a) (hab : a ≤ b) + (hf_diff : ∀ t ∈ Set.Icc a b, DifferentiableAt ℝ f t) + (h_cont : ContinuousOn (deriv f) [[a, b]]) : + ∑ k ∈ Ioc ⌊a⌋₊ ⌊b⌋₊, f k = + f a * B1 a - f b * B1 b + (∫ t in a..b, f t) + ∫ t in a..b, deriv f t * B1 t := by + have := sum_mul_eq_sub_sub_integral_mul (fun _ ↦ 1) ha hab hf_diff (Set.uIcc_of_le hab ▸ + h_cont).integrableOn_Icc + simp only [mul_one, sum_const, Nat.card_Icc, tsub_zero, nsmul_eq_mul, Nat.cast_add, + Nat.cast_one] at this + rw [this, ← intervalIntegral.integral_of_le hab] + rw [integral_deriv_mul_floor_add_one ha hab hf_diff h_cont] + unfold B1 + push_cast + ring + +end IwaniecLinearSievePNT diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MediumPNT.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MediumPNT.lean new file mode 100644 index 000000000..330fe578d --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MediumPNT.lean @@ -0,0 +1,3881 @@ +/- +Copyright (c) 2026 PrimeNumberTheoremAnd contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: PrimeNumberTheoremAnd contributors +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.MellinCalculus +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.ZetaBounds +public import Mathlib.NumberTheory.Chebyshev +import LeanPool.MooreBound.PrimeNumberTheoremAnd.SmoothExistence +import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.ZetaConj +import Mathlib.Algebra.Order.Interval.Set.Group +import Mathlib.Analysis.MellinInversion +import Mathlib.Analysis.Real.Pi.Bounds +import Mathlib.NumberTheory.Harmonic.ZetaAsymp + +/-! +Adapted from PrimeNumberTheoremAnd revision +`127b50e33f6033e2147921167a117af96d9ba4ea`, via Jason Davies's +Iwaniec linear sieve snapshot `c8d01549d2ae640b36ec198c1f0f6495f1b036cf` +(both Apache-2.0). Blueprint-only machinery is omitted. + +Supporting lemmas for Iwaniec's sieve and its prime-number-theorem input. +-/ + +@[expose] public section + +namespace IwaniecLinearSievePNT + + +open MooreBound + +open Set Function Filter Complex Real + +open ArithmeticFunction (vonMangoldt) +open scoped Chebyshev + +/- +The approach here is completely standard. We follow the use of +$\mathcal{M}(\widetilde{1_{\epsilon}})$ as in [Kontorovich 2015]. +-/ + +local notation (name := mellintransform2) "𝓜" => mellin + +local notation "Λ" => vonMangoldt + +local notation "ζ" => riemannZeta + +local notation "ζ'" => deriv ζ + + +theorem _root_.Chebyshev.psi_eq_sum_range (x : ℝ) : + ψ x = ∑ n ∈ Finset.range (⌊x⌋₊ + 1), Λ n := by + rw [Chebyshev.psi_eq_sum_Icc, Nat.range_succ_eq_Icc_zero] + + +/- +The (second) Chebyshev Psi function is defined as + $$ + \psi(x) := \sum_{n \le x} \Lambda(n), + $$ + where $\Lambda(n)$ is the von Mangoldt function. +-/ + +/-- The Chebyshev psi function used in the contour estimates. -/ +noncomputable abbrev ChebyshevPsi (x : ℝ) : ℝ := + Chebyshev.psi x + +/- +It has already been established that zeta doesn't vanish on the 1 line, and has a pole at $s=1$ +of order 1. +We also have the following. +-/ + +/- +We have that, for $\Re(s)>1$, + $$-\frac{\zeta'(s)}{\zeta(s)} = \sum_{n=1}^\infty \frac{\Lambda(n)}{n^s}. $$ +Already in Mathlib. +-/ +theorem LogDerivativeDirichlet (s : ℂ) (hs : 1 < s.re) : + - deriv riemannZeta s / riemannZeta s = ∑' n, Λ n / (n : ℂ) ^ s := by + rw [← ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div hs] + dsimp [LSeries, LSeries.term] + nth_rewrite 2 [Summable.tsum_eq_add_tsum_ite (b := 0) ?_] + · simp + · have := ArithmeticFunction.LSeriesSummable_vonMangoldt hs + dsimp [LSeriesSummable] at this + convert! this; rename ℕ => n + by_cases h : n = 0 <;> simp [LSeries.term, h] + +/- + +The main object of study is the following inverse Mellin-type transform, which will turn out to +be a smoothed Chebyshev function. +-/ + +/-- The Mellin integrand for the smoothed Chebyshev function. -/ +noncomputable abbrev SmoothedChebyshevIntegrand + (SmoothingF : ℝ → ℝ) (ε : ℝ) (X : ℝ) : ℂ → ℂ := + fun s ↦ (- deriv riemannZeta s) / riemannZeta s * + 𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) s * (X : ℂ) ^ s + +/- +Fix $\epsilon>0$, and a bumpfunction supported in $[1/2,2]$. Then we define the smoothed + Chebyshev function $\psi_{\epsilon}$ from $\mathbb{R}_{>0}$ to $\mathbb{C}$ by + $$\psi_{\epsilon}(X) = \frac{1}{2\pi i}\int_{(\sigma)}\frac{-\zeta'(s)}{\zeta(s)} + \mathcal{M}(\widetilde{1_{\epsilon}})(s) + X^{s}ds,$$ + where we'll take $\sigma = 1 + 1 / \log X$. +-/ +/-- The smoothed Chebyshev function, expressed by Mellin inversion. -/ +noncomputable def SmoothedChebyshev (SmoothingF : ℝ → ℝ) (ε : ℝ) (X : ℝ) : ℂ := + VerticalIntegral' (SmoothedChebyshevIntegrand SmoothingF ε X) ((1 : ℝ) + (Real.log X)⁻¹) + +open ComplexConjugate + +lemma smoothedChebyshevIntegrand_conj + {SmoothingF : ℝ → ℝ} {ε X : ℝ} (Xpos : 0 < X) (s : ℂ) : + SmoothedChebyshevIntegrand SmoothingF ε X (conj s) = + conj (SmoothedChebyshevIntegrand SmoothingF ε X s) := by + unfold SmoothedChebyshevIntegrand + simp only [map_mul, map_div₀, map_neg] + congr + · exact deriv_riemannZeta_conj s + · exact riemannZeta_conj s + · unfold mellin + rw[← integral_conj] + apply MeasureTheory.setIntegral_congr_fun measurableSet_Ioi + intro x xpos + simp only [smul_eq_mul, map_mul, Complex.conj_ofReal] + congr + nth_rw 1 [← map_one conj] + rw[← map_sub, Complex.cpow_conj, Complex.conj_ofReal] + rw[Complex.arg_ofReal_of_nonneg xpos.le] + exact Real.pi_ne_zero.symm + · rw[Complex.cpow_conj, Complex.conj_ofReal] + rw[Complex.arg_ofReal_of_nonneg Xpos.le] + exact Real.pi_ne_zero.symm + +open MeasureTheory + +/- +Fix a nonnegative, continuously differentiable function $F$ on $\mathbb{R}$ with support in + $[1/2,2]$, and total mass one, $\int_{(0,\infty)} F(x)/x dx = 1$. Then for any $\epsilon>0$, + and $\sigma\in (1, 2]$, the function + $$ + x \mapsto\mathcal{M}(\widetilde{1_{\epsilon}})(\sigma + ix) + $$ + is integrable on $\mathbb{R}$. +By Lemma \ref{MellinOfSmooth1b} the integrand is $O(1/t^2)$ as $t\rightarrow \infty$ and hence + the function is integrable. +-/ +lemma SmoothedChebyshevDirichlet_aux_integrable {SmoothingF : ℝ → ℝ} + (diffSmoothingF : ContDiff ℝ 1 SmoothingF) + (SmoothingFpos : ∀ x > 0, 0 ≤ SmoothingF x) + (suppSmoothingF : support SmoothingF ⊆ Icc (1 / 2) 2) + (mass_one : ∫ (x : ℝ) in Ioi 0, SmoothingF x / x = 1) + {ε : ℝ} (εpos : 0 < ε) (ε_lt_one : ε < 1) {σ : ℝ} (σ_gt : 1 < σ) (σ_le : σ ≤ 2) : + MeasureTheory.Integrable + (fun (y : ℝ) ↦ 𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (σ + y * I)) := by + obtain ⟨c, cpos, hc⟩ := MellinOfSmooth1b diffSmoothingF suppSmoothingF + apply Integrable.mono' (g := (fun t ↦ c / ε * 1 / (1 + t ^ 2))) + · apply Integrable.const_mul integrable_inv_one_add_sq + · apply Continuous.aestronglyMeasurable + apply continuous_iff_continuousAt.mpr + intro x + have := Smooth1MellinDifferentiable diffSmoothingF suppSmoothingF ⟨εpos, ε_lt_one⟩ + SmoothingFpos mass_one (s := σ + x * I) (by simp only [add_re, ofReal_re, mul_re, I_re, + mul_zero, ofReal_im, I_im, mul_one, sub_self, add_zero]; linarith) |>.continuousAt + fun_prop + · filter_upwards [] with t + calc + _≤ c / ε * 1 / (σ^2 + t^2) := by + convert hc (σ / 2) (by linarith) (σ + t * I) (by simp only [add_re, ofReal_re, mul_re, + I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, add_zero, half_le_self_iff]; linarith) + (by simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, add_zero]; linarith) ε εpos ε_lt_one using 1 + simp only [mul_one, Complex.sq_norm, normSq_apply, add_re, ofReal_re, mul_re, I_re, + mul_zero, ofReal_im, I_im, sub_self, add_zero, add_im, mul_im, zero_add, mul_inv_rev] + ring_nf + _ ≤ _ := by + gcongr; nlinarith + +-- TODO: add to mathlib +attribute [fun_prop] Continuous.const_cpow + +/- +Fix a nonnegative, continuously differentiable function $F$ on $\mathbb{R}$ with support in + $[1/2,2]$, and total mass one, $\int_{(0,\infty)} F(x)/x dx = 1$. Then for any $\epsilon>0$ and + $\sigma\in(1,2]$, the function + $x \mapsto \sum_{n=1}^\infty \frac{\Lambda(n)}{n^{\sigma+it}} + \mathcal{M}(\widetilde{1_{\epsilon}})(\sigma+it) x^{\sigma+it}$ is equal to + $\sum_{n=1}^\infty \int_{(0,\infty)} \frac{\Lambda(n)}{n^{\sigma+it}} + \mathcal{M}(\widetilde{1_{\epsilon}})(\sigma+it) x^{\sigma+it}$. +Interchange of summation and integration. +-/ +lemma SmoothedChebyshevDirichlet_aux_tsum_integral {SmoothingF : ℝ → ℝ} + (diffSmoothingF : ContDiff ℝ 1 SmoothingF) + (SmoothingFpos : ∀ x > 0, 0 ≤ SmoothingF x) + (suppSmoothingF : support SmoothingF ⊆ Icc (1 / 2) 2) + (mass_one : ∫ (x : ℝ) in Ioi 0, SmoothingF x / x = 1) {X : ℝ} + (X_pos : 0 < X) {ε : ℝ} (εpos : 0 < ε) + (ε_lt_one : ε < 1) {σ : ℝ} (σ_gt : 1 < σ) (σ_le : σ ≤ 2) : + ∫ (t : ℝ), + ∑' (n : ℕ), (ArithmeticFunction.vonMangoldt n) / (n : ℂ) ^ (σ + t * I) * + 𝓜 (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (σ + t * I) * (X : ℂ) ^ (σ + t * I) = + ∑' (n : ℕ), + ∫ (t : ℝ), (ArithmeticFunction.vonMangoldt n) / (n : ℂ) ^ (σ + ↑t * I) * + 𝓜 (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (σ + ↑t * I) * (X : ℂ) ^ (σ + t * I) := by + have cont_mellin_smooth : Continuous fun (a : ℝ) ↦ + 𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (σ + ↑a * I) := by + rw [← continuousOn_univ] + refine ContinuousOn.comp' ?_ ?_ ?_ (t := {z : ℂ | 0 < z.re }) + · refine continuousOn_of_forall_continuousAt ?_ + intro z hz + exact (Smooth1MellinDifferentiable diffSmoothingF suppSmoothingF ⟨εpos, ε_lt_one⟩ + SmoothingFpos mass_one hz).continuousAt + · fun_prop + · simp only [mapsTo_univ_iff, mem_ofPred_eq, add_re, ofReal_re, mul_re, I_re, mul_zero, + ofReal_im, I_im, mul_one, sub_self, add_zero, forall_const]; linarith + have abs_two : ∀ a : ℝ, ∀ i : ℕ, ‖(i : ℂ) ^ ((σ : ℂ) + ↑a * I)‖₊ = i ^ σ := by + intro a i + simp_rw [← norm_toNNReal] + rw [norm_natCast_cpow_of_re_ne_zero _ (by simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, + ofReal_im, I_im, mul_one, sub_self, add_zero, ne_eq]; linarith)] + simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + add_zero, Real.toNNReal_of_nonneg <| rpow_nonneg (y := σ) (x := i) (by linarith)] + norm_cast + rw [MeasureTheory.integral_tsum] + · have x_neq_zero : X ≠ 0 := by linarith + intro i + by_cases i_eq_zero : i = 0 + · simpa [i_eq_zero] using aestronglyMeasurable_const + · apply Continuous.aestronglyMeasurable + fun_prop (disch := simp[i_eq_zero, x_neq_zero]) + · rw [← lt_top_iff_ne_top] + simp_rw [enorm_mul, enorm_eq_nnnorm, nnnorm_div, ← norm_toNNReal, + Complex.norm_cpow_eq_rpow_re_of_pos X_pos, norm_toNNReal, abs_two] + simp only [nnnorm_real, add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, add_zero] + simp_rw [MeasureTheory.lintegral_mul_const' (r := ↑(X ^ σ).toNNReal) (hr := by simp), + ENNReal.tsum_mul_right] + apply ENNReal.mul_lt_top ?_ ENNReal.coe_lt_top + conv => + arg 1 + arg 1 + intro i + rw [MeasureTheory.lintegral_const_mul' (hr := by simp)] + rw [ENNReal.tsum_mul_right] + apply ENNReal.mul_lt_top + · rw [lt_top_iff_ne_top, ENNReal.tsum_coe_ne_top_iff_summable_coe] + push_cast + convert (ArithmeticFunction.LSeriesSummable_vonMangoldt (s := σ) + (by simp only [ofReal_re]; linarith)).norm + rw [LSeries.term_def] + split_ifs with h <;> simp[h] + · simp_rw [← enorm_eq_nnnorm] + rw [← MeasureTheory.hasFiniteIntegral_iff_enorm] + exact SmoothedChebyshevDirichlet_aux_integrable diffSmoothingF SmoothingFpos suppSmoothingF + mass_one εpos ε_lt_one σ_gt σ_le |>.hasFiniteIntegral + +/- +We have that + $$\psi_{\epsilon}(X) = \sum_{n=1}^\infty \Lambda(n)\widetilde{1_{\epsilon}}(n/X).$$ +We have that + $$\psi_{\epsilon}(X) = \frac{1}{2\pi i}\int_{(2)}\sum_{n=1}^\infty \frac{\Lambda(n)}{n^s} + \mathcal{M}(\widetilde{1_{\epsilon}})(s) + X^{s}ds.$$ + We have enough decay (thanks to quadratic decay of $\mathcal{M}(\widetilde{1_{\epsilon}})$) to + justify the interchange of summation and integration. We then get + $$\psi_{\epsilon}(X) = + \sum_{n=1}^\infty \Lambda(n)\frac{1}{2\pi i}\int_{(2)} + \mathcal{M}(\widetilde{1_{\epsilon}})(s) + (n/X)^{-s} + ds + $$ + and apply the Mellin inversion formula. +-/ +theorem SmoothedChebyshevDirichlet {SmoothingF : ℝ → ℝ} + (diffSmoothingF : ContDiff ℝ 1 SmoothingF) + (SmoothingFpos : ∀ x > 0, 0 ≤ SmoothingF x) + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (mass_one : ∫ x in Ioi (0 : ℝ), SmoothingF x / x = 1) + {X : ℝ} (X_gt : 3 < X) {ε : ℝ} (εpos : 0 < ε) (ε_lt_one : ε < 1) : + SmoothedChebyshev SmoothingF ε X = + ∑' n, ArithmeticFunction.vonMangoldt n * Smooth1 SmoothingF ε (n / X) := by + dsimp [SmoothedChebyshev, SmoothedChebyshevIntegrand, VerticalIntegral', VerticalIntegral] + set σ : ℝ := 1 + (Real.log X)⁻¹ + have log_gt : 1 < Real.log X := logt_gt_one X_gt.le + have σ_gt : 1 < σ := by + simp only [σ] + have : 0 < (Real.log X)⁻¹ := by + simp only [inv_pos] + linarith + linarith + have σ_le : σ ≤ 2 := by + simp only [σ] + have : (Real.log X)⁻¹ < 1 := inv_lt_one_of_one_lt₀ log_gt + linarith + calc + _ = 1 / (2 * π * I) * (I * ∫ (t : ℝ), ∑' n, Λ n / (n : ℂ) ^ (σ + ↑t * I) * + mellin (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (σ + ↑t * I) * X ^ (σ + ↑t * I)) := ?_ + _ = 1 / (2 * π * I) * (I * ∑' n, ∫ (t : ℝ), Λ n / (n : ℂ) ^ (σ + ↑t * I) * + mellin (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (σ + ↑t * I) * X ^ (σ + ↑t * I)) := ?_ + _ = 1 / (2 * π * I) * (I * ∑' n, Λ n * ∫ (t : ℝ), + mellin (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (σ + ↑t * I) * + (X / (n : ℂ)) ^ (σ + ↑t * I)) := ?_ + _ = 1 / (2 * π) * (∑' n, Λ n * ∫ (t : ℝ), + mellin (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (σ + ↑t * I) * + (X / (n : ℂ)) ^ (σ + ↑t * I)) := ?_ + _ = ∑' n, Λ n * (1 / (2 * π) * ∫ (t : ℝ), + mellin (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (σ + ↑t * I) * + (X / (n : ℂ)) ^ (σ + ↑t * I)) := ?_ + _ = ∑' n, Λ n * (1 / (2 * π) * ∫ (t : ℝ), + mellin (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (σ + ↑t * I) * + ((n : ℂ) / X) ^ (-(σ + ↑t * I))) := ?_ + _ = _ := ?_ + · congr; ext t + rw [LogDerivativeDirichlet] + · rw [← tsum_mul_right, ← tsum_mul_right] + · simp [σ_gt] + · congr + exact SmoothedChebyshevDirichlet_aux_tsum_integral diffSmoothingF SmoothingFpos + suppSmoothingF mass_one (by linarith) εpos ε_lt_one σ_gt σ_le + · field_simp; congr; ext n; rw [← MeasureTheory.integral_const_mul]; congr; ext t + by_cases n_ne_zero : n = 0 + · simp [n_ne_zero] + rw [mul_div_assoc, mul_assoc] + congr + rw [(div_eq_iff ?_).mpr] + · have := @mul_cpow_ofReal_nonneg (a := X / (n : ℝ)) (b := (n : ℝ)) (r := σ + I * t) ?_ ?_ + · push_cast at this ⊢ + rw [← this, div_mul_cancel₀] + · simp only [ne_eq, Nat.cast_eq_zero, n_ne_zero, not_false_eq_true] + · apply div_nonneg (by linarith : 0 ≤ X); simp + · simp + · simp only [ne_eq, cpow_eq_zero_iff, Nat.cast_eq_zero, n_ne_zero, false_and, + not_false_eq_true] + · conv => rw [← mul_assoc, div_mul]; lhs; lhs; rhs; simp + · simp_rw [← tsum_mul_left, ← mul_assoc, mul_comm] + · have ht (t : ℝ) : -(σ + t * I) = (-1) * (σ + t * I) := by simp + have hn (n : ℂ) : (n / X) ^ (-1 : ℂ) = X / n := by simp [cpow_neg_one] + have (n : ℕ) : (log ((n : ℂ) / (X : ℂ)) * -1).im = 0 := by + simp [Complex.log_im, arg_eq_zero_iff, div_nonneg (Nat.cast_nonneg _) (by linarith : 0 ≤ X)] + have h (n : ℕ) (t : ℝ) : ((n : ℂ) / X) ^ ((-1 : ℂ) * (σ + t * I)) = + ((n / X) ^ (-1 : ℂ)) ^ (σ + ↑t * I) := by + rw [cpow_mul] <;> {rw [this n]; simp [Real.pi_pos, Real.pi_nonneg]} + conv => rhs; lhs; intro n; rhs; rhs; rhs; intro t; rhs; rw [ht t, h n t]; lhs; rw [hn] + · push_cast + congr + ext n + by_cases n_zero : n = 0 + · simp [n_zero] + have n_pos : 0 < n := by + simpa only [n_zero, gt_iff_lt, false_or] using (Nat.eq_zero_or_pos n) + congr + have := mellinInv_mellin_eq σ (f := fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (x := n / X) + ?_ ?_ ?_ ?_ + · beta_reduce at this + dsimp [mellinInv, VerticalIntegral] at this + convert! this using 4 + · norm_cast + · rw [mul_comm] + norm_cast + · exact div_pos (by exact_mod_cast n_pos) (by linarith : 0 < X) + · apply Smooth1MellinConvergent diffSmoothingF suppSmoothingF ⟨εpos, ε_lt_one⟩ + SmoothingFpos mass_one + simp only [ofReal_re] + linarith + · dsimp [VerticalIntegrable] + apply SmoothedChebyshevDirichlet_aux_integrable diffSmoothingF SmoothingFpos + suppSmoothingF mass_one εpos ε_lt_one σ_gt σ_le + · refine ContinuousAt.comp (g := ofReal) RCLike.continuous_ofReal.continuousAt ?_ + exact Smooth1ContinuousAt diffSmoothingF SmoothingFpos suppSmoothingF + εpos (by positivity) + +/- +The smoothed Chebyshev function is close to the actual Chebyshev function. +-/ + +--open scoped ArithmeticFunction in +/-- A bounded nonnegative weight does not enlarge a finite von Mangoldt sum. -/ +private lemma mangoldt_weighted_segment_le (F : ℝ → ℝ) {X Y : ℝ} {a b : ℕ} + (ha : 0 < a) (hab : a ≤ b) (hb : (b : ℝ) ≤ Y) + (hF : ∀ n : ℕ, 0 < n → 0 ≤ F ((n : ℝ) / X) ∧ F ((n : ℝ) / X) ≤ 1) : + ∑ n ∈ Finset.range (b - a), ‖Λ (n + a)‖ * ‖F (((n : ℝ) + a) / X)‖ ≤ + ((b : ℝ) - a) * Real.log Y := by + calc + _ ≤ ∑ n ∈ Finset.range (b - a), Real.log Y := by + refine Finset.sum_le_sum fun n hn => ?_ + have hnpos : 0 < n + a := by omega + have hnleNat : n + a ≤ b := by have := Finset.mem_range.mp hn; omega + have hnle : ((n + a : ℕ) : ℝ) ≤ Y := (Nat.cast_le.mpr hnleNat).trans hb + have hlog : ‖Λ (n + a)‖ ≤ Real.log Y := by + rw [Real.norm_of_nonneg ArithmeticFunction.vonMangoldt_nonneg] + exact ArithmeticFunction.vonMangoldt_le_log.trans + (Real.log_le_log (by exact_mod_cast hnpos) hnle) + have hw : ‖F (((n : ℝ) + a) / X)‖ ≤ 1 := by + rw [← Nat.cast_add, Real.norm_of_nonneg (hF _ hnpos).1] + exact (hF _ hnpos).2 + exact (mul_le_mul_of_nonneg_left hw (norm_nonneg _)).trans (by simpa using hlog) + _ = _ := by simp [← Nat.cast_sub hab] + +theorem SmoothedChebyshevClose_aux {Smooth1 : (ℝ → ℝ) → ℝ → ℝ → ℝ} (SmoothingF : ℝ → ℝ) + (c₁ : ℝ) (c₁_pos : 0 < c₁) (c₁_lt : c₁ < 1) + (c₂ : ℝ) (c₂_pos : 0 < c₂) (c₂_lt : c₂ < 2) + (hc₂ : ∀ (ε x : ℝ), ε ∈ Ioo 0 1 → 1 + c₂ * ε ≤ x → Smooth1 SmoothingF ε x = 0) + (C : ℝ) (C_eq : C = 6 * (3 * c₁ + c₂)) + (ε : ℝ) (ε_pos : 0 < ε) (ε_lt_one : ε < 1) + (X : ℝ) (X_pos : 0 < X) (X_gt_three : 3 < X) + (X_bound_1 : 1 ≤ X * ε * c₁) (X_bound_2 : 1 ≤ X * ε * c₂) + (smooth1BddAbove : ∀ (n : ℕ), 0 < n → Smooth1 SmoothingF ε (↑n / X) ≤ 1) + (smooth1BddBelow : ∀ (n : ℕ), 0 < n → Smooth1 SmoothingF ε (↑n / X) ≥ 0) + (smoothIs1 : ∀ (n : ℕ), 0 < n → ↑n ≤ X * (1 - c₁ * ε) → + Smooth1 SmoothingF ε (↑n / X) = 1) + (smoothIs0 : ∀ (n : ℕ), 1 + c₂ * ε ≤ ↑n / X → Smooth1 SmoothingF ε (↑n / X) = 0) : + ‖(↑((∑' (n : ℕ), ArithmeticFunction.vonMangoldt n * Smooth1 SmoothingF ε (↑n / X))) : ℂ) - + ψ X‖ ≤ + C * ε * X * Real.log X := by + norm_cast + let F := Smooth1 SmoothingF ε + let n₀ := ⌈X * (1 - c₁ * ε)⌉₊ + have n₀_pos : 0 < n₀ := by + simp only [Nat.ceil_pos, n₀] + subst C_eq + simp_all only [mem_Ioo, and_imp, ge_iff_le, implies_true, mul_pos_iff_of_pos_left, sub_pos] + exact (mul_le_of_le_one_right c₁_pos.le ε_lt_one.le).trans_lt c₁_lt + have n₀_inside_le_X : X * (1 - c₁ * ε) ≤ X := + mul_le_of_le_one_right X_pos.le (sub_le_self _ (mul_nonneg c₁_pos.le ε_pos.le)) + have n₀_le : n₀ ≤ X * ((1 - c₁ * ε)) + 1 := by + simp only [n₀] + exact le_of_lt (Nat.ceil_lt_add_one (by bound)) + have n₀_gt : X * ((1 - c₁ * ε)) ≤ n₀ := by + simp only [n₀] + exact Nat.le_ceil (X * (1 - c₁ * ε)) + have sumΛ : Summable (fun (n : ℕ) ↦ Λ n * F (n / X)) := by + exact (summable_of_ne_finset_zero fun a s=>mul_eq_zero_of_right _ + (hc₂ _ _ (⟨ε_pos, ε_lt_one⟩) ((le_div_iff₀ X_pos).2 (Nat.ceil_le.1 (not_lt.1 + (s ∘ Finset.mem_range.2)))))) + have sumΛn₀ (n₀ : ℕ) : Summable (fun n ↦ Λ (n + n₀) * F ((n + n₀) / X)) := by + exact_mod_cast sumΛ.comp_injective fun Q => by omega + rw[← Summable.sum_add_tsum_nat_add' (k := n₀) (mod_cast sumΛn₀ n₀)] + let n₁ := ⌊X * (1 + c₂ * ε)⌋₊ + have n₁_pos : 0 < n₁ := by + dsimp only [n₁] + apply Nat.le_floor + rw[Nat.succ_eq_add_one, zero_add] + norm_cast + apply one_le_mul_of_one_le_of_one_le (by linarith) + apply le_add_of_nonneg_right + positivity + have n₁_ge : X * (1 + c₂ * ε) - 1 ≤ n₁ := by + simp only [tsub_le_iff_right, n₁] + exact le_of_lt (Nat.lt_floor_add_one (X * (1 + c₂ * ε))) + have n₁_le : (n₁ : ℝ) ≤ X * (1 + c₂ * ε) := by + simp only [n₁] + exact Nat.floor_le (by bound) + have n₁_ge_n₀ : n₀ ≤ n₁ := by + exact_mod_cast le_imp_le_of_le_of_le n₀_le n₁_ge (by linarith) + have n₁_sub_n₀ : (n₁ : ℝ) - n₀ ≤ X * ε * (c₂ + c₁) := by + calc + (n₁ : ℝ) - n₀ ≤ X * (1 + c₂ * ε) - n₀ := by + exact sub_le_sub_right n₁_le ↑n₀ + _ ≤ X * (1 + c₂ * ε) - (X * (1 - c₁ * ε)) := by + exact tsub_le_tsub_left n₀_gt (X * (1 + c₂ * ε)) + _ = X * ε * (c₂ + c₁) := by ring + rw[show (∑' (n : ℕ), Λ (n + n₀ : ) * F ((n + n₀ : ) / X)) = + (∑ n ∈ Finset.range (n₁ - n₀), Λ (n + n₀) * F ((n + n₀) / X)) + + (∑' (n : ℕ), Λ (n + n₁ : ) * F ((n + n₁ : ) / X)) by + rw[← Summable.sum_add_tsum_nat_add' (k := n₁ - n₀)] + · congr! 5 + · simp only [Nat.cast_add] + · omega + · congr! 1 + norm_cast + omega + · convert sumΛn₀ ((n₁ - n₀) + n₀) using 4 + · omega + · congr! 1 + norm_cast + omega] + rw [show(∑' (n : ℕ), Λ (n + n₁) * F (↑(n + n₁) / X)) = Λ (n₁) * F (↑n₁ / X) by + have : (∑' (n : ℕ), Λ (n + n₁) * F (↑(n + n₁) / X)) = + Λ (n₁) * F (↑n₁ / X) + (∑' (n : ℕ), Λ (n + 1 + n₁) * F (↑(n + 1 + n₁) / X)) := by + let fTemp := fun n ↦ Λ (n + n₁) * F ((↑n + ↑n₁) / X) + have hTemp (n : ℕ): fTemp n = Λ (n + n₁) * F (↑(n + n₁) / X) := by rw[Nat.cast_add] + rw[← tsum_congr hTemp, ← tsum_congr fun n ↦ (hTemp (n + 1))] + have : Λ n₁ * F (↑n₁ / X) = fTemp 0 := by + dsimp only [fTemp] + rw[← Nat.cast_add, zero_add] + rw[this] + exact Summable.tsum_eq_zero_add (sumΛn₀ n₁) + rw[this] + apply add_eq_left.mpr + convert tsum_zero with n + convert mul_zero _ + apply smoothIs0 + rw[← mul_le_mul_iff_left₀ X_pos] + rw [(by field_simp : ↑(n + 1 + n₁) / X * X = ↑(n + 1 + n₁)), + (by ring : (1 + c₂ * ε) * X = 1 + (X * (1 + c₂ * ε) - 1)), Nat.cast_add, Nat.cast_add] + bound] + have X_le_floor_add_one : X ≤ ↑⌊X + 1⌋₊ := by + rw[Nat.floor_add_one (by linarith), Nat.cast_add, Nat.cast_one] + apply le_trans <| Nat.le_ceil X + exact_mod_cast Nat.ceil_le_floor_add_one X + have floor_X_add_one_le_self : ↑⌊X + 1⌋₊ ≤ X + 1 := Nat.floor_le (by positivity) + rw [show ψ X = + (∑ x ∈ Finset.range n₀, Λ x) + + ∑ x ∈ Finset.range (⌊X + 1⌋₊ - n₀), Λ (x + ↑n₀) by + field_simp + simp only [add_comm _ n₀] + rw [← Finset.sum_range_add, Nat.add_sub_of_le, Chebyshev.psi_eq_sum_range, + Nat.floor_add_one X_pos.le] + dsimp only [n₀] + exact Nat.ceil_le.mpr (by linarith)] + rw [show ∑ n ∈ Finset.range n₀, Λ n * F (↑n / X) = + ∑ n ∈ Finset.range n₀, Λ n by + apply Finset.sum_congr rfl + intro n hn + obtain rfl|n_zero := eq_or_ne n 0 + · simp only [ArithmeticFunction.map_zero, CharP.cast_eq_zero, zero_div, zero_mul] + · convert mul_one _ + apply smoothIs1 n (Nat.zero_lt_of_ne_zero n_zero) ?_ + simp only [Finset.mem_range, n₀] at hn + exact Nat.lt_ceil.mp hn |>.le] + have bnd1 := mangoldt_weighted_segment_le F n₀_pos n₁_ge_n₀ n₁_le + (fun n hn => ⟨smooth1BddBelow n hn, smooth1BddAbove n hn⟩) + have hn₀ : n₀ ≤ ⌊X + 1⌋₊ := by + rw [Nat.ceil_le] + exact n₀_inside_le_X.trans X_le_floor_add_one + have bnd2 : + ∑ x ∈ Finset.range (⌊X + 1⌋₊ - n₀), ‖Λ (x + n₀)‖ ≤ + (⌊X + 1⌋₊ - n₀) * Real.log (X + 1) := by + simpa using mangoldt_weighted_segment_le (fun _ => 1) n₀_pos hn₀ + floor_X_add_one_le_self (X := X) (fun _ _ => ⟨zero_le_one, le_rfl⟩) + have inter1 : Real.log (X * (1 + c₂ * ε)) ≤ Real.log (3 * X) := by + apply Real.log_le_log (by positivity) + have const_le_2: 1 + c₂ * ε ≤ 3 := by + have : (3 : ℝ) = 1 + 2 := by ring + rw[this] + apply add_le_add_right + rw[← mul_one 2] + exact mul_le_mul (by linarith) (by linarith) (by positivity) (by positivity) + rw[mul_comm] + exact mul_le_mul const_le_2 (by rfl) (by positivity) (by positivity) + calc + _ = ‖∑ n ∈ Finset.range (n₁ - n₀), Λ (n + n₀) * F ((↑n + ↑n₀) / X) - + ∑ x ∈ Finset.range (⌊X + 1⌋₊ - n₀), Λ (x + n₀) + Λ n₁ * F (↑n₁ / X)‖ := by + congr 1 + ring + _ ≤ (∑ n ∈ Finset.range (n₁ - n₀), ‖Λ (n + n₀)‖ * ‖F ((↑n + ↑n₀) / X)‖) + + ∑ x ∈ Finset.range (⌊X + 1⌋₊ - n₀), ‖Λ (x + n₀)‖ + + ‖Λ n₁‖ * ‖F (↑n₁ / X)‖ := by + apply norm_add_le_of_le + · apply norm_sub_le_of_le + · apply norm_sum_le_of_le + intro b hb + exact norm_mul_le_of_le (by rfl) (by rfl) + apply norm_sum_le_of_le + intro b hb + rfl + exact_mod_cast norm_mul_le_of_le (by rfl) (by rfl) + _ ≤ 2 * (X * ε * (3 * c₁ + c₂)) * Real.log X + Real.log (3 * X) := by + apply add_le_add + · apply le_trans <| add_le_add bnd1 bnd2 + rw [(by ring : 2 * (X * ε * (3 * c₁ + c₂)) = 2 * (X * ε * (c₁ + c₂)) + 4 * (X * ε * c₁)), + add_mul] + apply add_le_add + · calc + _ ≤ (X * ε * (c₂ + c₁)) * (Real.log (X) + Real.log (3)) := by + apply mul_le_mul n₁_sub_n₀ _ (log_nonneg (by linarith)) (by positivity) + rw[← Real.log_mul (by positivity) (by positivity)] + nth_rewrite 3 [mul_comm] + exact inter1 + _ ≤ 2 * ((X * ε * (c₂ + c₁)) * Real.log X) := by + rw[two_mul, mul_add] + bound + _ = _ := by ring + calc + _ ≤ 2 * (X * ε * c₁) * (Real.log (X) + Real.log (3)) := by + apply mul_le_mul _ _ (log_nonneg (by linarith)) (by positivity) + · rw [(by ring : 2 * (X * ε * c₁) = (X * (1 + ε * c₁)) - (X * (1 - ε * c₁)))] + apply sub_le_sub + · apply le_trans floor_X_add_one_le_self + ring_nf + rw[add_comm, add_le_add_iff_left] + exact X_bound_1 + nth_rewrite 2 [mul_comm] + exact n₀_gt + rw[← Real.log_mul (by positivity) (by norm_num), mul_comm] + exact Real.log_le_log (by positivity) (by linarith) + _ = 2 * (X * ε * c₁ * Real.log X) + 2 * (X * ε * c₁ * Real.log 3) := by ring + _ ≤ 2 * (X * ε * c₁ * Real.log X) + 2 * (X * ε * c₁ * Real.log X) := by gcongr + _ = _ := by ring + · apply le_trans _ inter1 + rw[← mul_one (Real.log (X * (1 + c₂ * ε)))] + apply mul_le_mul _ _ (norm_nonneg _) (log_nonneg (by bound)) + · rw[Real.norm_of_nonneg ArithmeticFunction.vonMangoldt_nonneg] + exact le_trans ArithmeticFunction.vonMangoldt_le_log <| + Real.log_le_log (mod_cast n₁_pos) n₁_le + rw[Real.norm_of_nonneg <| smooth1BddBelow _ n₁_pos] + apply smooth1BddAbove _ n₁_pos + _ ≤ 2 * (X * ε * (3 * c₁ + c₂)) * (Real.log X + (Real.log X + Real.log 3)) := by + rw [← Real.log_mul (by positivity) (by positivity), mul_comm X 3] + nth_rewrite 2 [mul_add] + apply add_le_add_right + nth_rewrite 1 [← one_mul (Real.log (3 * X))] + apply mul_le_mul_of_nonneg_right _ (log_nonneg (by linarith)) + linarith + _ = 4 * (X * ε * (3 * c₁ + c₂)) * Real.log X + + 2 * (X * ε * (3 * c₁ + c₂)) * Real.log 3 := by ring + _ ≤ 4 * (X * ε * (3 * c₁ + c₂)) * Real.log X + + 2 * (X * ε * (3 * c₁ + c₂)) * Real.log X := by gcongr + _ = _ := by + rw [C_eq] + ring + +/- +We have that + $$\psi_{\epsilon}(X) = \psi(X) + O(\epsilon X \log X).$$ +Take the difference. By Lemma \ref{Smooth1Properties_above} and \ref{Smooth1Properties_below}, + the sums agree except when $1-c \epsilon \leq n/X \leq 1+c \epsilon$. This is an interval of + length $\ll \epsilon X$, and the summands are bounded by $\Lambda(n) \ll \log X$. + %[No longer relevant, as we will do better than any power of log savings...: This is not enough, + %as it loses a log! (Which is fine if our target is the strong PNT, with + %exp-root-log savings, but not here with the ``softer'' approach.) So we will need something like + %the Selberg sieve (already in Mathlib? Or close?) to conclude that the number of primes in this + %interval is $\ll \epsilon X / \log X + 1$. + %(The number of prime powers is $\ll X^{1/2}$.) + %And multiplying that by $\Lambda (n) \ll \log X$ gives the desired bound.] +-/ +theorem SmoothedChebyshevClose {SmoothingF : ℝ → ℝ} + (diffSmoothingF : ContDiff ℝ 1 SmoothingF) + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (SmoothingFnonneg : ∀ x > 0, 0 ≤ SmoothingF x) + (mass_one : ∫ x in Ioi 0, SmoothingF x / x = 1) : + ∃ C > 0, ∀ (X : ℝ) (_ : 3 < X) (ε : ℝ) (_ : 0 < ε) (_ : ε < 1) (_ : 2 < X * ε), + ‖SmoothedChebyshev SmoothingF ε X - ψ X‖ ≤ C * ε * X * Real.log X := by + obtain ⟨c₁, c₁_pos, c₁_eq, hc₁⟩ := Smooth1Properties_below suppSmoothingF mass_one + obtain ⟨c₂, c₂_pos, c₂_eq, hc₂⟩ := Smooth1Properties_above suppSmoothingF + have c₁_lt : c₁ < 1 := by + rw[c₁_eq] + exact lt_trans (Real.log_two_lt_d9) (by norm_num) + have c₂_lt : c₂ < 2 := by + rw[c₂_eq] + nth_rewrite 3 [← mul_one 2] + apply mul_lt_mul' + · rfl + · exact lt_trans (Real.log_two_lt_d9) (by norm_num) + · exact Real.log_nonneg (by norm_num) + · positivity + let C : ℝ := 6 * (3 * c₁ + c₂) + have C_eq : C = 6 * (3 * c₁ + c₂) := rfl + clear_value C + have Cpos : 0 < C := by + rw [C_eq] + positivity + refine ⟨C, Cpos, fun X X_ge_C ε εpos ε_lt_one ↦ ?_⟩ + have X_gt_zero : (0 : ℝ) < X := by linarith + have n_on_X_pos {n : ℕ} (npos : 0 < n) : + 0 < n / X := by + have : (0 : ℝ) < n := by exact_mod_cast npos + positivity + have smooth1BddAbove (n : ℕ) (npos : 0 < n) : + Smooth1 SmoothingF ε (n / X) ≤ 1 := + Smooth1LeOne SmoothingFnonneg mass_one εpos (n_on_X_pos npos) + have smooth1BddBelow (n : ℕ) (npos : 0 < n) : + Smooth1 SmoothingF ε (n / X) ≥ 0 := + Smooth1Nonneg SmoothingFnonneg (n_on_X_pos npos) εpos + have smoothIs1 (n : ℕ) (npos : 0 < n) (n_le : n ≤ X * (1 - c₁ * ε)) : + Smooth1 SmoothingF ε (↑n / X) = 1 := by + apply hc₁ (ε := ε) (n / X) εpos (n_on_X_pos npos) + exact (div_le_iff₀' X_gt_zero).mpr n_le + have smoothIs0 (n : ℕ) (n_le : (1 + c₂ * ε) ≤ n / X) := + hc₂ (ε := ε) (n / X) ⟨εpos, ε_lt_one⟩ n_le + have ε_pos: ε > 0 := by linarith + have X_pos: X > 0 := by linarith + have X_gt_three : 3 < X := by linarith + intro X_bound + have X_bound_1 : 1 ≤ X * ε * c₁ := by + rw[c₁_eq, ← div_le_iff₀] + · have : 1 / Real.log 2 < 2 := by + nth_rewrite 2 [← one_div_one_div 2] + rw[one_div_lt_one_div] + · exact lt_of_le_of_lt (by norm_num) (Real.log_two_gt_d9) + · exact Real.log_pos (by norm_num) + norm_num + exact le_of_lt (gt_trans X_bound this) + exact Real.log_pos (by norm_num) + have X_bound_2 : 1 ≤ X * ε * c₂ := by + rw[c₂_eq, ← div_le_iff₀] + · have : 1 / (2 * Real.log 2) < 2 := by + nth_rewrite 3 [← one_div_one_div 2] + · rw[one_div_lt_one_div, ← one_mul (1 / 2)] + · apply mul_lt_mul + · norm_num + · apply le_of_lt + exact lt_trans (by norm_num) (Real.log_two_gt_d9) + repeat norm_num + · norm_num + exact Real.log_pos (by norm_num) + · norm_num + exact le_of_lt (gt_trans X_bound this) + norm_num + exact Real.log_pos (by norm_num) + rw [SmoothedChebyshevDirichlet diffSmoothingF SmoothingFnonneg suppSmoothingF + mass_one (by linarith) εpos ε_lt_one] + convert SmoothedChebyshevClose_aux SmoothingF c₁ c₁_pos c₁_lt c₂ c₂_pos c₂_lt hc₂ C C_eq ε + ε_pos ε_lt_one X X_pos X_gt_three X_bound_1 X_bound_2 smooth1BddAbove smooth1BddBelow + smoothIs1 smoothIs0 + +/- +For constants $A$, $C$, $n_1$, and $n_2$ this is true if for all $3<|t|$ one has + $$1-\frac{A}{\log|t|^{n_1}}\leq\sigma\implies|(\zeta'/\zeta)(\sigma+it)|\leq C\,\log|t|^{n_2}.$$ +-/ +/-- A uniform logarithmic bound for the logarithmic derivative of zeta near the line `re = 1`. -/ +def LogDerivZetaHasBound (n₁ n₂ : ℝ) (A C : ℝ) : Prop := ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Ici (1 - A / Real.log |t| ^ n₁)), ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ ≤ + C * Real.log |t| ^ n₂ + +/- +Suppose we have an estimate of the form in Definition \ref{LogDerivZetaHasBound}. Returning to the +definition of $\psi_{\epsilon}$, fix a large $T$ to be chosen later, and set +$\sigma_0 = 1 + 1 / log X$, +$\sigma_1 = 1- A/ \log T^{n_1}$ (where $n_1$ comes from our estimate from Definition +\ref{LogDerivZetaHasBound}), and +$\sigma_2<\sigma_1$ a constant. +Pull +contours (via rectangles!) to go +from $\sigma_0-i\infty$ up to $\sigma_0-iT$, then over to $\sigma_1-iT$, up to $\sigma_1-3i$, +over to $\sigma_2-3i$, up to $\sigma_2+3i$, back over to $\sigma_1+3i$, up to $\sigma_1+iT$, +over to $\sigma_0+iT$, and finally up to $\sigma_0+i\infty$. + +In the process, we will pick up the residue at $s=1$. +We will do this in several stages. Here the interval integrals are defined as follows: +-/ + +/- +$$ + I_1(\nu, \epsilon, X, T) := \frac{1}{2\pi i} \int_{-\infty}^{-T} + \left( + \frac{-\zeta'}\zeta(\sigma_0 + t i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma_0 + t i) + X^{\sigma_0 + t i} + \ i \ dt + $$ +-/ +/-- The lower infinite vertical tail of the normalized Perron contour. -/ +noncomputable def I₁ (SmoothingF : ℝ → ℝ) (ε X T : ℝ) : ℂ := + (1 / (2 * π * I)) * (I * (∫ t : ℝ in Iic (-T), + SmoothedChebyshevIntegrand SmoothingF ε X ((1 + (Real.log X)⁻¹) + t * I))) + +/- +$$ + I_2(\nu, \epsilon, X, T, \sigma_1) := \frac{1}{2\pi i} \int_{\sigma_1}^{\sigma_0} + \left( + \frac{-\zeta'}\zeta(\sigma - i T) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma - i T) + X^{\sigma - i T} \ d\sigma + $$ +-/ +/-- The lower horizontal segment at imaginary part `-T`. -/ +noncomputable def I₂ (SmoothingF : ℝ → ℝ) (ε T X σ₁ : ℝ) : ℂ := + (1 / (2 * π * I)) * ((∫ σ in σ₁..(1 + (Real.log X)⁻¹), + SmoothedChebyshevIntegrand SmoothingF ε X (σ - T * I))) + +/- +$$ + I_{37}(\nu, \epsilon, X, T, \sigma_1) := \frac{1}{2\pi i} \int_{-T}^{T} + \left( + \frac{-\zeta'}\zeta(\sigma_1 + t i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma_1 + t i) + X^{\sigma_1 + t i} \ i \ dt + $$ +-/ +/-- The central vertical contour before splitting at imaginary parts `-3` and `3`. -/ +noncomputable def I₃₇ (SmoothingF : ℝ → ℝ) (ε T X σ₁ : ℝ) : ℂ := + (1 / (2 * π * I)) * (I * (∫ t in (-T)..T, + SmoothedChebyshevIntegrand SmoothingF ε X (σ₁ + t * I))) + +/- +$$ + I_8(\nu, \epsilon, X, T, \sigma_1) := \frac{1}{2\pi i} \int_{\sigma_1}^{\sigma_0} + \left( + \frac{-\zeta'}\zeta(\sigma + T i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma + T i) + X^{\sigma + T i} \ d\sigma + $$ +-/ +/-- The upper horizontal segment at imaginary part `T`. -/ +noncomputable def I₈ (SmoothingF : ℝ → ℝ) (ε T X σ₁ : ℝ) : ℂ := + (1 / (2 * π * I)) * ((∫ σ in σ₁..(1 + (Real.log X)⁻¹), + SmoothedChebyshevIntegrand SmoothingF ε X (σ + T * I))) + +/- +$$ + I_9(\nu, \epsilon, X, T) := \frac{1}{2\pi i} \int_{T}^{\infty} + \left( + \frac{-\zeta'}\zeta(\sigma_0 + t i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma_0 + t i) + X^{\sigma_0 + t i} \ i \ dt + $$ +-/ +/-- The upper infinite vertical tail of the normalized Perron contour. -/ +noncomputable def I₉ (SmoothingF : ℝ → ℝ) (ε X T : ℝ) : ℂ := + (1 / (2 * π * I)) * (I * (∫ t : ℝ in Ici T, + SmoothedChebyshevIntegrand SmoothingF ε X ((1 + (Real.log X)⁻¹) + t * I))) + +/- +$$ + I_3(\nu, \epsilon, X, T, \sigma_1) := \frac{1}{2\pi i} \int_{-T}^{-3} + \left( + \frac{-\zeta'}\zeta(\sigma_1 + t i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma_1 + t i) + X^{\sigma_1 + t i} \ i \ dt + $$ +-/ +/-- The lower vertical segment from imaginary part `-T` to `-3`. -/ +noncomputable def I₃ (SmoothingF : ℝ → ℝ) (ε T X σ₁ : ℝ) : ℂ := + (1 / (2 * π * I)) * (I * (∫ t in (-T)..(-3), + SmoothedChebyshevIntegrand SmoothingF ε X (σ₁ + t * I))) + +/- +$$ + I_7(\nu, \epsilon, X, T, \sigma_1) := \frac{1}{2\pi i} \int_{3}^{T} + \left( + \frac{-\zeta'}\zeta(\sigma_1 + t i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma_1 + t i) + X^{\sigma_1 + t i} \ i \ dt + $$ +-/ +/-- The upper vertical segment from imaginary part `3` to `T`. -/ +noncomputable def I₇ (SmoothingF : ℝ → ℝ) (ε T X σ₁ : ℝ) : ℂ := + (1 / (2 * π * I)) * (I * (∫ t in (3 : ℝ)..T, + SmoothedChebyshevIntegrand SmoothingF ε X (σ₁ + t * I))) + +/- +$$ + I_4(\nu, \epsilon, X, \sigma_1, \sigma_2) := \frac{1}{2\pi i} \int_{\sigma_2}^{\sigma_1} + \left( + \frac{-\zeta'}\zeta(\sigma - 3 i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma - 3 i) + X^{\sigma - 3 i} \ d\sigma + $$ +-/ +/-- The lower horizontal segment at imaginary part `-3`. -/ +noncomputable def I₄ (SmoothingF : ℝ → ℝ) (ε X σ₁ σ₂ : ℝ) : ℂ := + (1 / (2 * π * I)) * ((∫ σ in σ₂..σ₁, + SmoothedChebyshevIntegrand SmoothingF ε X (σ - 3 * I))) + +/- +$$ + I_6(\nu, \epsilon, X, \sigma_1, \sigma_2) := \frac{1}{2\pi i} \int_{\sigma_2}^{\sigma_1} + \left( + \frac{-\zeta'}\zeta(\sigma + 3 i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma + 3 i) + X^{\sigma + 3 i} \ d\sigma + $$ +-/ +/-- The upper horizontal segment at imaginary part `3`. -/ +noncomputable def I₆ (SmoothingF : ℝ → ℝ) (ε X σ₁ σ₂ : ℝ) : ℂ := + (1 / (2 * π * I)) * ((∫ σ in σ₂..σ₁, + SmoothedChebyshevIntegrand SmoothingF ε X (σ + 3 * I))) + +/- +$$ + I_5(\nu, \epsilon, X, \sigma_2) := \frac{1}{2\pi i} \int_{-3}^{3} + \left( + \frac{-\zeta'}\zeta(\sigma_2 + t i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma_2 + t i) + X^{\sigma_2 + t i} \ i \ dt + $$ +-/ +/-- The central vertical segment between imaginary parts `-3` and `3`. -/ +noncomputable def I₅ (SmoothingF : ℝ → ℝ) (ε X σ₂ : ℝ) : ℂ := + (1 / (2 * π * I)) * + (I * (∫ t in (-3)..3, SmoothedChebyshevIntegrand SmoothingF ε X (σ₂ + t * I))) + +theorem realDiff_of_complexDiff {f : ℂ → ℂ} (s : ℂ) (hf : DifferentiableAt ℂ f s) : + ContinuousAt (fun (x : ℝ) ↦ f (s.re + x * I)) s.im := by + apply ContinuousAt.comp _ (by fun_prop) + convert hf.continuousAt + simp + +/-- Holomorphy of the logarithmic derivative on the small rectangle, away from its pole. -/ +def LogDerivZetaIsHoloSmall (σ₂ : ℝ) : Prop := + HolomorphicOn (fun (s : ℂ) ↦ ζ' s / (ζ s)) + (((uIcc σ₂ 2) ×ℂ (uIcc (-3) 3)) \ {1}) + +theorem dlog_riemannZeta_bdd_on_vertical_lines_explicit {σ₀ : ℝ} (σ₀_gt : 1 < σ₀) : + ∀(t : ℝ), ‖(-ζ' (σ₀ + t * I) / ζ (σ₀ + t * I))‖ ≤ ‖(ζ' σ₀ / ζ σ₀)‖ := + fun _ ↦ dlog_riemannZeta_bdd_on_vertical_lines_generalized _ _ _ σ₀_gt <| le_refl _ + +-- TODO : Move elsewhere (should be in Mathlib!) NOT NEEDED +/- +For $\sigma_0 > 1$, there exists a constant $C > 0$ such that + $$ + \forall t \in \R, \quad + \left\| \frac{\zeta'(\sigma_0 + t i)}{\zeta(\sigma_0 + t i)} \right\| \leq C. + $$ +Write as Dirichlet series and estimate trivially using Theorem \ref{LogDerivativeDirichlet}. +-/ +theorem dlog_riemannZeta_bdd_on_vertical_lines {σ₀ : ℝ} (σ₀_gt : 1 < σ₀) : + ∃ c > 0, ∀(t : ℝ), ‖ζ' (σ₀ + t * I) / ζ (σ₀ + t * I)‖ ≤ c := by + refine ⟨1 + ‖(ζ' σ₀ / ζ σ₀)‖, (by positivity), fun t ↦ ?_⟩ + have := dlog_riemannZeta_bdd_on_vertical_lines_explicit σ₀_gt t + rw [neg_div, norm_neg] at this + exact le_trans this (lt_one_add _).le + +/- +The integrand $$\zeta'(s)/\zeta(s)\mathcal{M}(\widetilde{1_{\epsilon}})(s)X^{s}$$ + is integrable on the contour $\sigma_0 + t i$ for $t \in \R$ and $\sigma_0 > 1$. +The $\zeta'(s)/\zeta(s)$ term is bounded, as is $X^s$, and the smoothing function + $\mathcal{M}(\widetilde{1_{\epsilon}})(s)$ + decays like $1/|s|^2$ by Theorem \ref{MellinOfSmooth1b}. + Actually, we already know that + $\mathcal{M}(\widetilde{1_{\epsilon}})(s)$ + is integrable from Theorem \ref{SmoothedChebyshevDirichlet_aux_integrable}, + so we should just need to bound the rest. +-/ +theorem SmoothedChebyshevPull1_aux_integrable {SmoothingF : ℝ → ℝ} {ε : ℝ} (ε_pos : 0 < ε) + (ε_lt_one : ε < 1) + {X : ℝ} (X_gt : 3 < X) + {σ₀ : ℝ} (σ₀_gt : 1 < σ₀) (σ₀_le_2 : σ₀ ≤ 2) + (suppSmoothingF : support SmoothingF ⊆ Icc (1 / 2) 2) + (SmoothingFnonneg : ∀ x > 0, 0 ≤ SmoothingF x) + (mass_one : ∫ (x : ℝ) in Ioi 0, SmoothingF x / x = 1) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) + : + Integrable (fun (t : ℝ) ↦ + SmoothedChebyshevIntegrand SmoothingF ε X (σ₀ + (t : ℂ) * I)) volume := by + obtain ⟨C, C_pos, hC⟩ := dlog_riemannZeta_bdd_on_vertical_lines σ₀_gt + let c : ℝ := C * X ^ σ₀ + have : ∀ t, ‖(fun (t : ℝ) ↦ (- deriv riemannZeta (σ₀ + (t : ℂ) * I)) / + riemannZeta (σ₀ + (t : ℂ) * I) * + (X : ℂ) ^ (σ₀ + (t : ℂ) * I)) t‖ ≤ c := by + intro t + simp only [Complex.norm_mul, c] + gcongr + · convert! hC t using 1 + simp + · rw [Complex.norm_cpow_eq_rpow_re_of_nonneg] + · simp + · linarith + · simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + add_zero, ne_eq] + linarith + convert (SmoothedChebyshevDirichlet_aux_integrable ContDiffSmoothingF SmoothingFnonneg + suppSmoothingF mass_one ε_pos ε_lt_one σ₀_gt σ₀_le_2).bdd_mul + (c := c) ?_ (ae_of_all _ this) using 2 + · unfold SmoothedChebyshevIntegrand + ring + · apply Continuous.aestronglyMeasurable + rw [← continuousOn_univ] + intro t _ + let s := σ₀ + (t : ℂ) * I + have s_ne_one : s ≠ 1 := by + intro h + -- If σ₀ + t * I = 1, then taking real parts gives σ₀ = 1 + have : σ₀ = 1 := by + have := congr_arg Complex.re h + simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, add_zero, one_re, s] at this + exact this + -- But this contradicts 1 < σ₀ + linarith [σ₀_gt] + apply ContinuousAt.continuousWithinAt + apply ContinuousAt.mul + · have diffζ := differentiableAt_riemannZeta s_ne_one + apply ContinuousAt.div + · apply ContinuousAt.neg + have : DifferentiableAt ℂ (fun s ↦ deriv riemannZeta s) s := + differentiableAt_deriv_riemannZeta s_ne_one + convert realDiff_of_complexDiff (s := σ₀ + (t : ℂ) * I) this <;> simp + · convert realDiff_of_complexDiff (s := σ₀ + (t : ℂ) * I) diffζ <;> simp + · apply riemannZeta_ne_zero_of_one_lt_re + simp [σ₀_gt] + · apply ContinuousAt.comp _ (by fun_prop) + apply continuousAt_const_cpow + norm_cast + linarith + +/- +Let $g : \C \to \C$ be a holomorphic function on a rectangle, then $g$ is bounded above on the +rectangle. +Use the compactness of the rectangle and the fact that holomorphic functions are continuous. +-/ +lemma BddAboveOnRect {g : ℂ → ℂ} {z w : ℂ} (holoOn : HolomorphicOn g (z.Rectangle w)) : + BddAbove (norm ∘ g '' (z.Rectangle w)) := by + have compact_rect : IsCompact (z.Rectangle w) := by + apply IsCompact.reProdIm <;> apply isCompact_uIcc + refine IsCompact.bddAbove_image compact_rect ?_ + apply holoOn.continuousOn.norm + +/- +We have that + $$\psi_{\epsilon}(X) = + \mathcal{M}(\widetilde{1_{\epsilon}})(1) + X^{1} + + I_1 - I_2 +I_{37} + I_8 + I_9 + . + $$ +Pull rectangle contours and evaluate the pole at $s=1$. +-/ +theorem SmoothedChebyshevPull1 {SmoothingF : ℝ → ℝ} {ε : ℝ} (ε_pos : 0 < ε) + (ε_lt_one : ε < 1) + (X : ℝ) (X_gt : 3 < X) + {T : ℝ} (T_pos : 0 < T) {σ₁ : ℝ} + (σ₁_pos : 0 < σ₁) (σ₁_lt_one : σ₁ < 1) + (holoOn : HolomorphicOn (ζ' / ζ) ((Icc σ₁ 2) ×ℂ (Icc (-T) T) \ {1})) + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (SmoothingFnonneg : ∀ x > 0, 0 ≤ SmoothingF x) + (mass_one : ∫ x in Ioi 0, SmoothingF x / x = 1) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) : + SmoothedChebyshev SmoothingF ε X = + I₁ SmoothingF ε X T - + I₂ SmoothingF ε T X σ₁ + + I₃₇ SmoothingF ε T X σ₁ + + I₈ SmoothingF ε T X σ₁ + + I₉ SmoothingF ε X T + + 𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) 1 * X := by + unfold SmoothedChebyshev + unfold VerticalIntegral' + have X_eq_gt_one : 1 < 1 + (Real.log X)⁻¹ := by + nth_rewrite 1 [← add_zero 1] + bound + have X_eq_lt_two : (1 + (Real.log X)⁻¹) < 2 := by + rw[← one_add_one_eq_two] + gcongr + exact inv_lt_one_of_one_lt₀ <| logt_gt_one X_gt.le + have X_eq_le_two : 1 + (Real.log X)⁻¹ ≤ 2 := X_eq_lt_two.le + rw [verticalIntegral_split_three (a := -T) (b := T)] + swap + · exact SmoothedChebyshevPull1_aux_integrable ε_pos ε_lt_one X_gt X_eq_gt_one + X_eq_le_two suppSmoothingF SmoothingFnonneg mass_one ContDiffSmoothingF + · have temp : ↑(1 + (Real.log X)⁻¹) = (1 : ℂ) + ↑(Real.log X)⁻¹ := by simp + unfold I₁ + simp only [smul_eq_mul, mul_add, temp, sub_eq_add_neg, add_assoc, add_left_cancel_iff] + unfold I₉ + nth_rewrite 6 [add_comm] + simp only [← add_assoc] + rw [add_right_cancel_iff, + ← add_right_inj (1 / (2 * ↑π * I) * + -VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) (1 + (Real.log X)⁻¹) (-T) T), + ← mul_add, ← sub_eq_neg_add, sub_self, mul_zero] + unfold VIntegral I₂ I₃₇ I₈ + simp only [smul_eq_mul, temp, ← add_assoc, ← mul_neg, ← mul_add] + let fTempRR : ℝ → ℝ → ℂ := fun x ↦ fun y ↦ + SmoothedChebyshevIntegrand SmoothingF ε X ((x : ℝ) + (y : ℝ) * I) + let fTempC : ℂ → ℂ := fun z ↦ fTempRR z.re z.im + have : ∫ (y : ℝ) in -T..T, + SmoothedChebyshevIntegrand SmoothingF ε X (1 + ↑(Real.log X)⁻¹ + ↑y * I) = + ∫ (y : ℝ) in -T..T, fTempRR (1 + (Real.log X)⁻¹) y := by + unfold fTempRR + simp only [temp] + rw[this] + have : ∫ (σ₀ : ℝ) in σ₁..1 + (Real.log X)⁻¹, + SmoothedChebyshevIntegrand SmoothingF ε X (↑σ₀ - ↑T * I) = + ∫ (x : ℝ) in σ₁..1 + (Real.log X)⁻¹, fTempRR x (-T) := by + unfold fTempRR + simp only [ofReal_neg, neg_mul, sub_eq_add_neg] + rw[this] + have : ∫ (t : ℝ) in -T..T, + SmoothedChebyshevIntegrand SmoothingF ε X (↑σ₁ + ↑t * I) = + ∫ (y : ℝ) in -T..T, fTempRR σ₁ y := rfl + rw[this] + have : ∫ (σ₀ : ℝ) in σ₁..1 + (Real.log X)⁻¹, + SmoothedChebyshevIntegrand SmoothingF ε X (↑σ₀ + ↑T * I) = + ∫ (x : ℝ) in σ₁..1 + (Real.log X)⁻¹, fTempRR x T := rfl + rw[this] + have : (((I * -∫ (y : ℝ) in -T..T, fTempRR (1 + (Real.log X)⁻¹) y) + + -∫ (x : ℝ) in σ₁..1 + (Real.log X)⁻¹, fTempRR x (-T)) + + I * ∫ (y : ℝ) in -T..T, fTempRR σ₁ y) + + ∫ (x : ℝ) in σ₁..1 + (Real.log X)⁻¹, fTempRR x T = + -(2 * ↑π * I) * RectangleIntegral' fTempC (σ₁ - T * I) (1 + ↑(Real.log X)⁻¹ + T * I) := by + unfold RectangleIntegral' RectangleIntegral HIntegral VIntegral fTempC + simp only [mul_neg, one_div, mul_inv_rev, inv_I, neg_mul, sub_im, ofReal_im, mul_im, + ofReal_re, I_im, mul_one, I_re, mul_zero, add_zero, zero_sub, ofReal_neg, add_re, + neg_re, mul_re, sub_self, neg_zero, add_im, neg_im, zero_add, sub_re, sub_zero, + ofReal_inv, one_re, inv_re, normSq_ofReal, div_self_mul_self', one_im, inv_im, + zero_div, ofReal_add, ofReal_one, smul_eq_mul, neg_neg] + ring_nf + simp only [I_sq, neg_mul, one_mul, ne_eq, ofReal_eq_zero, pi_ne_zero, not_false_eq_true, + mul_inv_cancel_right₀, sub_neg_eq_add, I_pow_three] + ring_nf + rw[this] + field_simp + rw[mul_comm, eq_comm, neg_add_eq_zero] + have pInRectangleInterior : + (Rectangle (σ₁ - ↑T * I) (1 + (Real.log X)⁻¹ + T * I) ∈ nhds 1) := by + refine rectangle_mem_nhds_iff.mpr ?_ + refine mem_reProdIm.mpr ?_ + simp only [sub_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + sub_zero, ofReal_inv, add_re, one_re, inv_re, normSq_ofReal, div_self_mul_self', add_zero, + sub_im, mul_im, zero_sub, add_im, one_im, inv_im, neg_zero, zero_div, zero_add] + constructor + · unfold uIoo + rw [min_eq_left (by linarith), max_eq_right (by linarith)] + exact mem_Ioo.mpr ⟨σ₁_lt_one, (by linarith)⟩ + · unfold uIoo + rw [min_eq_left (by linarith), max_eq_right (by linarith)] + exact mem_Ioo.mpr ⟨(by linarith), (by linarith)⟩ + apply ResidueTheoremOnRectangleWithSimplePole' + · simp; linarith + · simp; linarith + · simp only [one_div] + exact pInRectangleInterior + · apply DifferentiableOn.mul + · apply DifferentiableOn.mul + · simp only [re_add_im] + have : (fun z ↦ -ζ' z / ζ z) = -(ζ' / ζ) := by ext; simp; ring + rw [this] + apply DifferentiableOn.neg + apply holoOn.mono + apply Set.sdiff_subset_sdiff_left + apply reProdIm_subset_iff'.mpr + left + simp only [sub_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + sub_zero, one_div, ofReal_inv, add_re, one_re, inv_re, normSq_ofReal, + div_self_mul_self', add_zero, sub_im, mul_im, zero_sub, add_im, one_im, inv_im, + neg_zero, zero_div, zero_add] + constructor <;> apply uIcc_subset_Icc <;> constructor <;> linarith + · intro s hs + apply DifferentiableAt.differentiableWithinAt + simp only [re_add_im] + apply Smooth1MellinDifferentiable ContDiffSmoothingF suppSmoothingF ⟨ε_pos, ε_lt_one⟩ + SmoothingFnonneg mass_one + have := mem_reProdIm.mp hs.1 |>.1 + simp only [sub_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + sub_zero, one_div, ofReal_inv, add_re, one_re, inv_re, normSq_ofReal, + div_self_mul_self', add_zero] at this + rw [uIcc_of_le (by linarith)] at this + linarith [this.1] + · intro s hs + apply DifferentiableAt.differentiableWithinAt + simp only [re_add_im] + apply DifferentiableAt.const_cpow (by fun_prop) + left + norm_cast + linarith + · let U : Set ℂ := Rectangle (σ₁ - ↑T * I) (1 + (Real.log X)⁻¹ + T * I) + let f : ℂ → ℂ := fun z ↦ -ζ' z / ζ z + let g : ℂ → ℂ := fun z ↦ 𝓜 (fun x ↦ ↑(Smooth1 SmoothingF ε x)) z * ↑X ^ z + unfold fTempC fTempRR SmoothedChebyshevIntegrand + simp only [re_add_im] + have g_holc : HolomorphicOn g U := by + intro u uInU + apply DifferentiableAt.differentiableWithinAt + simp only [g] + apply DifferentiableAt.mul + · apply Smooth1MellinDifferentiable ContDiffSmoothingF suppSmoothingF ⟨ε_pos, ε_lt_one⟩ + SmoothingFnonneg mass_one + simp only [ofReal_inv, U] at uInU + unfold Rectangle at uInU + rw[Complex.mem_reProdIm] at uInU + have := uInU.1 + simp only [sub_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + sub_zero, add_re, one_re, inv_re, normSq_ofReal, div_self_mul_self', add_zero] at this + rw [uIcc_of_le (by linarith)] at this + linarith [this.1] + · unfold HPow.hPow instHPow + apply DifferentiableAt.const_cpow differentiableAt_fun_id + left + norm_cast + linarith + have f_near_p : (f - fun (z : ℂ) => 1 * (z - 1)⁻¹) =O[nhdsWithin 1 {1}ᶜ] (1 : ℂ → ℂ) := by + simp only [one_mul, f] + exact riemannZetaLogDerivResidueBigO + convert ResidueMult g_holc pInRectangleInterior f_near_p using 1 + ext + simp [f, g] + ring + +lemma interval_membership (r : ℝ) (a b : ℝ) (h1 : r ∈ Set.Icc (min a b) (max a b)) (h2 : a < b) : + a ≤ r ∧ r ≤ b := by + -- Since a < b, we have min(a,b) = a and max(a,b) = b + have min_eq : min a b = a := min_eq_left (le_of_lt h2) + have max_eq : max a b = b := max_eq_right (le_of_lt h2) + rw [min_eq, max_eq] at h1 + rw [← @mem_Icc] + exact h1 + +lemma verticalIntegral_split_three_finite {s a b e σ : ℝ} {f : ℂ → ℂ} + (hf : IntegrableOn (fun t : ℝ ↦ f (σ + t * I)) (Icc s e)) + (hab: s < a ∧ a < b ∧ b < e): + VIntegral f σ s e = + VIntegral f σ s a + + VIntegral f σ a b + + VIntegral f σ b e := by + dsimp [VIntegral] + rw [← intervalIntegrable_iff_integrableOn_Icc_of_le (by linarith)] at hf + rw [← intervalIntegral.integral_add_adjacent_intervals (b := a), + ← intervalIntegral.integral_add_adjacent_intervals (a := a) (b := b)] + · ring + all_goals + apply IntervalIntegrable.mono_set hf + apply uIcc_subset_uIcc <;> apply mem_uIcc_of_le <;> linarith + +lemma verticalIntegral_split_three_finite' {s a b e σ : ℝ} {f : ℂ → ℂ} + (hf : IntegrableOn (fun t : ℝ ↦ f (σ + t * I)) (Icc s e)) + (hab: s < a ∧ a < b ∧ b < e): + (1 : ℂ) / (2 * π * I) * (VIntegral f σ s e) = + (1 : ℂ) / (2 * π * I) * (VIntegral f σ s a) + + (1 : ℂ) / (2 * π * I) * (VIntegral f σ a b) + + (1 : ℂ) / (2 * π * I) * (VIntegral f σ b e) := by + have : (1 : ℂ) / (2 * π * I) * (VIntegral f σ s a) + + (1 : ℂ) / (2 * π * I) * (VIntegral f σ a b) + + (1 : ℂ) / (2 * π * I) * (VIntegral f σ b e) = + (1 : ℂ) / (2 * π * I) * ((VIntegral f σ s a) + + (VIntegral f σ a b) + + (VIntegral f σ b e)) := by ring + rw [this] + clear this + rw [← verticalIntegral_split_three_finite hf hab] + +theorem SmoothedChebyshevPull2_aux1 {T σ₁ : ℝ} (σ₁lt : σ₁ < 1) + (holoOn : HolomorphicOn (ζ' / ζ) (Icc σ₁ 2 ×ℂ Icc (-T) T \ {1})) : + ContinuousOn (fun (t : ℝ) ↦ -ζ' (σ₁ + t * I) / ζ (σ₁ + t * I)) (Icc (-T) T) := by + rw [show (fun (t : ℝ) ↦ -ζ' (↑σ₁ + ↑t * I) / ζ (↑σ₁ + ↑t * I)) = + -(ζ' / ζ) ∘ (fun (t : ℝ) ↦ ↑σ₁ + ↑t * I) by ext; simp; ring_nf] + apply ContinuousOn.neg + apply holoOn.continuousOn.comp (by fun_prop) + intro t ht + simp only [Set.mem_sdiff, mem_singleton_iff] + constructor + · apply mem_reProdIm.mpr + simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + add_zero, add_im, mul_im, zero_add, left_mem_Icc, ht, and_true] + linarith + · intro h + replace h := congr_arg re h + simp at h + linarith + +/- +Next pull contours to another box. +-/ + +/- +We have that + $$ + I_{37} = + I_3 - I_4 + I_5 + I_6 + I_7 + . + $$ +Mimic the proof of Lemma \ref{SmoothedChebyshevPull1}. +-/ +theorem SmoothedChebyshevPull2 {SmoothingF : ℝ → ℝ} {ε : ℝ} (ε_pos : 0 < ε) (ε_lt_one : ε < 1) + (X : ℝ) (_ : 3 < X) + {T : ℝ} (T_pos : 3 < T) {σ₁ σ₂ : ℝ} + (σ₂_pos : 0 < σ₂) (σ₁_lt_one : σ₁ < 1) + (σ₂_lt_σ₁ : σ₂ < σ₁) + (holoOn : HolomorphicOn (ζ' / ζ) ((Icc σ₁ 2) ×ℂ (Icc (-T) T) \ {1})) + (holoOn2 : HolomorphicOn (SmoothedChebyshevIntegrand SmoothingF ε X) + (Icc σ₂ 2 ×ℂ Icc (-3) 3 \ {1})) + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (SmoothingFnonneg : ∀ x > 0, 0 ≤ SmoothingF x) + (mass_one : ∫ x in Ioi 0, SmoothingF x / x = 1) + (diff_SmoothingF : ContDiff ℝ 1 SmoothingF) : + I₃₇ SmoothingF ε T X σ₁ = + I₃ SmoothingF ε T X σ₁ - + I₄ SmoothingF ε X σ₁ σ₂ + + I₅ SmoothingF ε X σ₂ + + I₆ SmoothingF ε X σ₁ σ₂ + + I₇ SmoothingF ε T X σ₁ := by + let z : ℂ := σ₂ - 3 * I + let w : ℂ := σ₁ + 3 * I + have σ₁_pos : 0 < σ₁ := by linarith + -- Step (1) + -- Show that the Rectangle is in a given subset of holomorphicity + have sub : z.Rectangle w ⊆ Icc σ₂ 2 ×ℂ Icc (-3) 3 \ {1} := by + -- for every point x in the Rectangle + intro x hx + constructor + · -- x is in the locus of holomorphicity + simp only [Rectangle, uIcc] at hx + rw [Complex.mem_reProdIm] at hx ⊢ + obtain ⟨hx_re, hx_im⟩ := hx + -- the real part of x is in the correct interval + have hzw_re : z.re < w.re := by + simpa [z, w] using σ₂_lt_σ₁ + have x_re_bounds : z.re ≤ x.re ∧ x.re ≤ w.re := by + exact interval_membership x.re z.re w.re hx_re hzw_re + have x_re_in_Icc : x.re ∈ Icc σ₂ 2 := by + have ⟨h_left, h_right⟩ := x_re_bounds + have h_left' : σ₂ ≤ x.re := by + simpa [z] using h_left + have h_right' : x.re ≤ 2 := by + apply le_trans h_right + have : w.re ≤ 2 := by + simp [w] + linarith + exact this + exact ⟨h_left', h_right'⟩ + -- the imaginary part of x is in the correct interval + have hzw_im : z.im < w.im := by + norm_num [z, w] + have x_im_bounds : z.im ≤ x.im ∧ x.im ≤ w.im := by + exact interval_membership x.im z.im w.im hx_im hzw_im + have x_im_in_Icc : x.im ∈ Icc (-3) 3 := by + have ⟨h_left, h_right⟩ := x_im_bounds + have h_left' : -3 ≤ x.im := by + simpa [z] using h_left + have h_right' : x.im ≤ 3 := by + simpa [w] using h_right + exact ⟨h_left', h_right'⟩ + exact ⟨x_re_in_Icc, x_im_in_Icc⟩ + -- x is not in {1} by contradiction + · simp only [mem_singleton_iff] + -- x has real part less than 1 + have x_re_upper: x.re ≤ σ₁ := by + simp only [Rectangle, uIcc] at hx + rw [Complex.mem_reProdIm] at hx + obtain ⟨hx_re, _⟩ := hx + -- the real part of x is in the interval + have hzw_re : z.re < w.re := by + simpa [z, w] using σ₂_lt_σ₁ + have x_re_bounds : z.re ≤ x.re ∧ x.re ≤ w.re := by + exact interval_membership x.re z.re w.re hx_re hzw_re + have x_re_upper' : x.re ≤ w.re := x_re_bounds.2 + have hw_re : w.re = σ₁ := by simp [w] + linarith + -- by contracdiction + have h_x_ne_one : x ≠ 1 := by + intro h_eq + have h_re : x.re = 1 := by rw [h_eq, Complex.one_re] + have h1 : 1 ≤ σ₁ := by + rw [← h_re] + exact x_re_upper + linarith + exact h_x_ne_one + have zero_over_box := HolomorphicOn.vanishesOnRectangle holoOn2 sub + have splitting : I₃₇ SmoothingF ε T X σ₁ = + I₃ SmoothingF ε T X σ₁ + I₅ SmoothingF ε X σ₁ + I₇ SmoothingF ε T X σ₁ := by + unfold I₃₇ I₃ I₅ I₇ + apply verticalIntegral_split_three_finite' + · apply ContinuousOn.integrableOn_Icc + unfold SmoothedChebyshevIntegrand + apply ContinuousOn.mul + · apply ContinuousOn.mul + · apply SmoothedChebyshevPull2_aux1 σ₁_lt_one holoOn + · apply continuousOn_of_forall_continuousAt + intro t t_mem + have := Smooth1MellinDifferentiable diff_SmoothingF suppSmoothingF ⟨ε_pos, ε_lt_one⟩ + SmoothingFnonneg mass_one (s := ↑σ₁ + ↑t * I) (by simpa) + simpa using realDiff_of_complexDiff _ this + · apply continuousOn_of_forall_continuousAt + intro t t_mem + apply ContinuousAt.comp + · refine continuousAt_const_cpow' ?_ + intro h + have : σ₁ = 0 := by + have h_real : (↑σ₁ + ↑t * I).re = (0 : ℂ).re := by + rw [h] + simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, add_zero, zero_re] at h_real + exact h_real + linarith + · -- continuity -- failed + apply ContinuousAt.add + · exact continuousAt_const + · apply ContinuousAt.mul + · apply continuous_ofReal.continuousAt + · exact continuousAt_const + · refine ⟨by linarith, by linarith, by linarith⟩ + calc I₃₇ SmoothingF ε T X σ₁ = + I₃₇ SmoothingF ε T X σ₁ - (1 / (2 * π * I)) * (0 : ℂ) := by simp + _ = I₃₇ SmoothingF ε T X σ₁ - (1 / (2 * π * I)) * + (RectangleIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z w) := by rw [← + zero_over_box] + _ = I₃₇ SmoothingF ε T X σ₁ - (1 / (2 * π * I)) * + (HIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re w.re z.im + - HIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re w.re w.im + + VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) w.re z.im w.im + - VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re z.im w.im) := by + simp [RectangleIntegral] + _ = I₃₇ SmoothingF ε T X σ₁ - + ((1 / (2 * π * I)) * HIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re w.re z.im + - (1 / (2 * π * I)) * HIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re w.re w.im + + (1 / (2 * π * I)) * VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) w.re z.im w.im + - (1 / (2 * π * I)) * + VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re z.im w.im) := by ring + _ = I₃₇ SmoothingF ε T X σ₁ - (I₄ SmoothingF ε X σ₁ σ₂ + - (1 / (2 * π * I)) * HIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re w.re w.im + + (1 / (2 * π * I)) * VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) w.re z.im w.im + - (1 / (2 * π * I)) * VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re z.im w.im) := + by + simp only [one_div, mul_inv_rev, inv_I, neg_mul, HIntegral, sub_im, ofReal_im, mul_im, + re_ofNat, I_im, mul_one, im_ofNat, I_re, mul_zero, add_zero, zero_sub, ofReal_neg, + ofReal_ofNat, sub_re, ofReal_re, mul_re, sub_self, sub_zero, add_re, add_im, zero_add, + sub_neg_eq_add, I₄, sub_right_inj, add_left_inj, neg_inj, mul_eq_mul_left_iff, mul_eq_zero, + I_ne_zero, inv_eq_zero, ofReal_eq_zero, OfNat.ofNat_ne_zero, or_false, false_or, z, w] + left + rfl + _ = I₃₇ SmoothingF ε T X σ₁ - (I₄ SmoothingF ε X σ₁ σ₂ + - I₆ SmoothingF ε X σ₁ σ₂ + + (1 / (2 * π * I)) * VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) w.re z.im w.im + - (1 / (2 * π * I)) * VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re z.im w.im) := + by + simp only [one_div, mul_inv_rev, inv_I, neg_mul, HIntegral, add_im, ofReal_im, mul_im, + re_ofNat, I_im, mul_one, im_ofNat, I_re, mul_zero, add_zero, zero_add, ofReal_ofNat, sub_re, + ofReal_re, mul_re, sub_self, sub_zero, add_re, sub_neg_eq_add, sub_im, zero_sub, I₆, w, z] + _ = I₃₇ SmoothingF ε T X σ₁ - (I₄ SmoothingF ε X σ₁ σ₂ + - I₆ SmoothingF ε X σ₁ σ₂ + + I₅ SmoothingF ε X σ₁ + - (1 / (2 * π * I)) * VIntegral (SmoothedChebyshevIntegrand SmoothingF ε X) z.re z.im w.im) := + by + simp only [one_div, mul_inv_rev, inv_I, neg_mul, VIntegral, add_re, ofReal_re, mul_re, + re_ofNat, I_re, mul_zero, im_ofNat, I_im, mul_one, sub_self, add_zero, sub_im, ofReal_im, + mul_im, zero_sub, add_im, zero_add, smul_eq_mul, sub_re, sub_zero, sub_neg_eq_add, I₅, + w, z] + _ = I₃₇ SmoothingF ε T X σ₁ - (I₄ SmoothingF ε X σ₁ σ₂ + - I₆ SmoothingF ε X σ₁ σ₂ + + I₅ SmoothingF ε X σ₁ + - I₅ SmoothingF ε X σ₂) := by + simp only [I₅, one_div, mul_inv_rev, inv_I, neg_mul, VIntegral, sub_re, ofReal_re, mul_re, + re_ofNat, I_re, mul_zero, im_ofNat, I_im, mul_one, sub_self, sub_zero, sub_im, ofReal_im, + mul_im, add_zero, zero_sub, add_im, zero_add, smul_eq_mul, sub_neg_eq_add, z, w] + --- starting from now, we split the integral `I₃₇` into `I₃ σ₂ + I₅ σ₁ + I₇ σ₁` using + -- `verticalIntegral_split_three_finite` + _ = I₃ SmoothingF ε T X σ₁ + + I₅ SmoothingF ε X σ₁ + + I₇ SmoothingF ε T X σ₁ + - (I₄ SmoothingF ε X σ₁ σ₂ + - I₆ SmoothingF ε X σ₁ σ₂ + + I₅ SmoothingF ε X σ₁ + - I₅ SmoothingF ε X σ₂) := by + rw [splitting] + _ = I₃ SmoothingF ε T X σ₁ + - I₄ SmoothingF ε X σ₁ σ₂ + + I₅ SmoothingF ε X σ₂ + + I₆ SmoothingF ε X σ₁ σ₂ + + I₇ SmoothingF ε T X σ₁ := by + ring + +/- +We insert this information in $\psi_{\epsilon}$. We add and subtract the integral over the box +$[1-\delta,2] \times_{ℂ} [-T,T]$, which we evaluate as follows +-/ +/- +For all $\epsilon > 0$ sufficiently close to $0$, the rectangle integral over $[1-\delta,2] +\times_{ℂ} [-T,T]$ of the integrand in + $\psi_{\epsilon}$ is + $$ + \frac{X^{1}}{1}\mathcal{M}(\widetilde{1_{\epsilon}})(1) + = X(1+O(\epsilon)) + ,$$ + where the implicit constant is independent of $X$. +Unfold the definitions and apply Lemma \ref{MellinOfSmooth1c}. +-/ +theorem ZetaBoxEval {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (mass_one : ∫ x in Ioi 0, SmoothingF x / x = 1) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) : + ∃ C, ∀ᶠ ε in (nhdsWithin 0 (Ioi 0)), ∀ X : ℝ, 0 ≤ X → + ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) 1 * X - X‖ ≤ C * ε * X := by + have := MellinOfSmooth1c ContDiffSmoothingF suppSmoothingF mass_one + clear suppSmoothingF mass_one ContDiffSmoothingF + rw[Asymptotics.isBigO_iff] at this + obtain ⟨C, hC⟩ := this + use C + have εpos : ∀ᶠ (ε : ℝ) in nhdsWithin 0 (Ioi 0), ε > 0 := + eventually_mem_of_tendsto_nhdsWithin fun ⦃U⦄ hU ↦ hU + filter_upwards [hC, εpos] with ε hC εpos + rw[id_eq, norm_of_nonneg (le_of_lt εpos)] at hC + intro X Xnne + nth_rw 2 [← one_mul (X : ℂ)] + rw[← sub_mul, norm_mul, norm_real, norm_of_nonneg Xnne] + exact mul_le_mul_of_nonneg_right hC Xnne + +theorem poisson_kernel_integrable (x : ℝ) (hx : x ≠ 0) : + MeasureTheory.Integrable (fun (t : ℝ) ↦ (‖x + t * I‖^2)⁻¹) := by + -- First, simplify the complex norm + have h1 : ∀ t : ℝ, ‖x + t * I‖^2 = x^2 + t^2 := by + intro t + rw [← normSq_eq_norm_sq, normSq_add_mul_I] + -- Rewrite the integrand using this simplification + simp_rw [h1] + apply integrable_comp_mul_left_iff _ hx |>.mp + have : (fun t ↦ (x ^ 2 + (x * t) ^ 2) ⁻¹) = (fun t ↦ (1 / x ^ 2) * (1 + t ^ 2) ⁻¹) := by + ext + field_simp + rw [this] + apply integrable_inv_one_add_sq.const_mul + +theorem ae_volume_of_contains_compl_singleton_zero + (s : Set ℝ) + (h : (univ : Set ℝ) \ {0} ⊆ s) : + s ∈ (MeasureTheory.ae volume) := by + -- The key insight is that {0} has measure zero in ℝ + have h_zero_null : volume ({0} : Set ℝ) = 0 := by + exact volume_singleton + -- Since s contains univ \ {0} = ℝ \ {0}, its complement is contained in {0} + have h_compl_subset : sᶜ ⊆ {0} := by + intro x hx + -- If x is not in s, then x is not in ℝ \ {0} (since ℝ \ {0} is a subset of s) + -- This means x = 0 + by_contra h_not_zero + have : x ∈ univ \ {0} := ⟨trivial, h_not_zero⟩ + exact hx (h this) + -- Therefore, volume(sᶜ) ≤ volume({0}) = 0 + have h_compl_measure : volume sᶜ ≤ volume ({0} : Set ℝ) := + measure_mono h_compl_subset + -- So volume(sᶜ) = 0 + have h_compl_zero : volume sᶜ = 0 := by + rw [h_zero_null] at h_compl_measure + exact le_antisymm h_compl_measure (by positivity) + -- A set is in ae.sets iff its complement has measure zero + rwa [mem_ae_iff] + +theorem integral_evaluation (x : ℝ) (T : ℝ) (T_large : 3 < T) : + ∫ (t : ℝ) in Iic (-T), (‖x + t * I‖ ^ 2)⁻¹ ≤ T⁻¹ := by + have T00 : ∀ (x t : ℝ), t^2 ≤ ‖x + t * I‖^2 := by + intro x t + rw [Complex.norm_add_mul_I x t] + ring_nf + rw [Real.sq_sqrt _] + · simp only [le_add_iff_nonneg_right]; positivity + · positivity + have T0 : ∀ (x t : ℝ), t ≠ 0 → (‖x + t * I‖^2)⁻¹ ≤ (t^2)⁻¹ := by + intro x t hyp + have U0 : 0 < t^2 := by positivity + have U1 : 0 < ‖x + t * I‖^2 := by + rw [Complex.norm_add_mul_I x t, + Real.sq_sqrt _] + · positivity + · positivity + rw [inv_le_inv₀ U1 U0] + exact (T00 x t) + have T1 : (fun (t : ℝ) ↦ (‖x + t * I‖^2)⁻¹) ≤ᶠ[ae (volume.restrict (Iic (-T)))] (fun (t : ℝ) ↦ + (t^2)⁻¹) := by + unfold Filter.EventuallyLE + unfold Filter.Eventually + simp_all only [ne_eq, measurableSet_Iic, ae_restrict_eq] + refine mem_inf_of_left ?_ + · refine Filter.mem_sets.mp ?_ + · have U : {x_1 : ℝ | x_1 ≠ 0} ⊆ {x_1 : ℝ | (‖x + x_1 * I‖ ^ 2)⁻¹ ≤ (x_1 ^ 2)⁻¹} := by + rw [Set.ofPred_subset_ofPred] + intro t hyp_t + exact T0 x t hyp_t + have U1 : {x_1 : ℝ | x_1 ≠ 0} = (univ \ {0}) := by + apply Set.ext + intro x + simp_all only [ne_eq, ofPred_subset_ofPred, not_false_eq_true, implies_true, + mem_ofPred_eq, Set.mem_sdiff, mem_univ, mem_singleton_iff, true_and] + rw [U1] at U + exact ae_volume_of_contains_compl_singleton_zero _ U + have T3 : Integrable (fun (t : ℝ) ↦ (t^2)⁻¹) (volume.restrict (Iic (-T))) := by + have D3 := integrableOn_Ioi_rpow_of_lt (by norm_num : (-2 : ℝ) < -1) + (by linarith : 0 < T) |>.comp_neg + simp only [rpow_neg_ofNat, Int.reduceNeg, zpow_neg, neg_Ioi] at D3 + have D4 := + (integrableOn_Iic_iff_integrableOn_Iio' + (by + refine EReal.coe_ennreal_ne_coe_ennreal_iff.mp ?_ + simp_all only [ne_eq, measurableSet_Iic, ae_restrict_eq, measure_singleton, + EReal.coe_ennreal_zero, EReal.coe_ennreal_top, EReal.zero_ne_top, + not_false_eq_true])).mpr D3 + simp_all only [ne_eq, measurableSet_Iic, ae_restrict_eq] + unfold IntegrableOn at D4 + have eq_fun : (fun (x : ℝ) ↦ ((-x)^2)⁻¹) = fun x ↦ (x^2)⁻¹ := by + funext x + simp_all only [even_two, Even.neg_pow] + simp_all only [even_two, Even.neg_pow] + norm_cast at D4 + simp_all only [even_two, Even.neg_pow] + calc + _ ≤ ∫ (t : ℝ) in Iic (-T), (t^2)⁻¹ := by + apply MeasureTheory.integral_mono_of_nonneg _ T3 T1 + filter_upwards [] with x + simp + _ = _ := by + rw [← integral_comp_neg_Ioi] + conv => lhs; arg 2; ext x; rw [show ((-x) ^ 2)⁻¹ = x ^ (-2 : ℝ) by simp [zpow_ofNat]] + rw[integral_Ioi_rpow_of_lt (by norm_num) (by linarith)] + ring_nf + rw [rpow_neg_one] + +/- +It remains to estimate all of the integrals. +-/ + +/- +This auxiliary lemma is useful for what follows. +-/ +/- +Given a natural number $k$ and a real number $X_0 > 0$, there exists $C \geq 1$ so that for all $X +\geq X_0$, + $$ + \log^k X \le C \cdot X. + $$ +We use the fact that $\log^k X / X$ goes to $0$ as $X \to \infty$. + Then we use the extreme value theorem to find a constant $C$ that works for all $X \geq X_0$. +-/ +lemma IBound_aux1 (X₀ : ℝ) (X₀pos : X₀ > 0) {k : ℝ} (k_pos : 0 < k) : ∃ C ≥ 1, ∀ X ≥ X₀, Real.log + X ^ k ≤ C * X := by + -- When X is large, the ratio goes to 0. + have ⟨M, hM⟩ := Filter.eventually_atTop.mp (isLittleO_log_rpow_rpow_atTop k + zero_lt_one).eventuallyLE + -- When X is small, use the extreme value theorem. + let f := fun X ↦ Real.log X ^ k / X + set I := Icc X₀ M with defI + have : 0 ∉ I := notMem_Icc_of_lt X₀pos + have f_cont : ContinuousOn f (Icc X₀ M) := by + unfold f + refine ContinuousOn.div₀ (ContinuousOn.rpow (continuousOn_log.mono ?_) continuousOn_const (fun + _ _ ↦ Or.inr k_pos)) (continuousOn_id' _) (fun x hx h ↦ ?_) + · simp only [subset_compl_singleton_iff, ← defI, this, not_false_eq_true] + · rw [← defI, h] at hx + exact this hx + have ⟨C₁, hC₁⟩ := isCompact_Icc.exists_bound_of_continuousOn f_cont + use max C₁ 1, le_max_right C₁ 1 + intro X hX + have Xpos : X > 0 := lt_of_lt_of_le X₀pos hX + by_cases hXM : X ≤ M + · rw[← div_le_iff₀ Xpos] + calc + f X ≤ ‖f X‖ := le_norm_self _ + _ ≤ C₁ := hC₁ X ⟨hX, hXM⟩ + _ ≤ max C₁ 1 := le_max_left C₁ 1 + · calc + Real.log X ^ k ≤ ‖Real.log X ^ k‖ := le_norm_self _ + _ ≤ ‖X ^ 1‖ := by exact_mod_cast hM X (by linarith[hXM]) + _ = 1 * X := by + rw[pow_one, one_mul] + apply norm_of_nonneg + exact Xpos.le + _ ≤ max C₁ 1 * X := by + rw[mul_le_mul_iff_left₀ Xpos] + exact le_max_right C₁ 1 + +/-- The uniform estimate for contour segment `I₁` used in the PNT argument. -/ +def I1BoundGenProp (SmoothingF : ℝ → ℝ) : Prop := ∃ C > 0, ∀(ε : ℝ) (_ : 0 < ε) + (_ : ε < 1) + (X : ℝ) (_ : 3 < X) + {T : ℝ} (_ : 3 < T), + ‖I₁ SmoothingF ε X T‖ ≤ C * X * Real.log X / (ε * T) + +/- +We have that + $$ + \left|I_{1}(\nu, \epsilon, X, T)\ + \right| \ll \frac{X\log X}{\epsilon T} + . + $$ +Unfold the definitions and apply the triangle inequality. + $$ + \left|I_{1}(\nu, \epsilon, X, T)\right| = + \left| + \frac{1}{2\pi i} \int_{-\infty}^{-T} + \left( + \frac{-\zeta'}\zeta(\sigma_0 + t i) + \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma_0 + t i) + X^{\sigma_0 + t i} + \ i \ dt + \right| + $$ + By Theorem \ref{dlog_riemannZeta_bdd_on_vertical_lines}, + $\zeta'/\zeta (\sigma_0 + t i)$ is bounded by $\zeta'/\zeta(\sigma_0)$, and + Theorem \ref{riemannZetaLogDerivResidue} gives $\ll 1/(\sigma_0-1)$ for the latter. This gives: + $$ + \leq + \frac{1}{2\pi} + \left| + \int_{-\infty}^{-T} + C \log X\cdot + \frac{C'}{\epsilon|\sigma_0 + t i|^2} + X^{\sigma_0} + \ dt + \right| + , + $$ + where we used Theorem \ref{MellinOfSmooth1b}. + Continuing the calculation, we have + $$ + \leq + \log X \cdot + C'' \frac{X^{\sigma_0}}{\epsilon} + \int_{-\infty}^{-T} + \frac{1}{t^2} + \ dt + \ \leq \ + C''' \frac{X\log X}{\epsilon T} + , + $$ + where we used that $\sigma_0=1+1/\log X$, and $X^{\sigma_0} = X\cdot X^{1/\log X}=e \cdot X$. +-/ +theorem I1Bound + {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) (ContDiffSmoothingF : ContDiff + ℝ 1 SmoothingF) + (SmoothingFnonneg : ∀ x > 0, 0 ≤ SmoothingF x) + (mass_one : ∫ x in Ioi 0, SmoothingF x / x = 1) : + I1BoundGenProp SmoothingF := by + obtain ⟨M, ⟨M_is_pos, M_bounds_mellin_hard⟩⟩ := + MellinOfSmooth1b ContDiffSmoothingF suppSmoothingF + have G0 : ∃ K > 0, ∀ t σ : ℝ, 1 < σ → σ < 2 → + ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ ≤ K * (σ - 1)⁻¹ := by + obtain ⟨K, hKpos, hK⟩ := triv_bound_zeta + refine ⟨2 * (K + 1), by positivity, fun t σ hσ hσ₂ => ?_⟩ + have hinv : 1 ≤ (σ - 1)⁻¹ := (one_le_inv₀ (by linarith)).2 (by linarith) + have hb : ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ ≤ (σ - 1)⁻¹ + K := by + simpa only [neg_div, norm_neg] using hK σ t hσ + nlinarith [mul_le_mul_of_nonneg_left hinv (show 0 ≤ K + 1 by positivity)] + obtain ⟨K, ⟨K_is_pos, K_bounds_zeta_at_any_t'⟩⟩ := G0 + have C_final_pos : |π|⁻¹ * 2⁻¹ * (Real.exp 1 * K * M) > 0 := by + positivity + use (|π|⁻¹ * 2⁻¹ * (Real.exp 1 * K * M)) + use C_final_pos + intro eps eps_pos eps_less_one X X_large T T_large + let pts_re := 1 + (Real.log X)⁻¹ + let pts := fun (t : ℝ) ↦ (pts_re + t * I) + have pts_re_triv (t : ℝ) : (pts t).re = pts_re := by simp [pts] + have pts_re_ge_one : 1 < pts_re := by + unfold pts_re + simp only [lt_add_iff_pos_right, inv_pos] + have U : 1 < X := by linarith + exact Real.log_pos U + have pts_re_le_one : pts_re < 2 := by + have := inv_lt_one_of_one_lt₀ (logt_gt_one X_large.le) + dsimp [pts_re] + linarith + have inve : (pts_re - 1)⁻¹ = Real.log X := by + unfold pts_re + simp_all only [one_div, support_subset_iff, ne_eq, mem_Icc, mul_inv_rev, gt_iff_lt, + Complex.norm_div, add_sub_cancel_left, inv_inv] + have K_bounds_zeta_at_any_t : + ∀(t : ℝ), ‖ζ' (pts t) / ζ (pts t)‖ ≤ K * Real.log X := by + intro t + rw [←inve] + exact K_bounds_zeta_at_any_t' t pts_re pts_re_ge_one pts_re_le_one + have pts_re_pos : pts_re > 0 := by + unfold pts_re + positivity + have triv_pts_lo_bound : ∀(t : ℝ), pts_re ≤ (pts t).re := by + intro t + unfold pts_re + exact Eq.ge (pts_re_triv t) + have triv_pts_up_bound : ∀ t : ℝ, (pts t).re ≤ 2 := by + intro t + simpa [pts] using pts_re_le_one.le + have pts_re_ge_1 : 1 < pts_re := pts_re_ge_one + have X_pos_triv : 0 < X := by positivity + let f := fun (t : ℝ) ↦ SmoothedChebyshevIntegrand SmoothingF eps X (pts t) + /- Main pointwise bound -/ + have G : ∀(t : ℝ), ‖f t‖ ≤ (K * M) * Real.log X * (eps * ‖pts t‖^2)⁻¹ * X^pts_re := by + intro t + let M_bounds_mellin_easy := fun (t : ℝ) ↦ + M_bounds_mellin_hard pts_re pts_re_pos (pts t) (triv_pts_lo_bound t) (triv_pts_up_bound t) + eps eps_pos eps_less_one + let zeta_part := (fun (t : ℝ) ↦ -ζ' (pts t) / ζ (pts t)) + let mellin_part := (fun (t : ℝ) ↦ 𝓜 (fun x ↦ (Smooth1 SmoothingF eps x : ℂ)) (pts t)) + let X_part := (fun (t : ℝ) ↦ (↑X : ℂ) ^ (pts t)) + let g := fun (t : ℝ) ↦ (zeta_part t) * (mellin_part t) * (X_part t) + have X_part_eq : ∀(t : ℝ), ‖X_part t‖ = X^pts_re := by + intro t + have U := Complex.norm_cpow_eq_rpow_re_of_pos (X_pos_triv) (pts t) + rw [pts_re_triv t] at U + exact U + have X_part_bound : ∀(t : ℝ), ‖X_part t‖ ≤ X^pts_re := by + intro t + rw [←X_part_eq] + have mellin_bound : ∀(t : ℝ), ‖mellin_part t‖ ≤ M * (eps * ‖pts t‖ ^ 2)⁻¹ := by + intro t + exact M_bounds_mellin_easy t + have X_part_and_mellin_bound : + ∀(t : ℝ), ‖mellin_part t * X_part t‖ ≤ M * (eps * ‖pts t‖^2)⁻¹ * X^pts_re := by + intro t + exact norm_mul_le_of_le (mellin_bound t) (X_part_bound t) + have T2 : ∀(t : ℝ), ‖zeta_part t‖ = ‖ζ' (pts t) / ζ (pts t)‖ := by + intro t + unfold zeta_part + simp only [Complex.norm_div, norm_neg] + have zeta_bound : ∀(t : ℝ), ‖zeta_part t‖ ≤ K * Real.log X := by + intro t + unfold zeta_part + rw [T2] + exact K_bounds_zeta_at_any_t t + have g_bound : ∀(t : ℝ), ‖zeta_part t * (mellin_part t * X_part t)‖ ≤ + (K * Real.log X) * (M * (eps * ‖pts t‖^2)⁻¹ * X^pts_re) := by + intro t + exact norm_mul_le_of_le (zeta_bound t) (X_part_and_mellin_bound t) + have T1 : f = g := rfl + have final_bound_pointwise : + ‖f t‖ ≤ K * Real.log X * (M * (eps * ‖pts t‖^2)⁻¹ * X^pts_re) := by + rw [T1] + unfold g + rw [mul_assoc] + exact g_bound t + have trivialize : + K * Real.log X * (M * (eps * ‖pts t‖^2)⁻¹ * X^pts_re) = + (K * M) * Real.log X * (eps * ‖pts t‖^2)⁻¹ * X^pts_re := by ring_nf + rw [trivialize] at final_bound_pointwise + exact final_bound_pointwise + have σ₀_gt : 1 < pts_re := pts_re_ge_1 + have σ₀_le_2 : pts_re ≤ 2 := by + unfold pts_re + -- LOL! + exact + Preorder.le_trans (1 + (Real.log X)⁻¹) (pts (SmoothingF (SmoothingF M))).re 2 + (triv_pts_lo_bound (SmoothingF (SmoothingF M))) + (triv_pts_up_bound (SmoothingF (SmoothingF M))) + have f_integrable := SmoothedChebyshevPull1_aux_integrable eps_pos eps_less_one X_large σ₀_gt + σ₀_le_2 suppSmoothingF SmoothingFnonneg mass_one ContDiffSmoothingF + have S : X^pts_re = rexp 1 * X := by + unfold pts_re + calc + X ^ (1 + (Real.log X)⁻¹) = X * X ^ ((Real.log X)⁻¹) := by + refine rpow_one_add' ?_ ?_ + · positivity + · exact Ne.symm (ne_of_lt pts_re_pos) + _ = X * rexp 1 := by + refine (mul_right_inj' ?_).mpr ?_ + · exact Ne.symm (ne_of_lt X_pos_triv) + · refine rpow_inv_log X_pos_triv ?_ + · by_contra h + simp_all only [one_div, support_subset_iff, ne_eq, mem_Icc, mul_inv_rev, gt_iff_lt, + Complex.norm_div, Nat.not_ofNat_lt_one] + _ = rexp 1 * X := by ring_nf + have pts_re_neq_zero : pts_re ≠ 0 := + ne_of_gt (zero_lt_one.trans pts_re_ge_one) + have Z := + by + calc + ‖∫ (t : ℝ) in Iic (-T), f t‖ ≤ ∫ (t : ℝ) in Iic (-T), ‖f t‖ := + MeasureTheory.norm_integral_le_integral_norm f + _ ≤ ∫ (t : ℝ) in Iic (-T), (K * M) * Real.log X * (eps * ‖pts t‖ ^ 2)⁻¹ * X ^ pts_re := by + refine integral_mono ?_ ?_ (fun t ↦ G t) + · refine Integrable.norm ?_ + · unfold f + exact MeasureTheory.Integrable.restrict f_integrable + · have equ : ∀(t : ℝ), (K * M) * Real.log X * (eps * ‖pts t‖ ^ 2)⁻¹ * X ^ pts_re = (K + * M) * Real.log X * eps⁻¹ * X ^ pts_re * (‖pts t‖^2)⁻¹ := by + intro t; ring_nf + have fun_equ : (fun (t : ℝ) ↦ ((K * M) * Real.log X * (eps * ‖pts t‖ ^ 2)⁻¹ * X ^ + pts_re)) = (fun (t : ℝ) ↦ ((K * M) * Real.log X * eps⁻¹ * X ^ pts_re * (‖pts + t‖^2)⁻¹)) := by + funext t + exact equ t + rw [fun_equ] + have simple_int : MeasureTheory.Integrable (fun (t : ℝ) ↦ (‖pts t‖^2)⁻¹) + := by + unfold pts + exact poisson_kernel_integrable pts_re (pts_re_neq_zero) + have U := MeasureTheory.Integrable.const_mul simple_int + ((K * M) * Real.log X * eps⁻¹ * X ^ pts_re) + refine MeasureTheory.Integrable.restrict ?_ + exact U + _ = (K * M) * Real.log X * X ^ pts_re * eps⁻¹ * + ∫ (t : ℝ) in Iic (-T), (‖pts t‖ ^ 2)⁻¹ := by + have simpli_fun : + (fun (t : ℝ) ↦ (K * M) * Real.log X * (eps * ‖pts t‖ ^ 2)⁻¹ * X ^ pts_re) = + (fun (t : ℝ) ↦ ((K * M) * Real.log X * X ^ pts_re * eps⁻¹ * (‖pts t‖^2)⁻¹)) := + by funext t; ring_nf + rw [simpli_fun] + exact MeasureTheory.integral_const_mul ((K * M) * Real.log X * X ^ pts_re * eps⁻¹) + (fun (t : ℝ) ↦ (‖pts t‖^2)⁻¹) + _ ≤ (K * M) * Real.log X * X ^ pts_re * eps⁻¹ * T⁻¹ := by + have U := integral_evaluation (pts_re) T (T_large) + unfold pts + simp only [ge_iff_le] + have U2 : 0 ≤ (K * M) * Real.log X * X ^ pts_re * eps⁻¹ := by + simp_all only [one_div, support_subset_iff, ne_eq, mem_Icc, mul_inv_rev, gt_iff_lt, + Complex.norm_div, le_refl, implies_true, inv_pos, mul_nonneg_iff_of_pos_right] + refine Left.mul_nonneg ?_ ?_ + · refine Left.mul_nonneg ?_ ?_ + · exact Left.mul_nonneg (by positivity) (by positivity) + · refine log_nonneg ?_ + · linarith + · refine Left.mul_nonneg ?_ ?_ + · exact exp_nonneg 1 + · exact le_of_lt X_pos_triv + exact mul_le_mul_of_nonneg_left U U2 + _ = (Real.exp 1 * K * M) * Real.log X * X * eps⁻¹ * T⁻¹ := by + rw [S] + ring_nf + _ = (Real.exp 1 * K * M) * X * Real.log X / (eps * T) := by ring_nf + unfold I₁ + unfold f at Z + unfold pts at Z + have Z3 : (↑pts_re : ℂ) = 1 + (Real.log X)⁻¹ := by unfold pts_re; norm_cast + rw [Z3] at Z + rw [Complex.norm_mul (1 / (2 * ↑π * I)) _] + simp only [one_div, mul_inv_rev, inv_I, neg_mul, norm_neg, Complex.norm_mul, norm_I, norm_inv, + norm_real, norm_eq_abs, Complex.norm_ofNat, one_mul, ofReal_inv, ge_iff_le] + have Z2 : 0 ≤ |π|⁻¹ * 2⁻¹ := by positivity + simp only [ofReal_inv] at Z + simp only [ge_iff_le] + have Z4 := mul_le_mul_of_nonneg_left Z Z2 + ring_nf + ring_nf at Z4 + exact Z4 + +lemma I9I1 {SmoothingF : ℝ → ℝ} {ε X T : ℝ} (Xpos : 0 < X) : + I₉ SmoothingF ε X T = conj (I₁ SmoothingF ε X T) := by + unfold I₉ I₁ + simp only [map_mul, map_div₀, conj_I, conj_ofReal, conj_ofNat, map_one] + rw [neg_mul, mul_neg, ← neg_mul] + congr + · ring + · rw [← integral_conj, ← integral_comp_neg_Ioi, integral_Ici_eq_integral_Ioi] + apply setIntegral_congr_fun <| measurableSet_Ioi + intro t ht + simp only + rw[← smoothedChebyshevIntegrand_conj Xpos] + simp + +/-- The uniform estimate for contour segment `I₉` used in the PNT argument. -/ +def I9BoundGenProp (SmoothingF : ℝ → ℝ) : Prop := ∃ C > 0, ∀{ε : ℝ} (_ : 0 < ε) + (_ : ε < 1) + (X : ℝ) (_ : 3 < X) + {T : ℝ} (_ : 3 < T), + ‖I₉ SmoothingF ε X T‖ ≤ C * X * Real.log X / (ε * T) + +/- +We have that + $$ + \left|I_{1}(\nu, \epsilon, X, T)\ + \right| \ll \frac{X}{\epsilon T} + . + $$ +We deduce this from the corresponding bound for $I_1$, using the symmetry between $I_1$ and $I_9$. +-/ +theorem I9Bound + {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) (ContDiffSmoothingF : ContDiff + ℝ 1 SmoothingF) + (SmoothingFnonneg : ∀ x > 0, 0 ≤ SmoothingF x) + (mass_one : ∫ x in Ioi 0, SmoothingF x / x = 1) : + I9BoundGenProp SmoothingF := by + obtain ⟨C, Cpos, bound⟩ := I1Bound suppSmoothingF ContDiffSmoothingF SmoothingFnonneg mass_one + refine ⟨C, Cpos, ?_⟩ + intro ε εpos ε_lt_one X X_gt T T_gt + specialize bound ε εpos ε_lt_one X X_gt T_gt + rwa [I9I1 (by linarith), norm_conj] + +lemma one_add_inv_log {X : ℝ} (X_ge : 3 ≤ X) : (1 + (Real.log X)⁻¹) < 2 := by + rw[← one_add_one_eq_two] + refine (add_lt_add_iff_left 1).mpr ?_ + refine inv_lt_one_of_one_lt₀ (logt_gt_one X_ge) + +/-- The uniform estimate for contour segment `I₂` used in the PNT argument. -/ +def I2BoundGenProp (n : ℝ) (SmoothingF : ℝ → ℝ) (A : ℝ) : Prop := ∃ (C : ℝ) (_ : 0 < C), + ∀(X : ℝ) (_ : 3 < X) {ε : ℝ} (_ : 0 < ε) + (_ : ε < 1) {T : ℝ} (_ : 3 < T), + let σ₁ : ℝ := 1 - A / (Real.log T) ^ n + ‖I₂ SmoothingF ε T X σ₁‖ ≤ C * X / (ε * T) + +/- +Assuming a bound of the form of Definition \ref{LogDerivZetaHasBound} we have that + $$ + \left|I_2(\nu,\epsilon,X,T)\right|\ll\frac{X}{\epsilon T}. + $$ +Unfold the definitions and apply the triangle inequality. + $$ + \left|I_2(\nu, \epsilon, X, T, \sigma_1)\right|= + \left|\frac{1}{2\pi i}\int_{\sigma_1}^{\sigma_0} + \left(\frac{-\zeta'}\zeta(\sigma - T i) \right) \cdot + \mathcal M(\widetilde 1_\epsilon)(\sigma - T i) \cdot + X^{\sigma - T i} + \ d\sigma + \right| + $$ + $$\leq + \frac{1}{2\pi} + \int_{\sigma_1}^{\sigma_0} + C \cdot \log T ^{n_2} + \frac{C'}{\epsilon|\sigma - T i|^2} + X^{\sigma_0} + \ d\sigma + \leq + C'' \cdot \frac{X\log T^{n_2}}{\epsilon T^2} + , + $$ + where we used Theorems \ref{MellinOfSmooth1b}, the hypothesised bound on zeta and the fact that + $X^\sigma \le X^{\sigma_0} = X\cdot X^{1/\log X}=e \cdot X$. + Since $T>3$, we have $\log T^{n_2} \leq C''' T$. +-/ +lemma I2GenBound {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) + {n₁ n₂ : ℝ} (n₁_pos : 0 < n₁) (n₂_pos : 0 < n₂) {A C₂ : ℝ} (has_bound : LogDerivZetaHasBound + n₁ n₂ A C₂) (C₂pos : 0 < C₂) (A_in : A ∈ Ioc 0 (1 / 2)) : + I2BoundGenProp n₁ SmoothingF A := by + have ⟨C₁, C₁pos, Mbd⟩ := MellinOfSmooth1b ContDiffSmoothingF suppSmoothingF + have := (IBound_aux1 3 (by norm_num) n₂_pos) + obtain ⟨C₃, ⟨C₃_gt, hC₃⟩⟩ := this + let C' : ℝ := C₁ * C₂ * C₃ * rexp 1 + have : C' > 0 := by positivity + use ‖1/(2*π*I)‖ * (2 * C'), by + refine Right.mul_pos ?_ ?_ + · rw[norm_pos_iff] + simp[pi_ne_zero] + · simp[this] + intro X X_gt ε ε_pos ε_lt_one T T_gt σ₁ + have Xpos : 0 < X := lt_trans (by simp only [Nat.ofNat_pos]) X_gt + have Tpos : 0 < T := lt_trans (by norm_num) T_gt + unfold I₂ + rw[norm_mul, mul_assoc (c := X), ← mul_div] + refine mul_le_mul_of_nonneg_left ?_ (norm_nonneg _) + have interval_length_nonneg : σ₁ ≤ 1 + (Real.log X)⁻¹ := by + dsimp[σ₁] + rw[sub_le_iff_le_add] + nth_rw 1 [← add_zero 1] + rw[add_assoc] + apply add_le_add_right + refine Left.add_nonneg ?_ ?_ + · rw[inv_nonneg, log_nonneg_iff Xpos] + exact le_trans (by norm_num) (le_of_lt X_gt) + · refine div_nonneg ?_ ?_ + · exact A_in.1.le + apply Real.rpow_nonneg + rw[log_nonneg_iff Tpos] + exact le_trans (by norm_num) (le_of_lt T_gt) + have σ₁pos : 0 < σ₁ := by + rw[sub_pos] + calc + A / Real.log T ^ n₁ ≤ 1 / 2 / Real.log T ^ n₁ := by + refine div_le_div_of_nonneg_right (A_in.2) ?_ + apply Real.rpow_nonneg + rw[log_nonneg_iff Tpos] + exact le_trans (by norm_num) (le_of_lt T_gt) + _ ≤ 1 / 2 / 1 := by + refine div_le_div_of_nonneg_left (by norm_num) (by norm_num) (Real.one_le_rpow ?_ n₁_pos.le) + rw[Real.le_log_iff_exp_le Tpos] + linarith [Real.exp_one_lt_d9] + _ < 1 := by norm_num + suffices ∀ σ ∈ Ioc σ₁ (1 + (Real.log X)⁻¹), + ‖SmoothedChebyshevIntegrand SmoothingF ε X (↑σ - ↑T * I)‖ ≤ C' * X / (ε * T) by + calc + ‖∫ (σ : ℝ) in σ₁..1 + (Real.log X)⁻¹, + SmoothedChebyshevIntegrand SmoothingF ε X (↑σ - ↑T * I)‖ ≤ + C' * X / (ε * T) * |1 + (Real.log X)⁻¹ - σ₁| := by + refine intervalIntegral.norm_integral_le_of_norm_le_const ?_ + convert this using 3 + rw [uIoc_of_le interval_length_nonneg] + _ ≤ C' * X / (ε * T) * 2 := by + apply mul_le_mul_of_nonneg_left + · rw[abs_of_nonneg (sub_nonneg.mpr interval_length_nonneg)] + calc + 1 + (Real.log X)⁻¹ - σ₁ ≤ 1 + (Real.log X)⁻¹ := by linarith + _ ≤ 2 := (one_add_inv_log X_gt.le).le + positivity + _ = 2 * C' * X / (ε * T) := by ring + intro σ hσ + unfold SmoothedChebyshevIntegrand + have log_deriv_zeta_bound : ‖ζ' (σ - T * I) / ζ (σ - T * I)‖ ≤ C₂ * (C₃ * T) := by + calc + ‖ζ' (σ - (T : ℝ) * I) / ζ (σ - (T : ℝ) * I)‖ = ‖ζ' (σ + (-T : ℝ) * I) / ζ (σ + (-T : ℝ) * + I)‖ := by + have Z : σ - (T : ℝ) * I = σ + (- T : ℝ) * I := by simp; ring_nf + simp [Z] + _ ≤ C₂ * Real.log |-T| ^ n₂ := has_bound σ (-T) + (by simp only [abs_neg]; rw [abs_of_pos Tpos]; exact T_gt) + (by unfold σ₁ at hσ; simp only [mem_Ioc, abs_neg, log_abs, mem_Ici, + tsub_le_iff_right] at hσ ⊢; replace hσ := hσ.1; linarith) + _ ≤ C₂ * Real.log T ^ n₂ := by simp + _ ≤ C₂ * (C₃ * T) := by gcongr; exact hC₃ T (by linarith) + calc + ‖-ζ' (σ - T * I) / ζ (σ - T * I) * 𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) + (σ - T * I) * X ^ (σ - T * I)‖ = + ‖-ζ' (σ - T * I) / ζ (σ - T * I)‖ * ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) + (σ - T * I)‖ * ‖(X : ℂ) ^ (σ - T * I)‖ := by + repeat rw[norm_mul] + _ ≤ C₂ * (C₃ * T) * (C₁ * (ε * ‖σ - T * I‖ ^ 2)⁻¹) * (rexp 1 * X) := by + apply mul_le_mul₃ + · rw[neg_div, norm_neg] + exact log_deriv_zeta_bound + · refine Mbd σ₁ σ₁pos _ ?_ ?_ ε ε_pos ε_lt_one + · simp only [mem_Ioc, sub_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, sub_zero, σ₁] at hσ ⊢ + linarith + · simp only [mem_Ioc, sub_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, sub_zero, σ₁] at hσ ⊢ + linarith[one_add_inv_log X_gt.le] + · rw[cpow_def_of_ne_zero] + · rw[norm_exp,← ofReal_log, re_ofReal_mul] + · simp only [sub_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, + sub_zero] + rw [← le_log_iff_exp_le, Real.log_mul (exp_ne_zero 1), Real.log_exp, ← le_div_iff₀', + add_comm, add_div, div_self, one_div] + · exact hσ.2 + · refine (Real.log_pos ?_).ne.symm + linarith + · apply Real.log_pos + linarith + · linarith + · positivity + · positivity + · exact_mod_cast Xpos.ne.symm + · positivity + · positivity + · positivity + _ = (C' * X * T) / (ε * ‖σ - T * I‖ ^ 2) := by ring + _ ≤ C' * X / (ε * T) := by + have : ‖σ - T * I‖ ^ 2 ≥ T ^ 2 := by + calc + ‖σ - T * I‖ ^ 2 = ‖σ + (-T : ℝ) * I‖ ^ 2 := by + congr 2 + push_cast + ring + _ = normSq (σ + (-T : ℝ) * I) := (normSq_eq_norm_sq _).symm + _ = σ^2 + (-T)^2 := by + rw[Complex.normSq_add_mul_I] + _ ≥ T^2 := by + rw[neg_sq] + exact le_add_of_nonneg_left (sq_nonneg _) + calc + C' * X * T / (ε * ‖↑σ - ↑T * I‖ ^ 2) ≤ C' * X * T / (ε * T ^ 2) := by + rw[div_le_div_iff_of_pos_left, mul_le_mul_iff_right₀] + · exact this + · exact ε_pos + · positivity + · apply mul_pos ε_pos + exact lt_of_lt_of_le (pow_pos Tpos 2) this + · positivity + _ = C' * X / (ε * T) := by + field_simp + +/- +Symmetry between $I_2$ and $I_8$: + $$ + I_8(\nu, \epsilon, X, T) = -\overline{I_2(\nu, \epsilon, X, T)} + . + $$ +This is a direct consequence of the definitions of $I_2$ and $I_8$. +-/ +lemma I8I2 {SmoothingF : ℝ → ℝ} + {X ε T σ₁ : ℝ} (T_gt : 3 < T) : + I₈ SmoothingF ε X T σ₁ = -conj (I₂ SmoothingF ε X T σ₁) := by + unfold I₂ I₈ + rw[map_mul, ← neg_mul] + congr + · simp[conj_ofNat] + · rw[← intervalIntegral_conj] + apply intervalIntegral.integral_congr + intro σ hσ + simp only [] + rw[← smoothedChebyshevIntegrand_conj] + · simp only [map_sub, conj_ofReal, map_mul, conj_I, mul_neg, sub_neg_eq_add] + · exact lt_trans (by norm_num) T_gt + +/-- The uniform estimate for contour segment `I₈` used in the PNT argument. -/ +def I8BoundGenProp (n : ℝ) (SmoothingF : ℝ → ℝ) (A : ℝ) : Prop := ∃ (C : ℝ) (_ : 0 < C), + ∀(X : ℝ) (_ : 3 < X) {ε : ℝ} (_: 0 < ε) + (_ : ε < 1) + {T : ℝ} (_ : 3 < T), + let σ₁ : ℝ := 1 - A / (Real.log T) ^ n + ‖I₈ SmoothingF ε T X σ₁‖ ≤ C * X / (ε * T) + +/- +Assuming a bound of the form of Definition \ref{LogDerivZetaHasBound}, we have that + $$ + \left|I_8(\nu,\epsilon,X,T)\right|\ll\frac{X}{\epsilon T}. + $$ +We deduce this from the corresponding bound for $I_2$, using the symmetry between $I_2$ and $I_8$. +-/ +lemma I8GenBound {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) + {n₁ n₂ : ℝ} (n₁_pos : 0 < n₁) (n₂_pos : 0 < n₂) {A C₂ : ℝ} (has_bound : LogDerivZetaHasBound + n₁ n₂ A C₂) (C₂_pos : 0 < C₂) (A_in : A ∈ Ioc 0 (1 / 2)) : + I8BoundGenProp n₁ SmoothingF A := by + obtain ⟨C, hC, i2Bound⟩ := I2GenBound suppSmoothingF ContDiffSmoothingF n₁_pos n₂_pos has_bound + C₂_pos A_in + use C, hC + intro X hX ε hε0 hε1 T hT σ₁ + let i2Bound := i2Bound X hX hε0 hε1 hT + rw[I8I2 hX, norm_neg, norm_conj] + exact i2Bound + +/- +For all $00$ (depending on $n$) such that + $$ + \int_3^T\frac{(\log x)^n}{x^2}dx < C + $$ +Using the previous lemma, we know for all $0 3, ∫ x in Ioo 3 T, (Real.log x) ^ n / x ^ 2 < C := by + intro n n_pos + set c : ℝ := 2 * n with cDef + have cpos : 0 < c := by linarith + set g : ℝ → ℝ := fun x => c ^ n * x ^ (-(3 / 2) : ℝ) with gDef + have g_nonneg : ∀ x ∈ Ioi (3 : ℝ), 0 ≤ g x := by + intro x hx; simp only [mem_Ioi] at hx + exact mul_nonneg (Real.rpow_nonneg (by linarith) _) (Real.rpow_nonneg (by linarith) _) + have gInt_nonneg : 0 ≤ ∫ x in Ioi (3 : ℝ), g x := setIntegral_nonneg measurableSet_Ioi g_nonneg + have g_integrable : IntegrableOn g (Ioi 3) := + Integrable.const_mul (integrableOn_Ioi_rpow_of_lt (by linarith) (by linarith)) _ + have g_mono : ∀ x ∈ Ioi (3 : ℝ), Real.log x ^ n / x ^ 2 ≤ g x := by + intro x hx; simp only [mem_Ioi] at hx + have xpos : 0 < x := by linarith + have logxPos : 0 < Real.log x := by + rw [Real.log_pos_iff xpos.le] + linarith + have logBnd := Real.rpow_le_rpow logxPos.le (Real.log_le_const_mul_rpow cpos xpos) n_pos.le + rw [Real.mul_rpow cpos.le (Real.rpow_nonneg xpos.le _), ← Real.rpow_mul xpos.le, cDef] at logBnd + field_simp at logBnd + have : - ((3 : ℝ) / 2) = (1 / 2) - 2 := by norm_num + simp only [cDef, gDef, this, Real.rpow_sub xpos, ← mul_div_assoc, rpow_ofNat] + exact (div_le_div_iff_of_pos_right (sq_pos_iff.mpr (ne_of_gt xpos))).mpr logBnd + refine ⟨1 + (∫ x in Ioi (3 : ℝ), g x), by linarith, fun T _ => ?_⟩ + calc + _ ≤ ∫ (x : ℝ) in Ioo 3 T, g x := by + refine setIntegral_mono_on (IntegrableOn.mono_set (ContinuousOn.integrableOn_Icc + (ContinuousOn.div (ContinuousOn.rpow_const (ContinuousOn.log (continuousOn_id' _) + (fun x hx ↦ ?_)) ?_) (ContinuousOn.fun_pow (continuousOn_id' _) _) + (fun x hx ↦ pow_ne_zero _ ?_))) Ioo_subset_Icc_self) + (IntegrableOn.mono_set g_integrable Ioo_subset_Ioi_self) measurableSet_Ioo + (fun x hx ↦ g_mono x hx.1) + · linarith [hx.1] + · simp only [mem_Icc, ne_eq, log_eq_zero, not_or, n_pos.le, or_true, implies_true] + · linarith [hx.1] + _ ≤ ∫ (x : ℝ) in Ioi 3, g x := by + refine setIntegral_mono_set g_integrable ?_ (LE.le.eventuallyLE Ioo_subset_Ioi_self) + exact MeasureTheory.ae_restrict_of_forall_mem measurableSet_Ioi (fun x hx ↦ g_nonneg x hx) + linarith + +/-- The uniform estimate for contour segment `I₃` used in the PNT argument. -/ +def I3BoundGenProp (n : ℝ) (SmoothingF : ℝ → ℝ) (A : ℝ) : Prop := ∃ (C : ℝ) (_ : 0 < C), + ∀ (X : ℝ) (_ : 3 < X) + {ε : ℝ} (_ : 0 < ε) (_ : ε < 1) + {T : ℝ} (_ : 3 < T), + let σ₁ : ℝ := 1 - A / (Real.log T) ^ n + ‖I₃ SmoothingF ε T X σ₁‖ ≤ C * X * X ^ (- A / (Real.log T ^ n)) / ε + +-- Slow + +/- +Assuming a bound of the form of Definition \ref{LogDerivZetaHasBound}, we have that + $$ + \left|I_3(\nu,\epsilon,X,T)\right|\ll\frac{X}{\epsilon}\, X^{-\frac{A}{(\log T)^{n_1}}}. + $$ +Unfold the definitions and apply the triangle inequality. + $$ + \left|I_{3}(\nu, \epsilon, X, T, \sigma_1)\right| = + \left|\frac{1}{2\pi i} \int_{-T}^3 + \left(\frac{-\zeta'}\zeta(\sigma_1 + t i) \right) + \mathcal M(\widetilde 1_\epsilon)(\sigma_1 + t i) + X^{\sigma_1 + t i} + \ i \ dt + \right| + $$ + $$\leq + \frac{1}{2\pi} + \int_{-T}^3 + C \cdot\log t^{n_2} + \frac{C'}{\epsilon|\sigma_1 + t i|^2} + X^{\sigma_1} + \ dt + , + $$ + where we used Theorems \ref{MellinOfSmooth1b} and the hypothesised bound on zeta. + Now we estimate $X^{\sigma_1} = X \cdot X^{-A/ \log T^{n_1}}$, and the integral is absolutely + bounded. +-/ +theorem I3GenBound {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) + {n₁ n₂ : ℝ} (n₁_pos : 0 < n₁) (n₂_pos : 0 < n₂) {A Cζ : ℝ} (hCζ : LogDerivZetaHasBound n₁ n₂ A + Cζ) (Cζpos : 0 < Cζ) (hA : A ∈ Ioc 0 (1 / 2)) : + I3BoundGenProp n₁ SmoothingF A := by + obtain ⟨CM, CMpos, CMhyp⟩ := MellinOfSmooth1b ContDiffSmoothingF suppSmoothingF + obtain ⟨Cint, Cintpos, Cinthyp⟩ := log_pow_over_xsq_integral_bounded n₂ n₂_pos + refine ⟨Cint * CM * Cζ, mul_pos (mul_pos Cintpos CMpos) Cζpos, ?_⟩ + intro X Xgt3 ε εgt0 εlt1 T Tgt3 σ₁ + unfold I₃ + unfold SmoothedChebyshevIntegrand + have Xpos := zero_lt_three.trans Xgt3 + have Tgt3' : -T < -3 := neg_lt_neg_iff.mpr Tgt3 + have t_bounds : ∀ t ∈ Ioo (-T) (-3), 3 < |t| ∧ |t| < T := by + intro t ht + have : |t| = -t := by + refine abs_of_neg ?_ + exact ht.2.trans (by norm_num) + rw [← Set.neg_mem_Ioo_iff, mem_Ioo] at ht + rwa [this] + have logt2gt1_bounds : ∀ t ∈ Set.Icc (-T) (-3), 1 < Real.log |t| ^ n₂ := by + intro t ht + apply Real.one_lt_rpow _ n₂_pos + apply logt_gt_one + rw [abs_of_neg (by linarith [ht.2])] + linarith [ht.2] + have Aoverlogt2gtAoverlogT2_bounds : ∀ t, 3 < |t| ∧ |t| < T → + A / Real.log |t| ^ n₁ > A / Real.log T ^ n₁ := by + intro t ht + refine div_lt_div_of_pos_left hA.1 ?_ ?_ + · exact zero_lt_one.trans <| Real.one_lt_rpow (logt_gt_one ht.1.le) n₁_pos + · have h1 := log_lt_log (zero_lt_three.trans ht.1) ht.2 + have h2 := logt_gt_one ht.1.le + have h3 : 0 ≤ Real.log |t| := zero_le_one.trans h2.le + apply Real.rpow_lt_rpow h3 h1 n₁_pos + have hlogT : 1 < Real.log T ^ n₁ := + Real.one_lt_rpow (logt_gt_one Tgt3.le) n₁_pos + have AoverlogT1in0half : A / Real.log T ^ n₁ ∈ Ioo 0 (1 / 2) := by + refine ⟨div_pos hA.1 (by linarith), ?_⟩ + exact (div_lt_self hA.1 hlogT).trans_le hA.2 + have σ₁lt1 : σ₁ < 1 := by dsimp [σ₁]; linarith [AoverlogT1in0half.1] + have σ₁pos : 0 < σ₁ := by dsimp [σ₁]; linarith [AoverlogT1in0half.2] + have quotient_bound : ∀ t ∈ Ioo (-T) (-3), + Real.log |t| ^ n₂ / (σ₁ ^ 2 + t ^ 2) ≤ Real.log |t| ^ n₂ / t ^ 2 := by + intro t ht + exact div_le_div_of_nonneg_left (Real.rpow_nonneg (by + have := (t_bounds t ht).1; apply Real.log_nonneg; linarith) _) + (sq_pos_of_ne_zero (by have := ht.2; linarith)) (by nlinarith [sq_nonneg σ₁]) + have MellinBound : ∀ (t : ℝ), + ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (σ₁ + t * I)‖ ≤ + CM * (ε * ‖(σ₁ + t * I)‖ ^ 2)⁻¹ := by + intro t + refine CMhyp σ₁ σ₁pos _ ?_ ?_ _ εgt0 εlt1 <;> simp [σ₁lt1.le.trans one_le_two] + have logzetabnd : ∀ t : ℝ, 3 < |t| ∧ |t| < T → ‖ζ' (↑σ₁ + ↑t * I) / ζ (↑σ₁ + ↑t * I)‖ ≤ Cζ * + Real.log (|t| : ℝ) ^ n₂ := by + intro t tbounds + apply hCζ + · exact tbounds.1 + · unfold σ₁ + rw [mem_Ici, sub_le_sub_iff_left] + exact (Aoverlogt2gtAoverlogT2_bounds t tbounds).le + let f t := (-ζ' (↑σ₁ + ↑t * I) / ζ (↑σ₁ + ↑t * I)) * + 𝓜 (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (↑σ₁ + ↑t * I) * + ↑X ^ (↑σ₁ + ↑t * I) + let g t := Cζ * CM * Real.log |t| ^ n₂ / (ε * ‖↑σ₁ + ↑t * I‖ ^ 2) * X ^ σ₁ + have bound_integral : ∀ t ∈ Ioo (-T) (-3), ‖f t‖ ≤ g t := by + intro t ht + unfold f + have : ‖(-ζ' (↑σ₁ + ↑t * I) / ζ (↑σ₁ + ↑t * I)) * + 𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑σ₁ + ↑t * I) * + ↑X ^ (↑σ₁ + ↑t * I)‖ ≤ ‖ζ' (↑σ₁ + ↑t * I) / ζ (↑σ₁ + ↑t * I)‖ * + ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑σ₁ + ↑t * I)‖ * + ‖(↑(X : ℝ) : ℂ) ^ (↑σ₁ + ↑t * I)‖ := by + simp [norm_neg] + have : ‖ζ' (↑σ₁ + ↑t * I) / ζ (↑σ₁ + ↑t * I)‖ * + ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑σ₁ + ↑t * I)‖ * + ‖(↑X : ℂ) ^ (↑σ₁ + ↑t * I)‖ ≤ (Cζ * Real.log |t| ^ n₂) * + (CM * (ε * ‖↑σ₁ + ↑t * I‖ ^ 2)⁻¹) * X ^ σ₁:= by + have Xσ_bound : ‖↑(X : ℂ) ^ (↑σ₁ + ↑t * I)‖ = X ^ σ₁ := by + simp [norm_cpow_eq_rpow_re_of_pos Xpos] + obtain ⟨ht_gt3, ht_ltT⟩ := t_bounds _ ht + have logtgt1 : 1 < Real.log |t| := logt_gt_one ht_gt3.le + have hζ := logzetabnd t ⟨ht_gt3, ht_ltT⟩ + have h𝓜 := MellinBound t + rw[Xσ_bound] + gcongr + have : (Cζ * Real.log |t| ^ n₂) * (CM * (ε * ‖↑σ₁ + ↑t * I‖ ^ 2)⁻¹) * X ^ σ₁ = g t := by + unfold g + ring_nf + linarith + have int_with_f : + ∫ (t : ℝ) in (-T)..(-3), + -ζ' (↑σ₁ + ↑t * I) / ζ (↑σ₁ + ↑t * I) * + 𝓜 (fun x ↦ ↑(Smooth1 SmoothingF ε x)) (↑σ₁ + ↑t * I) * + ↑X ^ (↑σ₁ + ↑t * I) = + ∫ (t : ℝ) in (-T)..(-3), f t := by + simp only [f] + rw[int_with_f] + apply (norm_mul_le _ _).trans + rw [Complex.norm_mul, Complex.norm_I, one_mul] + have : ‖1 / (2 * ↑π * I)‖ * ‖∫ (t : ℝ) in (-T)..(-3), f ↑t‖ ≤ ‖∫ (t : ℝ) in (-T)..(-3), f ↑t‖ := + by + apply mul_le_of_le_one_left + · apply norm_nonneg + · simp only [one_div, norm_inv] + apply inv_le_one_of_one_le₀ + simp only [Complex.norm_mul, Complex.norm_ofNat, norm_real, norm_eq_abs, pi_nonneg, + abs_of_nonneg, norm_I, mul_one] + apply one_le_mul_of_one_le_of_one_le one_le_two + exact le_trans (by norm_num) pi_gt_three.le + apply le_trans this + apply le_trans (intervalIntegral.norm_integral_le_integral_norm Tgt3'.le) + have ne_zero_of_mem_uIcc (x) (hx : x ∈ uIcc (-T) (-3)) : x ≠ 0 := by + rintro rfl + norm_num [mem_uIcc] at hx + linarith + have cont1 : ContinuousOn (fun t ↦ Real.log |t| ^ n₂) (uIcc (-T) (-3)) := by + exact ContinuousOn.rpow (ContinuousOn.log continuous_abs.continuousOn (fun x hx ↦ + abs_ne_zero.mpr (ne_zero_of_mem_uIcc x hx))) continuousOn_const (fun _ _ ↦ Or.inr n₂_pos) + have g_cont : ContinuousOn g (uIcc (-T) (-3)) := by + unfold g + refine .mul ?_ continuousOn_const + refine ContinuousOn.div ?_ ?_ ?_ + · exact continuousOn_const.mul cont1 + · fun_prop + · intro x hx + apply mul_ne_zero εgt0.ne' + have : 0 < σ₁ ^ 2 + x ^ 2 := add_pos_of_pos_of_nonneg (sq_pos_of_pos σ₁pos) (sq_nonneg x) + simp only [Complex.sq_norm, normSq_add_mul_I, ne_eq, this.ne', not_false_eq_true] + have int_normf_le_int_g: ∫ (t : ℝ) in (-T)..(-3), ‖f ↑t‖ + ≤ ∫ (t : ℝ) in (-T)..(-3), g ↑t := by + by_cases h_int : IntervalIntegrable (fun t : ℝ ↦ ‖f t‖) volume (-T) (-3) + · exact intervalIntegral.integral_mono_on_of_le_Ioo + Tgt3'.le h_int g_cont.intervalIntegrable bound_integral + · rw [intervalIntegral.integral_undef h_int] + apply intervalIntegral.integral_nonneg Tgt3'.le + intro t ht + unfold g + have := logt2gt1_bounds t ht + positivity + apply le_trans int_normf_le_int_g + unfold g + simp only [σ₁] + have : X ^ (1 - A / Real.log T ^ n₁) = X * X ^ (- A / Real.log T ^ n₁) := by + rw [sub_eq_add_neg, Real.rpow_add Xpos, Real.rpow_one, neg_div] + rw[this] + have Bound_of_log_int: ∫ (t : ℝ) in (-T)..(-3), Real.log |t| ^ n₂ / (ε * ‖↑σ₁ + ↑t * I‖ ^ 2) ≤ + Cint / ε := by + have : ∫ (t : ℝ) in (-T)..(-3), Real.log |t| ^ n₂ / (ε * ‖↑σ₁ + ↑t * I‖ ^ 2) + = (1 / ε) * ∫ t in (-T)..(-3), Real.log |t| ^ n₂ / ‖↑σ₁ + ↑t * I‖ ^ 2 := by + rw [← intervalIntegral.integral_const_mul] + congr with t + field_simp [εgt0] + rw[this] + have bound : ∫ t in (-T)..(-3), Real.log |t| ^ n₂ / ‖↑σ₁ + ↑t * I‖ ^ 2 ≤ Cint := by + simp_rw [Complex.sq_norm, normSq_add_mul_I] + have : ∫ t in (-T)..(-3), Real.log |t| ^ n₂ / (σ₁ ^ 2 + t ^ 2) + ≤ ∫ t in (-T)..(-3), Real.log |t| ^ n₂ / t ^ 2 := by + refine intervalIntegral.integral_mono_on_of_le_Ioo Tgt3'.le ?_ ?_ ?_ + · have cont : ContinuousOn (fun t ↦ Real.log |t| ^ n₂ / (σ₁ ^ 2 + t ^ 2)) (Set.uIcc (-T) + (-3)) := by + refine ContinuousOn.div cont1 ?_ ?_ + · exact continuousOn_const.add (continuousOn_id.pow 2) + · intro t _ + exact (add_pos_of_pos_of_nonneg (sq_pos_of_pos σ₁pos) (sq_nonneg t)).ne' + apply cont.intervalIntegrable + · have cont : ContinuousOn (fun t ↦ Real.log |t| ^ n₂ / t ^ 2) (Set.uIcc (-T) (-3)) := by + refine ContinuousOn.div cont1 ?_ ?_ + · exact continuousOn_id.pow 2 + · intro t ht + exact pow_ne_zero 2 (ne_zero_of_mem_uIcc t ht) + apply cont.intervalIntegrable + · exact quotient_bound + apply le_trans this + rw [← intervalIntegral.integral_comp_neg] + simp only [abs_neg, log_abs, even_two, Even.neg_pow] + rw [intervalIntegral.integral_of_le Tgt3.le, MeasureTheory.integral_Ioc_eq_integral_Ioo] + exact (Cinthyp T Tgt3).le + rw [mul_comm, + ← mul_div_assoc, mul_one] + exact (div_le_div_iff_of_pos_right εgt0).mpr bound + have factor_out_constants : + ∫ (t : ℝ) in (-T)..(-3), Cζ * CM * Real.log |t| ^ n₂ / (ε * ‖↑σ₁ + ↑t * I‖ ^ 2) * (X * X ^ (-A / + Real.log T ^ n₁)) + = Cζ * CM * (X * X ^ (-A / Real.log T ^ n₁)) * ∫ (t : ℝ) in (-T)..(-3), Real.log |t| ^ n₂ / (ε * + ‖↑σ₁ + ↑t * I‖ ^ 2) := by + rw [mul_assoc, ← mul_assoc (Cζ * CM), ← mul_assoc] + field_simp + simp only [log_abs] + rw [← intervalIntegral.integral_const_mul] + apply intervalIntegral.integral_congr + intro t ht + ring_nf + rw [factor_out_constants] + have : Cζ * CM * (X * X ^ (-A / Real.log T ^ n₁)) * ∫ (t : ℝ) in (-T)..(-3), Real.log |t| ^ n₂ / + (ε * ‖↑σ₁ + ↑t * I‖ ^ 2) + ≤ Cζ * CM * ((X : ℝ) * X ^ (-A / Real.log T ^ n₁)) * (Cint / ε) := by + apply mul_le_mul_of_nonneg_left + · exact Bound_of_log_int + · positivity + apply le_trans this + ring_nf + field_simp + rfl + +lemma I7I3 {SmoothingF : ℝ → ℝ} {ε X T σ₁ : ℝ} (Xpos : 0 < X) : + I₇ SmoothingF ε T X σ₁ = conj (I₃ SmoothingF ε T X σ₁) := by + unfold I₃ I₇ + simp only [map_mul, map_div₀, conj_I, conj_ofReal, conj_ofNat, map_one] + rw [neg_mul, mul_neg, ← neg_mul] + congr + · ring + · rw [← intervalIntegral_conj, ← intervalIntegral.integral_comp_neg] + apply intervalIntegral.integral_congr + intro t ht + simp only + rw [← smoothedChebyshevIntegrand_conj Xpos] + simp + +/-- The uniform estimate for contour segment `I₇` used in the PNT argument. -/ +def I7BoundGenProp (n : ℝ) (SmoothingF : ℝ → ℝ) (A : ℝ) : Prop := ∃ (C : ℝ) (_ : 0 < C), + ∀ (X : ℝ) (_ : 3 < X) + {ε : ℝ} (_ : 0 < ε) (_ : ε < 1) + {T : ℝ} (_ : 3 < T), + let σ₁ : ℝ := 1 - A / (Real.log T) ^ n + ‖I₇ SmoothingF ε T X σ₁‖ ≤ C * X * X ^ (- A / (Real.log T ^ n)) / ε + +/- +Assuming a bound of the form of Definition \ref{LogDerivZetaHasBound}, we have that + $$ + \left|I_7(\nu,\epsilon,X,T)\right|\ll\frac{X}{\epsilon}\, X^{-\frac{A}{(\log T)^{n_1}}}. + $$ +We deduce this from the corresponding bound for $I_3$, using the symmetry between $I_3$ and $I_7$. +-/ +theorem I7GenBound {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) + {n₁ n₂ : ℝ} (n₁_pos : 0 < n₁) (n₂_pos : 0 < n₂) {A Cζ : ℝ} (hCζ : LogDerivZetaHasBound n₁ n₂ A + Cζ) (Cζpos : 0 < Cζ) (hA : A ∈ Ioc 0 (1 / 2)) : + I7BoundGenProp n₁ SmoothingF A := by + obtain ⟨C, Cpos, bound⟩ := I3GenBound suppSmoothingF ContDiffSmoothingF n₁_pos n₂_pos hCζ Cζpos hA + refine ⟨C, Cpos, fun X X_gt ε εpos ε_lt_one T T_gt ↦ ?_⟩ + specialize bound X X_gt εpos ε_lt_one T_gt + intro σ₁ + rwa [I7I3 (by linarith), norm_conj] + +/-- The uniform estimate for contour segment `I₄` used in the PNT argument. -/ +def I4BoundGenProp (n : ℝ) (SmoothingF : ℝ → ℝ) (A σ₂ : ℝ) : Prop := ∃ (C : ℝ) (_ : 0 ≤ C) (Tlb : + ℝ) (_ : 3 < Tlb), + ∀ (X : ℝ) (_ : 3 < X) + {ε : ℝ} (_ : 0 < ε) (_ : ε < 1) + {T : ℝ} (_ : Tlb < T), + let σ₁ : ℝ := 1 - A / (Real.log T) ^ n + ‖I₄ SmoothingF ε X σ₁ σ₂‖ ≤ C * X * X ^ (- A / (Real.log T ^ n)) / ε + +/- +Assuming a bound of the form of Definition \ref{LogDerivZetaHasBound}, we have that + $$ + \left|I_4(\nu,\epsilon,X,\sigma_1,\sigma_2)\right| + \ll\frac{X}{\epsilon}\,X^{-\frac{A}{(\log T)^{n_1}}}. + $$ +The analysis of $I_4$ is similar to that of $I_2$, (in Lemma \ref{I2Bound}) but even easier. + Let $C$ be the sup of $-\zeta'/\zeta$ on the curve $\sigma_2 + 3 i$ to $1+ 3i$ + (this curve is compact, and away from the pole at $s=1$). Apply Theorem \ref{MellinOfSmooth1b} + to get the bound $1/(\epsilon |s|^2)$, which is bounded by $C'/\epsilon$. And $X^s$ is bounded + by $X^{\sigma_1}=X \cdot X^{-A/ \log T^{n_1}}$. Putting these together gives the result. +-/ + +/-- The logarithmic derivative is bounded on the compact horizontal contour. -/ +private lemma logDeriv_horizontal_bddAbove {σ₂ : ℝ} + (h_logDeriv_holo : LogDerivZetaIsHoloSmall σ₂) (hσ₂ : σ₂ ∈ Ioo 0 1) : + BddAbove ((fun (t : ℝ) ↦ ↑‖-ζ' (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I) / ζ (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * + I)‖₊) '' Icc 0 1 : Set ℝ) := by + have reOne : re 1 = 1 := rfl + have imOne : im 1 = 0 := rfl + have reThree : re 3 = 3 := rfl + have imThree : im 3 = 0 := rfl + let S : Set ℝ := (fun (t : ℝ) ↦ ↑‖-ζ' (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I) / ζ (↑σ₂ + ↑t * (1 - ↑σ₂) - + 3 * I)‖₊) '' Icc 0 1 + change BddAbove S + refine IsCompact.bddAbove ?_ + unfold S + refine IsCompact.image_of_continuousOn ?_ ?_ + · exact isCompact_Icc + · refine ContinuousOn.norm ?_ + have : (fun (t : ℝ) ↦ -ζ' (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I) / ζ (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I)) = + (fun (t : ℝ) ↦ -(ζ' (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I) / ζ (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I))) := by + apply funext + intro x + apply neg_div + rw[this] + refine ContinuousOn.neg ?_ + have : (fun (t : ℝ) ↦ ζ' (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I) / ζ (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I)) = + ((ζ' / ζ) ∘ (fun (t : ℝ) ↦ (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I))) := rfl + rw[this] + apply h_logDeriv_holo.continuousOn.comp' (by fun_prop) + unfold MapsTo + intro x xInIcc + simp only [neg_le_self_iff, Nat.ofNat_nonneg, uIcc_of_le, Set.mem_sdiff, mem_singleton_iff] + have : ¬↑σ₂ + ↑x * (1 - ↑σ₂) - 3 * I = 1 := by + by_contra h + rw[Complex.ext_iff, sub_re, add_re, sub_im, add_im] at h + repeat rw[mul_im] at h + repeat rw[mul_re] at h + rw[sub_im, sub_re, reOne, imOne, reThree, imThree, I_im, I_re] at h + repeat rw[ofReal_re] at h + repeat rw[ofReal_im] at h + ring_nf at h + obtain ⟨_, ripGoal⟩ := h + linarith + refine ⟨?_, this⟩ + rw [mem_reProdIm] + simp only [sub_re, add_re, ofReal_re, mul_re, one_re, ofReal_im, sub_im, one_im, sub_self, + mul_zero, sub_zero, re_ofNat, I_re, im_ofNat, I_im, mul_one, add_im, mul_im, zero_mul, + add_zero, zero_sub, mem_Icc, le_refl, neg_le_self_iff, Nat.ofNat_nonneg, and_self, and_true] + rw [Set.uIcc_of_le] + · rw [mem_Icc] + constructor + · simp only [le_add_iff_nonneg_right] + apply mul_nonneg + · exact xInIcc.1 + · linarith [hσ₂.2] + · have : σ₂ + x * (1 - σ₂) = σ₂ * (1 - x) + x := by ring + rw [this] + clear this + have : (2 : ℝ) = 1 * 1 + 1 := by norm_num + rw [this] + clear this + gcongr + · linarith [xInIcc.2] + · exact hσ₂.2.le + · linarith [xInIcc.1] + · exact xInIcc.2 + · linarith [hσ₂.2] + +/-- The horizontal contour stays a positive distance from the origin. -/ +private lemma horizontal_norm_sInf_pos (σ₂ : ℝ) : 0 < sInf ((fun (t : ℝ) ↦ ‖↑σ₂ + ↑t * (1 - ↑σ₂) - + 3 * I‖₊ ^ 2) '' Icc 0 1) := by + have reOne : re 1 = 1 := rfl + have imOne : im 1 = 0 := rfl + have reThree : re 3 = 3 := rfl + have imThree : im 3 = 0 := rfl + refine (IsCompact.lt_sInf_iff_of_continuous ?_ ?_ ?_ 0).mpr ?_ + · exact isCompact_Icc + · exact Nonempty.of_subtype + · have : (fun (t : ℝ) ↦ ‖↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I‖₊ ^ 2) = + (fun (t : ℝ) ↦ ‖↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I‖₊ * ‖↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I‖₊) := by + apply funext + intro x + rw[pow_two] + rw[this] + have : ContinuousOn (fun (t : ℝ) ↦ ‖↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I‖₊) (Icc 0 1) := by + refine ContinuousOn.nnnorm ?_ + refine ContinuousOn.sub ?_ (by exact continuousOn_const) + refine ContinuousOn.add (by exact continuousOn_const) ?_ + exact ContinuousOn.mul (by exact Complex.continuous_ofReal.continuousOn) (by exact + continuousOn_const) + exact ContinuousOn.mul (by exact this) (by exact this) + · intro x xLoc + apply pow_pos + have temp : |(↑σ₂ + ↑x * (1 - ↑σ₂) - 3 * I).im| ≤ + ‖↑σ₂ + ↑x * (1 - ↑σ₂) - 3 * I‖₊ := by apply Complex.abs_im_le_norm + rw[sub_im, add_im, mul_im, mul_im, I_re, I_im, sub_im, sub_re] at temp + repeat rw[ofReal_re] at temp + repeat rw[ofReal_im] at temp + rw[reThree, imOne] at temp + ring_nf at temp ⊢ + rw[(by ring : σ₂ - σ₂ * x + x - I * 3 = σ₂ - σ₂ * x + (x - I * 3))] at temp ⊢ + rw[abs_of_neg, neg_neg] at temp + · have : (3 : NNReal) ≤ ‖↑σ₂ - ↑σ₂ * ↑x + (↑x - I * 3)‖₊ := temp + positivity + · rw[neg_lt_zero] + norm_num + +/-- A sufficiently high contour puts its left endpoint to the right of `σ₂`. -/ +private lemma horizontal_contour_endpoint_le {n A σ₂ T : ℝ} + (n_pos : 0 < n) (hA : A ∈ Ioc 0 (1 / 2)) (hσ₂ : σ₂ ∈ Ioo 0 1) + (T_gt_Tlb : max 4 (max (rexp (A ^ (n : ℝ)⁻¹)) (rexp ((A / (1 - σ₂)) ^ (n : ℝ)⁻¹))) < T) : + σ₂ ≤ 1 - A / Real.log T ^ n := by + let Tlb : ℝ := max 4 (max (rexp (A ^ (n : ℝ)⁻¹)) (rexp ((A / (1 - σ₂)) ^ (n : ℝ)⁻¹))) + have hTlb : 3 < Tlb := lt_of_lt_of_le (by norm_num) (le_max_left _ _) + let σ₁ : ℝ := 1 - A / Real.log T ^ n + change σ₂ ≤ σ₁ + have logTlb_pos : 0 < Real.log Tlb := by + rw[← Real.log_one] + exact log_lt_log (by norm_num) (by linarith [hTlb]) + have logTlb_nonneg : 0 ≤ Real.log Tlb := le_of_lt (by exact logTlb_pos) + have expr_nonneg : 0 ≤ A / (1 - σ₂) := by + apply div_nonneg + · linarith [hA.1] + · rw[sub_nonneg] + exact le_of_lt hσ₂.2 + have temp : σ₂ ≤ 1 - A / Real.log Tlb ^ n := by + have : rexp ((A / (1 - σ₂)) ^ (n : ℝ)⁻¹) ≤ Tlb := by + unfold Tlb + nth_rewrite 2 [max_comm] + rw[max_left_comm] + apply le_max_of_le_left (by rfl) + rw[← Real.le_log_iff_exp_le] at this + · have h1 : 0 ≤ (A / (1 - σ₂)) ^ (n : ℝ)⁻¹ := by apply Real.rpow_nonneg (by exact expr_nonneg) + rw[← Real.rpow_le_rpow_iff h1 logTlb_nonneg n_pos] at this + have h: ((A / (1 - σ₂)) ^ (n : ℝ)⁻¹) ^ (n : ℝ) = A / (1 - σ₂) := by + apply rpow_inv_rpow (by exact expr_nonneg) + exact Ne.symm (Std.ne_of_lt n_pos) + rw[h, div_le_iff₀, mul_comm, ← div_le_iff₀] at this + · linarith + · exact rpow_pos_of_pos (by exact logTlb_pos) _ + · rw[sub_pos] + exact hσ₂.2 + · positivity + have : 1 - A / Real.log Tlb ^ n ≤ 1 - A / Real.log T ^ n := by + apply sub_le_sub (by rfl) + apply div_le_div₀ + · exact le_of_lt (by exact hA.1) + · rfl + · apply Real.rpow_pos_of_pos + apply Real.log_pos + linarith + · exact Real.rpow_le_rpow logTlb_nonneg (log_le_log (by linarith [hTlb]) T_gt_Tlb.le) n_pos.le + exact le_trans temp this + +lemma I4GenBound {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) + {σ₂ : ℝ} (h_logDeriv_holo : LogDerivZetaIsHoloSmall σ₂) (hσ₂ : σ₂ ∈ Ioo 0 1) + {n : ℝ} (n_pos : n > 0) {A : ℝ} (hA : A ∈ Ioc 0 (1 / 2)) : + I4BoundGenProp n SmoothingF A σ₂ := by + have reOne : re 1 = 1 := rfl + have imOne : im 1 = 0 := rfl + have reThree : re 3 = 3 := rfl + have imThree : im 3 = 0 := rfl + unfold I4BoundGenProp I₄ SmoothedChebyshevIntegrand + let S : Set ℝ := (fun (t : ℝ) ↦ ↑‖-ζ' (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I) / ζ (↑σ₂ + ↑t * (1 - ↑σ₂) - + 3 * I)‖₊) '' Icc 0 1 + let C' : ℝ := sSup S + have bddAboveS : BddAbove S := logDeriv_horizontal_bddAbove h_logDeriv_holo hσ₂ + have CPrimeNonneg : 0 ≤ C' := by + apply Real.sSup_nonneg + intro x x_in_S + obtain ⟨t, ht, rfl⟩ := x_in_S + exact NNReal.coe_nonneg _ + obtain ⟨D, Dpos, MellinSmooth1bBound⟩ := MellinOfSmooth1b ContDiffSmoothingF suppSmoothingF + let C : ℝ := C' * D / sInf ((fun t => ‖ σ₂ + (t : ℝ) * (1 - σ₂) - 3 * I ‖₊ ^ 2) '' Set.Icc 0 1) + use C + have sInfPos := horizontal_norm_sInf_pos σ₂ + have CNonneg : 0 ≤ C := by + dsimp [C] + positivity + use CNonneg + let Tlb : ℝ := max 4 (max (rexp (A ^ (n : ℝ)⁻¹)) (rexp ((A / (1 - σ₂)) ^ (n : ℝ)⁻¹))) + use Tlb + have : 3 < Tlb := by + unfold Tlb + rw[lt_max_iff] + refine Or.inl ?_ + norm_num + use this + intro X X_gt_three ε ε_pos ε_lt_one T T_gt_Tlb σ₁ + have σ₂_le_σ₁ : σ₂ ≤ σ₁ := horizontal_contour_endpoint_le n_pos hA hσ₂ T_gt_Tlb + have minσ₂σ₁ : min σ₂ σ₁ = σ₂ := min_eq_left (by exact σ₂_le_σ₁) + have maxσ₂σ₁ : max σ₂ σ₁ = σ₁ := max_eq_right (by exact σ₂_le_σ₁) + have σ₁_lt_one : σ₁ < 1 := + sub_lt_self _ (div_pos hA.1 + (Real.rpow_pos_of_pos (Real.log_pos (by linarith)) _)) + rw[norm_mul, ← one_mul C] + have : 1 * C * X * X ^ (-A / Real.log T ^ n) / ε = 1 * (C * X * X ^ (-A / Real.log T ^ n) / ε) + := by ring + rw[this] + apply mul_le_mul + · simp only [norm_div, norm_one, norm_mul, Complex.norm_two, Complex.norm_real, + Real.norm_of_nonneg pi_nonneg, Complex.norm_I, mul_one] + exact (div_le_one (by positivity)).2 (by nlinarith [Real.pi_gt_three]) + · let f : ℝ → ℂ := fun σ ↦ (-ζ' (↑σ - 3 * I) / ζ (↑σ - 3 * I) * 𝓜 (fun x ↦ ↑(Smooth1 SmoothingF + ε x)) (↑σ - 3 * I) * ↑X ^ (↑σ - 3 * I)) + have temp : ‖∫ (σ : ℝ) in σ₂..σ₁, -ζ' (↑σ - 3 * I) / ζ (↑σ - 3 * I) * 𝓜 (fun x ↦ ↑(Smooth1 + SmoothingF ε x)) (↑σ - 3 * I) * ↑X ^ (↑σ - 3 * I)‖ ≤ + C * X * X ^ (-A / Real.log T ^ n) / ε * |σ₁ - σ₂| := by + have : ∀ x ∈ Set.uIoc σ₂ σ₁, ‖f x‖ ≤ C * X * X ^ (-A / Real.log T ^ n) / ε := by + intro x xInIoc + let t : ℝ := (x - σ₂) / (1 - σ₂) + have tInIcc : t ∈ Icc 0 1 := by + have hx : σ₂ < x ∧ x ≤ σ₁ := by + simpa only [uIoc_of_le σ₂_le_σ₁, mem_Ioc] using xInIoc + dsimp [t] + exact ⟨div_nonneg (by linarith [hx.1]) (by linarith [hσ₂.2]), + (div_le_one (by linarith [hσ₂.2])).2 (by linarith [hx.2])⟩ + have tExpr : (↑σ₂ + t * (1 - ↑σ₂) - 3 * I) = (↑x - 3 * I) := by + unfold t + simp only [ofReal_div, ofReal_sub, ofReal_one, sub_left_inj] + rw[div_mul_comm, div_self] + · simp only [one_mul, add_sub_cancel] + · refine sub_ne_zero_of_ne ?_ + apply Ne.symm + rw[Complex.ofReal_ne_one] + exact ne_of_lt (by exact hσ₂.2) + unfold f + simp only [Complex.norm_mul] + have : C * X * X ^ (-A / Real.log T ^ n) / ε = + (C / ε) * (X * X ^ (-A / Real.log T ^ n)) := by ring + rw[this] + have temp : ‖-ζ' (↑x - 3 * I) / ζ (↑x - 3 * I)‖ * ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : + ℂ)) (↑x - 3 * I)‖ ≤ + C / ε := by + unfold C + rw[div_div] + nth_rewrite 2 [div_eq_mul_inv] + have temp : ‖-ζ' (↑x - 3 * I) / ζ (↑x - 3 * I)‖ ≤ C' := by + unfold C' + have : ‖-ζ' (↑x - 3 * I) / ζ (↑x - 3 * I)‖ ∈ + (fun (t : ℝ) ↦ ↑‖-ζ' (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I) / ζ (↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * + I)‖₊) '' Icc 0 1 := by + rw[Set.mem_image] + use t + constructor + · exact tInIcc + · rw[tExpr] + rfl + exact le_csSup (by exact bddAboveS) (by exact this) + have : ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑x - 3 * I)‖ ≤ + D * ((sInf ((fun (t : ℝ) ↦ ‖↑σ₂ + ↑t * (1 - ↑σ₂) - 3 * I‖₊ ^ 2) '' Icc 0 1)) * ε)⁻¹ := + by + nth_rewrite 3 [mul_comm] + let s : ℂ := x - 3 * I + have : 𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑x - 3 * I) = + 𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) s := rfl + rw[this] + have temp : σ₂ ≤ s.re := by + unfold s + rw[sub_re, mul_re, I_re, I_im, reThree, imThree, ofReal_re] + ring_nf + apply le_of_lt + unfold uIoc at xInIoc + rw[minσ₂σ₁] at xInIoc + exact xInIoc.1 + have : s.re ≤ 2 := by + unfold s + rw[sub_re, mul_re, I_re, I_im, reThree, imThree, ofReal_re] + ring_nf + have : x < 1 := by + unfold uIoc at xInIoc + rw[maxσ₂σ₁] at xInIoc + exact lt_of_le_of_lt xInIoc.2 σ₁_lt_one + linarith + have temp : ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) s‖ ≤ D * (ε * ‖s‖ ^ 2)⁻¹ := by + exact MellinSmooth1bBound σ₂ hσ₂.1 s temp this ε ε_pos ε_lt_one + have : D * (ε * ‖s‖ ^ 2)⁻¹ ≤ D * (ε * ↑(sInf ((fun (t : ℝ) ↦ ‖↑σ₂ + ↑t * (1 - ↑σ₂) - 3 + * I‖₊ ^ 2) '' Icc 0 1)))⁻¹ := by + refine mul_le_mul (by rfl) ?_ ?_ (by exact le_of_lt (by exact Dpos)) + · rw[inv_le_inv₀] + · apply mul_le_mul (by rfl) + · rw[NNReal.coe_sInf] + apply csInf_le + · apply NNReal.bddBelow_coe + · unfold s + rw[Set.mem_image] + let xNorm : NNReal := ‖x - 3 * I‖₊ ^ 2 + use xNorm + constructor + · rw[Set.mem_image] + use t + exact ⟨tInIcc, by rw[tExpr]⟩ + · rfl + · exact le_of_lt (by exact sInfPos) + · exact le_of_lt (by exact ε_pos) + · apply mul_pos (ε_pos) + refine sq_pos_of_pos ?_ + refine norm_pos_iff.mpr ?_ + refine ne_zero_of_re_pos ?_ + unfold s + rw[sub_re, mul_re, I_re, I_im, reThree, imThree, ofReal_re] + ring_nf + unfold uIoc at xInIoc + rw[minσ₂σ₁] at xInIoc + exact lt_trans hσ₂.1 xInIoc.1 + · exact mul_pos (ε_pos) (sInfPos) + · rw[inv_nonneg] + apply mul_nonneg (by exact le_of_lt (by exact ε_pos)) + exact sq_nonneg ‖s‖ + exact le_trans temp this + rw[mul_assoc] + apply mul_le_mul (by exact temp) (by exact this) + · have this : 0 ≤ |(𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑x - 3 * I)).re| := by + apply abs_nonneg + exact le_trans this (by refine Complex.abs_re_le_norm ?_) + · exact CPrimeNonneg + have : ‖(X : ℂ) ^ (↑x - 3 * I)‖ ≤ X * X ^ (-A / Real.log T ^ n) := by + rw [Complex.norm_cpow_eq_rpow_re_of_pos (by linarith : 0 < X)] + simp only [sub_re, ofReal_re, mul_re, I_re, I_im, reThree, imThree, + mul_zero, zero_mul, sub_zero] + have hx : x ≤ σ₁ := by + unfold uIoc at xInIoc + rw [maxσ₂σ₁] at xInIoc + exact xInIoc.2 + calc + X ^ x ≤ X ^ σ₁ := Real.rpow_le_rpow_of_exponent_le (by linarith) hx + _ = X * X ^ (-A / Real.log T ^ n) := by + dsimp [σ₁] + rw [sub_eq_add_neg, Real.rpow_add (by linarith : 0 < X), + Real.rpow_one, neg_div] + apply mul_le_mul + · exact temp + · exact this + · rw[Complex.norm_cpow_eq_rpow_re_of_pos] + · rw[sub_re, mul_re, ofReal_re, I_re, I_im, reThree, imThree] + ring_nf + apply Real.rpow_nonneg + positivity + · positivity + · exact div_nonneg CNonneg (le_of_lt ε_pos) + exact intervalIntegral.norm_integral_le_of_norm_le_const this + have : C * X * X ^ (-A / Real.log T ^ n) / ε * |σ₁ - σ₂| ≤ + C * X * X ^ (-A / Real.log T ^ n) / ε := by + have : |σ₁ - σ₂| ≤ 1 := by + rw[abs_of_nonneg] + · rw[← sub_zero 1] + exact sub_le_sub σ₁_lt_one.le hσ₂.1.le + · rw[sub_nonneg] + exact σ₂_le_σ₁ + bound + exact le_trans temp this + · simp only [norm_nonneg] + norm_num + +lemma I6I4 {SmoothingF : ℝ → ℝ} {ε X σ₁ σ₂ : ℝ} (Xpos : 0 < X) : + I₆ SmoothingF ε X σ₁ σ₂ = -conj (I₄ SmoothingF ε X σ₁ σ₂) := by + unfold I₆ I₄ + simp only [map_mul, map_div₀, conj_ofReal, conj_I, map_one, conj_ofNat] + rw [← neg_mul] + congr + · ring + · rw [← intervalIntegral_conj] + apply intervalIntegral.integral_congr + intro σ hσ + simp only + rw[← smoothedChebyshevIntegrand_conj Xpos] + simp [conj_ofNat] + +/-- The uniform estimate for contour segment `I₆` used in the PNT argument. -/ +def I6BoundGenProp (n : ℝ) (SmoothingF : ℝ → ℝ) (A σ₂ : ℝ) : Prop := ∃ (C : ℝ) (_ : 0 ≤ C) (Tlb : + ℝ) (_ : 3 < Tlb), + ∀ (X : ℝ) (_ : 3 < X) + {ε : ℝ} (_ : 0 < ε) (_ : ε < 1) + {T : ℝ} (_ : Tlb < T), + let σ₁ : ℝ := 1 - A / (Real.log T) ^ n + ‖I₆ SmoothingF ε X σ₁ σ₂‖ ≤ C * X * X ^ (- A / (Real.log T ^ n)) / ε + +/- +Assuming a bound of the form of Definition \ref{LogDerivZetaHasBound}, we have that + $$ + \left|I_6(\nu,\epsilon,X,\sigma_1,\sigma_2)\right| + \ll\frac{X}{\epsilon}\,X^{-\frac{A}{(\log T)^{n_1}}}. + $$ +We deduce this from the corresponding bound for $I_4$, using the symmetry between $I_4$ and $I_6$. +-/ +lemma I6GenBound {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) + {σ₂ : ℝ} (h_logDeriv_holo : LogDerivZetaIsHoloSmall σ₂) (hσ₂ : σ₂ ∈ Ioo 0 1) + {n : ℝ} (n_pos : 0 < n) {A : ℝ} (hA : A ∈ Ioc 0 (1 / 2)) : + I6BoundGenProp n SmoothingF A σ₂ := by + obtain ⟨C, Cpos, Tlb, Tlb_gt, bound⟩ := I4GenBound suppSmoothingF ContDiffSmoothingF + h_logDeriv_holo hσ₂ n_pos hA + refine ⟨C, Cpos, Tlb, Tlb_gt, fun X X_gt ε εpos ε_lt_one T T_gt ↦ ?_⟩ + specialize bound X X_gt εpos ε_lt_one T_gt + intro σ₁ + rwa [I6I4 (by linarith), norm_neg, norm_conj] + +/-- The uniform estimate for contour segment `I₅` used in the PNT argument. -/ +def I5BoundGenProp (SmoothingF : ℝ → ℝ) (σ₂ : ℝ) : Prop := ∃ (C : ℝ) (_ : 0 < C), + ∀ (X : ℝ) (_ : 3 < X) {ε : ℝ} (_ : 0 < ε) (_ : ε < 1), + ‖I₅ SmoothingF ε X σ₂‖ ≤ C * X ^ σ₂ / ε + +/- +We have that + $$ + \left|I_5(\nu,\epsilon,X,\sigma_2)\right|\ll\frac{X^{\sigma_2}}{\epsilon}. + $$ +Here $\zeta'/\zeta$ is absolutely bounded on the compact interval $\sigma_2 + i [-3,3]$, and + $X^s$ is bounded by $X^{\sigma_2}$. Using Theorem \ref{MellinOfSmooth1b} gives the bound + $1/(\epsilon |s|^2)$, which is bounded by $C'/\epsilon$. Putting these together gives the result. +-/ +lemma I5Bound {SmoothingF : ℝ → ℝ} + (suppSmoothingF : Function.support SmoothingF ⊆ Icc (1 / 2) 2) + (ContDiffSmoothingF : ContDiff ℝ 1 SmoothingF) + {σ₂ : ℝ} (h_logDeriv_holo : LogDerivZetaIsHoloSmall σ₂) (hσ₂ : σ₂ ∈ Ioo 0 1) : + I5BoundGenProp SmoothingF σ₂ := by + unfold LogDerivZetaIsHoloSmall HolomorphicOn at h_logDeriv_holo + let zeta'_zeta_on_line := fun (t : ℝ) ↦ ζ' (σ₂ + t * I) / ζ (σ₂ + t * I) + have subst : {σ₂} ×ℂ uIcc (-3) 3 ⊆ (uIcc σ₂ 2 ×ℂ uIcc (-3) 3) \ {1} := by + simp! only [neg_le_self_iff, Nat.ofNat_nonneg, uIcc_of_le] + simp_all only [one_div, support_subset_iff, ne_eq, mem_Icc, neg_le_self_iff, + Nat.ofNat_nonneg, uIcc_of_le] + intro z hyp_z + simp only [mem_reProdIm, mem_singleton_iff, mem_Icc] at hyp_z + simp only [Set.mem_sdiff, mem_reProdIm, mem_Icc, mem_singleton_iff] + constructor + · constructor + · rw [hyp_z.1] + apply left_mem_uIcc + · exact hyp_z.2 + · push Not + by_contra h + rw [h] at hyp_z + simp only [one_re, one_im, Left.neg_nonpos_iff, Nat.ofNat_nonneg, and_self, and_true] at hyp_z + linarith [hσ₂.2] + have zeta'_zeta_cont := (h_logDeriv_holo.mono subst).continuousOn + have is_compact' : IsCompact ({σ₂} ×ℂ uIcc (-3) 3) := by + refine IsCompact.reProdIm ?_ ?_ + · exact isCompact_singleton + · exact isCompact_uIcc + let ⟨zeta_bound, zeta_prop⟩ := + IsCompact.exists_bound_of_continuousOn (is_compact') zeta'_zeta_cont + let ⟨M, ⟨M_is_pos, M_bounds_mellin_hard⟩⟩ := + MellinOfSmooth1b ContDiffSmoothingF suppSmoothingF + clear is_compact' zeta'_zeta_cont subst zeta'_zeta_on_line h_logDeriv_holo + unfold I5BoundGenProp I₅ SmoothedChebyshevIntegrand + let mellin_prop : ∀ (t ε : ℝ), + 0 < ε → ε < 1 → ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑σ₂ + ↑t * I)‖ ≤ M * (ε * ‖↑σ₂ + ↑t * + I‖ ^ 2)⁻¹ := + fun (t : ℝ) ↦ (M_bounds_mellin_hard σ₂ (by linarith[hσ₂.1]) (σ₂ + t * I) (by simp only [add_re, + ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, add_zero, le_refl]) + (by simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, add_zero]; linarith[hσ₂.2])) + simp only [mul_inv_rev] at mellin_prop + let Const := 1 + (σ₂^2)⁻¹ * (abs zeta_bound) * M + let C := |π|⁻¹ * 2⁻¹ * 6 * Const + use C + have C_pos : 0 < C := by positivity + use C_pos + clear C_pos + intros X X_gt ε ε_pos ε_lt_one + have mellin_bound := fun (t : ℝ) ↦ mellin_prop t ε ε_pos ε_lt_one + have U: 0 < σ₂^2 := by + exact sq_pos_of_pos (by linarith[hσ₂.1]) + have easy_bound : ∀(t : ℝ), (‖↑σ₂ + ↑t * I‖^2)⁻¹ ≤ (σ₂^2)⁻¹ := + by + intro t + rw [inv_le_inv₀] + · rw [Complex.sq_norm, Complex.normSq_apply] + simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + add_zero, add_im, mul_im, zero_add] + ring_nf + simp only [le_add_iff_nonneg_right] + exact zpow_two_nonneg t + · rw [Complex.sq_norm, Complex.normSq_apply] + simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + add_zero, add_im, mul_im, zero_add] + ring_nf + positivity + positivity + have T1 : ∀(t : ℝ), t ∈ uIoc (-3) (3 : ℝ) → ‖-ζ' (↑σ₂ + ↑t * I) / ζ (↑σ₂ + ↑t * I) * 𝓜 (fun x ↦ + ↑(Smooth1 SmoothingF ε x)) (↑σ₂ + ↑t * I) * + (↑X : ℂ) ^ (↑σ₂ + ↑t * I)‖ ≤ Const * ε⁻¹ * X ^ σ₂ := by + intro t hyp_t + have Z := by + calc + ‖(-ζ' (↑σ₂ + ↑t * I) / ζ (↑σ₂ + ↑t * I)) * (𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑σ₂ + + ↑t * I)) * + (↑X : ℂ) ^ (↑σ₂ + ↑t * I)‖ = ‖-ζ' (↑σ₂ + ↑t * I) / ζ (↑σ₂ + ↑t * I)‖ * ‖𝓜 (fun x ↦ + (Smooth1 SmoothingF ε x : ℂ)) (↑σ₂ + ↑t * I)‖ * ‖(↑X : ℂ) ^ (↑σ₂ + ↑t * I)‖ := by simp + only [Complex.norm_mul, + Complex.norm_div, norm_neg] + _ ≤ ‖ζ' (↑σ₂ + ↑t * I) / ζ (↑σ₂ + ↑t * I)‖ * ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) + (↑σ₂ + ↑t * I)‖ * ‖(↑X : ℂ) ^ (↑σ₂ + ↑t * I)‖ := by simp only [Complex.norm_div, + norm_neg, le_refl] + _ ≤ zeta_bound * ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑σ₂ + ↑t * I)‖ * ‖(↑X : ℂ) ^ + (↑σ₂ + ↑t * I)‖ := + by + have U := zeta_prop (↑σ₂ + t * I) (by + simp only [neg_le_self_iff, Nat.ofNat_nonneg, uIcc_of_le] + simp only [mem_reProdIm, add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, + mul_one, sub_self, add_zero, mem_singleton_iff, add_im, mul_im, zero_add, mem_Icc] + constructor + · trivial + · refine mem_Icc.mp ?_ + · refine mem_Icc_of_Ioc ?_ + · have T : (-3 : ℝ) ≤ 3 := by simp only [neg_le_self_iff, Nat.ofNat_nonneg] + rw [←Set.uIoc_of_le T] + exact hyp_t) + simp only [Complex.norm_div] at U + simp only [Complex.norm_div, ge_iff_le] + linear_combination U * ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑σ₂ + ↑t * I)‖ * + ‖(↑X : ℂ) ^ (↑σ₂ + ↑t * I)‖ + _ ≤ abs zeta_bound * ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑σ₂ + ↑t * I)‖ * ‖(↑X : ℂ) + ^ (↑σ₂ + ↑t * I)‖ := by + have U : zeta_bound ≤ abs zeta_bound := by simp only [le_abs_self] + linear_combination (U * ‖𝓜 (fun x ↦ (Smooth1 SmoothingF ε x : ℂ)) (↑σ₂ + ↑t * I)‖ * ‖(↑X + : ℂ) ^ (↑σ₂ + ↑t * I)‖ ) + _ ≤ abs zeta_bound * M * ((‖↑σ₂ + ↑t * I‖ ^ 2)⁻¹ * ε⁻¹) * ‖(↑X : ℂ) ^ (↑σ₂ + ↑t * I)‖ := by + have U := mellin_bound t + linear_combination (abs zeta_bound) * U * ‖(↑X : ℂ) ^ (↑σ₂ + ↑t * I)‖ + _ ≤ abs zeta_bound * M * (σ₂^2)⁻¹ * ε⁻¹ * ‖(↑X : ℂ) ^ (↑σ₂ + ↑t * I)‖ := by + linear_combination (abs zeta_bound * M * easy_bound t * ε⁻¹ * ‖(↑X : ℂ) ^ (↑σ₂ + ↑t * I)‖) + _ = abs zeta_bound * M * (σ₂^2)⁻¹ * ε⁻¹ * X ^ (σ₂) := by + rw [Complex.norm_cpow_eq_rpow_re_of_pos] + · simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, add_zero] + positivity + _ ≤ Const * ε⁻¹ * X ^ σ₂ := by + unfold Const + ring_nf + simp only [inv_pow, le_add_iff_nonneg_right, inv_pos, mul_nonneg_iff_of_pos_left, ε_pos] + positivity + exact Z + -- Now want to apply the triangle inequality + -- and bound everything trivially + simp only [one_div, mul_inv_rev, inv_I, neg_mul, norm_neg, Complex.norm_mul, norm_I, norm_inv, + norm_real, norm_eq_abs, Complex.norm_ofNat, one_mul, ge_iff_le] + have Z := + intervalIntegral.norm_integral_le_of_norm_le_const T1 + simp only [ge_iff_le] + have S : |π|⁻¹ * 2⁻¹ * (Const * ε⁻¹ * X ^ σ₂ * |3 + 3|) = C * X ^ σ₂ / ε := by + unfold C + ring_nf + simp only [sub_neg_eq_add] at Z + simp only [← S, ge_iff_le] + linear_combination (|π|⁻¹ * 2⁻¹ * Z) + +/-- A zero-free rectangle with a uniform bound for the logarithmic derivative of zeta. -/ +def LogDerivZetaBoundedAndHoloGenProp (n₁ n₂ : ℝ) : Prop := ∃ A C : ℝ, 0 < C ∧ A ∈ Ioc 0 (1 / 2) ∧ + LogDerivZetaHasBound n₁ n₂ A C + ∧ ∀ (T : ℝ) (_ : 3 ≤ T), + HolomorphicOn (fun (s : ℂ) ↦ ζ' s / (ζ s)) + (( (Icc ((1 : ℝ) - A / Real.log T ^ n₁) 2) ×ℂ (Icc (-T) T) ) \ {1}) + +lemma LogDerivZetaBoundedAndHoloGen {n₁ n₂ : ℝ} + (LogDerivZetaBndUnif : LogDerivZetaBndUnifGenProp n₁ n₂) + (LogDerivZetaHolcLargeT : LogDerivZetaHolcLargeTGenProp n₁) : + LogDerivZetaBoundedAndHoloGenProp n₁ n₂ := by + obtain ⟨A₁, A₁_in, C, C_pos, zeta_bnd⟩ := LogDerivZetaBndUnif + obtain ⟨A₂, A₂_in, holo⟩ := LogDerivZetaHolcLargeT + refine ⟨min A₁ A₂, C, C_pos, ?_, ?_, ?_⟩ + · exact ⟨lt_min A₁_in.1 A₂_in.1, le_trans (min_le_left _ _) A₁_in.2⟩ + · intro σ T hT hσ + apply zeta_bnd _ _ hT + apply mem_Ici.mpr (le_trans _ hσ) + gcongr + · bound + · apply min_le_left + · intro T hT + apply (holo _ hT).mono + intro s hs + simp only [Set.mem_sdiff, mem_singleton_iff, mem_reProdIm] at hs ⊢ + refine ⟨?_, hs.2⟩ + refine ⟨?_, hs.1.2⟩ + refine ⟨?_, hs.1.1.2⟩ + apply le_trans _ hs.1.1.1 + gcongr + · bound + · apply min_le_right + +lemma LogDerivZetaBoundedAndHolo99 : LogDerivZetaBoundedAndHoloGenProp 9 9 := by + exact LogDerivZetaBoundedAndHoloGen LogDerivZetaBndUnif99 LogDerivZetaHolcLargeT9 + +lemma MellinOfSmooth1cExplicit {ν : ℝ → ℝ} (diffν : ContDiff ℝ 1 ν) + (suppν : ν.support ⊆ Icc (1 / 2) 2) + (mass_one : ∫ x in Ioi 0, ν x / x = 1) : + ∃ ε₀ c : ℝ, 0 < ε₀ ∧ 0 < c ∧ + ∀ ε ∈ Ioo 0 ε₀, ‖𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 - 1‖ ≤ c * ε := by + have := MellinOfSmooth1c diffν suppν mass_one + rw [Asymptotics.isBigO_iff'] at this + rcases this with ⟨c, cpos, hc⟩ + unfold Filter.Eventually at hc + rw [mem_nhdsGT_iff_exists_Ioo_subset] at hc + rcases hc with ⟨ε₀, ε₀pos, h⟩ + refine ⟨ε₀, c, ε₀pos, cpos, fun ε hε ↦ ?_⟩ + specialize h hε + rw [mem_ofPred_eq, id_eq, norm_of_nonneg hε.1.le] at h + exact h + +open Filter Topology + +-- `x * rexp (-c * (log x) ^ B)) = Real.exp (Real.log x - c * (Real.log x) ^ B))` +-- so if `B < 1`, the exponent goes to infinity +lemma x_ε_to_inf (c : ℝ) {B : ℝ} (B_le : B < 1) : Tendsto + (fun x ↦ x * Real.exp (-c * (Real.log x) ^ B)) atTop atTop := by + have coeff_to_zero {B : ℝ} (B_le : B < 1) : + Tendsto (fun x ↦ Real.log x ^ (B - 1)) atTop (𝓝 0) := by + have B_minus_1_neg : B - 1 < 0 := by linarith + rw [← Real.zero_rpow (ne_of_lt B_minus_1_neg), + zero_rpow (ne_of_lt B_minus_1_neg)] + have one_minus_B_pos : 0 < 1 - B := by linarith + rw [show B - 1 = -(1 - B) by ring] + have : ∀ᶠ (x : ℝ) in atTop, Real.log x ^ (-(1 - B)) = (Real.log x ^ ((1 - B)))⁻¹ := by + filter_upwards [eventually_ge_atTop (1 : ℝ)] with x hx + apply Real.rpow_neg + exact Real.log_nonneg hx + rw [tendsto_congr' this] + apply tendsto_inv_atTop_zero.comp + apply (tendsto_rpow_atTop one_minus_B_pos).comp + exact tendsto_log_atTop + have log_sub_log_pow_inf (c : ℝ) {B : ℝ} (B_le : B < 1) : + Tendsto (fun (x : ℝ) ↦ Real.log x - c * Real.log x ^ B) atTop atTop := by + have factor_form : ∀ x > 1, Real.log x - c * Real.log x ^ B = + Real.log x * (1 - c * Real.log x ^ (B - 1)) := by + intro x hx + ring_nf + congr! 1 + rw [mul_assoc, mul_comm (Real.log x), mul_assoc] + congr! 1 + have log_pos : 0 < Real.log x := Real.log_pos hx + rw [(by simp : Real.log x ^ (-1 + B) * Real.log x = + Real.log x ^ (-1 + B) * (Real.log x) ^ (1 : ℝ))] + rw [← Real.rpow_add log_pos] + ring_nf + have coeff_to_one : Tendsto (fun x ↦ 1 - c * Real.log x ^ (B - 1)) atTop (𝓝 1) := by + specialize coeff_to_zero B_le + apply Tendsto.const_mul c at coeff_to_zero + convert (tendsto_const_nhds (x := (1 : ℝ)) (f := (atTop : Filter ℝ))).sub coeff_to_zero + ring + have eventually_factored : ∀ᶠ x in atTop, Real.log x - c * Real.log x ^ B = + Real.log x * (1 - c * Real.log x ^ (B - 1)) := by + filter_upwards [eventually_gt_atTop (1 : ℝ)] with x hx + exact factor_form x hx + rw [tendsto_congr' eventually_factored] + apply Tendsto.atTop_mul_pos (by norm_num : (0 : ℝ) < 1) tendsto_log_atTop coeff_to_one + have x_εx_eq (c B : ℝ) : ∀ᶠ (x : ℝ) in atTop, x * rexp (-c * Real.log x ^ B) = + rexp (Real.log x - c * Real.log x ^ B) := by + filter_upwards [eventually_gt_atTop 0] with x hx_pos + conv => + enter [1, 1] + rw [(Real.exp_log hx_pos).symm] + rw [← Real.exp_add] + ring_nf + rw [tendsto_congr' (x_εx_eq c B)] + exact tendsto_exp_atTop.comp (log_sub_log_pow_inf c B_le) + +/- +\section{MediumPNT} +-/ + +/- +Assuming a bound of the form of Definition \ref{LogDerivZetaHasBound}, we have that + $$\sum_{n \leq x}\Lambda(n)=x+O(x\exp(-c(\log x)^{1/(1+n_1)})).$$ +By Theorems \ref{SmoothedChebyshevPull1}, \ref{SmoothedChebyshevPull2}, + and \ref{SmoothedChebyshevClose} we have that + $$\mathcal{M}(\tilde{1}_\varepsilon)(1)\,x^1+I_1-I_2+I_3-I_4+I_5+I_6+I_7+I_8+I_9 + =\psi(x)+O(\varepsilon x\log x).$$ + Applying Theorems \ref{I1Bound}, \ref{I2GenBound}, \ref{I3GenBound}, \ref{I4GenBound}, + \ref{I5Bound}, \ref{I6GenBound}, \ref{I7GenBound}, \ref{I8GenBound}, \ref{I9Bound}, + and \ref{MellinOfSmooth1c} we have + $$\psi(x)=x+O(\varepsilon x)+O(\varepsilon x\log x)+O\left(\frac{X}{\varepsilon T}\right)+ + O\left(\frac{X\log X}{\varepsilon T}\right)+ + O\left(\frac{X}{\varepsilon}\,X^{-A/(\log T)^{n_1}}\right)+ + O\left(\frac{X^{\sigma_2}}{\varepsilon}\right).$$ + Balancing the error terms in $\varepsilon$ and $T$ completes the proof. +-/ +private lemma eventual_exp_log_rpow_mul_log_le {const1 const2 : ℝ} (const1pos : 0 < const1) + (const2pos : 0 < const2) : + ∀ᶠ (x : ℝ) in atTop, + rexp (-const1 * Real.log x ^ const2) * Real.log x ≤ + rexp 0 := by + have := ((isLittleO_log_rpow_atTop const2pos).bound const1pos) + have : ∀ᶠ (x : ℝ) in atTop, Real.log (Real.log x) ≤ + const1 * (Real.log x) ^ const2 := by + have := tendsto_log_atTop.eventually this + filter_upwards [this, eventually_gt_atTop 10] with x hx x_gt + convert hx using 1 + · rw [Real.norm_of_nonneg] + exact Real.log_nonneg (logt_gt_one (by linarith)).le + · congr! 1 + rw [Real.norm_of_nonneg] + apply Real.rpow_nonneg + apply Real.log_nonneg + linarith + have loglogx : ∀ᶠ (x : ℝ) in atTop, + Real.log x = rexp (Real.log (Real.log x)) := by + filter_upwards [eventually_gt_atTop 3] with x hx + rw [Real.exp_log] + apply Real.log_pos + linarith + filter_upwards [loglogx, this] with x loglogx hx + conv => + enter [1, 2] + rw [loglogx] + rw [← Real.exp_add] + apply Real.exp_monotone + grw [hx] + simp + +private lemma eventual_exp_log_rpow_mul_log_le_exp {const1 const1' const2 : ℝ} (const1bnds : + const1' < const1) + (const2pos : 0 < const2) : + ∀ᶠ (x : ℝ) in atTop, + rexp (-const1 * Real.log x ^ const2) * Real.log x ≤ + rexp (-const1' * Real.log x ^ const2) := by + have : 0 < const1 - const1' := by linarith + filter_upwards [eventual_exp_log_rpow_mul_log_le this const2pos] with x hx + have : rexp (-const1 * Real.log x ^ const2) * Real.log x + = rexp (-(const1') * Real.log x ^ const2) + * rexp (-(const1 - const1') * Real.log x ^ const2) * Real.log x := by + congr! 1 + rw [← Real.exp_add] + congr! 1 + ring + rw [this, + mul_assoc] + grw [hx] + simp + +private lemma balanced_rpow_exp_le {n₁ A : ℝ} (n₁_pos : 0 < n₁) + (A_in_Ioc : A ∈ Ioc 0 (1 / 2)) {const1 const1' const2 : ℝ} (const2_eq : const2 = 1 / (1 + n₁)) + (const1_eq : const1 = (A ^ const2 / 2)) (const1'_eq : const1' = (A ^ const2 / 4)) : + ∀ᶠ (x : ℝ) in atTop, + x ^ (-A / Real.log (rexp (A ^ const2 * Real.log x ^ const2)) ^ (n₁ : ℝ)) * + rexp (-(-const1 * Real.log x ^ const2)) ≤ + rexp (-const1' * Real.log x ^ const2) := by + have Apos : 0 < A := A_in_Ioc.1 + have : ∀ᶠ (x : ℝ) in atTop, x = rexp (Real.log x) := by + filter_upwards [eventually_gt_atTop 0] with x hx + rw [Real.exp_log hx] + filter_upwards [this, eventually_gt_atTop 3] with x hx x_gt_3 + have logxpos : 0 < Real.log x := by apply Real.log_pos; linarith + conv => + enter [1, 1, 1] + rw [hx] + rw [← Real.exp_mul, Real.log_exp, Real.mul_rpow] + · have {y : ℝ} (ypos : 0 < y) : y / (y ^ const2) ^ (n₁ : ℝ) = y ^ const2 := by + rw [← Real.rpow_mul ypos.le, + div_eq_mul_inv] + rw [← Real.rpow_neg ypos.le] + conv => + enter [1, 1] + rw [← Real.rpow_one y] + rw [← Real.rpow_add ypos, const2_eq] + field_simp + ring_nf + rw [div_mul_eq_div_div, neg_div, this (A_in_Ioc.1), mul_div] + conv => + enter [1, 1, 1, 1] + rw [mul_comm] + rw [← mul_div, this (y := Real.log x) logxpos, ← Real.exp_add] + apply Real.exp_monotone + have : -A ^ const2 * Real.log x ^ const2 + -(-const1 * Real.log x ^ const2) + = (-(A ^ const2 - const1) * Real.log x ^ const2) := by ring + rw [this] + gcongr + rw [const1'_eq, const1_eq] + have : 0 ≤ A ^ const2 := by + apply Real.rpow_nonneg A_in_Ioc.1.le + linarith + · rw [const2_eq] + positivity + · apply Real.rpow_nonneg + apply Real.log_nonneg + linarith + +private lemma tendsto_const_mul_log_rpow_neg {pow2 : ℝ} (pow2_neg : pow2 < 0) (c' : ℝ) : + Tendsto (fun x ↦ c' * Real.log x ^ pow2) atTop (𝓝 0) := by + rw [← mul_zero c'] + apply Tendsto.const_mul + have := tendsto_rpow_neg_atTop (y := -pow2) (by linarith) + rw [neg_neg] at this + apply this.comp + exact Real.tendsto_log_atTop + +private lemma eventual_const_mul_log_rpow_lt {pow2 : ℝ} (pow2_neg : pow2 < 0) {c : ℝ} (cpos : 0 < + c) (c' : ℝ) : + ∀ᶠ (x : ℝ) in atTop, c' * (Real.log x) ^ pow2 < c := by + apply (tendsto_const_mul_log_rpow_neg pow2_neg c').eventually_lt_const + exact cpos + +private lemma eventual_log_linear_nonnegative {c1 : ℝ} (c1pos : 0 < c1) (c2 : ℝ) {pow1 : ℝ} + (pow1_lt : pow1 < 1) : + ∀ᶠ (x : ℝ) in atTop, 0 ≤ Real.log x * (c1 - c2 * (Real.log x) ^ (pow1 - 1)) := by + filter_upwards [eventually_gt_atTop 3 , eventual_const_mul_log_rpow_lt (by linarith : pow1 - 1 < + 0) + (by linarith : 0 < c1 / 2) c2] with x x_gt hx + have : 0 ≤ Real.log x := by + apply Real.log_nonneg + linarith + apply mul_nonneg this + linarith + +private lemma eventual_log_linear_domination {const1 : ℝ} (const1_lt : const1 < 1) (const2 const3 + : ℝ) + {pow1 : ℝ} (pow1_lt : pow1 < 1) : ∀ᶠ (x : ℝ) in atTop, + const1 * Real.log x + const2 * Real.log x ^ pow1 + ≤ Real.log x - const3 * Real.log x ^ pow1 := by + filter_upwards [eventual_log_linear_nonnegative (by linarith : 0 < 1 - const1) (const2 + const3) + pow1_lt, + eventually_gt_atTop 3] with x hx x_gt + have : + Real.log x - const3 * Real.log x ^ pow1 - (const1 * Real.log x + const2 * Real.log x ^ pow1) + = (1 - const1) * Real.log x - (const2 + const3) * Real.log x ^ pow1 := by ring + rw [← sub_nonneg, this] + convert hx using 1 + ring_nf + congr! 1 + · have : Real.log x * const2 * Real.log x ^ (-1 + pow1) + = const2 * Real.log x ^ pow1 := by + rw [mul_assoc, mul_comm, mul_assoc] + congr! 1 + conv => + enter [1, 2] + rw [← Real.rpow_one (Real.log x)] + rw [← Real.rpow_add (Real.log_pos (by linarith))] + ring_nf + rw [this] + have : Real.log x * const3 * Real.log x ^ (-1 + pow1) + = const3 * Real.log x ^ pow1 := by + rw [mul_assoc, mul_comm, mul_assoc] + congr! 1 + conv => + enter [1, 2] + rw [← Real.rpow_one (Real.log x)] + rw [← Real.rpow_add (Real.log_pos (by linarith))] + ring_nf + rw [this] + +/-- Assemble the nine contour estimates into a pointwise Chebyshev error bound. -/ +private theorem pnt_from_contour_estimates {n₁ : ℝ} (n₁_pos : 0 < n₁) (ν : ℝ → ℝ) (ν_supp : + support ν ⊆ Icc (1 / 2) 2) + (ContDiff1ν : ContDiff ℝ 1 ν) (ν_nonneg : ∀ x > 0, 0 ≤ ν x) (ν_massOne : ∫ (x : ℝ) in Ioi 0, ν x + / x = 1) (A : ℝ) + (A_in_Ioc : A ∈ Ioc 0 (1 / 2)) + (holo1 : ∀ (T : ℝ), 3 ≤ T → HolomorphicOn (fun s => ζ' s / ζ s) (Icc (1 - A / Real.log T ^ n₁) 2 + ×ℂ Icc (-T) T \ {1})) + (σ₂ : ℝ) (σ₂InIoo : σ₂ ∈ Ioo 0 1) (holo2 : HolomorphicOn (fun s => ζ' s / ζ s) (uIcc σ₂ 2 ×ℂ + uIcc (-3) 3 \ {1})) + (c_close : ℝ) + (h_close : + ∀ (X : ℝ), + 3 < X → ∀ (ε : ℝ), 0 < ε → ε < 1 → 2 < X * ε → ‖SmoothedChebyshev ν ε X - ↑(ψ X)‖ ≤ c_close + * ε * X * Real.log X) + (ε_main C_main : ℝ) (C_main_pos : 0 < C_main) + (h_main : ∀ ε ∈ Ioo 0 ε_main, ‖𝓜 (fun x => (Smooth1 ν ε x : ℂ)) 1 - 1‖ ≤ C_main * ε) (c₁ : ℝ) + (hc₁ : ∀ (ε : ℝ), 0 < ε → ε < 1 → ∀ (X : ℝ), 3 < X → ∀ {T : ℝ}, 3 < T → ‖I₁ ν ε X T‖ ≤ c₁ * X * + Real.log X / (ε * T)) + (c₂ : ℝ) (c₂pos : 0 < c₂) + (hc₂ : + ∀ (X : ℝ), + 3 < X → + ∀ {ε : ℝ}, + 0 < ε → + ε < 1 → + ∀ {T : ℝ}, + 3 < T → + ‖I₂ ν ε T X (1 - A / Real.log T ^ n₁)‖ ≤ c₂ * X / (ε * T)) + (c₃ : ℝ) + (hc₃ : + ∀ (X : ℝ), + 3 < X → + ∀ {ε : ℝ}, + 0 < ε → + ε < 1 → + ∀ {T : ℝ}, + 3 < T → + ‖I₃ ν ε T X (1 - A / Real.log T ^ n₁)‖ ≤ c₃ * X * X ^ (-A / Real.log T ^ n₁) / ε) + (c₅ : ℝ) (hc₅ : ∀ (X : ℝ), 3 < X → ∀ {ε : ℝ}, 0 < ε → ε < 1 → ‖I₅ ν ε X σ₂‖ ≤ c₅ * X ^ σ₂ / ε) + (c₇ : ℝ) + (hc₇ : + ∀ (X : ℝ), + 3 < X → + ∀ {ε : ℝ}, + 0 < ε → + ε < 1 → + ∀ {T : ℝ}, + 3 < T → + ‖I₇ ν ε T X (1 - A / Real.log T ^ n₁)‖ ≤ c₇ * X * X ^ (-A / Real.log T ^ n₁) / ε) + (c₈ : ℝ) (c₈pos : 0 < c₈) + (hc₈ : + ∀ (X : ℝ), + 3 < X → + ∀ {ε : ℝ}, + 0 < ε → + ε < 1 → + ∀ {T : ℝ}, + 3 < T → + ‖I₈ ν ε T X (1 - A / Real.log T ^ n₁)‖ ≤ c₈ * X / (ε * T)) + (c₉ : ℝ) + (hc₉ : ∀ {ε : ℝ}, 0 < ε → ε < 1 → ∀ (X : ℝ), 3 < X → ∀ {T : ℝ}, 3 < T → ‖I₉ ν ε X T‖ ≤ c₉ * X * + Real.log X / (ε * T)) + (c₄ : ℝ) (Tlb₄ : ℝ) + (hc₄ : + ∀ (X : ℝ), + 3 < X → + ∀ {ε : ℝ}, + 0 < ε → + ε < 1 → + ∀ {T : ℝ}, + Tlb₄ < T → + ‖I₄ ν ε X (1 - A / Real.log T ^ n₁) σ₂‖ ≤ c₄ * X * X ^ (-A / Real.log T ^ n₁) / ε) + (c₆ : ℝ) (Tlb₆ : ℝ) + (hc₆ : + ∀ (X : ℝ), + 3 < X → + ∀ {ε : ℝ}, + 0 < ε → + ε < 1 → + ∀ {T : ℝ}, + Tlb₆ < T → + ‖I₆ ν ε X (1 - A / Real.log T ^ n₁) σ₂‖ ≤ c₆ * X * X ^ (-A / Real.log T ^ n₁) / ε) + (C' C'' C''' c C : ℝ) (εx Tx : ℝ → ℝ) (X : ℝ) (X_gt_3 : 3 < X) (ε_lt_one : εx X < 1) (ε_X : 2 < + X * εx X) + (T_gt_3 : 3 < Tx X) (T_gt_Tlb₄ : Tlb₄ < Tx X) (T_gt_Tlb₆ : Tlb₆ < Tx X) (σ₂_lt_σ₁ : σ₂ < 1 - A / + Real.log (Tx X) ^ n₁) + (ε_lt_ε_main : εx X < ε_main) (logX_ge : 1 ≤ Real.log X) + (event_1 : C' * εx X * X * Real.log X ≤ C' * X * rexp (-c * Real.log X ^ (1 / (1 + n₁)))) + (event_2 : C'' * X * Real.log X / (εx X * Tx X) ≤ C'' * X * rexp (-c * Real.log X ^ (1 / (1 + + n₁)))) + (event_3 : C''' * X * X ^ (-A / Real.log (Tx X) ^ n₁) / εx X ≤ C''' * X * rexp (-c * Real.log X + ^ (1 / (1 + n₁)))) + (event_4 : c₅ * X ^ σ₂ / εx X ≤ c₅ * X * rexp (-c * Real.log X ^ (1 / (1 + n₁)))) (C'_def : C' = + c_close + C_main) + (C''_def : C'' = c₁ + c₂ + c₈ + c₉) (C'''_def : C''' = c₃ + c₄ + c₆ + c₇) (C_def : C = C' + C'' + + C''' + c₅) + (εx_pos : 0 < εx X) : ‖Chebyshev.psi X - X‖ ≤ C * ‖X * rexp (-c * Real.log X ^ (1 / (1 + n₁)))‖ + := by + subst C' C'' C''' C + let C' := c_close + C_main + let C'' := c₁ + c₂ + c₈ + c₉ + let C''' := c₃ + c₄ + c₆ + c₇ + let C := C' + C'' + C''' + c₅ + let ε : ℝ := εx X + have ε_pos : 0 < ε := εx_pos + specialize h_close X X_gt_3 ε ε_pos ε_lt_one ε_X + let ψ_ε_of_X := SmoothedChebyshev ν ε X + let T : ℝ := Tx X + specialize holo1 T T_gt_3.le + let σ₁ : ℝ := 1 - A / (Real.log T) ^ n₁ + have σ₁pos : 0 < σ₁ := by calc + 1 - A / (Real.log T) ^ n₁ >= 1 - (1/2) / 1 ^ n₁ := by + gcongr + · exact A_in_Ioc.2 + · exact (logt_gt_one T_gt_3.le).le + _ > 0 := by norm_num + have σ₁_lt_one : σ₁ < 1 := by + apply sub_lt_self + apply div_pos A_in_Ioc.1 + bound + rw [uIcc_of_le (by linarith), uIcc_of_le (by linarith)] at holo2 + have holo2a : HolomorphicOn (SmoothedChebyshevIntegrand ν ε X) + (Icc σ₂ 2 ×ℂ Icc (-3) 3 \ {1}) := by + apply DifferentiableOn.mul + · apply DifferentiableOn.mul + · rw [(by ext; ring : (fun s ↦ -ζ' s / ζ s) = (fun s ↦ -(ζ' s / ζ s)))] + apply DifferentiableOn.neg holo2 + · intro s hs + apply DifferentiableAt.differentiableWithinAt + apply Smooth1MellinDifferentiable ContDiff1ν ν_supp ⟨ε_pos, ε_lt_one⟩ ν_nonneg ν_massOne + linarith [mem_reProdIm.mp hs.1 |>.1.1, σ₂InIoo.1] + · intro s hs + apply DifferentiableAt.differentiableWithinAt + apply DifferentiableAt.const_cpow (by fun_prop) + left + norm_cast + linarith + have ψ_ε_diff : ‖ψ_ε_of_X - 𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 * X‖ ≤ ‖I₁ ν ε X T‖ + ‖I₂ ν ε T X + σ₁‖ + + ‖I₃ ν ε T X σ₁‖ + ‖I₄ ν ε X σ₁ σ₂‖ + ‖I₅ ν ε X σ₂‖ + ‖I₆ ν ε X σ₁ σ₂‖ + ‖I₇ ν ε T X σ₁‖ + + ‖I₈ ν ε T X σ₁‖ + ‖I₉ ν ε X T‖ := by + unfold ψ_ε_of_X + rw [SmoothedChebyshevPull1 ε_pos ε_lt_one X X_gt_3 (T := T) (by linarith) + σ₁pos σ₁_lt_one holo1 ν_supp ν_nonneg ν_massOne ContDiff1ν] + rw [SmoothedChebyshevPull2 ε_pos ε_lt_one X X_gt_3 (T := T) (by linarith) + σ₂InIoo.1 σ₁_lt_one σ₂_lt_σ₁ holo1 holo2a ν_supp ν_nonneg ν_massOne ContDiff1ν] + ring_nf + iterate 5 + apply le_trans (by apply norm_add_le) + gcongr + rw [(by ring : I₁ ν ε X T - I₂ ν ε T X σ₁ + I₃ ν ε T X σ₁ - I₄ ν ε X σ₁ σ₂ = (I₁ ν ε X T - I₂ + ν ε T X σ₁) + (I₃ ν ε T X σ₁ - I₄ ν ε X σ₁ σ₂))] + apply le_trans (by apply norm_add_le) + rw [(by ring : ‖I₁ ν ε X T‖ + ‖I₂ ν ε T X σ₁‖ + ‖I₃ ν ε T X σ₁‖ + ‖I₄ ν ε X σ₁ σ₂‖ = + (‖I₁ ν ε X T‖ + ‖I₂ ν ε T X σ₁‖) + (‖I₃ ν ε T X σ₁‖ + ‖I₄ ν ε X σ₁ σ₂‖))] + gcongr <;> apply le_trans (by apply norm_sub_le) <;> rfl + specialize h_main ε ⟨ε_pos, ε_lt_ε_main⟩ + have main : ‖𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 * X - X‖ ≤ C_main * ε * X := by + nth_rewrite 2 [← one_mul X] + push_cast + rw [← sub_mul, norm_mul] + gcongr + rw [norm_real, norm_of_nonneg (by linarith)] + specialize hc₁ ε ε_pos ε_lt_one X X_gt_3 T_gt_3 + specialize hc₂ X X_gt_3 ε_pos ε_lt_one T_gt_3 + specialize hc₃ X X_gt_3 ε_pos ε_lt_one T_gt_3 + specialize hc₅ X X_gt_3 ε_pos ε_lt_one + specialize hc₇ X X_gt_3 ε_pos ε_lt_one T_gt_3 + specialize hc₈ X X_gt_3 ε_pos ε_lt_one T_gt_3 + specialize hc₉ ε_pos ε_lt_one X X_gt_3 T_gt_3 + specialize hc₄ X X_gt_3 ε_pos ε_lt_one T_gt_Tlb₄ + specialize hc₆ X X_gt_3 ε_pos ε_lt_one T_gt_Tlb₆ + clear ν_nonneg ν_massOne ContDiff1ν ν_supp holo2 + have C'bnd : c_close * ε * X * Real.log X + C_main * ε * X ≤ C' * ε * X * Real.log X := by + have : C_main * ε * X * 1 ≤ C_main * ε * X * Real.log X := by + gcongr + linarith + have C''bnd : c₁ * X * Real.log X / (ε * T) + c₂ * X / (ε * T) + c₈ * X / (ε * T) + + c₉ * X * Real.log X / (ε * T) ≤ C'' * X * Real.log X / (ε * T) := by + unfold C'' + rw [(by ring : (c₁ + c₂ + c₈ + c₉) * X * Real.log X / (ε * T) + = c₁ * X * Real.log X / (ε * T) + c₂ * X * Real.log X / (ε * T) + + c₈ * X * Real.log X / (ε * T) + c₉ * X * Real.log X / (ε * T))] + have : c₂ * X / (ε * T) * 1 ≤ c₂ * X / (ε * T) * Real.log X := by + gcongr + have : c₂ * X / (ε * T) ≤ c₂ * X * Real.log X / (ε * T) := by + ring_nf at this ⊢ + linarith + grw [this] + have : c₈ * X / (ε * T) * 1 ≤ c₈ * X / (ε * T) * Real.log X := by + gcongr + have : c₈ * X / (ε * T) ≤ c₈ * X * Real.log X / (ε * T) := by + ring_nf at this ⊢ + linarith + grw [this] + have C'''bnd : c₃ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₄ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₆ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₇ * X * X ^ (-A / Real.log T ^ n₁) / ε + ≤ C''' * X * X ^ (-A / Real.log T ^ n₁) / ε := by + apply le_of_eq + ring + calc + _ = ‖(ψ X - ψ_ε_of_X) + (ψ_ε_of_X - X)‖ := by ring_nf; norm_cast + _ ≤ ‖ψ X - ψ_ε_of_X‖ + ‖ψ_ε_of_X - X‖ := norm_add_le _ _ + _ = ‖ψ X - ψ_ε_of_X‖ + ‖(ψ_ε_of_X - 𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 * X) + + (𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 * X - X)‖ := by ring_nf + _ ≤ ‖ψ X - ψ_ε_of_X‖ + ‖ψ_ε_of_X - 𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 * X‖ + + ‖𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 * X - X‖ := by + rw [add_assoc] + gcongr + apply norm_add_le + _ = ‖ψ X - ψ_ε_of_X‖ + ‖𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 * X - X‖ + + ‖ψ_ε_of_X - 𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 * X‖ := by ring + _ ≤ ‖ψ X - ψ_ε_of_X‖ + ‖𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 * X - X‖ + + (‖I₁ ν ε X T‖ + ‖I₂ ν ε T X σ₁‖ + ‖I₃ ν ε T X σ₁‖ + ‖I₄ ν ε X σ₁ σ₂‖ + + ‖I₅ ν ε X σ₂‖ + ‖I₆ ν ε X σ₁ σ₂‖ + ‖I₇ ν ε T X σ₁‖ + ‖I₈ ν ε T X σ₁‖ + + ‖I₉ ν ε X T‖) := by gcongr + _ ≤ c_close * ε * X * Real.log X + C_main * ε * X + + (c₁ * X * Real.log X / (ε * T) + c₂ * X / (ε * T) + + c₃ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₄ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₅ * X ^ σ₂ / ε + + c₆ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₇ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₈ * X / (ε * T) + + c₉ * X * Real.log X / (ε * T)) := by + gcongr + convert! h_close using 1 + rw [← norm_neg] + congr + ring + _ = (c_close * ε * X * Real.log X + C_main * ε * X) + + ((c₁ * X * Real.log X / (ε * T) + c₂ * X / (ε * T) + + c₈ * X / (ε * T) + + c₉ * X * Real.log X / (ε * T)) + + (c₃ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₄ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₆ * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₇ * X * X ^ (-A / Real.log T ^ n₁) / ε) + + c₅ * X ^ σ₂ / ε + ) := by ring + _ ≤ C' * ε * X * Real.log X + + (C'' * X * Real.log X / (ε * T) + + C''' * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₅ * X ^ σ₂ / ε + ) := by + gcongr + _ = C' * ε * X * Real.log X + + C'' * X * Real.log X / (ε * T) + + C''' * X * X ^ (-A / Real.log T ^ n₁) / ε + + c₅ * X ^ σ₂ / ε + := by ring + _ ≤ C' * X * rexp (-c * Real.log X ^ ((1 : ℝ) / (1 + n₁))) + + C'' * X * rexp (-c * Real.log X ^ ((1 : ℝ) / (1 + n₁))) + + C''' * X * rexp (-c * Real.log X ^ ((1 : ℝ) / (1 + n₁))) + + c₅ * X * rexp (-c * Real.log X ^ ((1 : ℝ) / (1 + n₁))) + := by + gcongr + _ = C * X * rexp (-c * Real.log X ^ ((1 : ℝ) / (1 + n₁))) + := by ring + _ = _ := by + rw [Real.norm_of_nonneg] + · rw [← mul_assoc] + · positivity + +lemma GenStrengthPNT {n₁ n₂ : ℝ} + (LogDerivZetaBoundedAndHolo : LogDerivZetaBoundedAndHoloGenProp n₁ n₂) + (n₁_pos : 0 < n₁) (n₂_pos : 0 < n₂) : ∃ c > 0, + (ψ - id) =O[atTop] + fun (x : ℝ) ↦ x * Real.exp (-c * (Real.log x) ^ ((1 : ℝ) / (1 + n₁))) := by + have ⟨ν, ContDiffν, ν_nonneg', ν_supp, ν_massOne'⟩ := SmoothExistence + have ContDiff1ν : ContDiff ℝ 1 ν := by exact ContDiffν.of_le (by simp) + have ν_nonneg : ∀ x > 0, 0 ≤ ν x := fun x _ ↦ ν_nonneg' x + have ν_massOne : ∫ x in Ioi 0, ν x / x = 1 := by rwa [← integral_Ici_eq_integral_Ioi] + obtain ⟨A, C_bnd, C_bnd_pos, A_in_Ioc, zeta_bnd, holo1⟩ := LogDerivZetaBoundedAndHolo + obtain ⟨σ₂, σ₂InIoo, holo2⟩ := LogDerivZetaHolcSmallT' + obtain ⟨c_close, c_close_pos, h_close⟩ := SmoothedChebyshevClose ContDiff1ν ν_supp ν_nonneg + ν_massOne + obtain ⟨ε_main, C_main, ε_main_pos, C_main_pos, h_main⟩ := MellinOfSmooth1cExplicit ContDiff1ν + ν_supp ν_massOne + obtain ⟨c₁, c₁pos, hc₁⟩ := I1Bound ν_supp ContDiff1ν ν_nonneg ν_massOne + obtain ⟨c₂, c₂pos, hc₂⟩ := I2GenBound ν_supp ContDiff1ν n₁_pos n₂_pos zeta_bnd C_bnd_pos A_in_Ioc + obtain ⟨c₃, c₃pos, hc₃⟩ := I3GenBound ν_supp ContDiff1ν n₁_pos n₂_pos zeta_bnd C_bnd_pos A_in_Ioc + obtain ⟨c₅, c₅pos, hc₅⟩ := I5Bound ν_supp ContDiff1ν holo2 σ₂InIoo + obtain ⟨c₇, c₇pos, hc₇⟩ := I7GenBound ν_supp ContDiff1ν n₁_pos n₂_pos zeta_bnd C_bnd_pos A_in_Ioc + obtain ⟨c₈, c₈pos, hc₈⟩ := I8GenBound ν_supp ContDiff1ν n₁_pos n₂_pos zeta_bnd C_bnd_pos A_in_Ioc + obtain ⟨c₉, c₉pos, hc₉⟩ := I9Bound ν_supp ContDiff1ν ν_nonneg ν_massOne + obtain ⟨c₄, c₄pos, Tlb₄, Tlb₄bnd, hc₄⟩ := I4GenBound ν_supp ContDiff1ν holo2 σ₂InIoo n₁_pos + A_in_Ioc + obtain ⟨c₆, c₆pos, Tlb₆, Tlb₆bnd, hc₆⟩ := I6GenBound ν_supp ContDiff1ν holo2 σ₂InIoo n₁_pos + A_in_Ioc + let C' := c_close + C_main + let C'' := c₁ + c₂ + c₈ + c₉ + let C''' := c₃ + c₄ + c₆ + c₇ + let c : ℝ := A ^ ((1 : ℝ) / (1 + n₁)) / 4 + have cpos : 0 < c := by + simp_all only [one_div, support_subset_iff, ne_eq, mem_Icc, gt_iff_lt, mem_Ioo, and_imp, + mem_Ioc, Nat.ofNat_pos, neg_le_self_iff, Nat.ofNat_nonneg, uIcc_of_le, + div_pos_iff_of_pos_right, c] + obtain ⟨left, right⟩ := A_in_Ioc + positivity + refine ⟨c, cpos, ?_⟩ + rw [Asymptotics.isBigO_iff] + let C : ℝ := C' + C'' + C''' + c₅ + refine ⟨C, ?_⟩ + let c_εx : ℝ := A ^ ((1 : ℝ) / (1 + n₁)) / 2 + have c_εx_pos : 0 < c_εx := by + simp_all only [one_div, support_subset_iff, ne_eq, mem_Icc, gt_iff_lt, mem_Ioo, and_imp, + mem_Ioc, Nat.ofNat_pos, neg_le_self_iff, Nat.ofNat_nonneg, uIcc_of_le, + div_pos_iff_of_pos_right, c, c_εx] + let c_Tx : ℝ := A ^ ((1 : ℝ) / (1 + n₁)) + have c_Tx_pos : 0 < c_Tx := by + simp_all only [one_div, support_subset_iff, ne_eq, mem_Icc, gt_iff_lt, mem_Ioo, and_imp, + mem_Ioc, Nat.ofNat_pos, neg_le_self_iff, Nat.ofNat_nonneg, uIcc_of_le, + div_pos_iff_of_pos_right, c, c_εx, c_Tx] + let εx := (fun x ↦ Real.exp (-c_εx * (Real.log x) ^ ((1 : ℝ) / (1 + n₁)))) + let Tx := (fun x ↦ Real.exp (c_Tx * (Real.log x) ^ ((1 : ℝ) / (1 + n₁)))) + have one_div_succ_n₁_pos : 0 < (1 : ℝ) / (1 + n₁) := by + simp only [one_div, inv_pos] + linarith + have one_div_succ_n₁_lt_one : (1 : ℝ) / (1 + n₁) < 1 := by + rw [one_div, inv_lt_one₀ (one_div_pos.mp one_div_succ_n₁_pos)] + norm_num [n₁_pos] + have Tx_to_inf : Tendsto Tx atTop atTop := by + unfold Tx + apply tendsto_exp_atTop.comp + apply Tendsto.pos_mul_atTop c_Tx_pos tendsto_const_nhds + exact (tendsto_rpow_atTop one_div_succ_n₁_pos).comp Real.tendsto_log_atTop + have ex_to_zero : Tendsto εx atTop (𝓝 0) := by + unfold εx + apply Real.tendsto_exp_atBot.comp + have this (x) : -c_εx * Real.log x ^ ((1 : ℝ) / (1 + n₁)) = -(c_εx * Real.log x ^ ((1 : ℝ) / + (1 + n₁))) := by + ring + simp_rw [this] + rw [tendsto_neg_atBot_iff] + apply Tendsto.const_mul_atTop c_εx_pos + exact (tendsto_rpow_atTop one_div_succ_n₁_pos).comp tendsto_log_atTop + have eventually_εx_lt_one : ∀ᶠ (x : ℝ) in atTop, εx x < 1 := by + apply (tendsto_order.mp ex_to_zero).2 + norm_num + have eventually_2_lt : ∀ᶠ (x : ℝ) in atTop, 2 < x * εx x := by + have := x_ε_to_inf c_εx one_div_succ_n₁_lt_one + exact this.eventually_gt_atTop 2 + have eventually_T_gt_3 : ∀ᶠ (x : ℝ) in atTop, 3 < Tx x := by + exact Tx_to_inf.eventually_gt_atTop 3 + have eventually_T_gt_Tlb₄ : ∀ᶠ (x : ℝ) in atTop, Tlb₄ < Tx x := by + exact Tx_to_inf.eventually_gt_atTop _ + have eventually_T_gt_Tlb₆ : ∀ᶠ (x : ℝ) in atTop, Tlb₆ < Tx x := by + exact Tx_to_inf.eventually_gt_atTop _ + have eventually_σ₂_lt_σ₁ : ∀ᶠ (x : ℝ) in atTop, σ₂ < 1 - A / (Real.log (Tx x)) ^ n₁ := by + apply (tendsto_order.mp ?_).1 + · exact σ₂InIoo.2 + have := tendsto_inv_atTop_zero.comp ((tendsto_rpow_atTop n₁_pos).comp + (tendsto_log_atTop.comp Tx_to_inf)) + have := Tendsto.const_mul (b := A) this + convert (tendsto_const_nhds (x := (1 : ℝ))).sub this using 2 + · simp only [comp_apply, div_eq_mul_inv] + · simp + have eventually_ε_lt_ε_main : ∀ᶠ (x : ℝ) in atTop, εx x < ε_main := by + apply (tendsto_order.mp ex_to_zero).2 + assumption + have event_logX_ge : ∀ᶠ (x : ℝ) in atTop, 1 ≤ Real.log x := by + apply Real.tendsto_log_atTop.eventually_ge_atTop + have event_1 : ∀ᶠ (x : ℝ) in atTop, C' * (εx x) * x * Real.log x ≤ + C' * x * rexp (-c * Real.log x ^ ((1 : ℝ) / (1 + n₁))) := by + unfold c εx c_εx + have const1bnd : (A ^ ((1 : ℝ) / (1 + n₁)) / 4) < (A ^ ((1 : ℝ) / (1 + n₁)) / 2) := by + linarith + have this (x) : + C' * rexp (-(A ^ ((1 : ℝ) / (1 + n₁)) / 2) * Real.log x ^ ((1 : ℝ) / (1 + n₁))) * x * + Real.log x = + C' * x * (rexp (-(A ^ ((1 : ℝ) / (1 + n₁)) / 2) * Real.log x ^ ((1 : ℝ) / (1 + n₁))) * + Real.log x) := by ring + simp_rw [this] + filter_upwards [eventual_exp_log_rpow_mul_log_le_exp const1bnd one_div_succ_n₁_pos, + eventually_gt_atTop 3] with x x_bnd x_gt + grw [x_bnd] + have event_2 : ∀ᶠ (x : ℝ) in atTop, C'' * x * Real.log x / (εx x * Tx x) ≤ + C'' * x * rexp (-c * Real.log x ^ ((1 : ℝ) / (1 + n₁))) := by + unfold c εx c_εx Tx c_Tx + set const2 : ℝ := 1 / (1 + n₁) + have const2bnd : 0 < const2 := one_div_succ_n₁_pos + set const1 := (A ^ const2 / 2) + set const1' := (A ^ const2 / 4) + have this (x) : -(-const1 * Real.log x ^ const2 + A ^ const2 * Real.log x ^ const2) = + -(A ^ const2 - const1) * Real.log x ^ const2 := by ring + simp_rw [← Real.exp_add, div_eq_mul_inv, ← Real.exp_neg, this] + have const1bnd : const1' < (A ^ const2 - const1) := by + unfold const1' const1 + linarith + filter_upwards [eventual_exp_log_rpow_mul_log_le_exp const1bnd const2bnd, eventually_gt_atTop + 3] with x x_bnd x_gt + rw [mul_assoc] + conv => + enter [1, 2] + rw [mul_comm] + grw [x_bnd] + have event_3 : ∀ᶠ (x : ℝ) in atTop, C''' * x * x ^ (-A / Real.log (Tx x) ^ n₁) / (εx x) ≤ + C''' * x * rexp (-c * Real.log x ^ ((1 : ℝ) / (1 + n₁))) := by + unfold c Tx c_Tx εx c_εx + set const2 : ℝ := 1 / (1 + n₁) with const2eq + set const1 := (A ^ const2 / 2) with const1eq + set const1' := (A ^ const2 / 4) with const1'eq + conv => + enter [1, x, 1] + rw [div_eq_mul_inv, ← Real.exp_neg] + filter_upwards [balanced_rpow_exp_le n₁_pos A_in_Ioc const2eq const1eq const1'eq, + eventually_gt_atTop 3] with x x_bnd x_gt + have this (x) : C''' * x * x ^ (-A / Real.log (rexp (A ^ const2 * Real.log x ^ const2)) ^ n₁) + * rexp (-(-const1 * Real.log x ^ const2)) + = C''' * x * (x ^ (-A / Real.log (rexp (A ^ const2 * Real.log x ^ const2)) ^ (n₁ : ℝ)) + * rexp (-(-const1 * Real.log x ^ const2))) := by + ring + rw [this] + grw [x_bnd] + have event_4_aux : ∀ᶠ (x : ℝ) in atTop, + c₅ * rexp (σ₂ * Real.log x + (A ^ ((1 : ℝ) / (1 + n₁)) / 2) * Real.log x ^ ((1 : ℝ) / (1 + + n₁))) ≤ + c₅ * rexp (Real.log x - (A ^ ((1 : ℝ) / (1 + n₁)) / 4) * Real.log x ^ ((1 : ℝ) / (1 + n₁))) + := by + filter_upwards [eventually_gt_atTop 3, eventual_log_linear_domination σ₂InIoo.2 (A ^ ((1 : ℝ) + / (1 + n₁)) / 2) + (A ^ ((1 : ℝ) / (1 + n₁)) / 4) one_div_succ_n₁_lt_one] with x x_gt hx + rw [mul_le_mul_iff_right₀ c₅pos] + apply Real.exp_monotone + convert hx + have event_4 : ∀ᶠ (x : ℝ) in atTop, c₅ * x ^ σ₂ / (εx x) ≤ + c₅ * x * rexp (-c * Real.log x ^ ((1 : ℝ) / (1 + n₁))) := by + unfold εx c_εx c + filter_upwards [event_4_aux, eventually_gt_atTop 0] with x hx xpos + convert hx using 1 + · rw [← mul_div] + congr! 1 + rw [div_eq_mul_inv, ← Real.exp_neg] + conv => + enter [1, 1, 1] + rw [← Real.exp_log xpos] + rw [← exp_mul, ← Real.exp_add] + ring_nf + · rw [mul_assoc] + congr! 1 + conv => + enter [1, 1] + rw [← Real.exp_log xpos] + rw [← Real.exp_add] + ring_nf + filter_upwards [eventually_gt_atTop 3, eventually_εx_lt_one, eventually_2_lt, + eventually_T_gt_3, eventually_T_gt_Tlb₄, eventually_T_gt_Tlb₆, + eventually_σ₂_lt_σ₁, eventually_ε_lt_ε_main, event_logX_ge, event_1, event_2, + event_3, event_4] with X X_gt_3 ε_lt_one ε_X T_gt_3 T_gt_Tlb₄ T_gt_Tlb₆ + σ₂_lt_σ₁ ε_lt_ε_main logX_ge event_1 event_2 event_3 event_4 + clear eventually_εx_lt_one eventually_2_lt eventually_T_gt_3 eventually_T_gt_Tlb₄ + eventually_T_gt_Tlb₆ eventually_σ₂_lt_σ₁ eventually_ε_lt_ε_main event_logX_ge + exact pnt_from_contour_estimates n₁_pos ν ν_supp ContDiff1ν ν_nonneg ν_massOne + A A_in_Ioc holo1 σ₂ σ₂InIoo holo2 c_close h_close + ε_main C_main C_main_pos h_main c₁ hc₁ c₂ c₂pos hc₂ c₃ hc₃ + c₅ hc₅ c₇ hc₇ c₈ c₈pos hc₈ c₉ hc₉ + c₄ Tlb₄ hc₄ c₆ Tlb₆ hc₆ C' C'' C''' c C εx Tx + X X_gt_3 ε_lt_one ε_X T_gt_3 T_gt_Tlb₄ T_gt_Tlb₆ σ₂_lt_σ₁ ε_lt_ε_main logX_ge + event_1 event_2 event_3 event_4 rfl rfl rfl rfl (by positivity) + +/-- *** Prime Number Theorem (Medium Strength) *** The `ChebyshevPsi` function is asymptotic to +`x`. -/ +/- +We have + $$\sum_{n \leq x}\Lambda(n)=x+O(x \exp(-c(\log x)^{1/10})).$$ +This follows as a corollary of Theorems \ref{GenStrengthPNT} and \ref{LogDerivZetaBnd}. +-/ +theorem MediumPNT : ∃ c > 0, + (ψ - id) =O[atTop] + fun (x : ℝ) ↦ x * Real.exp (-c * (Real.log x) ^ ((1 : ℝ) / 10)) := by + have := GenStrengthPNT LogDerivZetaBoundedAndHolo99 (by linarith) (by linarith); ring_nf at this + simpa only [gt_iff_lt, one_div, neg_mul] using this + +end IwaniecLinearSievePNT diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MellinCalculus.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MellinCalculus.lean new file mode 100644 index 000000000..dc8698852 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MellinCalculus.lean @@ -0,0 +1,1470 @@ +/- +Copyright (c) 2026 PrimeNumberTheoremAnd contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: PrimeNumberTheoremAnd contributors +-/ + +module + +public import Mathlib.Analysis.MellinTransform +import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.Auxiliary + +/-! +Adapted from PrimeNumberTheoremAnd revision +`127b50e33f6033e2147921167a117af96d9ba4ea`, via Jason Davies's +Iwaniec linear sieve snapshot `c8d01549d2ae640b36ec198c1f0f6495f1b036cf` +(both Apache-2.0). Blueprint-only machinery is omitted. + +Supporting lemmas for Iwaniec's sieve and its prime-number-theorem input. +-/ + +@[expose] public section + +namespace IwaniecLinearSievePNT + +open MeasureTheory Function + + + +open scoped ContDiff + + +-- TODO: move near `MeasureTheory.setIntegral_prod` +theorem _root_.MeasureTheory.setIntegral_integral_swap {α : Type*} {β : Type*} {E : Type*} + [MeasurableSpace α] [MeasurableSpace β] {μ : MeasureTheory.Measure α} + {ν : MeasureTheory.Measure β} [NormedAddCommGroup E] + [MeasureTheory.SigmaFinite ν] [NormedSpace ℝ E] [MeasureTheory.SigmaFinite μ] + (f : α → β → E) {s : Set α} {t : Set β} + (hf : IntegrableOn (f.uncurry) (s ×ˢ t) (μ.prod ν)) : + (∫ (x : α) in s, ∫ (y : β) in t, f x y ∂ν ∂μ) + = ∫ (y : β) in t, ∫ (x : α) in s, f x y ∂μ ∂ν := by + apply integral_integral_swap + convert hf.integrable + exact Measure.prod_restrict s t + +-- How to deal with this coercion?... Ans: (f ·) +--- noncomputable def funCoe (f : ℝ → ℝ) : ℝ → ℂ := fun x ↦ f x + +open Complex Topology Filter Real MeasureTheory Set + +variable {𝕂 : Type*} [RCLike 𝕂] + +lemma _root_.MeasureTheory.integral_comp_mul_right_I0i_haar + (f : ℝ → 𝕂) {a : ℝ} (ha : 0 < a) : + ∫ (y : ℝ) in Ioi 0, f (y * a) / y = ∫ (y : ℝ) in Ioi 0, f y / y := by + have := integral_comp_mul_right_Ioi (fun y ↦ f y / y) 0 ha + simp only [RCLike.ofReal_mul, zero_mul, eq_inv_smul_iff₀ (ne_of_gt ha)] at this + rw [← integral_smul] at this + rw [← this, setIntegral_congr_fun (by simp)] + intro _ _ + simp only [RCLike.real_smul_eq_coe_mul] + rw [mul_comm (a : 𝕂), div_mul, mul_div_assoc, div_self ?_, mul_one] + exact (RCLike.ofReal_ne_zero).mpr <| ne_of_gt ha + +lemma _root_.MeasureTheory.integral_comp_mul_right_I0i_haar_real + (f : ℝ → ℝ) {a : ℝ} (ha : 0 < a) : + ∫ (y : ℝ) in Ioi 0, f (y * a) / y = ∫ (y : ℝ) in Ioi 0, f y / y := + MeasureTheory.integral_comp_mul_right_I0i_haar f ha + +lemma _root_.MeasureTheory.integral_comp_mul_left_I0i_haar + (f : ℝ → 𝕂) {a : ℝ} (ha : 0 < a) : + ∫ (y : ℝ) in Ioi 0, f (a * y) / y = ∫ (y : ℝ) in Ioi 0, f y / y := by + convert integral_comp_mul_right_I0i_haar f ha using 5; ring + +-- TODO: generalize to `RCLike` +lemma _root_.MeasureTheory.integral_comp_rpow_I0i_haar_real (f : ℝ → ℝ) {p : ℝ} (hp : p ≠ 0) : + ∫ (y : ℝ) in Ioi 0, |p| * f (y ^ p) / y = ∫ (y : ℝ) in Ioi 0, f y / y := by + rw [← integral_comp_rpow_Ioi (fun y ↦ f y / y) hp, setIntegral_congr_fun (by simp)] + intro y hy + have ypos : 0 < y := mem_Ioi.mp hy + simp only [rpow_sub_one ypos.ne', smul_eq_mul] + field_simp + +lemma _root_.MeasureTheory.integral_comp_inv_I0i_haar (f : ℝ → 𝕂) : + ∫ (y : ℝ) in Ioi 0, f (1 / y) / y = ∫ (y : ℝ) in Ioi 0, f y / y := by + have := integral_comp_rpow_Ioi (fun y ↦ f y / y) (p := -1) (by simp) + rw [← this, setIntegral_congr_fun (by simp)] + intro y hy + have : (y : 𝕂) ≠ 0 := (RCLike.ofReal_ne_zero).mpr <| LT.lt.ne' hy + simp only [abs_neg, abs_one, rpow_neg_one, map_inv₀, div_inv_eq_mul, + RCLike.real_smul_eq_coe_mul, RCLike.algebraMap_eq_ofReal] + ring_nf + simp [field] + +lemma _root_.MeasureTheory.integral_comp_div_I0i_haar + (f : ℝ → 𝕂) {a : ℝ} (ha : 0 < a) : + ∫ (y : ℝ) in Ioi 0, f (a / y) / y = ∫ (y : ℝ) in Ioi 0, f y / y := by + calc + _ = ∫ (y : ℝ) in Ioi 0, f (a * y) / y := ?_ + _ = _ := integral_comp_mul_left_I0i_haar f ha + convert (integral_comp_inv_I0i_haar fun y ↦ f (a * (1 / y))).symm using 4 + · rw [mul_one_div] + · rw [one_div_one_div] + +theorem _root_.Complex.ofReal_rpow {x : ℝ} (h : x > 0) (y : ℝ) : + (((x : ℝ) ^ (y : ℝ)) : ℝ) = (x : ℂ) ^ (y : ℂ) := by + rw [rpow_def_of_pos h, ofReal_exp, ofReal_mul, Complex.ofReal_log h.le, + Complex.cpow_def_of_ne_zero] + simp only [ne_eq, ofReal_eq_zero, ne_of_gt h, not_false_eq_true] + +@[simp] +lemma _root_.Function.support_abs {α : Type*} (f : α → 𝕂) : + (fun x ↦ ‖f x‖).support = f.support := by + simp only [support, ne_eq]; simp_rw [norm_ne_zero_iff] + +@[simp] +lemma _root_.Function.support_ofReal {f : ℝ → ℝ} : + (fun x ↦ ((f x) : ℂ)).support = f.support := by + apply Function.support_comp_eq (g := ofReal); simp + +lemma _root_.Function.support_mul_subset_of_subset {s : Set ℝ} {f g : ℝ → 𝕂} + (fSupp : f.support ⊆ s) : (f * g).support ⊆ s := by + simp_rw [support_mul', inter_subset, subset_union_of_subset_right fSupp] + +lemma _root_.Function.support_of_along_fiber_subset_subset {α β M : Type*} [Zero M] + {f : α × β → M} {s : Set α} {t : Set β} + (hx : ∀ (y : β), (fun x ↦ f (x, y)).support ⊆ s) + (hy : ∀ (x : α), (fun y ↦ f (x, y)).support ⊆ t) : + f.support ⊆ s ×ˢ t := by + intro ⟨x, y⟩ hxy + constructor + · exact hx y (by simp only [Function.mem_support, ne_eq] at hxy ⊢; exact hxy) + · exact hy x (by simp only [Function.mem_support, ne_eq] at hxy ⊢; exact hxy) + +lemma _root_.Function.support_deriv_subset_Icc {a b : ℝ} {f : ℝ → 𝕂} + (fSupp : f.support ⊆ Set.Icc a b) : + (deriv f).support ⊆ Set.Icc a b := by + have := support_deriv_subset (f := fun x ↦ f x) + dsimp [tsupport] at this + have := subset_trans this <| closure_mono fSupp + rwa [closure_Icc] at this + +lemma IntervalIntegral.integral_eq_integral_of_support_subset_Icc {a b : ℝ} {μ : Measure ℝ} + [NullSingletonClass μ] {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] + {f : ℝ → E} (h : f.support ⊆ Icc a b) : + ∫ x in a..b, f x ∂μ = ∫ x, f x ∂μ := by + rcases le_total a b with hab | hab + · rw [intervalIntegral.integral_of_le hab, ← integral_Icc_eq_integral_Ioc, + ← integral_indicator measurableSet_Icc, indicator_eq_self.2 h] + · by_cases hab2 : b = a + · rw [hab2] at h ⊢ + simp only [intervalIntegral.integral_same] + simp only [Icc_self] at h + have : ∫ (x : ℝ), f x ∂μ = ∫ (x : ℝ) in {a}, f x ∂μ := by + rw [ ← integral_indicator (by simp), indicator_eq_self.2 h] + rw [this, integral_singleton]; simp [Measure.real] + · rw [Icc_eq_empty_iff.mpr <| by exact fun x ↦ hab2 <| le_antisymm hab x, subset_empty_iff, + Function.support_eq_empty_iff] at h; simp [h] + +lemma SetIntegral.integral_eq_integral_inter_of_support_subset {μ : Measure ℝ} + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {s t : Set ℝ} {f : ℝ → E} (h : f.support ⊆ t) (ht : MeasurableSet t) : + ∫ x in s, f x ∂μ = ∫ x in s ∩ t, f x ∂μ := by + rw [← setIntegral_indicator ht, indicator_eq_self.2 h] + +lemma SetIntegral.integral_eq_integral_inter_of_support_subset_Icc {a b} {μ : Measure ℝ} + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {s : Set ℝ} {f : ℝ → E} (h : f.support ⊆ Icc a b) (hs : Icc a b ⊆ s) : + ∫ x in s, f x ∂μ = ∫ x in Icc a b, f x ∂μ := by + rw [SetIntegral.integral_eq_integral_inter_of_support_subset h measurableSet_Icc, + inter_eq_self_of_subset_right hs] + +lemma _root_.intervalIntegral.norm_integral_le_of_norm_le_const' {a b C : ℝ} + {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + {f : ℝ → E} (hab : a ≤ b) (h : ∀ x ∈ (Icc a b), ‖f x‖ ≤ C) : + ‖∫ x in a..b, f x‖ ≤ C * |b - a| := by + apply intervalIntegral.norm_integral_le_of_norm_le_const + exact fun x hx ↦ h x <| mem_Icc_of_Ioc <| uIoc_of_le hab ▸ hx + +lemma _root_.Filter.TendstoAtZero_of_support_in_Icc {a b : ℝ} (f : ℝ → 𝕂) (ha : 0 < a) + (fSupp : f.support ⊆ Set.Icc a b) : + Tendsto f (𝓝[>]0) (𝓝 0) := by + apply Tendsto.comp (tendsto_nhds_of_eventually_eq ?_) tendsto_id + filter_upwards [Ioo_mem_nhdsGT ha] with c hc; replace hc := (mem_Ioo.mp hc).2 + have h : c ∉ Icc a b := fun h ↦ by linarith [mem_Icc.mp h] + convert mt (Function.support_subset_iff.mp fSupp c) h; simp + +lemma _root_.Filter.TendstoAtTop_of_support_in_Icc {a b : ℝ} (f : ℝ → 𝕂) + (fSupp : f.support ⊆ Set.Icc a b) : + Tendsto f atTop (𝓝 0) := by + apply Tendsto.comp (tendsto_nhds_of_eventually_eq ?_) tendsto_id + filter_upwards [Ioi_mem_atTop b] with c hc; rw [mem_Ioi] at hc + have h : c ∉ Icc a b := fun h ↦ by linarith [mem_Icc.mp h] + convert mt (Function.support_subset_iff.mp fSupp c) h; simp + +lemma _root_.Filter.BigO_zero_atZero_of_support_in_Icc {a b : ℝ} (f : ℝ → 𝕂) (ha : 0 < a) + (fSupp : f.support ⊆ Set.Icc a b) : + f =O[𝓝[>] 0] fun _ ↦ (0 : ℝ) := by + refine Eventually.isBigO ?_ + filter_upwards [Ioo_mem_nhdsGT (by linarith : (0 : ℝ) < a)] with c hc + refine norm_le_zero_iff.mpr <| Function.support_subset_iff'.mp fSupp c ?_ + exact fun h ↦ by linarith [mem_Icc.mp h, (mem_Ioo.mp hc).2] + +lemma _root_.Filter.BigO_zero_atTop_of_support_in_Icc {a b : ℝ} (f : ℝ → 𝕂) + (fSupp : f.support ⊆ Set.Icc a b) : + f =O[atTop] fun _ ↦ (0 : ℝ) := by + refine Eventually.isBigO ?_ + filter_upwards [Ioi_mem_atTop b] with c hc; replace hc := mem_Ioi.mp hc + refine norm_le_zero_iff.mpr <| Function.support_subset_iff'.mp fSupp c ?_ + exact fun h ↦ by linarith [mem_Icc.mp h] + +lemma _root_.deriv.ofReal_comp' {f : ℝ → ℝ} : + deriv (fun x : ℝ ↦ (f x : ℂ)) = (fun x ↦ ((deriv f) x : ℂ)) := + funext fun _ ↦ deriv.ofReal_comp + +lemma _root_.deriv.comp_ofReal' {e : ℂ → ℂ} (hf : Differentiable ℂ e) : + deriv (fun x : ℝ ↦ e x) = fun (x : ℝ) ↦ deriv e x := + funext fun _ ↦ deriv.comp_ofReal (hf.differentiableAt) + + +/-- *Need differentiability, and decay at `0` and `∞`* -/ +/- +Let $f, g$ be once differentiable functions from $\mathbb{R}_{>0}$ to $\mathbb{C}$ so that $fg'$ + and $f'g$ are both integrable, and $f\cdot g (x)\to 0$ as $x\to 0^+,\infty$. + Then + $$ + \int_0^\infty f(x)g'(x) dx = -\int_0^\infty f'(x)g(x)dx. + $$ +Partial integration. +-/ +lemma PartialIntegration (f g : ℝ → ℂ) + (fDiff : DifferentiableOn ℝ f (Ioi 0)) + (gDiff : DifferentiableOn ℝ g (Ioi 0)) + (fDerivgInt : IntegrableOn (f * deriv g) (Ioi 0)) + (gDerivfInt : IntegrableOn (deriv f * g) (Ioi 0)) + (lim_at_zero : Tendsto (f * g) (𝓝[>] 0) (𝓝 0)) + (lim_at_inf : Tendsto (f * g) atTop (𝓝 0)) : + ∫ x in Ioi 0, f x * deriv g x = -∫ x in Ioi 0, deriv f x * g x := by + simpa using integral_Ioi_mul_deriv_eq_deriv_mul + (fun x hx ↦ fDiff.hasDerivAt (Ioi_mem_nhds hx)) + (fun x hx ↦ gDiff.hasDerivAt (Ioi_mem_nhds hx)) + fDerivgInt gDerivfInt lim_at_zero lim_at_inf + + +lemma PartialIntegration_of_support_in_Icc {a b : ℝ} (f g : ℝ → ℂ) (ha : 0 < a) + (h : a ≤ b) + (fSupp : f.support ⊆ Set.Icc a b) + (fDiff : DifferentiableOn ℝ f (Ioi 0)) + (gDiff : DifferentiableOn ℝ g (Ioi 0)) + (fderivCont : ContinuousOn (deriv f) (Ioi 0)) + (gderivCont : ContinuousOn (deriv g) (Ioi 0)) : + ∫ x in Ioi 0, f x * deriv g x = -∫ x in Ioi 0, deriv f x * g x := by + have Icc_sub : Icc a b ⊆ Ioi 0 := (Icc_subset_Ioi_iff h).mpr ha + have fderivSupp := Function.support_deriv_subset_Icc fSupp + have fgSupp : (f * g).support ⊆ Icc a b := Function.support_mul_subset_of_subset fSupp + have fDerivgInt : IntegrableOn (f * deriv g) (Ioi 0) := by + apply (integrableOn_iff_integrable_of_support_subset <| + Function.support_mul_subset_of_subset fSupp).mp + exact fDiff.continuousOn.mono Icc_sub |>.mul (gderivCont.mono Icc_sub) |>.integrableOn_Icc + have gDerivfInt : IntegrableOn (deriv f * g) (Ioi 0) := by + apply (integrableOn_iff_integrable_of_support_subset <| + Function.support_mul_subset_of_subset fderivSupp).mp + exact fderivCont.mono Icc_sub |>.mul (gDiff.continuousOn.mono Icc_sub) |>.integrableOn_Icc + have lim_at_zero : Tendsto (f * g) (𝓝[>]0) (𝓝 0) := + TendstoAtZero_of_support_in_Icc (f * g) ha fgSupp + have lim_at_inf : Tendsto (f * g) atTop (𝓝 0) := TendstoAtTop_of_support_in_Icc (f * g) fgSupp + apply PartialIntegration f g fDiff gDiff fDerivgInt gDerivfInt lim_at_zero lim_at_inf + +/- +In this section, we define the Mellin transform (already in Mathlib, thanks to David Loeffler), +prove its inversion formula, and +derive a number of important properties of some special functions and bumpfunctions. + +Def: (Already in Mathlib) +Let $f$ be a function from $\mathbb{R}_{>0}$ to $\mathbb{C}$. We define the Mellin transform of +$f$ to be the function $\mathcal{M}(f)$ from $\mathbb{C}$ to $\mathbb{C}$ defined by +$$\mathcal{M}(f)(s) = \int_0^\infty f(x)x^{s-1}dx.$$ + +[Note: My preferred way to think about this is that we are integrating over the multiplicative +group $\mathbb{R}_{>0}$, multiplying by a (not necessarily unitary!) character $|\cdot|^s$, and +integrating with respect to the invariant Haar measure $dx/x$. This is very useful in the kinds +of calculations carried out below. But may be more difficult to formalize as things now stand. So +we might have clunkier calculations, which ``magically'' turn out just right - of course they're +explained by the aforementioned structure...] + +-/ + + +local notation (name := mellintransform) "𝓜" => mellin + + +/- +Finally, we need Mellin Convolutions and properties thereof. +-/ +/- +Let $f$ and $g$ be functions from $\mathbb{R}_{>0}$ to $\mathbb{C}$. Then we define the + Mellin convolution of $f$ and $g$ to be the function $f\ast g$ from $\mathbb{R}_{>0}$ + to $\mathbb{C}$ defined by + $$(f\ast g)(x) = \int_0^\infty f(y)g(x/y)\frac{dy}{y}.$$ +-/ +/-- Multiplicative convolution with respect to the measure `dy / y` on the positive reals. -/ +noncomputable def MellinConvolution (f g : ℝ → 𝕂) (x : ℝ) : 𝕂 := + ∫ y in Ioi 0, f y * g (x / y) / y + +/- +Let us start with a simple property of the Mellin convolution. +-/ +/- +Let $f$ and $g$ be functions from $\mathbb{R}_{>0}$ to $\mathbb{R}$ or $\mathbb{C}$, for $x\neq0$, + $$ + (f\ast g)(x)=(g\ast f)(x) + . + $$ +By Definition \ref{MellinConvolution}, + $$ + (f\ast g)(x) = \int_0^\infty f(y)g(x/y)\frac{dy}{y} + $$ + in which we change variables to $z=x/y$: + $$ + (f\ast g)(x) = \int_0^\infty f(x/z)g(z)\frac{dz}{z} + =(g\ast f)(x) + . + $$ +-/ +lemma MellinConvolutionSymmetric (f g : ℝ → 𝕂) {x : ℝ} (xpos : 0 < x) : + MellinConvolution f g x = MellinConvolution g f x := by + unfold MellinConvolution + calc + _ = ∫ y in Ioi 0, f (y * x) * g (1 / y) / y := ?_ + _ = _ := ?_ + · rw [← integral_comp_mul_right_I0i_haar (fun y ↦ f y * g (x / y)) xpos] + simp [div_mul_cancel_right₀ <| ne_of_gt xpos] + · convert (integral_comp_inv_I0i_haar fun y ↦ f (y * x) * g (1 / y)).symm using 3 + rw [one_div_one_div, mul_comm, mul_comm_div, one_mul] + +open Pointwise in +lemma support_MellinConvolution_subsets {f g : ℝ → 𝕂} {A B : Set ℝ} (hf : f.support ⊆ A) + (hg : g.support ⊆ B) : (MellinConvolution f g).support ⊆ A * B := by + rw [Function.support_subset_iff'] at hf hg ⊢ + intro x hx + unfold MellinConvolution + simp only [Set.mem_mul, not_exists, not_and] at hx + apply MeasureTheory.integral_eq_zero_of_ae + filter_upwards [ae_restrict_mem (by measurability)] + intro y hy + simp only [mem_Ioi] at hy + simp only [Pi.zero_apply, div_eq_zero_iff, mul_eq_zero, map_eq_zero] + left + by_cases hyA : y ∈ A + · right + apply hg + intro hxyB + apply hx _ hyA _ hxyB + field_simp + · left + apply hf _ hyA + +open Pointwise in +lemma support_MellinConvolution (f g : ℝ → 𝕂) : + (MellinConvolution f g).support ⊆ f.support * g.support := + support_MellinConvolution_subsets subset_rfl subset_rfl + +/- +The Mellin transform of a convolution is the product of the Mellin transforms. +-/ +/- +Let $f$ and $g$ be functions from $\mathbb{R}_{>0}$ to $\mathbb{C}$ such that + \begin{equation} + (x,y)\mapsto f(y)\frac{g(x/y)}yx^{s-1} + \label{eq:assm_integrable_Mconv} + \end{equation} + is absolutely integrable on $[0,\infty)^2$. + Then + $$\mathcal{M}(f\ast g)(s) = \mathcal{M}(f)(s)\mathcal{M}(g)(s).$$ +By Definitions \ref{MellinTransform} and \ref{MellinConvolution} + $$ + \mathcal M(f\ast g)(s)= + \int_0^\infty \int_0^\infty f(y)g(x/y)x^{s-1}\frac{dy}ydx + $$ + By (\ref{eq:assm_integrable_Mconv}) and Fubini's theorem, + $$ + \mathcal M(f\ast g)(s)= + \int_0^\infty \int_0^\infty f(y)g(x/y)x^{s-1}dx\frac{dy}y + $$ + in which we change variables from $x$ to $z=x/y$: + $$ + \mathcal M(f\ast g)(s)= + \int_0^\infty \int_0^\infty f(y)g(z)y^{s-1}z^{s-1}dzdy + $$ + which, by Definition \ref{MellinTransform}, is + $$ + \mathcal M(f\ast g)(s)= + \mathcal M(f)(s)\mathcal M(g)(s) + . + $$ +-/ +lemma MellinConvolutionTransform (f g : ℝ → ℂ) (s : ℂ) + (hf : IntegrableOn (fun x y ↦ f y * g (x / y) / (y : ℂ) * (x : ℂ) ^ (s - 1)).uncurry + (Ioi 0 ×ˢ Ioi 0)) : + 𝓜 (MellinConvolution f g) s = 𝓜 f s * 𝓜 g s := by + dsimp [mellin, MellinConvolution] + set f₁ : ℝ × ℝ → ℂ := + fun ⟨x, y⟩ ↦ f y * g (x / y) / (y : ℂ) * (x : ℂ) ^ (s - 1) + calc + _ = ∫ (x : ℝ) in Ioi 0, ∫ (y : ℝ) in Ioi 0, f₁ (x, y) := ?_ + _ = ∫ (y : ℝ) in Ioi 0, ∫ (x : ℝ) in Ioi 0, f₁ (x, y) := + setIntegral_integral_swap _ hf + _ = ∫ (y : ℝ) in Ioi 0, ∫ (x : ℝ) in Ioi 0, + f y * g (x / y) / ↑y * ↑x ^ (s - 1) := rfl + _ = ∫ (y : ℝ) in Ioi 0, ∫ (x : ℝ) in Ioi 0, + f y * g (x * y / y) / ↑y * ↑(x * y) ^ (s - 1) * y := ?_ + _ = ∫ (y : ℝ) in Ioi 0, ∫ (x : ℝ) in Ioi 0, + f y * ↑y ^ (s - 1) * (g x * ↑x ^ (s - 1)) := ?_ + _ = ∫ (y : ℝ) in Ioi 0, + f y * ↑y ^ (s - 1) * ∫ (x : ℝ) in Ioi 0, g x * ↑x ^ (s - 1) := ?_ + _ = _ := integral_mul_const _ _ + <;> try (rw [setIntegral_congr_fun (by simp)]; intro y hy; simp only [ofReal_mul]) + · simp only [integral_mul_const, f₁, mul_comm] + · simp only [integral_mul_const] + have := integral_comp_mul_right_Ioi + (fun x ↦ f y * g (x / y) / (y : ℂ) * (x : ℂ) ^ (s - 1)) 0 hy + have y_ne_zeroℂ : (y : ℂ) ≠ 0 := slitPlane_ne_zero (Or.inl hy) + field_simp at this ⊢ + simp only [ofReal_mul, one_div, mul_zero, real_smul, ofReal_inv, field] at this ⊢ + rw [← this] + field_simp + congr with x + ring_nf + · rw [setIntegral_congr_fun (by simp)] + intro x hx + have y_ne_zeroℝ : y ≠ 0 := ne_of_gt (mem_Ioi.mp hy) + have y_ne_zeroℂ : (y : ℂ) ≠ 0 := by exact_mod_cast y_ne_zeroℝ + field_simp + rw [mul_cpow_ofReal_nonneg hy.le hx.le] + ring + · apply integral_const_mul + · congr <;> ext <;> ring + + + +lemma mem_within_strip (σ₁ σ₂ : ℝ) : + {s : ℂ | σ₁ ≤ s.re ∧ s.re ≤ σ₂} ∈ + 𝓟 {s | σ₁ ≤ s.re ∧ s.re ≤ σ₂} := + mem_principal_self _ + +lemma MellinOfPsi_aux {ν : ℝ → ℝ} (diffν : ContDiff ℝ 1 ν) + (suppν : ν.support ⊆ Set.Icc (1 / 2) 2) + {s : ℂ} (hs : s ≠ 0) : + ∫ (x : ℝ) in Ioi 0, (ν x) * (x : ℂ) ^ (s - 1) = + - (1 / s) * ∫ (x : ℝ) in Ioi 0, (deriv ν x) * (x : ℂ) ^ s := by + let g (s : ℂ) := fun (x : ℝ) ↦ x ^ s / s + have gderiv {s : ℂ} (hs : s ≠ 0) {x: ℝ} (hx : x ∈ Ioi 0) : + deriv (g s) x = x ^ (s - 1) := by + have := HasDerivAt.cpow_const (c := s) (hasDerivAt_id (x : ℂ)) (Or.inl hx) + simp_rw [mul_one, id_eq] at this + rw [deriv_div_const, deriv.comp_ofReal (e := fun x ↦ x ^ s)] + · rw [this.deriv, mul_div_right_comm, div_self hs, one_mul] + · apply hasDerivAt_deriv_iff.mp + simp only [this.deriv, this] + calc + _ = ∫ (x : ℝ) in Ioi 0, ↑(ν x) * deriv (@g s) x := ?_ + _ = -∫ (x : ℝ) in Ioi 0, deriv (fun x ↦ ↑(ν x)) x * @g s x := ?_ + _ = -∫ (x : ℝ) in Ioi 0, deriv ν x * @g s x := ?_ + _ = -∫ (x : ℝ) in Ioi 0, deriv ν x * x ^ s / s := by simp only [mul_div, g] + _ = _ := ?_ + · rw [setIntegral_congr_fun (by simp)] + intro _ hx + simp only [gderiv hs hx] + · apply PartialIntegration_of_support_in_Icc (ν ·) (g s) + (a := 1 / 2) (b := 2) (by norm_num) (by norm_num) + · simpa only [Function.support_subset_iff, ne_eq, ofReal_eq_zero] + · exact (Differentiable.ofReal_comp_iff.mpr + (diffν.differentiable (by norm_num))).differentiableOn + · refine DifferentiableOn.div_const ?_ s + intro a ha + refine DifferentiableAt.comp_ofReal (e := fun x ↦ x ^ s) ?_ |>.differentiableWithinAt + apply differentiableAt_fun_id.cpow (differentiableAt_const s) <| by exact Or.inl ha + · simp only [deriv.ofReal_comp'] + exact continuous_ofReal.comp (diffν.continuous_deriv (by norm_num)) |>.continuousOn + · apply ContinuousOn.congr (f := fun (x : ℝ) ↦ (x : ℂ) ^ (s - 1)) ?_ + fun x hx ↦ gderiv hs hx + exact Continuous.continuousOn (by continuity) |>.cpow continuousOn_const (by simp) + · congr; funext; congr + apply (hasDerivAt_deriv_iff.mpr ?_).ofReal_comp.deriv + exact diffν.contDiffAt.differentiableAt (by norm_num) + · simp only [neg_mul, neg_inj] + conv => lhs; rhs; intro; rw [← mul_one_div, mul_comm] + rw [integral_const_mul] + +/- +The $\nu$ function has Mellin transform $\mathcal{M}(\nu)(s)$ which is entire and decays (at +least) like $1/|s|$. + +[Of course it decays faster than any power of $|s|$, but it turns out that we will just need one +power.] +-/ + +-- filter-free version: +/- +The Mellin transform of $\nu$ is + $$\mathcal{M}(\nu)(s) = O\left(\frac{1}{|s|}\right),$$ + as $|s|\to\infty$ with $\sigma_1 \le \Re(s) \le 2$. +Integrate by parts: + $$ + \left|\int_0^\infty \nu(x)x^s\frac{dx}{x}\right| = + \left|-\int_0^\infty \nu'(x)\frac{x^{s}}{s}dx\right| + $$ + $$ + \le \frac{1}{|s|} \int_{1/2}^2|\nu'(x)|x^{\Re(s)}dx. + $$ + Since $\Re(s)$ is bounded, the right-hand side is bounded by a + constant times $1/|s|$. +-/ +lemma MellinOfPsi {ν : ℝ → ℝ} (diffν : ContDiff ℝ 1 ν) + (suppν : ν.support ⊆ Set.Icc (1 / 2) 2) : + ∃ C > 0, ∀ (σ₁ : ℝ) (_ : 0 < σ₁) (s : ℂ) (_ : σ₁ ≤ s.re) (_ : s.re ≤ 2), + ‖𝓜 (fun x ↦ (ν x : ℂ)) s‖ ≤ C * ‖s‖⁻¹ := by + let f := fun (x : ℝ) ↦ ‖deriv ν x‖ + have cont : ContinuousOn f (Icc (1 / 2) 2) := + (Continuous.comp (by continuity) <| diffν.continuous_deriv (by norm_num)).continuousOn + obtain ⟨a, _, max⟩ := isCompact_Icc.exists_isMaxOn (f := f) (by norm_num) cont + let σ₂ : ℝ := 2 + let C : ℝ := f a * 2 ^ σ₂ * (3 / 2) + have mainBnd : ∀ (σ₁ : ℝ), 0 < σ₁ → ∀ (s : ℂ), σ₁ ≤ s.re → s.re ≤ 2 → + ‖𝓜 (fun x ↦ (ν x : ℂ)) s‖ ≤ C * ‖s‖⁻¹ := by + intro σ₁ σ₁pos s hs₁ hs₂ + have s_ne_zero: s ≠ 0 := fun h ↦ by linarith [zero_re ▸ h ▸ hs₁] + simp only [mellin, f, MellinOfPsi_aux diffν suppν s_ne_zero, norm_mul, smul_eq_mul, mul_comm] + gcongr + · simp + calc + _ ≤ ∫ (x : ℝ) in Ioi 0, ‖(deriv ν x * (x : ℂ) ^ s)‖ := ?_ + _ = ∫ (x : ℝ) in Icc (1 / 2) 2, ‖(deriv ν x * (x : ℂ) ^ s)‖ := ?_ + _ ≤ ‖∫ (x : ℝ) in Icc (1 / 2) 2, ‖(deriv ν x * (x : ℂ) ^ s)‖‖ := + le_abs_self _ + _ ≤ _ := ?_ + · simp_rw [norm_integral_le_integral_norm] + · apply SetIntegral.integral_eq_integral_inter_of_support_subset_Icc + · simp only [Function.support_abs, Function.support_mul, Function.support_ofReal] + apply subset_trans (by apply inter_subset_left) <| Function.support_deriv_subset_Icc suppν + · exact (Icc_subset_Ioi_iff (by norm_num)).mpr (by norm_num) + · have := intervalIntegral.norm_integral_le_of_norm_le_const' (C := f a * 2 ^ σ₂) + (f := fun x ↦ f x * ‖(x : ℂ) ^ s‖) (a := (1 / 2 : ℝ)) ( b := 2) (by norm_num) ?_ + · simp only [Real.norm_eq_abs, norm_real, norm_mul] at this ⊢ + rwa [(by norm_num: |(2 : ℝ) - 1 / 2| = 3 / 2), + intervalIntegral.integral_of_le (by norm_num), ← integral_Icc_eq_integral_Ioc] at this + · intro x hx; + have f_bound := isMaxOn_iff.mp max x hx + have pow_bound : ‖(x : ℂ) ^ s‖ ≤ 2 ^ σ₂ := by + rw [norm_cpow_eq_rpow_re_of_pos (by linarith [mem_Icc.mp hx])] + have xpos : 0 ≤ x := by linarith [(mem_Icc.mp hx).1] + have h := rpow_le_rpow xpos (mem_Icc.mp hx).2 (by linarith : 0 ≤ s.re) + exact le_trans h <| rpow_le_rpow_of_exponent_le (by norm_num) hs₂ + convert! mul_le_mul f_bound pow_bound (norm_nonneg _) ?_ using 1 <;> simp [f] + have Cnonneg : 0 ≤ C := by + have hh := mainBnd 1 (by norm_num) ((3 : ℂ) / 2) (by norm_num) (by norm_num) + have hhh : 0 ≤ ‖𝓜 (fun x ↦ (ν x : ℂ)) ((3 : ℂ) / 2)‖ := by positivity + have hhhh : 0 < ‖(3 : ℂ) / 2‖⁻¹ := by norm_num + have := hhh.trans hh + exact (mul_nonneg_iff_of_pos_right hhhh).mp this + by_cases CeqZero : C = 0 + · refine ⟨1, by linarith, ?_⟩ + intro ε εpos s hs₁ hs₂ + have := mainBnd ε εpos s hs₁ hs₂ + rw [CeqZero, zero_mul] at this + have : 0 ≤ 1 * ‖s‖⁻¹ := by positivity + linarith + · exact ⟨C, lt_of_le_of_ne Cnonneg fun a ↦ CeqZero (id (Eq.symm a)), mainBnd⟩ + + + +/- +We can make a delta spike out of this bumpfunction, as follows. +-/ + +/- +Let $\nu$ be a bumpfunction supported in $[1/2,2]$. Then for any $\epsilon>0$, we define the + delta spike $\nu_\epsilon$ to be the function from $\mathbb{R}_{>0}$ to $\mathbb{C}$ defined by + $$\nu_\epsilon(x) = \frac{1}{\epsilon}\nu\left(x^{\frac{1}{\epsilon}}\right).$$ +-/ +/-- A rescaled smoothing kernel concentrated near the multiplicative identity. -/ +noncomputable def DeltaSpike (ν : ℝ → ℝ) (ε : ℝ) : ℝ → ℝ := + fun x ↦ ν (x ^ (1 / ε)) / ε + +/- +This spike still has mass one: +-/ + +/- +For any $\epsilon>0$, we have + $$\int_0^\infty \nu_\epsilon(x)\frac{dx}{x} = 1.$$ +Substitute $y=x^{1/\epsilon}$, and use the fact that $\nu$ has mass one, and that $dx/x$ is Haar + measure. +-/ +lemma DeltaSpikeMass {ν : ℝ → ℝ} (mass_one : ∫ x in Ioi 0, ν x / x = 1) {ε : ℝ} + (εpos : 0 < ε) : ∫ x in Ioi 0, ((DeltaSpike ν ε) x) / x = 1 := + calc + _ = ∫ (x : ℝ) in Ioi 0, (|1/ε| * x ^ (1 / ε - 1)) • + ((fun z ↦ (ν z) / z) (x ^ (1 / ε))) := by + apply setIntegral_congr_ae measurableSet_Ioi + filter_upwards with x hx + simp only [smul_eq_mul, abs_of_pos (one_div_pos.mpr εpos)] + symm; calc + _ = (ν (x ^ (1 / ε)) / x ^ (1 / ε)) * x ^ (1 / ε - 1) * (1 / ε) := by ring + _ = _ := by rw [rpow_sub hx, rpow_one] + _ = (ν (x ^ (1 / ε)) / x ^ (1 / ε) * x ^ (1 / ε) / x) * (1/ ε) := by ring + _ = _ := by rw [div_mul_cancel₀ _ (ne_of_gt (rpow_pos_of_pos hx (1/ε)))] + _ = (ν (x ^ (1 / ε)) / ε / x) := by ring + _ = 1 := by + rw [integral_comp_rpow_Ioi (fun z ↦ (ν z) / z), ← mass_one] + simp only [ne_eq, div_eq_zero_iff, one_ne_zero, εpos.ne', or_self, not_false_eq_true] + + + +lemma DeltaSpikeSupport_aux {ν : ℝ → ℝ} {ε : ℝ} (εpos : 0 < ε) + (suppν : ν.support ⊆ Icc (1 / 2) 2) : + (fun x ↦ if x < 0 then 0 else DeltaSpike ν ε x).support ⊆ Icc (2 ^ (-ε)) (2 ^ ε) := by + unfold DeltaSpike + simp only [one_div, Function.support_subset_iff, ne_eq, ite_eq_left_iff, not_lt, div_eq_zero_iff, + not_forall, exists_prop, mem_Icc, and_imp] + intro x hx h; push Not at h + have := suppν <| Function.mem_support.mpr h.1 + simp only [one_div, mem_Icc] at this + have hl := (le_rpow_inv_iff_of_pos (by norm_num) hx εpos).mp this.1 + rw [inv_rpow (by norm_num) ε, ← rpow_neg (by norm_num)] at hl + refine ⟨hl, (rpow_inv_le_iff_of_pos ?_ (by norm_num) εpos).mp this.2⟩ + linarith [(by apply rpow_nonneg (by norm_num) : 0 ≤ (2 : ℝ) ^ (-ε))] + +lemma DeltaSpikeSupport' {ν : ℝ → ℝ} {ε x : ℝ} (εpos : 0 < ε) (xnonneg : 0 ≤ x) + (suppν : ν.support ⊆ Icc (1 / 2) 2) : + DeltaSpike ν ε x ≠ 0 → x ∈ Icc (2 ^ (-ε)) (2 ^ ε) := by + intro h + have : (fun x ↦ if x < 0 then 0 else DeltaSpike ν ε x) x = DeltaSpike ν ε x := by + simp [xnonneg] + rw [← this] at h + exact (Function.support_subset_iff.mp <| DeltaSpikeSupport_aux εpos suppν) _ h + +lemma DeltaSpikeSupport {ν : ℝ → ℝ} {ε x : ℝ} (εpos : 0 < ε) (xnonneg : 0 ≤ x) + (suppν : ν.support ⊆ Icc (1 / 2) 2) : + x ∉ Icc (2 ^ (-ε)) (2 ^ ε) → DeltaSpike ν ε x = 0 := by + contrapose!; exact DeltaSpikeSupport' εpos xnonneg suppν + +@[fun_prop] +lemma DeltaSpikeContinuous {ν : ℝ → ℝ} {ε : ℝ} (εpos : 0 < ε) + (diffν : ContDiff ℝ 1 ν) : Continuous (fun x ↦ DeltaSpike ν ε x) := by + apply diffν.continuous.comp (g := ν) _ |>.div_const + exact continuous_id.rpow_const fun _ ↦ Or.inr <| div_nonneg (by norm_num) εpos.le + +lemma DeltaSpikeOfRealContinuous {ν : ℝ → ℝ} {ε : ℝ} (εpos : 0 < ε) + (diffν : ContDiff ℝ 1 ν) : Continuous (fun x ↦ (DeltaSpike ν ε x : ℂ)) := + continuous_ofReal.comp <| DeltaSpikeContinuous εpos diffν + +/- +The Mellin transform of the delta spike is easy to compute. +-/ +/- +For any $\epsilon>0$, the Mellin transform of $\nu_\epsilon$ is + $$\mathcal{M}(\nu_\epsilon)(s) = \mathcal{M}(\nu)\left(\epsilon s\right).$$ +Substitute $y=x^{1/\epsilon}$, use Haar measure; direct calculation. +-/ +theorem MellinOfDeltaSpike (ν : ℝ → ℝ) {ε : ℝ} (εpos : ε > 0) (s : ℂ) : + 𝓜 (fun x ↦ (DeltaSpike ν ε x : ℂ)) s = 𝓜 (fun x ↦ (ν x : ℂ)) (ε * s) := by + unfold DeltaSpike + push_cast + rw [mellin_div_const, mellin_comp_rpow (fun x ↦ (ν x : ℂ)), abs_of_nonneg (by positivity)] + simp only [one_div, inv_inv, ofReal_inv, div_inv_eq_mul, real_smul] + rw [mul_div_cancel_left₀ _ (ne_zero_of_re_pos εpos)] + ring_nf + + + +/- +In particular, for $s=1$, we have that the Mellin transform of $\nu_\epsilon$ is $1+O(\epsilon)$. +-/ + +/- +For any $\epsilon>0$, we have + $$\mathcal{M}(\nu_\epsilon)(1) = + \mathcal{M}(\nu)(\epsilon).$$ +This is immediate from the above theorem. +-/ +lemma MellinOfDeltaSpikeAt1 (ν : ℝ → ℝ) {ε : ℝ} (εpos : ε > 0) : + 𝓜 (fun x ↦ (DeltaSpike ν ε x : ℂ)) 1 = 𝓜 (fun x ↦ (ν x : ℂ)) ε := by + convert MellinOfDeltaSpike ν εpos 1; simp [mul_one] + + + +/- +As $\epsilon\to 0$, we have + $$\mathcal{M}(\nu_\epsilon)(1) = 1+O(\epsilon).$$ +By Lemma \ref{MellinOfDeltaSpikeAt1}, + $$ + \mathcal M(\nu_\epsilon)(1)=\mathcal M(\nu)(\epsilon) + $$ + which by Definition \ref{MellinTransform} is + $$ + \mathcal M(\nu)(\epsilon)=\int_0^\infty\nu(x)x^{\epsilon-1}dx + . + $$ + Since $\nu(x) x^{\epsilon-1}$ is integrable (because $\nu$ is continuous and compactly + supported), + $$ + \mathcal M(\nu)(\epsilon)-\int_0^\infty\nu(x)\frac{dx}x + =\int_0^\infty\nu(x)(x^{\epsilon-1}-x^{-1})dx + . + $$ + By Taylor's theorem, + $$ + x^{\epsilon-1}-x^{-1}=O(\epsilon) + $$ + so, since $\nu$ is absolutely integrable, + $$ + \mathcal M(\nu)(\epsilon)-\int_0^\infty\nu(x)\frac{dx}x=O(\epsilon) + . + $$ + We conclude the proof using Theorem \ref{SmoothExistence}. +-/ +lemma MellinOfDeltaSpikeAt1_asymp {ν : ℝ → ℝ} (diffν : ContDiff ℝ 1 ν) + (suppν : ν.support ⊆ Set.Icc (1 / 2) 2) + (mass_one : ∫ x in Set.Ioi 0, ν x / x = 1) : + (fun (ε : ℝ) ↦ (𝓜 (fun x ↦ (ν x : ℂ)) ε) - 1) =O[𝓝[>]0] id := by + have diff : DifferentiableWithinAt ℝ + (fun (ε : ℝ) ↦ 𝓜 (fun x ↦ (ν x : ℂ)) ε - 1) (Ioi 0) 0 := by + apply DifferentiableAt.differentiableWithinAt + simp only [(differentiableAt_const _).fun_sub_iff_left] + refine DifferentiableAt.comp_ofReal ?_ + refine mellin_differentiableAt_of_isBigO_rpow (a := 1) (b := -1) ?_ ?_ (by simp) ?_ (by simp) + · apply (Continuous.continuousOn ?_).locallyIntegrableOn (by simp) + have := diffν.continuous; continuity + · apply Asymptotics.IsBigO.trans_le (g' := fun _ ↦ (0 : ℝ)) ?_ (by simp) + apply BigO_zero_atTop_of_support_in_Icc (a := 1 / 2) (b := 2) + rwa [ν.support_ofReal] + · apply Asymptotics.IsBigO.trans_le (g' := fun _ ↦ (0 : ℝ)) ?_ (by simp) + apply BigO_zero_atZero_of_support_in_Icc (a := 1 / 2) (b := 2) (ha := (by norm_num)) + rwa [ν.support_ofReal] + have := ofReal_zero ▸ diff.isBigO_sub + simp only [sub_sub_sub_cancel_right, sub_zero] at this + convert! this using 1 + simp only [mellin, zero_sub, cpow_neg_one, smul_eq_mul] + funext ε + congr 1 + symm + calc (∫ (t : ℝ) in Ioi 0, (↑t)⁻¹ * ↑(ν t) : ℂ) + = ∫ (t : ℝ) in Ioi 0, ((ν t / t : ℝ) : ℂ) := + integral_congr_ae (Filter.Eventually.of_forall fun t => by push_cast; ring) + _ = ((∫ t in Ioi 0, ν t / t : ℝ) : ℂ) := integral_ofReal + _ = 1 := by rw [mass_one, ofReal_one] + + + +/- +Let $1_{(0,1]}$ be the function from $\mathbb{R}_{>0}$ to $\mathbb{C}$ defined by +$$1_{(0,1]}(x) = \begin{cases} +1 & \text{ if }x\leq 1\\ +0 & \text{ if }x>1 +\end{cases}.$$ +This has Mellin transform: +[Note: this already exists in mathlib] +-/ +/- +The Mellin transform of $1_{(0,1]}$ is + $$\mathcal{M}(1_{(0,1]})(s) = \frac{1}{s}.$$ +This is a straightforward calculation. +-/ +lemma MellinOf1 (s : ℂ) (h : s.re > 0) : + 𝓜 ((fun x ↦ if 0 < x ∧ x ≤ 1 then 1 else 0)) s = 1 / s := by + convert (hasMellin_one_Ioc h).right + congr + + + +/- +What will be essential for us is properties of the smooth version of $1_{(0,1]}$, obtained as the + Mellin convolution of $1_{(0,1]}$ with $\nu_\epsilon$. +-/ +/- +Let $\epsilon>0$. Then we define the smooth function $\widetilde{1_{\epsilon}}$ from + $\mathbb{R}_{>0}$ to $\mathbb{C}$ by + $$\widetilde{1_{\epsilon}} = 1_{(0,1]}\ast\nu_\epsilon.$$ +Let $c:=2^\epsilon > 1$, in terms of which we wish to prove + $$ + -1 < c \log c - c . + $$ + Letting $f(x):=x\log x - x$, we can rewrite this as $f(1) < f(c)$. + Since + $$ + \frac {d}{dx}f(x) = \log x > 0 , + $$ + $f$ is monotone increasing on [1, \infty), and we are done. +-/ +/-- The indicator of `(0, 1]` smoothed by multiplicative convolution with `DeltaSpike`. -/ +noncomputable def Smooth1 (ν : ℝ → ℝ) (ε : ℝ) : ℝ → ℝ := + MellinConvolution (fun x ↦ if 0 < x ∧ x ≤ 1 then 1 else 0) (DeltaSpike ν ε) + +-- This lemma might not be necessary, but the RHS is supported on [0, infinity), which makes +-- results like `support_MellinConvolution_subsets` easier to apply. +lemma Smooth1_def_ite {ν : ℝ → ℝ} {ε x : ℝ} (xpos : 0 < x) : + Smooth1 ν ε x = MellinConvolution (fun x ↦ if 0 < x ∧ x ≤ 1 then 1 else 0) + (fun x ↦ if x < 0 then 0 else DeltaSpike ν ε x) x := by + unfold Smooth1 + rw [MellinConvolutionSymmetric _ _ xpos] + conv => lhs; rw [MellinConvolutionSymmetric _ _ xpos] + unfold MellinConvolution + apply MeasureTheory.integral_congr_ae + filter_upwards [MeasureTheory.ae_restrict_mem measurableSet_Ioi] + simp +contextual only [mem_Ioi, true_and, ite_mul, one_mul, zero_mul, RCLike.ofReal_real_eq_id, + id_eq, mul_ite, mul_zero] + intro y ypos + rw [eq_comm, ite_eq_right (by push Not; positivity)] + +/-% ** Wrong delimiters on purpose, no need to include this in blueprint +\begin{lemma}[Smooth1Properties_estimate]\label{Smooth1Properties_estimate} +\lean{Smooth1Properties_estimate}\leanok +For $\epsilon>0$, +$$ + \log2>\frac{1-2^{-\epsilon}}\epsilon +$$ +\end{lemma} +%-/ +lemma Smooth1Properties_estimate {ε : ℝ} (εpos : 0 < ε) : + (1 - 2 ^ (-ε)) / ε < Real.log 2 := by + apply (div_lt_iff₀' εpos).mpr + have : 1 - 1 / (2 : ℝ) ^ ε = ((2 : ℝ) ^ ε - 1) / (2 : ℝ) ^ ε := by + rw [sub_div, div_self (by positivity)] + rw [← Real.log_rpow (by norm_num), rpow_neg (by norm_num), inv_eq_one_div (2 ^ ε), this] + set c := (2 : ℝ) ^ ε + have hc : 1 < c := by + rw [← rpow_zero (2 : ℝ)] + apply Real.rpow_lt_rpow_of_exponent_lt (by norm_num) εpos + apply (div_lt_iff₀' (by positivity)).mpr <| lt_sub_iff_add_lt'.mp ?_ + let f := (fun x ↦ x * Real.log x - x) + rw [(by simp [f] : -1 = f 1), (by simp [f] : c * Real.log c - c = f c)] + have mono: StrictMonoOn f <| Ici 1 := by + refine strictMonoOn_of_deriv_pos (convex_Ici _) ?_ ?_ + · apply continuousOn_id.mul (continuousOn_id.log ?_) |>.sub continuousOn_id + intro x hx; simp only [mem_Ici] at hx; simp only [id_eq, ne_eq]; linarith + · intro x hx; simp only [nonempty_Iio, interior_Ici', mem_Ioi] at hx + dsimp only [f] + rw [deriv_fun_sub, deriv_fun_mul, Real.deriv_log, deriv_id'', one_mul, mul_inv_cancel₀] + · simp [log_pos hx] + · linarith + · simp only [differentiableAt_fun_id] + · simp only [differentiableAt_log_iff, ne_eq]; linarith + · exact differentiableAt_fun_id.mul <| differentiableAt_fun_id.log (by linarith) + · simp only [differentiableAt_fun_id] + exact mono (by rw [mem_Ici]) (mem_Ici.mpr <| le_of_lt hc) hc + + + +/- +In particular, we have the following two properties. +-/ +lemma Smooth1Properties_below_aux {x ε : ℝ} (hx : x ≤ 1 - Real.log 2 * ε) (εpos : 0 < ε) : + x < 2 ^ (-ε) := by + calc + x ≤ 1 - Real.log 2 * ε := hx + _ < 2 ^ (-ε) := ?_ + rw [sub_lt_iff_lt_add, add_comm, ← sub_lt_iff_lt_add] + exact (div_lt_iff₀ εpos).mp <| Smooth1Properties_estimate εpos + +/- +Fix $\epsilon>0$. There is an absolute constant $c>0$ so that: + If $0 < x \leq (1-c\epsilon)$, then + $$\widetilde{1_{\epsilon}}(x) = 1.$$ +Opening the definition, we have that the Mellin convolution of $1_{(0,1]}$ with $\nu_\epsilon$ is + $$ + \int_0^\infty 1_{(0,1]}(y)\nu_\epsilon(x/y)\frac{dy}{y} + = + \int_0^1 \nu_\epsilon(x/y)\frac{dy}{y}. + $$ + The support of $\nu_\epsilon$ is contained in $[1/2^\epsilon,2^\epsilon]$, so it suffices to + consider $y \in [1/2^\epsilon x,2^\epsilon x]$ for nonzero contributions. If $x < 2^{-\epsilon}$, + then the integral is the same as that over $(0,\infty)$: + $$ + \int_0^1 \nu_\epsilon(x/y)\frac{dy}{y} + = + \int_0^\infty \nu_\epsilon(x/y)\frac{dy}{y}, + $$ + in which we change variables to $z=x/y$ (using $x>0$): + $$ + \int_0^\infty \nu_\epsilon(x/y)\frac{dy}{y} + = + \int_0^\infty \nu_\epsilon(z)\frac{dz}{z}, + $$ + which is equal to one by Lemma \ref{DeltaSpikeMass}. + We then choose + $$ + c:=\log 2, + $$ + which satisfies + $$ + c > \frac{1-2^{-\epsilon}}\epsilon + $$ + by Lemma \ref{Smooth1Properties_estimate}, so + $$ + 1-c\epsilon < 2^{-\epsilon}. + $$ +-/ +lemma Smooth1Properties_below {ν : ℝ → ℝ} (suppν : ν.support ⊆ Icc (1 / 2) 2) + (mass_one : ∫ x in Ioi 0, ν x / x = 1) : + ∃ (c : ℝ), 0 < c ∧ c = Real.log 2 ∧ + ∀ (ε x) (_ : 0 < ε), 0 < x → x ≤ 1 - c * ε → Smooth1 ν ε x = 1 := by + set c := Real.log 2; use c + refine ⟨log_pos (by norm_num), rfl, ?_⟩ + intro ε x εpos xpos hx + have hx2 := Smooth1Properties_below_aux hx εpos + rewrite [← DeltaSpikeMass mass_one εpos] + unfold Smooth1 MellinConvolution + calc + _ = ∫ (y : ℝ) in Ioi 0, + indicator (Ioc 0 1) (fun y ↦ DeltaSpike ν ε (x / y) / ↑y) y := ?_ + _ = ∫ (y : ℝ) in Ioi 0, DeltaSpike ν ε (x / y) / y := ?_ + _ = _ := integral_comp_div_I0i_haar (fun y ↦ DeltaSpike ν ε y) xpos + · rw [setIntegral_congr_fun (by simp)] + intro y hy + by_cases h : y ≤ 1 <;> simp [indicator, mem_Ioi.mp hy, h] + · rw [setIntegral_congr_fun (by simp)] + intro y hy + have : y ≠ 0 := by + rintro rfl + simp at hy + simp only [indicator_apply_eq_self, mem_Ioc, not_and, not_le, div_eq_zero_iff, this, or_false] + intro hy2; replace hy2 := hy2 <| mem_Ioi.mp hy + apply DeltaSpikeSupport εpos ?_ suppν + · simp only [mem_Icc, not_and, not_le]; intro + linarith [(by apply (div_lt_iff₀ (by linarith)).mpr; nlinarith : x / y < 2 ^ (-ε))] + · rw [le_div_iff₀ (by linarith), zero_mul]; exact xpos.le + + + +lemma Smooth1Properties_above_aux {x ε : ℝ} (hx : 1 + (2 * Real.log 2) * ε ≤ x) + (hε : ε ∈ Ioo 0 1) : + 2 ^ ε < x := by + calc + x ≥ 1 + (2 * Real.log 2) * ε := hx + _ > 2 ^ ε := ?_ + refine lt_add_of_sub_left_lt <| (div_lt_iff₀ hε.1).mp ?_ + calc + 2 * Real.log 2 > 2 * (1 - 2 ^ (-ε)) / ε := ?_ + _ > 2 ^ ε * (1 - 2 ^ (-ε)) / ε := ?_ + _ = (2 ^ ε - 1) / ε := ?_ + · field_simp + exact Smooth1Properties_estimate hε.1 + · have : (2 : ℝ) ^ ε < 2 := by + have h := rpow_lt_rpow_of_exponent_lt (x := 2) (by norm_num) hε.2 + rwa [Real.rpow_one] at h + have pos: 0 < (1 - 2 ^ (-ε)) / ε := by + refine div_pos ?_ hε.1 + rw [sub_pos] + have h := rpow_lt_rpow_of_exponent_lt (x := 2) (by norm_num) (neg_lt_zero.mpr hε.1) + rwa [Real.rpow_zero] at h + have := (mul_lt_mul_iff_left₀ pos).mpr this + ring_nf at this ⊢ + exact this + · have : (2 : ℝ) ^ ε * (2 : ℝ) ^ (-ε) = (2 : ℝ) ^ (ε - ε) := by + rw [← rpow_add (by norm_num), add_neg_cancel, sub_self] + conv => lhs; lhs; ring_nf; rhs; simp [this] + +lemma Smooth1Properties_above_aux2 {x y ε : ℝ} (hε : ε ∈ Ioo 0 1) (hy : y ∈ Ioc 0 1) + (hx2 : 2 ^ ε < x) : + 2 < (x / y) ^ (1 / ε) := by + obtain ⟨εpos, ε1⟩ := hε + obtain ⟨ypos, y1⟩ := hy + calc + _ > (2 ^ ε / y) ^ (1 / ε) := ?_ + _ = 2 / y ^ (1 / ε) := ?_ + _ ≥ 2 / y := ?_ + _ ≥ 2 := ?_ + · rw [gt_iff_lt, div_rpow, div_rpow, lt_div_iff₀, mul_comm_div, div_self, mul_one] + <;> try positivity + · exact rpow_lt_rpow (by positivity) hx2 (by positivity) + · exact LT.lt.le <| lt_trans (by positivity) hx2 + · rw [div_rpow, ← rpow_mul, mul_div_cancel₀ 1 <| ne_of_gt εpos, rpow_one] <;> positivity + · have : y ^ (1 / ε) ≤ y := by + nth_rewrite 2 [← rpow_one y] + exact rpow_le_rpow_of_exponent_ge ypos y1 (by linarith [one_lt_one_div εpos ε1]) + have pos : 0 < y ^ (1 / ε) := rpow_pos_of_pos ypos _ + rw [ge_iff_le, div_le_iff₀, div_mul_eq_mul_div, le_div_iff₀', mul_comm] <;> try linarith + · rw [ge_iff_le, le_div_iff₀ <| ypos]; exact (mul_le_iff_le_one_right zero_lt_two).mpr y1 + +/- +Fix $0<\epsilon<1$. There is an absolute constant $c>0$ so that: + if $x\geq (1+c\epsilon)$, then + $$\widetilde{1_{\epsilon}}(x) = 0.$$ +Again the Mellin convolution is + $$\int_0^1 \nu_\epsilon(x/y)\frac{dy}{y},$$ + but now if $x > 2^\epsilon$, then the support of $\nu_\epsilon$ is disjoint + from the region of integration, and hence the integral is zero. + We choose + $$ + c:=2\log 2 + . + $$ + By Lemma \ref{Smooth1Properties_estimate}, + $$ + c > 2\frac{1-2^{-\epsilon}}\epsilon > 2^\epsilon\frac{1-2^{-\epsilon}}\epsilon + = + \frac{2^\epsilon-1}\epsilon, + $$ + so + $$ + 1+c\epsilon > 2^\epsilon. + $$ +-/ +lemma Smooth1Properties_above {ν : ℝ → ℝ} (suppν : ν.support ⊆ Icc (1 / 2) 2) : + ∃ (c : ℝ), 0 < c ∧ c = 2 * Real.log 2 ∧ + ∀ (ε x) (_ : ε ∈ Ioo 0 1), 1 + c * ε ≤ x → Smooth1 ν ε x = 0 := by + set c := 2 * Real.log 2; use c + constructor + · simp only [c, zero_lt_two, mul_pos_iff_of_pos_left]; exact log_pos (by norm_num) + constructor + · rfl + intro ε x hε hx + have hx2 := Smooth1Properties_above_aux hx hε + unfold Smooth1 MellinConvolution + simp only [ite_mul, one_mul, zero_mul, RCLike.ofReal_real_eq_id, id_eq] + apply setIntegral_eq_zero_of_forall_eq_zero + intro y hy + have ypos := mem_Ioi.mp hy + by_cases y1 : y ≤ 1 + swap + · simp [ypos, y1] + simp only [mem_Ioi.mp hy, y1, and_self, ↓reduceIte, div_eq_zero_iff]; left + apply DeltaSpikeSupport hε.1 ?_ suppν + on_goal 1 => + simp only [mem_Icc, not_and, not_le] + on_goal 2 => + suffices h : 2 ^ ε < x / y by + linarith [(by apply rpow_pos_of_pos (by norm_num) : 0 < (2 : ℝ) ^ ε)] + all_goals + try intro + have : x / y = ((x / y) ^ (1 / ε)) ^ ε := by + rw [← rpow_mul] + simp only [one_div, inv_mul_cancel₀ (ne_of_gt hε.1), rpow_one] + apply div_nonneg_iff.mpr; left; + exact ⟨(le_trans (rpow_pos_of_pos (by norm_num) ε).le) hx2.le, ypos.le⟩ + rw [this] + refine rpow_lt_rpow (by norm_num) ?_ hε.1 + exact Smooth1Properties_above_aux2 hε ⟨ypos, y1⟩ hx2 + + +lemma DeltaSpikeNonNeg_of_NonNeg {ν : ℝ → ℝ} (νnonneg : ∀ x > 0, 0 ≤ ν x) + {x ε : ℝ} (xpos : 0 < x) (εpos : 0 < ε) : + 0 ≤ DeltaSpike ν ε x := by + dsimp [DeltaSpike] + have : 0 < x ^ (1 / ε) := by positivity + have : 0 ≤ ν (x ^ (1 / ε)) := νnonneg _ this + positivity + +lemma MellinConvNonNeg_of_NonNeg {f g : ℝ → ℝ} (f_nonneg : ∀ x > 0, 0 ≤ f x) + (g_nonneg : ∀ x > 0, 0 ≤ g x) {x : ℝ} (xpos : 0 < x) : + 0 ≤ MellinConvolution f g x := by + dsimp [MellinConvolution] + apply MeasureTheory.setIntegral_nonneg + · exact measurableSet_Ioi + · intro y ypos; simp only [mem_Ioi] at ypos + have : 0 ≤ f y := f_nonneg _ ypos + have : 0 < x / y := by positivity + have : 0 ≤ g (x / y) := g_nonneg _ this + positivity + + +/- +If $\nu$ is nonnegative, then $\widetilde{1_{\epsilon}}(x)$ is nonnegative. +By Definitions \ref{Smooth1}, \ref{MellinConvolution} and \ref{DeltaSpike} + $$ + \widetilde{1_\epsilon}(x) + =\int_0^\infty 1_{(0,1]}(y)\frac1\epsilon\nu((x/y)^{\frac1\epsilon}) \frac{dy}y + $$ + and all the factors in the integrand are nonnegative. +-/ +lemma Smooth1Nonneg {ν : ℝ → ℝ} (νnonneg : ∀ x > 0, 0 ≤ ν x) {ε x : ℝ} + (xpos : 0 < x) (εpos : 0 < ε) : 0 ≤ Smooth1 ν ε x := by + dsimp [Smooth1] + apply MellinConvNonNeg_of_NonNeg ?_ ?_ xpos + · intro y hy; by_cases h : y ≤ 1 <;> simp [h, hy] + · intro y ypos; exact DeltaSpikeNonNeg_of_NonNeg νnonneg ypos εpos + + +lemma Smooth1LeOne_aux {x ε : ℝ} {ν : ℝ → ℝ} (xpos : 0 < x) (εpos : 0 < ε) + (mass_one : ∫ x in Ioi 0, ν x / x = 1) : + ∫ (y : ℝ) in Ioi 0, ν ((x / y) ^ (1 / ε)) / ε / y = 1 := by + calc + _ = ∫ (y : ℝ) in Ioi 0, (ν (y ^ (1 / ε)) / ε) / y := ?_ + _ = ∫ (y : ℝ) in Ioi 0, ν y / y := ?_ + _ = 1 := mass_one + · have := integral_comp_div_I0i_haar (fun y ↦ ν ((x / y) ^ (1 / ε)) / ε) xpos + convert! this.symm using 1 + congr; funext y; congr; field_simp [mul_comm] + · have := integral_comp_rpow_I0i_haar_real (fun y ↦ ν y) (one_div_ne_zero εpos.ne') + rw [← this, abs_of_pos <| one_div_pos.mpr εpos] + field_simp + + +/- +If $\nu$ is nonnegative and has mass one, then $\widetilde{1_{\epsilon}}(x)\le 1$, $\forall x>0$. +By Definitions \ref{Smooth1}, \ref{MellinConvolution} and \ref{DeltaSpike} + $$ + \widetilde{1_\epsilon}(x) + =\int_0^\infty 1_{(0,1]}(y)\frac1\epsilon\nu((x/y)^{\frac1\epsilon}) \frac{dy}y + $$ + and since $1_{(0,1]}(y)\le 1$, and all the factors in the integrand are nonnegative, + $$ + \widetilde{1_\epsilon}(x)\le\int_0^\infty \frac1\epsilon\nu((x/y)^{\frac1\epsilon}) \frac{dy}y + $$ + (because in mathlib the integral of a non-integrable function is $0$, for the inequality above + to be true, we must prove that $\nu((x/y)^{\frac1\epsilon})/y$ is integrable; this follows from + the computation below). + We then change variables to $z=(x/y)^{\frac1\epsilon}$: + $$ + \widetilde{1_\epsilon}(x)\le\int_0^\infty \nu(z) \frac{dz}z + $$ + which by Theorem \ref{SmoothExistence} is 1. +-/ +lemma Smooth1LeOne {ν : ℝ → ℝ} (νnonneg : ∀ x > 0, 0 ≤ ν x) + (mass_one : ∫ x in Ioi 0, ν x / x = 1) {ε : ℝ} (εpos : 0 < ε) {x : ℝ} (xpos : 0 < x) : + Smooth1 ν ε x ≤ 1 := by + unfold Smooth1 MellinConvolution DeltaSpike + have := Smooth1LeOne_aux xpos εpos mass_one + calc + _ = ∫ (y : ℝ) in Ioi 0, + (fun y ↦ if y ∈ Ioc 0 1 then 1 else 0) y * (ν ((x / y) ^ (1 / ε)) / ε / y) := ?_ + _ ≤ ∫ (y : ℝ) in Ioi 0, (ν ((x / y) ^ (1 / ε)) / ε) / y := ?_ + _ = 1 := this + · rw [setIntegral_congr_fun (by simp)] + simp only [ite_mul, one_mul, zero_mul, RCLike.ofReal_real_eq_id, id_eq, mem_Ioc] + intro y hy; aesop + · refine setIntegral_mono_on ?_ (integrable_of_integral_eq_one this) (by simp) ?_ + · refine integrable_of_integral_eq_one this |>.bdd_mul ?_ + (ae_of_all _ <| by aesop) + have : (fun x ↦ if 0 < x ∧ x ≤ 1 then 1 else 0) = + indicator (Ioc 0 1) (1 : ℝ → ℝ) := by + aesop + simp only [mem_Ioc, this, measurableSet_Ioc, aestronglyMeasurable_indicator_iff] + exact aestronglyMeasurable_one + · simp only [ite_mul, one_mul, zero_mul] + intro y hy + by_cases h : y ≤ 1 + · aesop + field_simp + simp only [mem_Ioc, h, and_false, ↓reduceIte, one_div, mul_zero] + simp only [mem_Ioi] at hy + apply div_nonneg + · apply νnonneg; exact rpow_pos_of_pos (div_pos xpos <| mem_Ioi.mp hy) _ + · positivity + + + +/- +Combining the above, we have the following three Main Lemmata of this section on the Mellin +transform of $\widetilde{1_{\epsilon}}$. +-/ +/- +Fix $\epsilon>0$. Then the Mellin transform of $\widetilde{1_{\epsilon}}$ is + $$\mathcal{M}(\widetilde{1_{\epsilon}})(s) = + \frac{1}{s}\left(\mathcal{M}(\nu)\left(\epsilon s\right)\right).$$ +By Definition \ref{Smooth1}, + $$ + \mathcal M(\widetilde{1_\epsilon})(s) + =\mathcal M(1_{(0,1]}\ast\nu_\epsilon)(s) + . + $$ + We wish to apply Theorem \ref{MellinConvolutionTransform}. + To do so, we must prove that + $$ + (x,y)\mapsto 1_{(0,1]}(y)\nu_\epsilon(x/y)/y + $$ + is integrable on $[0,\infty)^2$. + It is actually easier to do this for the convolution: $\nu_\epsilon\ast 1_{(0,1]}$, so we use + Lemma \ref{MellinConvolutionSymmetric}: for $x\neq0$, + $$ + 1_{(0,1]}\ast\nu_\epsilon(x)=\nu_\epsilon\ast 1_{(0,1]}(x) + . + $$ + Now, for $x=0$, both sides of the equation are 0, so the equation also holds for $x=0$. + Therefore, + $$ + \mathcal M(\widetilde{1_\epsilon})(s) + =\mathcal M(\nu_\epsilon\ast 1_{(0,1]})(s) + . + $$ + Now, + $$ + (x,y)\mapsto \nu_\epsilon(y)1_{(0,1]}(x/y)\frac{x^{s-1}}y + $$ + has compact support that is bounded away from $y=0$ (specifically + $y\in[2^{-\epsilon},2^\epsilon]$ and $x\in(0,y]$), so it is integrable. + We can thus apply Theorem \ref{MellinConvolutionTransform} and find + $$ + \mathcal M(\widetilde{1_\epsilon})(s) + =\mathcal M(\nu_\epsilon)(s)\mathcal M(1_{(0,1]})(s) + . + $$ + By Lemmas \ref{MellinOf1} and \ref{MellinOfDeltaSpike}, + $$ + \mathcal M(\widetilde{1_\epsilon})(s) + =\frac1s\mathcal M(\nu)(\epsilon s) + . + $$ +-/ +lemma MellinOfSmooth1a {ν : ℝ → ℝ} (diffν : ContDiff ℝ 1 ν) + (suppν : ν.support ⊆ Icc (1 / 2) 2) + {ε : ℝ} (εpos : 0 < ε) {s : ℂ} (hs : 0 < s.re) : + 𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) s = + s⁻¹ * 𝓜 (fun x ↦ (ν x : ℂ)) (ε * s) := by + classical + let f' : ℝ → ℂ := fun x ↦ DeltaSpike ν ε x + let f : ℝ → ℂ := fun x ↦ DeltaSpike ν ε x / x + let g : ℝ → ℂ := fun x ↦ if 0 < x ∧ x ≤ 1 then 1 else 0 + let F : ℝ × ℝ → ℂ := Function.uncurry fun x y ↦ f y * g (x / y) * (x : ℂ) ^ (s - 1) + let S := {⟨x, y⟩ : ℝ × ℝ | 0 < x ∧ x ≤ y ∧ 2 ^ (-ε) ≤ y ∧ y ≤ 2 ^ ε} + let F' : ℝ × ℝ → ℂ := piecewise S (fun ⟨x, y⟩ ↦ f y * (x : ℂ) ^ (s - 1)) + (fun _ ↦ 0) + let Tx := Ioc 0 ((2 : ℝ) ^ ε) + let Ty := Icc ((2 : ℝ) ^ (-ε)) ((2 : ℝ) ^ ε) + have Seq : S = (Tx ×ˢ Ty) ∩ {(x, y) : ℝ × ℝ | x ≤ y} := by + ext ⟨x, y⟩; constructor + · exact fun h ↦ ⟨⟨⟨h.1, le_trans h.2.1 h.2.2.2⟩, ⟨h.2.2.1, h.2.2.2⟩⟩, h.2.1⟩ + · exact fun h ↦ ⟨h.1.1.1, ⟨h.2, h.1.2.1, h.1.2.2⟩⟩ + have SsubI : S ⊆ Ioi 0 ×ˢ Ioi 0 := + fun z hz ↦ ⟨hz.1, lt_of_lt_of_le (by apply rpow_pos_of_pos; norm_num) hz.2.2.1⟩ + have SsubT: S ⊆ Tx ×ˢ Ty := by simp_rw [Seq, inter_subset_left] + have Smeas : MeasurableSet S := by + rw [Seq]; apply MeasurableSet.inter ?_ <| measurableSet_le measurable_fst measurable_snd + simp [measurableSet_prod, Tx, Ty] + have int_F: IntegrableOn F (Ioi 0 ×ˢ Ioi 0) := by + apply IntegrableOn.congr_fun (f := F') ?_ ?_ (by simp [measurableSet_prod]); swap + · simp only [F, F', f, g, mul_ite, mul_one, mul_zero] + intro ⟨x, y⟩ hz + by_cases hS : ⟨x, y⟩ ∈ S <;> simp only [hS, piecewise] + <;> simp only [mem_prod, mem_Ioi, mem_ofPred_eq, not_and, not_le, S] at hz hS + · simp [div_pos hz.1 hz.2, (div_le_one hz.2).mpr hS.2.1] + · by_cases hxy : x / y ≤ 1 + swap + · simp [hxy] + have hy : y ∉ Icc (2 ^ (-ε)) (2 ^ ε) := by + simp only [mem_Icc, not_and, not_le]; exact hS hz.1 <| (div_le_one hz.2).mp hxy + simp [DeltaSpikeSupport εpos hz.2.le suppν hy] + · apply Integrable.piecewise Smeas ?_ integrableOn_zero + simp only [IntegrableOn, Measure.restrict_restrict_of_subset SsubI] + apply MeasureTheory.Integrable.mono_measure ?_ + · apply MeasureTheory.Measure.restrict_mono' SsubT.eventuallyLE le_rfl + have : volume.restrict (Tx ×ˢ Ty) = (volume.restrict Tx).prod (volume.restrict Ty) := by + rw [Measure.prod_restrict, MeasureTheory.Measure.volume_eq_prod] + erw [this]; conv => lhs; intro; rw [mul_comm] + apply MeasureTheory.Integrable.mul_prod (f := fun x ↦ (x : ℂ) ^ (s - 1)) + (μ := Measure.restrict volume Tx) + · simp only [Tx] + rw [← IntegrableOn, integrableOn_Ioc_iff_integrableOn_Ioo, + intervalIntegral.integrableOn_Ioo_cpow_iff] + · simp [hs] + · apply rpow_pos_of_pos (by norm_num) + · apply (ContinuousOn.div ?_ ?_ ?_).integrableOn_compact isCompact_Icc + · exact (DeltaSpikeOfRealContinuous εpos diffν).continuousOn + · exact continuous_ofReal.continuousOn + · intro x hx; simp only [mem_Icc] at hx; simp only [ofReal_ne_zero] + linarith [(by apply rpow_pos_of_pos (by norm_num) : (0 : ℝ) < 2 ^ (-ε))] + have : 𝓜 (MellinConvolution g f') s = 𝓜 g s * 𝓜 f' s := by + rw [mul_comm, ← MellinConvolutionTransform f' g s + (by convert int_F using 1; simp only [f', F, f]; field_simp)] + dsimp [mellin]; rw [setIntegral_congr_fun (by simp)] + intro x hx; simp_rw [MellinConvolutionSymmetric _ _ <| mem_Ioi.mp hx] + convert! this using 1 + · congr; funext x; convert! integral_ofReal.symm + simp only [MellinConvolution, RCLike.ofReal_div, ite_mul, one_mul, zero_mul, @apply_ite ℝ ℂ, + algebraMap.coe_zero, g]; rfl + · rw [MellinOf1 s hs, MellinOfDeltaSpike ν εpos s] + simp + + + +/- +Given $0<\sigma_1\le\sigma_2$, for any $s$ such that $\sigma_1\le\mathcal Re(s)\le\sigma_2$, + we have + $$\mathcal{M}(\widetilde{1_{\epsilon}})(s) = O\left(\frac{1}{\epsilon|s|^2}\right).$$ +Use Lemma \ref{MellinOfSmooth1a} and the bound in Lemma \ref{MellinOfPsi}. +-/ +lemma MellinOfSmooth1b {ν : ℝ → ℝ} (diffν : ContDiff ℝ 1 ν) + (suppν : ν.support ⊆ Set.Icc (1 / 2) 2) : + ∃ (C : ℝ) (_ : 0 < C), ∀ (σ₁ : ℝ) (_ : 0 < σ₁) + (s) (_ : σ₁ ≤ s.re) (_ : s.re ≤ 2) (ε : ℝ) (_ : 0 < ε) (_ : ε < 1), + ‖𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) s‖ ≤ C * (ε * ‖s‖ ^ 2)⁻¹ := by + obtain ⟨C, Cpos, hC⟩ := MellinOfPsi diffν suppν + refine ⟨C, Cpos, ?_⟩ + intro σ₁ σ₁pos s hs1 hs2 ε εpos ε_lt_one + rw [MellinOfSmooth1a diffν suppν εpos <| lt_of_le_of_lt' hs1 σ₁pos] + have hh1 : ε * σ₁ ≤ (ε * s).re := by + simp only [mul_re, ofReal_re, ofReal_im, zero_mul, sub_zero] + nlinarith + have hh2 : (ε * s).re ≤ 2 := by + simp only [mul_re, ofReal_re, ofReal_im, zero_mul, sub_zero] + nlinarith + calc + ‖s⁻¹ * 𝓜 (fun x ↦ (ν x : ℂ)) (ε * s)‖ = + ‖s⁻¹‖ * ‖𝓜 (fun x ↦ (ν x : ℂ)) (ε * s)‖ := by simp + _ ≤ ‖s⁻¹‖ * (C * (ε * ‖s‖)⁻¹) := by + gcongr + convert! hC (ε * σ₁) (by positivity) (ε * s) hh1 hh2 + simp [abs_eq_self.mpr εpos.le] + _ = C * (ε * ‖s‖ ^ 2)⁻¹ := by + simp only [norm_inv, mul_inv_rev] + ring + + + + +/- +At $s=1$, we have + $$\mathcal{M}(\widetilde{1_{\epsilon}})(1) = 1+O(\epsilon)).$$ +Follows from Lemmas \ref{MellinOfSmooth1a}, \ref{MellinOfDeltaSpikeAt1} and + \ref{MellinOfDeltaSpikeAt1_asymp}. +-/ +lemma MellinOfSmooth1c {ν : ℝ → ℝ} (diffν : ContDiff ℝ 1 ν) + (suppν : ν.support ⊆ Icc (1 / 2) 2) + (mass_one : ∫ x in Ioi 0, ν x / x = 1) : + (fun ε ↦ 𝓜 (fun x ↦ (Smooth1 ν ε x : ℂ)) 1 - 1) =O[𝓝[>]0] id := by + have h := MellinOfDeltaSpikeAt1_asymp diffν suppν mass_one + rw [Asymptotics.isBigO_iff] at h ⊢ + obtain ⟨c, hc⟩ := h + use c + filter_upwards [hc, Ioo_mem_nhdsGT (by linarith : (0 : ℝ) < 1)] with ε hε hε' + rw [MellinOfSmooth1a diffν suppν hε'.1 (s := 1) (by norm_num)] + simp only [inv_one, mul_one, one_mul, id_eq, Real.norm_eq_abs] + exact hε + + + +/- +Fix a nonnegative, continuously differentiable function $F$ on $\mathbb{R}$ with support in + $[1/2,2]$. Then for any $\epsilon>0$, the function + $x \mapsto \int_{(0,\infty)} x^{1+it} \widetilde{1_{\epsilon}}(x) dx$ is continuous at any $y>0$. +Use Lemma \ref{MellinconvolutionSymmetric} to write $\widetilde{1_{\epsilon}}(x)$ as an integral + over an integral near $1$, in particular avoiding the singularity at $0$. The integrand may be + bounded by $2^{\epsilon}\nu_\epsilon(t)$ which is independent of $x$ and we can use dominated + convergence to prove continuity. +-/ +lemma Smooth1ContinuousAt {SmoothingF : ℝ → ℝ} + (diffSmoothingF : ContDiff ℝ 1 SmoothingF) + (SmoothingFpos : ∀ x > 0, 0 ≤ SmoothingF x) + (suppSmoothingF : SmoothingF.support ⊆ Icc (1 / 2) 2) + {ε : ℝ} (εpos : 0 < ε) {y : ℝ} (ypos : 0 < y) : + ContinuousAt (fun x ↦ Smooth1 SmoothingF ε x) y := by + apply ContinuousAt.congr + (f := (fun x ↦ MellinConvolution (DeltaSpike SmoothingF ε) + (fun x ↦ if 0 < x ∧ x ≤ 1 then 1 else 0) x)) _ + · filter_upwards [lt_mem_nhds ypos] with x hx + apply MellinConvolutionSymmetric _ _ hx + apply continuousAt_of_dominated (bound := (fun x ↦ 2 ^ ε * DeltaSpike SmoothingF ε x)) + · filter_upwards [lt_mem_nhds ypos] with x hx + apply Measurable.aestronglyMeasurable + apply Measurable.mul + · apply Measurable.mul + · exact Continuous.measurable <| DeltaSpikeContinuous εpos diffSmoothingF + · apply Measurable.ite _ (by fun_prop) (by fun_prop) + apply MeasurableSet.congr (s := Ici x) (by measurability) + ext a + constructor + · intro ha + have apos : 0 < a := lt_of_lt_of_le hx ha + constructor + · exact div_pos hx apos + · exact (div_le_one apos).mpr ha + · intro ha + have : 0 < a := (div_pos_iff_of_pos_left hx).mp ha.1 + exact (div_le_one this).mp ha.2 + · fun_prop + · filter_upwards [lt_mem_nhds ypos] with x hx + filter_upwards [ae_restrict_mem (by measurability)] with t ht + simp only [mul_ite, mul_one, mul_zero, RCLike.ofReal_real_eq_id, id_eq, norm_div, norm_eq_abs] + by_cases! h : DeltaSpike SmoothingF ε t = 0 + · simp [h] + have := DeltaSpikeSupport' εpos ht.le suppSmoothingF h + have dsnonneg : 0 ≤ DeltaSpike SmoothingF ε t := by + apply DeltaSpikeNonNeg_of_NonNeg <;> assumption + calc + _ ≤ |DeltaSpike SmoothingF ε t| / |t| := by + gcongr + · split_ifs with h + · apply le_refl + · exact dsnonneg + _ ≤ _ := by + rw [_root_.abs_of_nonneg dsnonneg, mul_comm, div_eq_mul_one_div, _root_.abs_of_pos ht] + gcongr + apply (one_div_le ht (by bound)).mpr + · convert this.1 using 1 + rw [div_eq_iff (by positivity), ← rpow_add (by norm_num), neg_add_cancel, rpow_zero] + · apply Integrable.const_mul + apply (integrable_indicator_iff (by measurability)).mp + apply (integrableOn_iff_integrable_of_support_subset (s := Icc (2 ^ (-ε)) (2 ^ ε)) _).mp + · apply ContinuousOn.integrableOn_compact isCompact_Icc + apply ContinuousOn.congr (f := DeltaSpike SmoothingF ε) + · apply Continuous.continuousOn + apply DeltaSpikeContinuous<;> assumption + · intro x hx + have : x ∈ Ioi 0 := by + apply mem_Ioi.mpr + apply lt_of_lt_of_le (by bound) hx.1 + rw [indicator, ite_eq_left this] + · unfold indicator + simp_rw [mem_Ioi] + apply Function.support_subset_iff.mpr + simp only [ne_eq, ite_eq_right_iff, Classical.not_imp, mem_Icc, and_imp] + intro x hx + apply DeltaSpikeSupport' εpos hx.le suppSmoothingF + · have : ∀ᵐ (a : ℝ) ∂volume.restrict (Ioi 0), a ≠ y := by + apply ae_iff.mpr + simp + filter_upwards [ae_restrict_mem (by measurability), this] with x hx hx2 + simp only [mem_Ioi] at hx + apply ContinuousAt.div_const + apply ContinuousAt.mul (by fun_prop) + have : (fun x_1 ↦ if 0 < x_1 / x ∧ x_1 / x ≤ 1 then 1 else 0) = + (Ioc 0 x).indicator (fun _ ↦ (1 : ℝ)) := by + ext t + unfold indicator + simp [div_pos_iff_of_pos_right, div_le_one₀, hx] + rw [this] + apply ContinuousOn.continuousAt_indicator (by fun_prop) + simp [frontier_Ioc hx, ypos.ne', hx2.symm] + + + + +lemma Smooth1MellinConvergent {Ψ : ℝ → ℝ} {ε : ℝ} (diffΨ : ContDiff ℝ 1 Ψ) + (suppΨ : Ψ.support ⊆ Icc (1 / 2) 2) (hε : ε ∈ Ioo 0 1) + (Ψnonneg : ∀ x > 0, 0 ≤ Ψ x) (mass_one : ∫ x in Ioi 0, Ψ x / x = 1) + {s : ℂ} (hs : 0 < s.re) : MellinConvergent (fun x ↦ (Smooth1 Ψ ε x : ℂ)) s := by + apply mellinConvergent_of_isBigO_rpow_exp zero_lt_one _ _ _ hs + · apply ContinuousOn.locallyIntegrableOn _ (by measurability) + apply continuousOn_of_forall_continuousAt + exact fun x hx ↦ Smooth1ContinuousAt diffΨ Ψnonneg suppΨ hε.1 hx |>.ofReal + · rw [Asymptotics.isBigO_iff] + use 1 + obtain ⟨c, cpos, ceq, hc⟩ := Smooth1Properties_above suppΨ + filter_upwards [eventually_ge_atTop (1 + c * ε)] with x hx + rw [hc _ _ hε hx] + simp only [ofReal_zero, norm_zero, neg_mul, one_mul, norm_eq_abs, abs_exp] + bound + · rw [Asymptotics.isBigO_iff] + use 1 + filter_upwards [eventually_mem_nhdsWithin] with x hx + simp only [norm_real, norm_eq_abs, neg_zero, rpow_zero, one_mem, CStarRing.norm_of_mem_unitary, + mul_one] + rw [_root_.abs_of_nonneg <| Smooth1Nonneg Ψnonneg hx hε.1] + exact Smooth1LeOne Ψnonneg mass_one hε.1 hx + +lemma Smooth1MellinDifferentiable {Ψ : ℝ → ℝ} {ε : ℝ} (diffΨ : ContDiff ℝ 1 Ψ) + (suppΨ : Ψ.support ⊆ Icc (1 / 2) 2) (hε : ε ∈ Ioo 0 1) + (Ψnonneg : ∀ x > 0, 0 ≤ Ψ x) (mass_one : ∫ x in Ioi 0, Ψ x / x = 1) + {s : ℂ} (hs : 0 < s.re) : + DifferentiableAt ℂ (𝓜 (fun x ↦ (Smooth1 Ψ ε x : ℂ))) s := by + apply mellin_differentiableAt_of_isBigO_rpow_exp zero_lt_one _ _ _ hs + · apply ContinuousOn.locallyIntegrableOn _ (by measurability) + apply continuousOn_of_forall_continuousAt + exact fun x hx ↦ Smooth1ContinuousAt diffΨ Ψnonneg suppΨ hε.1 hx |>.ofReal + · rw [Asymptotics.isBigO_iff] + use 1 + obtain ⟨c, cpos, ceq, hc⟩ := Smooth1Properties_above suppΨ + filter_upwards [eventually_ge_atTop (1 + c * ε)] with x hx + rw [hc _ _ hε hx] + simp only [ofReal_zero, norm_zero, neg_mul, one_mul, norm_eq_abs, abs_exp] + bound + · rw [Asymptotics.isBigO_iff] + use 1 + filter_upwards [eventually_mem_nhdsWithin] with x hx + simp only [norm_real, norm_eq_abs, neg_zero, rpow_zero, one_mem, CStarRing.norm_of_mem_unitary, + mul_one] + rw [_root_.abs_of_nonneg <| Smooth1Nonneg Ψnonneg hx hε.1] + exact Smooth1LeOne Ψnonneg mass_one hε.1 hx + +end IwaniecLinearSievePNT diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/Rectangle.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/Rectangle.lean new file mode 100644 index 000000000..32ae3a094 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/Rectangle.lean @@ -0,0 +1,305 @@ +/- +Copyright (c) 2026 PrimeNumberTheoremAnd contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: PrimeNumberTheoremAnd contributors +-/ + +module + +public import Mathlib.Analysis.InnerProductSpace.Basic +import Mathlib.Analysis.Complex.Convex +import Mathlib.Analysis.Normed.Order.Lattice +import Mathlib.Order.Interval.Set.Monotone + +/-! +Adapted from PrimeNumberTheoremAnd revision +`127b50e33f6033e2147921167a117af96d9ba4ea`, via Jason Davies's +Iwaniec linear sieve snapshot `c8d01549d2ae640b36ec198c1f0f6495f1b036cf` +(both Apache-2.0). Blueprint-only machinery is omitted. + +Supporting lemmas for Iwaniec's sieve and its prime-number-theorem input. +-/ + +@[expose] public section + +namespace IwaniecLinearSievePNT + + +open Complex Set Topology + +open scoped Interval + +variable {z w : ℂ} {c : ℝ} + +/- +This files gathers definitions and basic properties about rectangles. +-/ + +namespace Rectangle + +lemma symm : Rectangle z w = Rectangle w z := by + simp [Rectangle, uIcc_comm] + +lemma symm_re : Rectangle (w.re + z.im * I) (z.re + w.im * I) = Rectangle z w := by + simp [Rectangle, uIcc_comm] + +end Rectangle + +/- +The border of a rectangle is the union of its four sides. +-/ +/-- A `RectangleBorder` has corners `z` and `w`. -/ +/- +A Rectangle's border, given corners $z$ and $w$ is the union of the four + sides. +-/ +def RectangleBorder (z w : ℂ) : Set ℂ := + [[z.re, w.re]] ×ℂ {z.im} ∪ {z.re} ×ℂ [[z.im, w.im]] ∪ + [[z.re, w.re]] ×ℂ {w.im} ∪ {w.re} ×ℂ [[z.im, w.im]] + +/-- The axis-aligned square centered at `p` with half-side length `c`. -/ +def Square (p : ℂ) (c : ℝ) : Set ℂ := Rectangle (-c - c * I + p) (c + c * I + p) + +lemma Square_apply (p : ℂ) (cpos : c > 0) : + Square p c = Icc (-c + p.re) (c + p.re) ×ℂ Icc (-c + p.im) (c + p.im) := by + rw [Square, Rectangle, uIcc_of_le (by simp; linarith), uIcc_of_le (by simp; linarith)] + simp + + +@[simp] +theorem preimage_equivRealProdCLM_reProdIm (s t : Set ℝ) : + equivRealProdCLM.symm ⁻¹' (s ×ℂ t) = s ×ˢ t := + rfl + +@[simp] +theorem _root_.ContinuousLinearEquiv.coe_toLinearEquiv_symm {R : Type*} {S : Type*} [Semiring R] + [Semiring S] {σ : R →+* S} {σ' : S →+* R} [RingHomInvPair σ σ'] [RingHomInvPair σ' σ] + (M : Type*) [TopologicalSpace M] + [AddCommMonoid M] {M₂ : Type*} [TopologicalSpace M₂] [AddCommMonoid M₂] [Module R M] + [Module S M₂] (e : M ≃SL[σ] M₂) : + ⇑e.toLinearEquiv.symm = e.symm := + rfl + +/-- The axis-parallel complex rectangle with opposite corners `z` and `w` is complex product of + two intervals, which is also the convex hull of the four corners. Golfed from mathlib4\#9598. -/ +lemma segment_reProdIm_segment_eq_convexHull (z w : ℂ) : + [[z.re, w.re]] ×ℂ [[z.im, w.im]] = + convexHull ℝ {z, z.re + w.im * I, w.re + z.im * I, w} := by + simp_rw [← segment_eq_uIcc, ← convexHull_pair, ← convexHull_reProdIm, reProdIm] + exact congrArg _ <| Set.ext <| by simpa [Complex.ext_iff] using by tauto + +/-- If the four corners of a rectangle are contained in a convex set `U`, then the whole + rectangle is. Golfed from mathlib4\#9598. -/ +lemma rectangle_in_convex {U : Set ℂ} (U_convex : Convex ℝ U) {z w : ℂ} (hz : z ∈ U) + (hw : w ∈ U) (hzw : (z.re + w.im * I) ∈ U) (hwz : (w.re + z.im * I) ∈ U) : + Rectangle z w ⊆ U := by + rw [Rectangle, segment_reProdIm_segment_eq_convexHull] + exact convexHull_min (by simp_all [insert_subset_iff]) U_convex + +lemma mem_Rect {z w : ℂ} (zRe_lt_wRe : z.re ≤ w.re) (zIm_lt_wIm : z.im ≤ w.im) (p : ℂ) : + p ∈ Rectangle z w ↔ + z.re ≤ p.re ∧ p.re ≤ w.re ∧ z.im ≤ p.im ∧ p.im ≤ w.im := by + rw [Rectangle, uIcc_of_le zRe_lt_wRe, uIcc_of_le zIm_lt_wIm] + exact and_assoc + +lemma square_neg (p : ℂ) (c : ℝ) : Square p (-c) = Square p c := by + simpa [Square] using! Rectangle.symm + + +theorem _root_.Set.left_not_mem_uIoo {a b : ℝ} : a ∉ Set.uIoo a b := + fun ⟨h1, h2⟩ ↦ (left_lt_sup.mp h2) (le_of_not_ge (inf_lt_left.mp h1)) + +theorem _root_.Set.right_not_mem_uIoo {a b : ℝ} : b ∉ Set.uIoo a b := + fun ⟨h1, h2⟩ ↦ (right_lt_sup.mp h2) (le_of_not_ge (inf_lt_right.mp h1)) + +theorem _root_.Set.ne_left_of_mem_uIoo {a b c : ℝ} (hc : c ∈ Set.uIoo a b) : c ≠ a := + fun h ↦ Set.left_not_mem_uIoo (h ▸ hc) + +theorem _root_.Set.ne_right_of_mem_uIoo {a b c : ℝ} (hc : c ∈ Set.uIoo a b) : c ≠ b := + fun h ↦ Set.right_not_mem_uIoo (h ▸ hc) + +lemma left_mem_rect (z w : ℂ) : z ∈ Rectangle z w := ⟨left_mem_uIcc, left_mem_uIcc⟩ + +lemma right_mem_rect (z w : ℂ) : w ∈ Rectangle z w := ⟨right_mem_uIcc, right_mem_uIcc⟩ + +lemma rect_subset_iff {z w z' w' : ℂ} : + Rectangle z' w' ⊆ Rectangle z w ↔ z' ∈ Rectangle z w ∧ w' ∈ Rectangle z w := by + use fun h ↦ ⟨h (left_mem_rect z' w'), h (right_mem_rect z' w')⟩ + intro ⟨⟨⟨hz're_ge, hz're_le⟩, ⟨hz'im_ge, hz'im_le⟩⟩, + ⟨⟨hw're_ge, hw're_le⟩, ⟨hw'im_ge, hw'im_le⟩⟩⟩ x + ⟨⟨hxre_ge, hxre_le⟩, ⟨hxim_ge, hxim_le⟩⟩ + refine ⟨⟨?_, ?_⟩, ⟨?_, ?_⟩⟩ + · exact (le_inf hz're_ge hw're_ge).trans hxre_ge + · exact (le_sup_iff.mp hxre_le).casesOn (fun h ↦ h.trans hz're_le) + (fun h ↦ h.trans hw're_le) + · exact (le_inf hz'im_ge hw'im_ge).trans hxim_ge + · exact (le_sup_iff.mp hxim_le).casesOn (fun h ↦ h.trans hz'im_le) + (fun h ↦ h.trans hw'im_le) + +lemma RectSubRect {x₀ x₁ x₂ x₃ y₀ y₁ y₂ y₃ : ℝ} (x₀_le_x₁ : x₀ ≤ x₁) + (x₁_le_x₂ : x₁ ≤ x₂) (x₂_le_x₃ : x₂ ≤ x₃) (y₀_le_y₁ : y₀ ≤ y₁) + (y₁_le_y₂ : y₁ ≤ y₂) (y₂_le_y₃ : y₂ ≤ y₃) : + Rectangle (x₁ + y₁ * I) (x₂ + y₂ * I) ⊆ + Rectangle (x₀ + y₀ * I) (x₃ + y₃ * I) := by + rw [rect_subset_iff, mem_Rect, mem_Rect] + · refine ⟨⟨?_, ?_, ?_, ?_⟩, ?_, ?_, ?_, ?_⟩ + all_goals simpa using by linarith + all_goals simpa using by linarith + +lemma RectSubRect' {z₀ z₁ z₂ z₃ : ℂ} (x₀_le_x₁ : z₀.re ≤ z₁.re) + (x₁_le_x₂ : z₁.re ≤ z₂.re) (x₂_le_x₃ : z₂.re ≤ z₃.re) + (y₀_le_y₁ : z₀.im ≤ z₁.im) (y₁_le_y₂ : z₁.im ≤ z₂.im) + (y₂_le_y₃ : z₂.im ≤ z₃.im) : + Rectangle z₁ z₂ ⊆ Rectangle z₀ z₃ := by + rw [← re_add_im z₀, ← re_add_im z₁, ← re_add_im z₂, ← re_add_im z₃] + exact RectSubRect x₀_le_x₁ x₁_le_x₂ x₂_le_x₃ y₀_le_y₁ y₁_le_y₂ y₂_le_y₃ + +lemma rectangleBorder_subset_rectangle (z w : ℂ) : RectangleBorder z w ⊆ Rectangle z w := by + intro x hx + obtain ⟨⟨h | h⟩ | h⟩ | h := hx + · exact ⟨h.1, h.2 ▸ left_mem_uIcc⟩ + · exact ⟨h.1 ▸ left_mem_uIcc, h.2⟩ + · exact ⟨h.1, h.2 ▸ right_mem_uIcc⟩ + · exact ⟨h.1 ▸ right_mem_uIcc, h.2⟩ + +/-- Note: try using `by simp` for `h`. -/ +lemma rectangle_disjoint_singleton {z w p : ℂ} + (h : (p.re < z.re ∧ p.re < w.re) ∨ (p.im < z.im ∧ p.im < w.im) ∨ + (z.re < p.re ∧ w.re < p.re) ∨ (z.im < p.im ∧ w.im < p.im)) : + Disjoint (Rectangle z w) {p} := by + refine disjoint_singleton_right.mpr (not_and_or.mpr ?_) + obtain h | h | h | h := h + · exact Or.inl (notMem_uIcc_of_lt h.1 h.2) + · exact Or.inr (notMem_uIcc_of_lt h.1 h.2) + · exact Or.inl (notMem_uIcc_of_gt h.1 h.2) + · exact Or.inr (notMem_uIcc_of_gt h.1 h.2) + +lemma rectangleBorder_disjoint_singleton {z w p : ℂ} + (h : p.re ≠ z.re ∧ p.re ≠ w.re ∧ p.im ≠ z.im ∧ p.im ≠ w.im) : + Disjoint (RectangleBorder z w) {p} := by + refine disjoint_singleton_right.mpr ?_ + simp_rw [RectangleBorder, Set.mem_union, not_or] + exact ⟨⟨⟨fun hc ↦ h.2.2.1 hc.2, fun hc ↦ h.1 hc.1⟩, fun hc ↦ h.2.2.2 hc.2⟩, + fun hc ↦ h.2.1 hc.1⟩ + +lemma rectangle_subset_punctured_rect {z₀ z₁ z₂ z₃ p : ℂ} + (hz : z₀.re ≤ z₁.re ∧ z₁.re ≤ z₂.re ∧ z₂.re ≤ z₃.re ∧ + z₀.im ≤ z₁.im ∧ z₁.im ≤ z₂.im ∧ z₂.im ≤ z₃.im) + (hp : (p.re < z₁.re ∧ p.re < z₂.re) ∨ (p.im < z₁.im ∧ p.im < z₂.im) ∨ + (z₁.re < p.re ∧ z₂.re < p.re) ∨ (z₁.im < p.im ∧ z₂.im < p.im)) : + Rectangle z₁ z₂ ⊆ Rectangle z₀ z₃ \ {p} := + Set.subset_sdiff.mpr ⟨by apply RectSubRect' <;> tauto, rectangle_disjoint_singleton hp⟩ + +lemma rectangleBorder_subset_punctured_rect {z₀ z₁ z₂ z₃ p : ℂ} + (hz : z₀.re ≤ z₁.re ∧ z₁.re ≤ z₂.re ∧ z₂.re ≤ z₃.re ∧ + z₀.im ≤ z₁.im ∧ z₁.im ≤ z₂.im ∧ z₂.im ≤ z₃.im) + (hp : p.re ≠ z₁.re ∧ p.re ≠ z₂.re ∧ p.im ≠ z₁.im ∧ p.im ≠ z₂.im) : + RectangleBorder z₁ z₂ ⊆ Rectangle z₀ z₃ \ {p} := + Set.subset_sdiff.mpr ⟨ + (rectangleBorder_subset_rectangle _ _).trans (by apply RectSubRect' <;> tauto), + rectangleBorder_disjoint_singleton hp⟩ + +lemma rectangle_mem_nhds_iff {z w p : ℂ} : + Rectangle z w ∈ 𝓝 p ↔ p ∈ (Set.uIoo z.re w.re) ×ℂ (Set.uIoo z.im w.im) := by + simp_rw [← mem_interior_iff_mem_nhds, Rectangle, Complex.interior_reProdIm, uIoo, uIcc, + interior_Icc] + +lemma mapsTo_rectangle_left_re (z w : ℂ) : + MapsTo (fun (y : ℝ) => ↑z.re + ↑y * I) [[z.im, w.im]] (Rectangle z w) := + fun _ hx ↦ ⟨by simp, by simp [hx]⟩ + +lemma mapsTo_rectangle_right_re (z w : ℂ) : + MapsTo (fun (y : ℝ) => ↑w.re + ↑y * I) [[z.im, w.im]] (Rectangle z w) := + fun _ hx ↦ ⟨by simp, by simp [hx]⟩ + +lemma mapsTo_rectangle_left_im (z w : ℂ) : + MapsTo (fun (x : ℝ) => ↑x + z.im * I) [[z.re, w.re]] (Rectangle z w) := + fun _ hx ↦ ⟨by simp [hx], by simp⟩ + +lemma mapsTo_rectangle_right_im (z w : ℂ) : + MapsTo (fun (x : ℝ) => ↑x + w.im * I) [[z.re, w.re]] (Rectangle z w) := + fun _ hx ↦ ⟨by simp [hx], by simp⟩ + +lemma mapsTo_rectangleBorder_left_re (z w : ℂ) : + MapsTo (fun (y : ℝ) => ↑z.re + ↑y * I) [[z.im, w.im]] (RectangleBorder z w) := + (Set.mapsTo_image _ _).mono subset_rfl fun _ ↦ + by simp_all [verticalSegment_eq, RectangleBorder] + +lemma mapsTo_rectangleBorder_right_re (z w : ℂ) : + MapsTo (fun (y : ℝ) => ↑w.re + ↑y * I) [[z.im, w.im]] (RectangleBorder z w) := + (Set.mapsTo_image _ _).mono subset_rfl fun _ ↦ + by simp_all [verticalSegment_eq, RectangleBorder] + +lemma mapsTo_rectangleBorder_left_im (z w : ℂ) : + MapsTo (fun (x : ℝ) => ↑x + z.im * I) [[z.re, w.re]] (RectangleBorder z w) := + (Set.mapsTo_image _ _).mono subset_rfl fun _ ↦ + by simp_all [horizontalSegment_eq, RectangleBorder] + +lemma mapsTo_rectangleBorder_right_im (z w : ℂ) : + MapsTo (fun (x : ℝ) => ↑x + w.im * I) [[z.re, w.re]] (RectangleBorder z w) := + (Set.mapsTo_image _ _).mono subset_rfl fun _ ↦ + by simp_all [horizontalSegment_eq, RectangleBorder] + +lemma mapsTo_rectangle_left_re_NoP (z w : ℂ) {p : ℂ} + (pNotOnBorder : p ∉ RectangleBorder z w) : + MapsTo (fun (y : ℝ) => ↑z.re + ↑y * I) [[z.im, w.im]] (Rectangle z w \ {p}) := by + refine (mapsTo_rectangleBorder_left_re z w).mono_right (Set.subset_sdiff.mpr ?_) + exact ⟨rectangleBorder_subset_rectangle z w, disjoint_singleton_right.mpr pNotOnBorder⟩ + +lemma mapsTo_rectangle_right_re_NoP (z w : ℂ) {p : ℂ} + (pNotOnBorder : p ∉ RectangleBorder z w) : + MapsTo (fun (y : ℝ) => ↑w.re + ↑y * I) [[z.im, w.im]] (Rectangle z w \ {p}) := by + refine (mapsTo_rectangleBorder_right_re z w).mono_right (Set.subset_sdiff.mpr ?_) + exact ⟨rectangleBorder_subset_rectangle z w, disjoint_singleton_right.mpr pNotOnBorder⟩ + +lemma mapsTo_rectangle_left_im_NoP (z w : ℂ) {p : ℂ} + (pNotOnBorder : p ∉ RectangleBorder z w) : + MapsTo (fun (x : ℝ) => ↑x + z.im * I) [[z.re, w.re]] (Rectangle z w \ {p}) := by + refine (mapsTo_rectangleBorder_left_im z w).mono_right (Set.subset_sdiff.mpr ?_) + exact ⟨rectangleBorder_subset_rectangle z w, disjoint_singleton_right.mpr pNotOnBorder⟩ + +lemma mapsTo_rectangle_right_im_NoP (z w : ℂ) {p : ℂ} + (pNotOnBorder : p ∉ RectangleBorder z w) : + MapsTo (fun (x : ℝ) => ↑x + w.im * I) [[z.re, w.re]] (Rectangle z w \ {p}) := by + refine (mapsTo_rectangleBorder_right_im z w).mono_right (Set.subset_sdiff.mpr ?_) + exact ⟨rectangleBorder_subset_rectangle z w, disjoint_singleton_right.mpr pNotOnBorder⟩ + +theorem not_mem_rectangleBorder_of_rectangle_mem_nhds {z w p : ℂ} + (hp : Rectangle z w ∈ 𝓝 p) : + p ∉ RectangleBorder z w := by + refine Set.disjoint_right.mp (rectangleBorder_disjoint_singleton ?_) rfl + have h1 := rectangle_mem_nhds_iff.mp hp + exact ⟨Set.ne_left_of_mem_uIoo h1.1, Set.ne_right_of_mem_uIoo h1.1, + Set.ne_left_of_mem_uIoo h1.2, Set.ne_right_of_mem_uIoo h1.2⟩ + +theorem _root_.Complex.nhds_hasBasis_square (p : ℂ) : (𝓝 p).HasBasis (0 < ·) (Square p ·) := by + suffices + (𝓝 p.re ×ˢ 𝓝 p.im).HasBasis (0 < ·) + (equivRealProdCLM.symm.toHomeomorph ⁻¹' Square p ·) + by simpa only [← nhds_prod_eq, Homeomorph.map_nhds_eq, Homeomorph.image_preimage] + using! this.map equivRealProdCLM.symm.toHomeomorph + apply ((nhds_basis_Icc_pos p.re).prod_same_index_mono (nhds_basis_Icc_pos p.im) ?_ ?_).congr + · intro; rfl + · intros + rw [← uIcc_of_lt (by linarith), ← uIcc_of_lt (by linarith)] + simpa [Square, Rectangle] using by ring_nf + all_goals exact (antitone_const_tsub.Icc (monotone_id.const_add _)).monotoneOn _ + +lemma square_mem_nhds (p : ℂ) {c : ℝ} (hc : c ≠ 0) : + Square p c ∈ 𝓝 p := by + wlog hc_pos : 0 < c generalizing c with h + · rw [← square_neg] + exact h (neg_ne_zero.mpr hc) <| neg_pos.mpr <| hc.lt_of_le <| not_lt.mp hc_pos + exact (Complex.nhds_hasBasis_square p).mem_of_mem hc_pos + +lemma square_subset_square {p : ℂ} {c₁ c₂ : ℝ} (hc₁ : 0 < c₁) (hc : c₁ ≤ c₂) : + Square p c₁ ⊆ Square p c₂ := by + apply RectSubRect' <;> simpa using by linarith + +lemma SmallSquareInRectangle {z w p : ℂ} (pInRectInterior : Rectangle z w ∈ nhds p) : + ∀ᶠ (c : ℝ) in 𝓝[>]0, Square p c ⊆ Rectangle z w := by + obtain ⟨ε, hε0, hε⟩ := ((Complex.nhds_hasBasis_square p).1 _).mp pInRectInterior + filter_upwards [Ioo_mem_nhdsGT (hε0)] with _ ⟨hε'0, hε'⟩ + exact subset_trans (square_subset_square hε'0 hε'.le) hε + +end IwaniecLinearSievePNT diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean new file mode 100644 index 000000000..a20b13f57 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean @@ -0,0 +1,1301 @@ +/- +Copyright (c) 2026 PrimeNumberTheoremAnd contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: PrimeNumberTheoremAnd contributors +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.Rectangle +public import Mathlib.Analysis.Meromorphic.Order +public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Arctan +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic +import Mathlib.Analysis.Complex.RemovableSingularity +import Mathlib.Analysis.Meromorphic.NormalForm +import Mathlib.Analysis.SpecialFunctions.Integrals.Basic + +/-! +Adapted from PrimeNumberTheoremAnd revision +`127b50e33f6033e2147921167a117af96d9ba4ea`, via Jason Davies's +Iwaniec linear sieve snapshot `c8d01549d2ae640b36ec198c1f0f6495f1b036cf` +(both Apache-2.0). Blueprint-only machinery is omitted. + +Supporting lemmas for Iwaniec's sieve and its prime-number-theorem input. +-/ + +@[expose] public section + +namespace IwaniecLinearSievePNT + + +open Complex BigOperators Nat Real Topology Filter +open Set MeasureTheory intervalIntegral Asymptotics + +open scoped Interval + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] {f g : ℂ → E} {z w p c A : ℂ} + {x x₁ x₂ y y₁ y₂ σ : ℝ} + +/-- The contour integral along a horizontal line segment. -/ +noncomputable def HIntegral (f : ℂ → E) (x₁ x₂ y : ℝ) : E := + ∫ x in x₁..x₂, f (x + y * I) + +/-- The contour integral along a vertical line segment, including its tangent factor `I`. -/ +noncomputable def VIntegral (f : ℂ → E) (x y₁ y₂ : ℝ) : E := + I • ∫ y in y₁..y₂, f (x + y * I) + +/-- The horizontal contour integral normalized by `1 / (2 * π * I)`. -/ +noncomputable def HIntegral' (f : ℂ → E) (x₁ x₂ y : ℝ) : E := + (1 / (2 * π * I)) • HIntegral f x₁ x₂ y + +/-- The vertical contour integral normalized by `1 / (2 * π * I)`. -/ +noncomputable def VIntegral' (f : ℂ → E) (x y₁ y₂ : ℝ) : E := + (1 / (2 * π * I)) • VIntegral f x y₁ y₂ + +lemma HIntegral_symm : + HIntegral f x₁ x₂ y = -HIntegral f x₂ x₁ y := integral_symm _ _ + +lemma VIntegral_symm : + VIntegral f x y₁ y₂ = -VIntegral f x y₂ y₁ := by + simp_rw [VIntegral, integral_symm y₁ y₂, smul_neg, neg_neg] + +/-- A `RectangleIntegral` of a function `f` is one over a rectangle + determined by `z` and `w` in `ℂ`. -/ +/- +A RectangleIntegral of a function $f$ is one over a rectangle + determined by $z$ and $w$ in $\C$. + We will sometimes denote it by $\int_{z}^{w} f$. + (There is also a primed version, which is + $1/(2\pi i)$ times the original.) +-/ +noncomputable def RectangleIntegral (f : ℂ → E) (z w : ℂ) : E := + HIntegral f z.re w.re z.im - HIntegral f z.re w.re w.im + + VIntegral f w.re z.im w.im - VIntegral f z.re z.im w.im + +/-- A `RectangleIntegral'` of a function `f` is one over a rectangle + determined by `z` and `w` in `ℂ`, divided by `2 * π * I`. -/ +noncomputable abbrev RectangleIntegral' (f : ℂ → E) (z w : ℂ) : E := + (1 / (2 * π * I)) • RectangleIntegral f z w + +/- An UpperUIntegral is the integral of a function over a |\_| shape. -/ +/- +An UpperUIntegral of a function $f$ comes from + $\sigma+i\infty$ down to $\sigma+iT$, over to + $\sigma'+iT$, and back up to $\sigma'+i\infty$. +-/ +/-- The contour integral over the upper U-shaped contour, oriented from left to right. -/ +noncomputable def UpperUIntegral (f : ℂ → E) (σ σ' T : ℝ) : E := + HIntegral f σ σ' T + + I • (∫ y : ℝ in Ici T, f (σ' + y * I)) - + I • (∫ y : ℝ in Ici T, f (σ + y * I)) + +/- A LowerUIntegral is the integral of a function over a |-| shape. -/ +/- +A LowerUIntegral of a function $f$ comes from + $\sigma-i\infty$ up to $\sigma-iT$, over to + $\sigma'-iT$, and back down to $\sigma'-i\infty$. +-/ +/-- The contour integral over the lower U-shaped contour, oriented from left to right. -/ +noncomputable def LowerUIntegral (f : ℂ → E) (σ σ' T : ℝ) : E := + HIntegral f σ σ' (-T) - + I • (∫ y : ℝ in Iic (-T), f (σ' + y * I)) + + I • (∫ y : ℝ in Iic (-T), f (σ + y * I)) + +/- +It is very convenient to define integrals along vertical lines +in the complex plane, as follows. +-/ +/- +Let $f$ be a function from $\mathbb{C}$ to $\mathbb{C}$, + and let $\sigma$ be a real number. Then we define + $$\int_{(\sigma)}f(s)ds = + \int_{\sigma-i\infty}^{\sigma+i\infty}f(s)ds.$$ +-/ +/-- The contour integral over the entire upward vertical line with real part `σ`. -/ +noncomputable def VerticalIntegral (f : ℂ → E) (σ : ℝ) : E := + I • ∫ t : ℝ, f (σ + t * I) + +/- +We also have a version with a factor of $1/(2\pi i)$. -/ +/-- The full vertical contour integral normalized by `1 / (2 * π * I)`. -/ +noncomputable abbrev VerticalIntegral' (f : ℂ → E) (σ : ℝ) : E := + (1 / (2 * π * I)) • VerticalIntegral f σ + +lemma verticalIntegral_split_three (a b : ℝ) + (hf : Integrable (fun t : ℝ ↦ f (σ + t * I))) : + VerticalIntegral f σ = + I • (∫ t in Iic a, f (σ + t * I)) + VIntegral f σ a b + + I • ∫ t in Ici b, f (σ + t * I) := by + simp_rw [VerticalIntegral, VIntegral, ← smul_add] + congr + rw [← integral_Iic_sub_Iic hf.restrict hf.restrict, add_sub_cancel, + integral_Iic_eq_integral_Iio, integral_Iio_add_Ici hf.restrict hf.restrict] + +/- +The difference of two vertical integrals and a rectangle is + the difference of an upper and a lower U integrals. +Follows directly from the definitions. +-/ +lemma DiffVertRect_eq_UpperLowerUs {σ σ' T : ℝ} + (f_int_σ : Integrable (fun (t : ℝ) ↦ f (σ + t * I))) + (f_int_σ' : Integrable (fun (t : ℝ) ↦ f (σ' + t * I))) : + VerticalIntegral f σ' - VerticalIntegral f σ - + RectangleIntegral f (σ - I * T) (σ' + I * T) = + UpperUIntegral f σ σ' T - LowerUIntegral f σ σ' T := by + rw [verticalIntegral_split_three (-T) T f_int_σ, verticalIntegral_split_three (-T) T f_int_σ'] + simp only [RectangleIntegral, UpperUIntegral, LowerUIntegral] + simp only [sub_re, mul_re, I_re, add_re, ofReal_re, I_im, ofReal_im, sub_im, mul_im, add_im] + ring_nf + abel + +/-- A function is `HolomorphicOn` a set if it is complex + differentiable on that set. -/ +abbrev HolomorphicOn (f : ℂ → E) (s : Set ℂ) : Prop := + DifferentiableOn ℂ f s + +/- +If $f$ is differentiable on a set $s$ except at $c\in s$, + and $f$ is bounded above on $s\setminus\{c\}$, then there + exists a differentiable function $g$ on $s$ such that $f$ + and $g$ agree on $s\setminus\{c\}$. +This is the Riemann Removable Singularity Theorem, slightly + rephrased from what's in Mathlib. (We don't care what the + function $g$ is, just that it's holomorphic.) +-/ +theorem existsDifferentiableOn_of_bddAbove [CompleteSpace E] + {s : Set ℂ} {c : ℂ} (hc : s ∈ nhds c) + (hd : HolomorphicOn f (s \ {c})) + (hb : BddAbove (norm ∘ f '' (s \ {c}))) : + ∃ (g : ℂ → E), + HolomorphicOn g s ∧ Set.EqOn f g (s \ {c}) := + ⟨Function.update f c (limUnder (𝓝[{c}ᶜ] c) f), + differentiableOn_update_limUnder_of_bddAbove hc hd hb, + fun z hz ↦ if h : z = c then (hz.2 h).elim + else by simp [h]⟩ + +/- +If $f$ is holomorphic on a rectangle $z$ and $w$, then the + integral of $f$ over the rectangle with corners $z$ and $w$ + is $0$. +This is in a Mathlib PR. +-/ +theorem HolomorphicOn.vanishesOnRectangle + {U : Set ℂ} (f_holo : HolomorphicOn f U) + (hU : Rectangle z w ⊆ U) : + RectangleIntegral f z w = 0 := + integral_boundary_rect_eq_zero_of_differentiableOn f z w + (f_holo.mono hU) + +theorem RectangleIntegral_congr (h : Set.EqOn f g (RectangleBorder z w)) : + RectangleIntegral f z w = RectangleIntegral g z w := by + unfold RectangleIntegral VIntegral + congrm ?_ - ?_ + I • ?_ - I • ?_ + all_goals refine integral_congr fun _ _ ↦ h ?_ + · exact Or.inl <| Or.inl <| Or.inl ⟨by simpa, by simp⟩ + · exact Or.inl <| Or.inr ⟨by simpa, by simp⟩ + · exact Or.inr ⟨by simp, by simpa⟩ + · exact Or.inl <| Or.inl <| Or.inr ⟨by simp, by simpa⟩ + +theorem RectangleIntegral'_congr (h : Set.EqOn f g (RectangleBorder z w)) : + RectangleIntegral' f z w = RectangleIntegral' g z w := by + rw [RectangleIntegral', RectangleIntegral_congr h] + +theorem rectangleIntegral_symm (f : ℂ → E) (z w : ℂ) : + RectangleIntegral f z w = RectangleIntegral f w z := by + simp_rw [RectangleIntegral, HIntegral, VIntegral, intervalIntegral.integral_symm w.re, + intervalIntegral.integral_symm w.im, sub_neg_eq_add, smul_neg, sub_neg_eq_add, + ← sub_eq_add_neg, neg_add_eq_sub, sub_add_eq_add_sub] + +theorem rectangleIntegral_symm_re (f : ℂ → E) (z w : ℂ) : + RectangleIntegral f (w.re + z.im * I) (z.re + w.im * I) = -RectangleIntegral f z w := by + simp only [RectangleIntegral, add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, + mul_one, sub_self, add_zero, add_im, mul_im, zero_add, neg_sub, ← sub_eq_zero, sub_zero] + rw [HIntegral_symm (y := z.im), HIntegral_symm (y := w.im)] + abel + +/-- Integrability of the integrand on each of the four sides of a rectangle. -/ +def RectangleBorderIntegrable (f : ℂ → E) (z w : ℂ) : Prop := + IntervalIntegrable (fun x => f (x + z.im * I)) volume z.re w.re ∧ + IntervalIntegrable (fun x => f (x + w.im * I)) volume z.re w.re ∧ + IntervalIntegrable (fun y => f (w.re + y * I)) volume z.im w.im ∧ + IntervalIntegrable (fun y => f (z.re + y * I)) volume z.im w.im + +theorem RectangleBorderIntegrable.add {f g : ℂ → E} + (hf : RectangleBorderIntegrable f z w) (hg : RectangleBorderIntegrable g z w) : + RectangleIntegral (f + g) z w = RectangleIntegral f z w + RectangleIntegral g z w := by + dsimp [RectangleIntegral, HIntegral, VIntegral] + have h₁ := intervalIntegral.integral_add hf.1 hg.1 + have h₂ := intervalIntegral.integral_add hf.2.1 hg.2.1 + have h₃ := intervalIntegral.integral_add hf.2.2.1 hg.2.2.1 + have h₄ := intervalIntegral.integral_add hf.2.2.2 hg.2.2.2 + rw [h₁, h₂, h₃, h₄] + module + +omit [NormedSpace ℂ E] in +theorem _root_.ContinuousOn.rectangleBorder_integrable (hf : ContinuousOn f (RectangleBorder z w)) : + RectangleBorderIntegrable f z w := + ⟨(hf.comp (by fun_prop) (mapsTo_rectangleBorder_left_im z w)).intervalIntegrable, + (hf.comp (by fun_prop) (mapsTo_rectangleBorder_right_im z w)).intervalIntegrable, + (hf.comp (by fun_prop) (mapsTo_rectangleBorder_right_re z w)).intervalIntegrable, + (hf.comp (by fun_prop) (mapsTo_rectangleBorder_left_re z w)).intervalIntegrable⟩ + +omit [NormedSpace ℂ E] in +theorem _root_.ContinuousOn.rectangleBorderIntegrable (hf : ContinuousOn f (Rectangle z w)) : + RectangleBorderIntegrable f z w := + ContinuousOn.rectangleBorder_integrable (hf.mono (rectangleBorder_subset_rectangle z w)) + +omit [NormedSpace ℂ E] in +theorem _root_.ContinuousOn.rectangleBorderNoPIntegrable + (hf : ContinuousOn f (Rectangle z w \ {p})) (pNotOnBorder : p ∉ RectangleBorder z w) : + RectangleBorderIntegrable f z w := by + refine ContinuousOn.rectangleBorder_integrable (hf.mono (Set.subset_sdiff.mpr ?_)) + exact ⟨rectangleBorder_subset_rectangle z w, disjoint_singleton_right.mpr pNotOnBorder⟩ + +theorem HolomorphicOn.rectangleBorderIntegrable' + (hf : HolomorphicOn f (Rectangle z w \ {p})) (hp : Rectangle z w ∈ nhds p) : + RectangleBorderIntegrable f z w := + hf.continuousOn.rectangleBorderNoPIntegrable (not_mem_rectangleBorder_of_rectangle_mem_nhds hp) + +theorem HolomorphicOn.rectangleBorderIntegrable (hf : HolomorphicOn f (Rectangle z w)) : + RectangleBorderIntegrable f z w := hf.continuousOn.rectangleBorderIntegrable + +/-- Given `x₀ a x₁ : ℝ`, and `y₀ y₁ : ℝ` and a function +`f : ℂ → ℂ` so that both `(t : ℝ) ↦ f(t + y₀ * I)` and +`(t : ℝ) ↦ f(t + y₁ * I)` are integrable over both +`t ∈ Icc x₀ a` and `t ∈ Icc a x₁`, we have that +`RectangleIntegral f (x₀ + y₀ * I) (x₁ + y₁ * I)` is the sum of +`RectangleIntegral f (x₀ + y₀ * I) (a + y₁ * I)` and +`RectangleIntegral f (a + y₀ * I) (x₁ + y₁ * I)`. -/ +lemma RectangleIntegralHSplit {a x₀ x₁ y₀ y₁ : ℝ} + (f_int_x₀_a_bot : IntervalIntegrable (fun x => f (↑x + ↑y₀ * I)) volume x₀ a) + (f_int_a_x₁_bot : IntervalIntegrable (fun x => f (↑x + ↑y₀ * I)) volume a x₁) + (f_int_x₀_a_top : IntervalIntegrable (fun x => f (↑x + ↑y₁ * I)) volume x₀ a) + (f_int_a_x₁_top : IntervalIntegrable (fun x => f (↑x + ↑y₁ * I)) volume a x₁) : + RectangleIntegral f (x₀ + y₀ * I) (x₁ + y₁ * I) = + RectangleIntegral f (x₀ + y₀ * I) (a + y₁ * I) + + RectangleIntegral f (a + y₀ * I) (x₁ + y₁ * I) := by + dsimp [RectangleIntegral, HIntegral, VIntegral] + simp only [Complex.mul_re, Complex.mul_im, Complex.ofReal_re, Complex.ofReal_im, Complex.I_re, + Complex.I_im, mul_one, mul_zero, add_zero, zero_add, sub_self] + have h₁ := integral_add_adjacent_intervals f_int_x₀_a_bot f_int_a_x₁_bot + have h₂ := integral_add_adjacent_intervals f_int_x₀_a_top f_int_a_x₁_top + have h₁' : + (∫ (x : ℝ) in x₀..a, f (↑x + ↑y₀ * I)) + + ∫ (x : ℝ) in a..x₁, f (↑y₀ * I + ↑x) = + ∫ (x : ℝ) in x₀..x₁, f (↑x + ↑y₀ * I) := by + simpa [add_comm] using h₁ + have h₂' : + (∫ (x : ℝ) in x₀..a, f (↑x + ↑y₁ * I)) + + ∫ (x : ℝ) in a..x₁, f (↑y₁ * I + ↑x) = + ∫ (x : ℝ) in x₀..x₁, f (↑x + ↑y₁ * I) := by + simpa [add_comm] using h₂ + rw [← h₁', ← h₂'] + have hcomm₁ : + ∫ (x : ℝ) in a..x₁, f (↑y₀ * I + ↑x) = + ∫ (x : ℝ) in a..x₁, f (↑x + ↑y₀ * I) := by + apply intervalIntegral.integral_congr + intro x _ + exact congrArg f (by ring) + have hcomm₂ : + ∫ (x : ℝ) in a..x₁, f (↑y₁ * I + ↑x) = + ∫ (x : ℝ) in a..x₁, f (↑x + ↑y₁ * I) := by + apply intervalIntegral.integral_congr + intro x _ + exact congrArg f (by ring) + rw [hcomm₁, hcomm₂] + abel + +lemma RectangleIntegralHSplit' {a x₀ x₁ y₀ y₁ : ℝ} + (ha : a ∈ [[x₀, x₁]]) + (hf : RectangleBorderIntegrable f (↑x₀ + ↑y₀ * I) (↑x₁ + ↑y₁ * I)) : + RectangleIntegral f (x₀ + y₀ * I) (x₁ + y₁ * I) = + RectangleIntegral f (x₀ + y₀ * I) (a + y₁ * I) + + RectangleIntegral f (a + y₀ * I) (x₁ + y₁ * I) := + RectangleIntegralHSplit + (IntervalIntegrable.mono (by simpa using hf.1) (uIcc_subset_uIcc left_mem_uIcc ha) le_rfl) + (IntervalIntegrable.mono (by simpa using hf.1) (uIcc_subset_uIcc ha right_mem_uIcc) le_rfl) + (IntervalIntegrable.mono (by simpa using hf.2.1) (uIcc_subset_uIcc left_mem_uIcc ha) le_rfl) + (IntervalIntegrable.mono (by simpa using hf.2.1) (uIcc_subset_uIcc ha right_mem_uIcc) le_rfl) + +lemma RectangleIntegralVSplit {b x₀ x₁ y₀ y₁ : ℝ} + (f_int_y₀_b_left : IntervalIntegrable (fun y => f (x₀ + y * I)) volume y₀ b) + (f_int_b_y₁_left : IntervalIntegrable (fun y => f (x₀ + y * I)) volume b y₁) + (f_int_y₀_b_right : IntervalIntegrable (fun y => f (x₁ + y * I)) volume y₀ b) + (f_int_b_y₁_right : IntervalIntegrable (fun y => f (x₁ + y * I)) volume b y₁) : + RectangleIntegral f (x₀ + y₀ * I) (x₁ + y₁ * I) = + RectangleIntegral f (x₀ + y₀ * I) (x₁ + b * I) + + RectangleIntegral f (x₀ + b * I) (x₁ + y₁ * I) := by + dsimp [RectangleIntegral, HIntegral, VIntegral] + simp only [Complex.mul_re, Complex.mul_im, Complex.ofReal_re, Complex.ofReal_im, Complex.I_re, + Complex.I_im, mul_one, mul_zero, add_zero, zero_add, sub_self] + have h₁ := integral_add_adjacent_intervals f_int_y₀_b_left f_int_b_y₁_left + have h₂ := integral_add_adjacent_intervals f_int_y₀_b_right f_int_b_y₁_right + rw [← h₁, ← h₂] + module + +lemma RectangleIntegralVSplit' {b x₀ x₁ y₀ y₁ : ℝ} + (hb : b ∈ [[y₀, y₁]]) + (hf : RectangleBorderIntegrable f (↑x₀ + ↑y₀ * I) (↑x₁ + ↑y₁ * I)) : + RectangleIntegral f (x₀ + y₀ * I) (x₁ + y₁ * I) = + RectangleIntegral f (x₀ + y₀ * I) (x₁ + b * I) + + RectangleIntegral f (x₀ + b * I) (x₁ + y₁ * I) := + RectangleIntegralVSplit + (IntervalIntegrable.mono (by simpa using hf.2.2.2) (uIcc_subset_uIcc left_mem_uIcc hb) le_rfl) + (IntervalIntegrable.mono (by simpa using hf.2.2.2) (uIcc_subset_uIcc hb right_mem_uIcc) le_rfl) + (IntervalIntegrable.mono (by simpa using hf.2.2.1) (uIcc_subset_uIcc left_mem_uIcc hb) le_rfl) + (IntervalIntegrable.mono (by simpa using hf.2.2.1) (uIcc_subset_uIcc hb right_mem_uIcc) le_rfl) + +lemma RectanglePullToNhdOfPole' {z₀ z₁ z₂ z₃ p : ℂ} + (h_orientation : z₀.re ≤ z₃.re ∧ z₀.im ≤ z₃.im ∧ + z₁.re ≤ z₂.re ∧ z₁.im ≤ z₂.im) + (hp : Rectangle z₁ z₂ ∈ 𝓝 p) (hz : Rectangle z₁ z₂ ⊆ Rectangle z₀ z₃) + (fHolo : HolomorphicOn f (Rectangle z₀ z₃ \ {p})) : + RectangleIntegral f z₀ z₃ = RectangleIntegral f z₁ z₂ := by + obtain ⟨hz₀_re, hz₀_im, hz₁_re, hz₁_im⟩ := h_orientation + have := rect_subset_iff.mp hz + rw [Rectangle, uIcc_of_le hz₀_re, uIcc_of_le hz₀_im] at this + obtain ⟨⟨⟨_, _⟩, ⟨_, _⟩⟩, ⟨_, _⟩, ⟨_, _⟩⟩ := this + obtain ⟨⟨_, _⟩, ⟨_, _⟩⟩ := + (uIoo_of_le hz₁_re) ▸ (uIoo_of_le hz₁_im) ▸ rectangle_mem_nhds_iff.mp hp + obtain ⟨_, _, _, _⟩ := show + p.re < z₂.re ∧ p.re < z₃.re ∧ p.im < z₂.im ∧ p.im < z₃.im from + ⟨by linarith, by linarith, by linarith, by linarith⟩ + obtain ⟨_, _, _, _⟩ := show + z₀.re < p.re ∧ z₁.re < p.re ∧ z₀.im < p.im ∧ z₁.im < p.im from + ⟨by linarith, by linarith, by linarith, by linarith⟩ + have fCont := fHolo.continuousOn + have hbot : RectangleBorderIntegrable f (↑z₀.re + ↑z₀.im * I) + (↑z₃.re + ↑z₃.im * I) := by + refine ContinuousOn.rectangleBorder_integrable + (fCont.mono (rectangleBorder_subset_punctured_rect ?_ ?_)) + · simp_all + · simpa using ⟨by linarith, by linarith, by linarith, by linarith⟩ + have htop : RectangleBorderIntegrable f (↑z₀.re + ↑z₁.im * I) + (↑z₃.re + ↑z₃.im * I) := by + refine ContinuousOn.rectangleBorder_integrable + (fCont.mono (rectangleBorder_subset_punctured_rect ?_ ?_)) + · simp_all + · simpa using ⟨by linarith, by linarith, by linarith, by linarith⟩ + have hleft : RectangleBorderIntegrable f (↑z₀.re + ↑z₁.im * I) + (↑z₃.re + ↑z₂.im * I) := by + refine ContinuousOn.rectangleBorder_integrable + (fCont.mono (rectangleBorder_subset_punctured_rect ?_ ?_)) + · simp_all + · simpa using ⟨by linarith, by linarith, by linarith, by linarith⟩ + have hright : RectangleBorderIntegrable f (↑z₁.re + ↑z₁.im * I) + (↑z₃.re + ↑z₂.im * I) := by + refine ContinuousOn.rectangleBorder_integrable + (fCont.mono (rectangleBorder_subset_punctured_rect ?_ ?_)) + · simp_all + · simpa using ⟨by linarith, by linarith, by linarith, by linarith⟩ + have hbot' : z₁.im ∈ [[z₀.im, z₃.im]] := by + rw [Set.uIcc_of_le] + constructor + all_goals assumption + have htop' : z₂.im ∈ [[z₁.im, z₃.im]] := by + rw [Set.uIcc_of_le] + constructor + all_goals assumption + have hleft' : z₁.re ∈ [[z₀.re, z₃.re]] := by + rw [Set.uIcc_of_le] + constructor + all_goals assumption + have hright' : z₂.re ∈ [[z₁.re, z₃.re]] := by + rw [Set.uIcc_of_le] + constructor + all_goals assumption + have hbot'' : Rectangle (↑z₀.re + ↑z₀.im * I) (↑z₃.re + ↑z₁.im * I) ⊆ + Rectangle z₀ z₃ \ {p} := by + apply rectangle_subset_punctured_rect <;> simp_all + have htop'' : Rectangle (↑z₀.re + ↑z₂.im * I) (↑z₃.re + ↑z₃.im * I) ⊆ + Rectangle z₀ z₃ \ {p} := by + apply rectangle_subset_punctured_rect <;> simp_all + have hleft'' : Rectangle (↑z₀.re + ↑z₁.im * I) (↑z₁.re + ↑z₂.im * I) ⊆ + Rectangle z₀ z₃ \ {p} := by + apply rectangle_subset_punctured_rect <;> simp_all + have hright'' : Rectangle (↑z₂.re + ↑z₁.im * I) (↑z₃.re + ↑z₂.im * I) ⊆ + Rectangle z₀ z₃ \ {p} := by + apply rectangle_subset_punctured_rect <;> simp_all + have h₁ := RectangleIntegralVSplit' hbot' hbot + have h₂ := fHolo.vanishesOnRectangle hbot'' + have h₃ := RectangleIntegralVSplit' htop' htop + have h₄ := fHolo.vanishesOnRectangle htop'' + have h₅ := RectangleIntegralHSplit' hleft' hleft + have h₆ := fHolo.vanishesOnRectangle hleft'' + have h₇ := RectangleIntegralHSplit' hright' hright + have h₈ := fHolo.vanishesOnRectangle hright'' + simp only [re_add_im] at * + linear_combination (norm := abel) h₁ + h₂ + h₃ + h₄ + h₅ + h₆ + h₇ + h₈ + +/- +The next lemma allows to zoom a big rectangle down to a small +square, centered at a pole. +-/ +/-- Given `f` holomorphic on a rectangle `z` and `w` except at +a point `p`, the integral of `f` over the rectangle with +corners `z` and `w` is the same as the integral of `f` over a +small square centered at `p`. -/ +/- +If $f$ is holomorphic on a rectangle $z$ and $w$ except at + a point $p$, then the integral of $f$ over the rectangle + with corners $z$ and $w$ is the same as the integral of $f$ + over a small square centered at $p$. +Chop the big rectangle with two vertical cuts and two + horizontal cuts into smaller rectangles, the middle one + being the desired square. The integral over each of the + outer rectangles vanishes, since $f$ is holomorphic there. + (The constant $c$ being ``small enough'' here just means + that the inner square is strictly contained in the big + rectangle.) +-/ +lemma RectanglePullToNhdOfPole {z w p : ℂ} + (zRe_lt_wRe : z.re ≤ w.re) (zIm_lt_wIm : z.im ≤ w.im) + (hp : Rectangle z w ∈ 𝓝 p) (fHolo : HolomorphicOn f (Rectangle z w \ {p})) : + ∀ᶠ (c : ℝ) in 𝓝[>]0, + RectangleIntegral f z w = RectangleIntegral f (-c - I * c + p) (c + I * c + p) := by + filter_upwards [Ioo_mem_nhdsGT zero_lt_one, SmallSquareInRectangle hp] + intro c ⟨cpos, _⟩ hc + simp_rw [mul_comm I] + exact RectanglePullToNhdOfPole' (by simp_all [cpos.le]) + (square_mem_nhds p (ne_of_gt cpos)) hc fHolo + +lemma RectanglePullToNhdOfPole'' {z w p : ℂ} + (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : z.im ≤ w.im) + (pInRectInterior : Rectangle z w ∈ 𝓝 p) (fHolo : HolomorphicOn f (Rectangle z w \ {p})) : + ∀ᶠ (c : ℝ) in 𝓝[>]0, + RectangleIntegral' f z w = RectangleIntegral' f (-c - I * c + p) (c + I * c + p) := by + filter_upwards [RectanglePullToNhdOfPole zRe_le_wRe zIm_le_wIm pInRectInterior fHolo] with c h + simp_rw [RectangleIntegral', h] + +theorem ResidueTheoremAtOrigin_aux1c (a b : ℝ) : + let f : ℝ → ℂ := fun y => (y + I)⁻¹ + IntervalIntegrable f volume a b := + (ContinuousOn.inv₀ (by fun_prop) + (by simp [Complex.ext_iff])).intervalIntegrable + +theorem ResidueTheoremAtOrigin_aux1c' (a b : ℝ) : + let f : ℝ → ℂ := fun y => (y - I)⁻¹ + IntervalIntegrable f volume a b := + (ContinuousOn.inv₀ (by fun_prop) + (by simp [Complex.ext_iff])).intervalIntegrable + +theorem ResidueTheoremAtOrigin_aux2c (a b : ℝ) : + let f : ℝ → ℂ := fun y => (1 + y * I)⁻¹ + IntervalIntegrable f volume a b := + (ContinuousOn.inv₀ (by fun_prop) + (by simp [Complex.ext_iff])).intervalIntegrable + +theorem ResidueTheoremAtOrigin_aux2c' (a b : ℝ) : + let f : ℝ → ℂ := fun y => (-1 + y * I)⁻¹ + IntervalIntegrable f volume a b := + (ContinuousOn.inv₀ (by fun_prop) + (by simp [Complex.ext_iff])).intervalIntegrable + +theorem RectangleIntegral.const_smul (f : ℂ → E) (z w c : ℂ) : + RectangleIntegral (fun s => c • f s) z w = c • RectangleIntegral f z w := by + simp [RectangleIntegral, HIntegral, VIntegral, smul_add, smul_sub, smul_smul, mul_comm] + +theorem RectangleIntegral.const_mul' (f : ℂ → E) (z w c : ℂ) : + RectangleIntegral' (fun s => c • f s) z w = c • RectangleIntegral' f z w := by + simp [RectangleIntegral', RectangleIntegral.const_smul, smul_smul] + ring_nf + +theorem RectangleIntegral.translate (f : ℂ → E) (z w p : ℂ) : + RectangleIntegral (fun s => f (s - p)) z w = RectangleIntegral f (z - p) (w - p) := by + simp_rw [RectangleIntegral, HIntegral, VIntegral, sub_re, sub_im, + ← intervalIntegral.integral_comp_sub_right] + congr <;> ext <;> congr 1 <;> simp [Complex.ext_iff] + +theorem RectangleIntegral.translate' (f : ℂ → E) (z w p : ℂ) : + RectangleIntegral' (fun s => f (s - p)) z w = RectangleIntegral' f (z - p) (w - p) := by + simp_rw [RectangleIntegral', RectangleIntegral.translate] + +lemma _root_.Complex.inv_re_add_im : (x + y * I)⁻¹ = (x - I * y) / (x ^ 2 + y ^ 2) := by + rw [Complex.inv_def, div_eq_mul_inv] + congr <;> simp [conj_ofReal, normSq] <;> ring + +lemma sq_add_sq_ne_zero (hy : y ≠ 0) : x ^ 2 + y ^ 2 ≠ 0 := by + linarith [sq_nonneg x, sq_pos_iff.mpr hy] + +lemma continuous_self_div_sq_add_sq (hy : y ≠ 0) : + Continuous fun x => x / (x ^ 2 + y ^ 2) := + continuous_id.div (continuous_id.pow 2 |>.add continuous_const) (fun _ => sq_add_sq_ne_zero hy) + +lemma integral_self_div_sq_add_sq (hy : y ≠ 0) : + ∫ x in x₁..x₂, x / (x ^ 2 + y ^ 2) = + Real.log (x₂ ^ 2 + y ^ 2) / 2 - Real.log (x₁ ^ 2 + y ^ 2) / 2 := by + let f (x : ℝ) : ℝ := Real.log (x ^ 2 + y ^ 2) / 2 + have e1 {x} := HasDerivAt.add_const (y ^ 2) (by simpa using hasDerivAt_pow 2 x) + have e2 {x} : HasDerivAt f (x / (x ^ 2 + y ^ 2)) x := by + convert! (e1.log (sq_add_sq_ne_zero hy)).div_const 2 using 1 + field_simp + have e3 : deriv f = fun x => x / (x ^ 2 + y ^ 2) := funext (fun _ => e2.deriv) + have e4 : Continuous (deriv f) := by simpa only [e3] using continuous_self_div_sq_add_sq hy + simp_rw [← e2.deriv] + exact integral_deriv_eq_sub (fun _ _ => e2.differentiableAt) (e4.intervalIntegrable _ _) + +lemma integral_const_div_sq_add_sq (hy : y ≠ 0) : + ∫ x in x₁..x₂, y / (x ^ 2 + y ^ 2) = arctan (x₂ / y) - arctan (x₁ / y) := by + nth_rewrite 1 [← div_mul_cancel₀ x₁ hy, ← div_mul_cancel₀ x₂ hy] + simp_rw [← mul_integral_comp_mul_right, ← intervalIntegral.integral_const_mul, + ← integral_one_div_one_add_sq] + exact integral_congr fun x _ => by + field_simp + ring + +lemma integral_const_div_self_add_im (hy : y ≠ 0) : + ∫ x : ℝ in x₁..x₂, A / (x + y * I) = + A * (Real.log (x₂ ^ 2 + y ^ 2) / 2 - Real.log (x₁ ^ 2 + y ^ 2) / 2) - + A * I * (arctan (x₂ / y) - arctan (x₁ / y)) := by + have e1 {x : ℝ} : A / (x + y * I) = A * x / (x ^ 2 + y ^ 2) - A * I * y / (x ^ 2 + y ^ 2) := by + ring_nf + simp_rw [inv_re_add_im] + ring + have e2 : IntervalIntegrable (fun x ↦ A * x / (x ^ 2 + y ^ 2)) volume x₁ x₂ := by + apply Continuous.intervalIntegrable + simp_rw [mul_div_assoc] + norm_cast + exact continuous_const.mul (continuous_ofReal.comp (continuous_self_div_sq_add_sq hy)) + have e3 : IntervalIntegrable (fun x ↦ A * I * y / (x ^ 2 + y ^ 2)) volume x₁ x₂ := by + apply Continuous.intervalIntegrable + refine continuous_const.div (by fun_prop) (fun x => ?_) + norm_cast + exact sq_add_sq_ne_zero hy + simp_rw [integral_congr (fun _ _ => e1), integral_sub e2 e3, mul_div_assoc] + norm_cast + simp_rw [intervalIntegral.integral_const_mul, intervalIntegral.integral_ofReal, + integral_self_div_sq_add_sq hy, integral_const_div_sq_add_sq hy] + +lemma integral_const_div_re_add_self (hx : x ≠ 0) : + ∫ y : ℝ in y₁..y₂, A / (x + y * I) = + A / I * (Real.log (y₂ ^ 2 + (-x) ^ 2) / 2 - Real.log (y₁ ^ 2 + (-x) ^ 2) / 2) - + A / I * I * (arctan (y₂ / -x) - arctan (y₁ / -x)) := by + have l1 {y : ℝ} : A / (x + y * I) = A / I / (y + ↑(-x) * I) := by + have e1 : x + y * I ≠ 0 := by + contrapose! hx + simpa using congr_arg re hx + have e2 : y + I * ↑(-x) ≠ 0 := by + contrapose! hx + simpa using congr_arg im hx + field_simp [*] + push_cast + ring_nf + simp + have l2 : -x ≠ 0 := by rwa [neg_ne_zero] + simp_rw [l1, integral_const_div_self_add_im l2] + +lemma ResidueTheoremAtOrigin' {z w c : ℂ} + (h1 : z.re < 0) (h2 : z.im < 0) (h3 : 0 < w.re) (h4 : 0 < w.im) : + RectangleIntegral (fun s => c / s) z w = 2 * I * π * c := by + simp only [RectangleIntegral, HIntegral, VIntegral, smul_eq_mul] + rw [integral_const_div_re_add_self h1.ne, integral_const_div_re_add_self h3.ne.symm] + rw [integral_const_div_self_add_im h2.ne, integral_const_div_self_add_im h4.ne.symm] + have l1 : z.im * w.re⁻¹ = (w.re * z.im⁻¹)⁻¹ := by group + have l3 := arctan_inv_of_neg <| mul_neg_of_pos_of_neg h3 <| inv_lt_zero.mpr h2 + have l4 : w.im * z.re⁻¹ = (z.re * w.im⁻¹)⁻¹ := by group + have l6 := arctan_inv_of_neg <| mul_neg_of_neg_of_pos h1 <| inv_pos.mpr h4 + have r1 : z.im * z.re⁻¹ = (z.re * z.im⁻¹)⁻¹ := by group + have r3 := arctan_inv_of_pos <| mul_pos_of_neg_of_neg h1 <| inv_lt_zero.mpr h2 + have r4 : w.im * w.re⁻¹ = (w.re * w.im⁻¹)⁻¹ := by group + have r6 := arctan_inv_of_pos <| mul_pos h3 <| inv_pos.mpr h4 + ring_nf + simp only [one_div, inv_I, mul_neg, neg_mul, I_sq, neg_neg, arctan_neg, ofReal_neg, + sub_neg_eq_add] + rw [l1, l3, l4, l6, r1, r3, r4, r6] + ring_nf + simp only [I_sq, ofReal_sub, ofReal_mul, ofReal_ofNat, ofReal_div, ofReal_neg, ofReal_one] + ring_nf + +theorem ResidueTheoremInRectangle + (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : z.im ≤ w.im) + (pInRectInterior : Rectangle z w ∈ 𝓝 p) : + RectangleIntegral' (fun s => c / (s - p)) z w = c := by + simp only [rectangle_mem_nhds_iff, uIoo_of_le zRe_le_wRe, uIoo_of_le zIm_le_wIm, + mem_reProdIm, mem_Ioo] at pInRectInterior + rw [RectangleIntegral.translate', RectangleIntegral'] + have : 1 / (2 * ↑π * I) * (2 * I * ↑π * c) = c := by + field_simp + rwa [ResidueTheoremAtOrigin'] + all_goals simp [*] + +/- +The rectangle (square) integral of $f(s) = 1/s$ with + corners $-1-i$ and $1+i$ is equal to $2\pi i$. +This is a special case of the more general result above. +-/ +lemma ResidueTheoremAtOrigin : + RectangleIntegral' (fun s ↦ 1 / s) (-1 - I) (1 + I) = 1 := by + rw [RectangleIntegral', ResidueTheoremAtOrigin'] + all_goals simp [field] + +/- +Suppose that $f$ is a holomorphic function on a rectangle, + except for a simple pole at $p$. + By the latter, we mean that there is a function $g$ + holomorphic on the rectangle such that, + $f = g + A/(s-p)$ for some $A\in\C$. Then the integral of + $f$ over the rectangle is $A$. +Replace $f$ with $g + A/(s-p)$ in the integral. + The integral of $g$ vanishes by + Lemma \ref{HolomorphicOn.vanishesOnRectangle}. + To evaluate the integral of $1/(s-p)$, pull everything to a + square about the origin using + Lemma \ref{RectanglePullToNhdOfPole}, and rescale by $c$; + what remains is handled by + Lemma \ref{ResidueTheoremAtOrigin}. +-/ +lemma ResidueTheoremOnRectangleWithSimplePole {f g : ℂ → ℂ} {z w p A : ℂ} + (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : z.im ≤ w.im) + (pInRectInterior : Rectangle z w ∈ 𝓝 p) (gHolo : HolomorphicOn g (Rectangle z w)) + (principalPart : Set.EqOn (f - fun s ↦ A / (s - p)) g (Rectangle z w \ {p})) : + RectangleIntegral' f z w = A := by + have principalPart' : Set.EqOn f (g + (fun s ↦ A / (s - p))) (Rectangle z w \ {p}) := + fun s hs => by rw [Pi.add_apply, ← principalPart hs, Pi.sub_apply, sub_add_cancel] + have : Set.EqOn f (g + (fun s ↦ A / (s - p))) (RectangleBorder z w) := + principalPart'.mono <| Set.subset_sdiff.mpr + ⟨rectangleBorder_subset_rectangle z w, + disjoint_singleton_right.mpr + (not_mem_rectangleBorder_of_rectangle_mem_nhds pInRectInterior)⟩ + rw [RectangleIntegral'_congr this] + have t1 : RectangleBorderIntegrable g z w := + gHolo.rectangleBorderIntegrable + have t2 : HolomorphicOn (fun s ↦ A / (s - p)) (Rectangle z w \ {p}) := by + apply DifferentiableOn.mono (t := {p}ᶜ) + · apply DifferentiableOn.div + · exact differentiableOn_const _ + · exact DifferentiableOn.sub differentiableOn_id (differentiableOn_const _) + · exact fun x hx => by + rw [sub_ne_zero] + exact hx + · rintro s ⟨_, hs⟩ + exact hs + have t3 : RectangleBorderIntegrable (fun s ↦ A / (s - p)) z w := + HolomorphicOn.rectangleBorderIntegrable' t2 pInRectInterior + rw [RectangleIntegral', RectangleBorderIntegrable.add t1 t3, smul_add] + rw [gHolo.vanishesOnRectangle (by rfl), smul_zero, zero_add] + exact ResidueTheoremInRectangle zRe_le_wRe zIm_le_wIm pInRectInterior + +lemma IsBigO_to_BddAbove {f : ℂ → ℂ} {p : ℂ} + (f_near_p : f =O[𝓝[≠] p] (1 : ℂ → ℂ)) : + ∃ U ∈ 𝓝 p, BddAbove (norm ∘ f '' (U \ {p})) := by + simp only [isBigO_iff, Pi.one_apply, one_mem, CStarRing.norm_of_mem_unitary, mul_one] at f_near_p + obtain ⟨c, hc⟩ := f_near_p + dsimp [Filter.Eventually, nhdsWithin] at hc + rw [mem_inf_principal'] at hc + obtain ⟨U, hU, ⟨U_is_open, p_in_U⟩⟩ := mem_nhds_iff.mp hc + use U + constructor + · exact IsOpen.mem_nhds U_is_open p_in_U + · refine bddAbove_def.mpr ?_ + use c + intro y hy + simp only [Function.comp_apply, mem_image, Set.mem_sdiff, mem_singleton_iff] at hy + obtain ⟨x, ⟨x_in_U, x_not_p⟩, fxy⟩ := hy + rw [← fxy] + simpa [x_not_p] using hU x_in_U + +theorem BddAbove_on_rectangle_of_bdd_near {z w p : ℂ} {f : ℂ → ℂ} + (f_cont : ContinuousOn f (Rectangle z w \ {p})) + (f_near_p : f =O[𝓝[≠] p] (1 : ℂ → ℂ)) : + BddAbove (norm ∘ f '' (Rectangle z w \ {p})) := by + obtain ⟨V, V_in_nhds, V_prop⟩ := IsBigO_to_BddAbove f_near_p + rw [mem_nhds_iff] at V_in_nhds + obtain ⟨W, W_subset, W_open, p_in_W⟩ := V_in_nhds + set U := Rectangle z w + have : U \ {p} = (U \ W) ∪ ((U ∩ W) \ {p}) := by + ext x + simp only [Set.mem_sdiff, mem_singleton_iff, mem_union, mem_inter_iff] + constructor + · intro ⟨xu, x_not_p⟩ + tauto + · intro h + rcases h with ⟨h1, h2⟩ | ⟨⟨h1, h2⟩, h3⟩ + · refine ⟨h1, ?_⟩ + intro h + rw [← h] at p_in_W + exact h2 p_in_W + · tauto + rw [this, image_union] + apply BddAbove.union + · apply IsCompact.bddAbove_image + · apply IsCompact.diff _ W_open + exact IsCompact.reProdIm isCompact_uIcc isCompact_uIcc + · apply f_cont.norm.mono + apply Set.sdiff_subset_sdiff_right + simpa + · exact V_prop.mono + (image_mono <| Set.sdiff_subset_sdiff_left <| subset_trans inter_subset_right W_subset) + +theorem ResidueTheoremOnRectangleWithSimplePole' {f : ℂ → ℂ} {z w p A : ℂ} + (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : z.im ≤ w.im) + (pInRectInterior : Rectangle z w ∈ 𝓝 p) (fHolo : HolomorphicOn f (Rectangle z w \ {p})) + (near_p : (f - (fun s ↦ A / (s - p))) =O[𝓝[≠] p] (1 : ℂ → ℂ)) : + RectangleIntegral' f z w = A := by + set g := f - (fun s ↦ A / (s - p)) + have gHolo : HolomorphicOn g (Rectangle z w \ {p}) := by + apply DifferentiableOn.sub fHolo + intro s hs + have : s - p ≠ 0 := sub_ne_zero.mpr hs.2 + exact DifferentiableWithinAt.div (by fun_prop) (by fun_prop) this + have := BddAbove_on_rectangle_of_bdd_near gHolo.continuousOn near_p + obtain ⟨h, ⟨hHolo, hEq⟩⟩ := existsDifferentiableOn_of_bddAbove pInRectInterior gHolo this + exact ResidueTheoremOnRectangleWithSimplePole zRe_le_wRe zIm_le_wIm pInRectInterior hHolo hEq + +/-! ## Residue calculus: residues, simple poles, and the rectangle residue theorem + +The simple-pole `residue`, `sumResiduesIn`, the `HasSimplePolesOn` scaffold, and the rectangle +residue theorem `RectangleIntegral'_eq_sumResiduesIn`. Extracted from `CH2.lean` as general, +reusable contour-integration lemmas (see issue #1537). -/ + +/-- Every pole of `f` in `s` is at most simple: the meromorphic order is `≥ -1` everywhere on `s` +(no poles of order `≤ -2`). + +**Temporary scaffold.** The placeholder `residue` below (and Mathlib's current residue-theorem API) +is only correct for simple poles, so this hypothesis is added to Lemma 5.1 / Proposition 5.2 and +their sub-lemmas to make them provable with the present API. It holds in the intended applications +(e.g. `ζ'/ζ`, whose poles are all simple) and is to be removed once Mathlib gains general +higher-order residue support. -/ +def HasSimplePolesOn (f : ℂ → ℂ) (s : Set ℂ) : Prop := + ∀ z ∈ s, (-1 : ℤ) ≤ meromorphicOrderAt f z + +lemma HasSimplePolesOn.mono {f : ℂ → ℂ} {s t : Set ℂ} + (h : HasSimplePolesOn f t) (hst : s ⊆ t) : HasSimplePolesOn f s := by + intro z hz + exact h z (hst hz) + +/-- **Placeholder definition — valid only for simple poles.** The residue of `f` at `z₀`, defined +as the simple-pole limit `lim_{z → z₀} (z - z₀) · f z` (matching the convention of +`Phi_circ.residue` / `Phi_star.residue`). At a point of analyticity this is `0` and at a simple +pole it is the usual residue, but at a higher-order or essential singularity the limit diverges +and this returns a junk value. + +A general complex residue (and the residue theorem) is planned for Mathlib but not yet available, +so results stated in terms of this `residue` are likely **not provable in full generality** with +the current API. This is a deliberate stopgap, to be replaced with the robust notion once the +Mathlib residue-theorem API lands. -/ +noncomputable def residue (f : ℂ → ℂ) (z₀ : ℂ) : ℂ := + Filter.limUnder (nhdsWithin z₀ {z₀}ᶜ) (fun z ↦ (z - z₀) * f z) + +/-- The sum of residues of `f` over a region `S`, as a `tsum` over `S`. Points of analyticity +contribute `0`, so this is effectively the sum over the poles of `f` in `S`; when finitely many +poles lie in `S` the `tsum` equals the finite sum of their residues, regardless of `|S|`. (With +infinitely many poles, summability must be assumed for the value to be meaningful.) -/ +noncomputable def sumResiduesIn (f : ℂ → ℂ) (S : Set ℂ) : ℂ := + ∑' z : S, residue f z + +lemma residue_eq_of_tendsto {f : ℂ → ℂ} {p c : ℂ} + (h : Filter.Tendsto (fun z ↦ (z - p) * f z) (nhdsWithin p {p}ᶜ) (nhds c)) : + residue f p = c := by + unfold residue + exact h.limUnder_eq + +lemma residue_analyticAt_eq_zero {f : ℂ → ℂ} {p : ℂ} (hf : AnalyticAt ℂ f p) : + residue f p = 0 := by + apply residue_eq_of_tendsto + have hsub : Filter.Tendsto (fun z : ℂ ↦ z - p) (nhdsWithin p {p}ᶜ) (nhds 0) := + tendsto_sub_nhds_zero_iff.mpr (tendsto_id.mono_left nhdsWithin_le_nhds) + have hf' : Filter.Tendsto f (nhdsWithin p {p}ᶜ) (nhds (f p)) := + hf.continuousAt.continuousWithinAt.tendsto + simpa using hsub.mul hf' + +lemma simplePole_sub_residue_isBigO_one {f : ℂ → ℂ} {p : ℂ} + (hf : MeromorphicAt f p) (hord : meromorphicOrderAt f p = (-1 : ℤ)) : + (f - (fun z ↦ residue f p / (z - p))) =O[nhdsWithin p {p}ᶜ] (1 : ℂ → ℂ) := by + obtain ⟨g, hg_analytic, hg_ne, hg_eq⟩ := (meromorphicOrderAt_eq_int_iff hf).1 hord + have hres : residue f p = g p := + residue_eq_of_tendsto (hg_analytic.continuousAt.continuousWithinAt.tendsto.congr' + (show (fun z ↦ (z - p) * f z) =ᶠ[nhdsWithin p {p}ᶜ] g from by + filter_upwards [hg_eq, self_mem_nhdsWithin] with z hz hz_ne + simp [hz, sub_ne_zero.mpr hz_ne]).symm) + have hdslope : (fun z ↦ (z - p)⁻¹ * (g z - g p)) =O[nhdsWithin p {p}ᶜ] (1 : ℂ → ℂ) := by + have hcont : ContinuousAt (dslope g p) p := + continuousAt_dslope_same.2 hg_analytic.differentiableAt + have hbig : dslope g p =O[nhds p] (1 : ℂ → ℂ) := + hcont.norm.isBoundedUnder_le.isBigO_one ℂ + have hbig_ne : dslope g p =O[nhdsWithin p {p}ᶜ] (1 : ℂ → ℂ) := + IsBigO.mono hbig inf_le_left + simpa [slope] using! hbig_ne.congr' (dslope_eventuallyEq_slope_nhdsNE (f := g) (a := p)) .rfl + refine hdslope.congr' ?_ .rfl + filter_upwards [hg_eq, self_mem_nhdsWithin] with z hz hz_ne + simp [hz, hres, div_eq_mul_inv, sub_eq_add_neg]; ring + +-- If two functions `f g : ℂ → ℂ` agree on a `codiscreteWithin R` full set, and `φ : ℝ → ℂ` is +-- an analytic non-constant path mapping `[a,b]` into `R`, then `∫ f(φ x) dx = ∫ g(φ x) dx`. +-- (a.e. agreement along the preimage suffices for interval integrals) +private lemma intervalIntegral_congr_ae_of_codiscreteWithin_along_path + {f g : ℂ → ℂ} {R : Set ℂ} + (heq : {s : ℂ | f s = g s} ∈ Filter.codiscreteWithin R) + {a b : ℝ} {p : ℝ → ℂ} + (hp_an : AnalyticOnNhd ℝ p (Set.uIcc a b)) + (hp_nonconst : ∀ x ∈ Set.uIcc a b, ¬Filter.EventuallyConst p (nhds x)) + (hp_maps : Set.MapsTo p (Set.uIcc a b) R) : + ∫ x in a..b, f (p x) = ∫ x in a..b, g (p x) := by + refine intervalIntegral.integral_congr_ae_restrict (μ := volume) ?_ + apply ae_restrict_le_codiscreteWithin measurableSet_uIoc + change {x : ℝ | f (p x) = g (p x)} ∈ Filter.codiscreteWithin (Set.uIoc a b) + simpa [Set.preimage] using Filter.codiscreteWithin_mono Set.uIoc_subset_uIcc + (hp_an.preimage_mem_codiscreteWithin hp_nonconst + (Filter.codiscreteWithin_mono + (by intro s hs; rcases hs with ⟨x, hx, rfl⟩; exact hp_maps hx) heq)) + +-- Under `HasSimplePolesOn f U`, every point with strictly negative meromorphic order has order +-- exactly -1: the simple-pole hypothesis gives `(-1 : ℤ) ≤ order`, negativity gives `order < 0`, +-- so the only integer fitting both is -1. +private lemma meromorphicOrderAt_eq_neg_one_of_simplePole + {f : ℂ → ℂ} {U : Set ℂ} {p : ℂ} + (hpU : p ∈ U) + (hf_simple : HasSimplePolesOn f U) + (hpneg : meromorphicOrderAt f p < 0) : + meromorphicOrderAt f p = (-1 : ℤ) := by + lift meromorphicOrderAt f p to ℤ using hpneg.ne_top with n hn + have hsimple : (-1 : ℤ) ≤ n := WithTop.coe_le_coe.mp (hn ▸ hf_simple p hpU) + have hneg : n < 0 := by exact_mod_cast hpneg + have hn1 : n = -1 := by omega + simp [hn1] + +-- At a simple pole `p` of `f` inside `U`, the residue of the meromorphic normal form +-- `toMeromorphicNFOn f U` equals the residue of `f`. The two functions agree on a punctured +-- neighborhood of `p` (by definition of the normal form), so their `(z - p) * ·` limits coincide. +private lemma residue_toMeromorphicNFOn_eq_residue + {f : ℂ → ℂ} {U : Set ℂ} {p : ℂ} + (hpU : p ∈ U) + (hf_mero : MeromorphicOn f U) + (hf_simple : HasSimplePolesOn f U) + (hpneg : meromorphicOrderAt f p < 0) : + residue (toMeromorphicNFOn f U) p = residue f p := by + have hmero : MeromorphicAt f p := hf_mero p hpU + have h_exists : ∃ c, Filter.Tendsto (fun z : ℂ ↦ (z - p) * f z) (nhdsWithin p ({p}ᶜ)) (nhds c) + := by + have hmul_mero : MeromorphicAt (fun z : ℂ ↦ (z - p) * f z) p := + (by fun_prop : MeromorphicAt (fun z : ℂ ↦ z - p) p).mul hmero + have hmul_nonneg : 0 ≤ meromorphicOrderAt (fun z : ℂ ↦ (z - p) * f z) p := by + change 0 ≤ meromorphicOrderAt ((fun z ↦ z - p) * f) p + rw [meromorphicOrderAt_mul (by fun_prop : MeromorphicAt (fun z : ℂ ↦ z - p) p) hmero, + meromorphicOrderAt_id_sub_const, + meromorphicOrderAt_eq_neg_one_of_simplePole hpU hf_simple hpneg] + norm_num + exact tendsto_nhds_of_meromorphicOrderAt_nonneg hmul_mero hmul_nonneg + have h_tendsto : Filter.Tendsto (fun z : ℂ ↦ (z - p) * f z) (nhdsWithin p ({p}ᶜ)) (nhds (residue + f p)) := by + simpa [residue] using tendsto_nhds_limUnder h_exists + have h_eq : + (fun z ↦ (z - p) * toMeromorphicNFOn f U z) =ᶠ[nhdsWithin p ({p}ᶜ)] + (fun z ↦ (z - p) * f z) := by + filter_upwards [hf_mero.toMeromorphicNFOn_eq_self_on_nhdsNE hpU] with z hz + simp [hz] + exact residue_eq_of_tendsto + (h_tendsto.congr' h_eq.symm) + +-- Non-constancy of horizontal paths `x ↦ x + h * I`. +private lemma horizontalPath_not_eventuallyConst (h : ℝ) (x : ℝ) : + ¬Filter.EventuallyConst (fun r : ℝ ↦ (r : ℂ) + (h : ℂ) * Complex.I) (nhds x) := by + intro hc + obtain ⟨c, hc⟩ := Filter.eventuallyConst_iff_exists_eventuallyEq.1 hc + have hpath : HasDerivAt (fun r : ℝ ↦ (r : ℂ) + (h : ℂ) * Complex.I) 1 x := by + simpa using (Complex.ofRealCLM.hasDerivAt (x := x)).add_const ((h : ℂ) * Complex.I) + have hconst : HasDerivAt (fun r : ℝ ↦ (r : ℂ) + (h : ℂ) * Complex.I) 0 x := + (hasDerivAt_const x c).congr_of_eventuallyEq hc + exact one_ne_zero (hpath.unique hconst) + +-- Non-constancy of vertical paths `y ↦ r + y * I`. +lemma verticalPath_not_eventuallyConst (r : ℝ) (x : ℝ) : + ¬Filter.EventuallyConst (fun y : ℝ ↦ (r : ℂ) + (y : ℂ) * Complex.I) (nhds x) := by + intro hc + obtain ⟨c, hc⟩ := Filter.eventuallyConst_iff_exists_eventuallyEq.1 hc + have hpath : HasDerivAt (fun y : ℝ ↦ (r : ℂ) + (y : ℂ) * Complex.I) Complex.I x := by + simpa using ((Complex.ofRealCLM.hasDerivAt (x := x)).mul_const Complex.I).const_add (r : ℂ) + have hconst : HasDerivAt (fun y : ℝ ↦ (r : ℂ) + (y : ℂ) * Complex.I) 0 x := + (hasDerivAt_const x c).congr_of_eventuallyEq hc + exact Complex.I_ne_zero (hpath.unique hconst) + +-- Helper for horizontal integral congruence on codiscrete set +private lemma HIntegral_congr_codiscreteWithin {f g : ℂ → ℂ} {R : Set ℂ} {a b c : ℝ} + (h_eq : {s : ℂ | f s = g s} ∈ Filter.codiscreteWithin R) + (hmaps : ∀ x ∈ Set.uIcc a b, (↑x + ↑c * Complex.I) ∈ R) : + HIntegral f a b c = HIntegral g a b c := by + unfold HIntegral + exact intervalIntegral_congr_ae_of_codiscreteWithin_along_path h_eq + (by intro x _; exact (Complex.ofRealCLM.analyticAt x).add analyticAt_const) + (fun x _ ↦ horizontalPath_not_eventuallyConst c x) hmaps + +-- Helper for vertical integral congruence on codiscrete set +private lemma VIntegral_congr_codiscreteWithin {f g : ℂ → ℂ} {R : Set ℂ} {c a b : ℝ} + (h_eq : {s : ℂ | f s = g s} ∈ Filter.codiscreteWithin R) + (hmaps : ∀ y ∈ Set.uIcc a b, (↑c + ↑y * Complex.I) ∈ R) : + VIntegral f c a b = VIntegral g c a b := by + unfold VIntegral; simp only [smul_eq_mul]; congr 1 + exact intervalIntegral_congr_ae_of_codiscreteWithin_along_path h_eq + (by intro y _; exact analyticAt_const.add ((Complex.ofRealCLM.analyticAt y).mul + analyticAt_const)) + (fun x _ ↦ verticalPath_not_eventuallyConst c x) hmaps + +-- At the boundary, `f` and its normal-form representative differ only at a discrete set +-- of poles, so their boundary integrals coincide. +private lemma rectangleIntegral'_toMeromorphicNFOn_eq {f : ℂ → ℂ} {z w : ℂ} + (f_mero : MeromorphicOn f (Rectangle z w)) : + RectangleIntegral' f z w = RectangleIntegral' (toMeromorphicNFOn f (Rectangle z w)) z w := by + classical + let R : Set ℂ := Rectangle z w + let fNF : ℂ → ℂ := toMeromorphicNFOn f R + have h_eq : {s : ℂ | f s = fNF s} ∈ Filter.codiscreteWithin R := by + simpa [Filter.EventuallyEq, Filter.Eventually, fNF] using + (toMeromorphicNFOn_eqOn_codiscrete (f := f) (U := R) f_mero) + have hbot := HIntegral_congr_codiscreteWithin h_eq + (by simpa [R] using! mapsTo_rectangle_left_im z w) + have htop := HIntegral_congr_codiscreteWithin h_eq + (by simpa [R] using! mapsTo_rectangle_right_im z w) + have hright := VIntegral_congr_codiscreteWithin h_eq + (by simpa [R] using! mapsTo_rectangle_right_re z w) + have hleft := VIntegral_congr_codiscreteWithin h_eq + (by simpa [R] using! mapsTo_rectangle_left_re z w) + unfold RectangleIntegral'; congr 1; unfold RectangleIntegral + rw [hbot, htop, hright, hleft] + +private lemma principalPart_meromorphicOn {R : Set ℂ} {polesFin : Finset ℂ} {c : ℂ → ℂ} : + MeromorphicOn (fun s ↦ ∑ p ∈ polesFin, c p / (s - p)) R := by + intro x _ + refine MeromorphicAt.fun_sum (G := fun p s ↦ c p / (s - p)) ?_ + intro p _ + exact (analyticAt_const.meromorphicAt.div + ((analyticAt_id.sub analyticAt_const).meromorphicAt)) + +private lemma sub_principalPart_analyticAt_of_not_mem_poles + {f : ℂ → ℂ} {polesFin : Finset ℂ} {x : ℂ} + (h_nf : MeromorphicNFAt f x) + (hxnp : x ∉ polesFin) + (hxneg : 0 ≤ meromorphicOrderAt f x) : + AnalyticAt ℂ (f - fun s ↦ ∑ p ∈ polesFin, residue f p / (s - p)) x := by + have h_f_analytic : AnalyticAt ℂ f x := + h_nf.meromorphicOrderAt_nonneg_iff_analyticAt.1 hxneg + have h_principal_analytic : AnalyticAt ℂ (fun s ↦ ∑ p ∈ polesFin, residue f p / (s - p)) x := by + refine Finset.analyticAt_fun_sum polesFin ?_ + intro p hp + have hxp : x ≠ p := by + intro heq + subst heq + exact hxnp hp + have : AnalyticAt ℂ (fun z : ℂ ↦ residue f p / (z - p)) x := by + fun_prop (disch := exact sub_ne_zero.mpr hxp) + simpa using this + exact h_f_analytic.sub h_principal_analytic + +private lemma meromorphicOrderAt_sub_principalPart_nonneg + {f : ℂ → ℂ} {polesFin : Finset ℂ} {p : ℂ} + (hpFin : p ∈ polesFin) + (h_mero : MeromorphicAt f p) + (h_ord : meromorphicOrderAt f p = -1) : + 0 ≤ meromorphicOrderAt (f - fun s ↦ ∑ q ∈ polesFin, residue f q / (s - q)) p := by + have hcore : (f - fun z ↦ residue f p / (z - p)) =O[nhdsWithin p ({p}ᶜ)] (1 : ℂ → ℂ) := by + exact simplePole_sub_residue_isBigO_one h_mero h_ord + let rest : ℂ → ℂ := fun z ↦ ∑ q ∈ polesFin.erase p, residue f q / (z - q) + have hrest_cont : ContinuousAt rest p := by + dsimp [rest] + refine tendsto_finsetSum _ (fun q hq ↦ ?_) + have hpq : p - q ≠ 0 := sub_ne_zero.mpr (Finset.mem_erase.mp hq).1.symm + have h_cont : ContinuousAt (fun z : ℂ ↦ residue f q / (z - q)) p := by + fun_prop (disch := exact hpq) + exact h_cont + have hrest : rest =O[nhdsWithin p ({p}ᶜ)] (1 : ℂ → ℂ) := by + have hbig : rest =O[nhds p] (1 : ℂ → ℂ) := + hrest_cont.norm.isBoundedUnder_le.isBigO_one ℂ + exact IsBigO.mono hbig inf_le_left + have hraw_big : (f - fun s ↦ ∑ q ∈ polesFin, residue f q / (s - q)) =O[nhdsWithin p ({p}ᶜ)] (1 : + ℂ → ℂ) := by + have htmp : (fun z : ℂ ↦ (f z - residue f p / (z - p)) - rest z) =O[nhdsWithin p ({p}ᶜ)] (1 : + ℂ → ℂ) := + hcore.sub hrest + have hdecomp : (f - fun s ↦ ∑ q ∈ polesFin, residue f q / (s - q)) = + (fun z : ℂ ↦ (f z - residue f p / (z - p)) - rest z) := by + funext z + dsimp [rest] + rw [← Finset.add_sum_erase (s := polesFin) (f := fun q ↦ residue f q / (z - q)) hpFin] + simp [sub_eq_add_neg, add_assoc, add_comm] + simpa [hdecomp, rest] using htmp + by_contra hneg + have hnorm : Filter.Tendsto (fun z : ℂ ↦ ‖(f - fun s ↦ ∑ q ∈ polesFin, residue f q / (s - q)) + z‖) (nhdsWithin p ({p}ᶜ)) Filter.atTop := by + rw [tendsto_norm_atTop_iff_cobounded] + exact tendsto_cobounded_of_meromorphicOrderAt_neg (not_le.mp hneg) + exact (Filter.not_isBoundedUnder_of_tendsto_atTop hnorm) hraw_big.isBoundedUnder_le + +private lemma holoPart_holomorphicOn {f : ℂ → ℂ} {z w : ℂ} + (f_mero : MeromorphicOn f (Rectangle z w)) + (f_simple_poles : HasSimplePolesOn f (Rectangle z w)) + (f_poles_finite : (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}).Finite) : + HolomorphicOn (toMeromorphicNFOn (toMeromorphicNFOn f (Rectangle z w) - + fun s ↦ ∑ p ∈ f_poles_finite.toFinset, residue (toMeromorphicNFOn f (Rectangle z w)) p / (s + - p)) (Rectangle z w)) (Rectangle z w) := by + classical + let R := Rectangle z w + let poles := R ∩ {u | meromorphicOrderAt f u < 0} + let polesFin := f_poles_finite.toFinset + let fNF := toMeromorphicNFOn f R + let principalPart := fun s ↦ ∑ p ∈ polesFin, residue fNF p / (s - p) + let holoPart := toMeromorphicNFOn (fNF - principalPart) R + have h_fNF_mero : MeromorphicOn fNF R := by + simpa [fNF] using + (meromorphicNFOn_toMeromorphicNFOn (f := f) (U := R)).meromorphicOn + have h_principalPart_mero : MeromorphicOn principalPart R := principalPart_meromorphicOn + have h_raw_mero : MeromorphicOn (fNF - principalPart) R := h_fNF_mero.sub h_principalPart_mero + intro x hx + have h_raw_nonneg : 0 ≤ meromorphicOrderAt (fNF - principalPart) x := by + by_cases hxp : x ∈ poles + · have hpFin : x ∈ polesFin := by simpa [polesFin, poles] using hxp + have hord : meromorphicOrderAt f x = (-1 : ℤ) := + meromorphicOrderAt_eq_neg_one_of_simplePole hxp.1 f_simple_poles hxp.2 + have hordNF : meromorphicOrderAt fNF x = (-1 : ℤ) := by + rw [show meromorphicOrderAt fNF x = meromorphicOrderAt f x by + simpa [fNF] using + (meromorphicOrderAt_toMeromorphicNFOn (f := f) (U := R) f_mero hxp.1)] + exact hord + exact meromorphicOrderAt_sub_principalPart_nonneg hpFin (h_fNF_mero x hxp.1) hordNF + · have hxnp : x ∉ polesFin := by + intro h + exact hxp (by simpa [polesFin, poles] using h) + have h_fNF_nonneg : 0 ≤ meromorphicOrderAt fNF x := by + rw [show meromorphicOrderAt fNF x = meromorphicOrderAt f x by + simpa [fNF] using + (meromorphicOrderAt_toMeromorphicNFOn (f := f) (U := R) f_mero hx)] + exact le_of_not_gt fun hxneg => hxp ⟨hx, hxneg⟩ + have h_fNF_nf : MeromorphicNFAt fNF x := by + simpa [fNF] using + (meromorphicNFOn_toMeromorphicNFOn (f := f) (U := R) hx) + exact (sub_principalPart_analyticAt_of_not_mem_poles h_fNF_nf hxnp + h_fNF_nonneg).meromorphicOrderAt_nonneg + have h_nf : MeromorphicNFAt holoPart x := by + simpa [holoPart] using + (meromorphicNFOn_toMeromorphicNFOn (f := fNF - principalPart) (U := R) hx) + have h_ord : + meromorphicOrderAt holoPart x = meromorphicOrderAt (fNF - principalPart) x := by + simpa [holoPart] using + (meromorphicOrderAt_toMeromorphicNFOn (f := fNF - principalPart) (U := R) h_raw_mero hx) + exact (h_nf.meromorphicOrderAt_nonneg_iff_analyticAt.1 (h_ord.symm ▸ + h_raw_nonneg)).differentiableAt.differentiableWithinAt + +-- Since no poles lie on the boundary of the rectangle, the principal part is continuous +-- on the boundary and therefore integrable. +private lemma principalPart_borderIntegrable {f : ℂ → ℂ} {z w : ℂ} + (f_no_poles_boundary : Disjoint (RectangleBorder z w) {z | meromorphicOrderAt f z < 0}) + (f_poles_finite : (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}).Finite) : + RectangleBorderIntegrable (fun s ↦ ∑ p ∈ f_poles_finite.toFinset, residue (toMeromorphicNFOn f + (Rectangle z w)) p / (s - p)) z w := by + classical + let R := Rectangle z w + let poles := R ∩ {u | meromorphicOrderAt f u < 0} + let polesFin := f_poles_finite.toFinset + let fNF := toMeromorphicNFOn f R + let principalPart := fun s ↦ ∑ p ∈ polesFin, residue fNF p / (s - p) + refine ContinuousOn.rectangleBorder_integrable ?_ + refine continuousOn_finsetSum _ ?_ + intro p hp s hs + have hsp : s ≠ p := fun hsp => Set.disjoint_right.mp f_no_poles_boundary + ((by simpa [polesFin, poles] using hp : p ∈ poles).2) (hsp ▸ hs) + have : ContinuousAt (fun z : ℂ ↦ residue fNF p / (z - p)) s := by + fun_prop (disch := exact sub_ne_zero.mpr hsp) + exact this.continuousWithinAt + +private lemma rectangle_mem_nhds_of_interior {z w p : ℂ} + (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : z.im ≤ w.im) + (hpR : p ∈ Rectangle z w) (hpnot : p ∉ RectangleBorder z w) : + Rectangle z w ∈ nhds p := by + rw [mem_Rect zRe_le_wRe zIm_le_wIm] at hpR + have hp_re_left : z.re < p.re := + lt_of_le_of_ne hpR.1 fun hEq => hpnot + (by simp [RectangleBorder, hEq, hpR.2.2.1, hpR.2.2.2, zIm_le_wIm, mem_reProdIm]) + have hp_re_right : p.re < w.re := + lt_of_le_of_ne hpR.2.1 fun hEq => hpnot + (by simp [RectangleBorder, hEq, hpR.2.2.1, hpR.2.2.2, zIm_le_wIm, mem_reProdIm]) + have hp_im_left : z.im < p.im := + lt_of_le_of_ne hpR.2.2.1 fun hEq => hpnot + (by simp [RectangleBorder, hEq, hpR.1, hpR.2.1, zRe_le_wRe, mem_reProdIm]) + have hp_im_right : p.im < w.im := + lt_of_le_of_ne hpR.2.2.2 fun hEq => hpnot + (by simp [RectangleBorder, hEq, hpR.1, hpR.2.1, zRe_le_wRe, mem_reProdIm]) + rw [rectangle_mem_nhds_iff, mem_reProdIm, Set.uIoo_of_le zRe_le_wRe, Set.uIoo_of_le zIm_le_wIm] + exact ⟨⟨hp_re_left, hp_re_right⟩, ⟨hp_im_left, hp_im_right⟩⟩ + +private lemma sum_div_rectangleBorderIntegrable {z w : ℂ} {S : Finset ℂ} + (hS_disjoint : Disjoint (RectangleBorder z w) S) (c : ℂ → ℂ) : + RectangleBorderIntegrable (fun s ↦ ∑ p ∈ S, c p / (s - p)) z w := by + refine ContinuousOn.rectangleBorder_integrable ?_ + refine continuousOn_finsetSum _ ?_ + intro p hp s hs + have hsp : s ≠ p := fun hsp => Set.disjoint_right.mp hS_disjoint hp (hsp ▸ hs) + have : ContinuousAt (fun z : ℂ ↦ c p / (z - p)) s := by + fun_prop (disch := exact sub_ne_zero.mpr hsp) + exact this.continuousWithinAt + +-- The integral of a sum of simple pole terms `c p / (s - p)` along the boundary of the rectangle +-- equals the sum of the coefficients `c p` for all points `p` in the interior. +private lemma rectangleIntegral'_sum_div_sub {z w : ℂ} (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : + z.im ≤ w.im) + {S : Finset ℂ} (hS_subset : (S : Set ℂ) ⊆ Rectangle z w) + (hS_disjoint : Disjoint (RectangleBorder z w) S) + (c : ℂ → ℂ) : + RectangleIntegral' (fun s ↦ ∑ p ∈ S, c p / (s - p)) z w = ∑ p ∈ S, c p := by + classical + have h_partial_border : ∀ (S' : Finset ℂ), S' ⊆ S → RectangleBorderIntegrable (fun s ↦ ∑ p ∈ S', + c p / (s - p)) z w := by + intro S' hS' + exact sum_div_rectangleBorderIntegrable (Disjoint.mono_right hS' hS_disjoint) c + have h_term_integral : ∀ {p : ℂ}, p ∈ S → RectangleIntegral' (fun s ↦ c p / (s - p)) z w = c p := + fun {p} hp => ResidueTheoremInRectangle zRe_le_wRe zIm_le_wIm + (rectangle_mem_nhds_of_interior zRe_le_wRe zIm_le_wIm + (hS_subset hp) (Set.disjoint_right.mp hS_disjoint hp)) + have h_partial_integral : + ∀ (S' : Finset ℂ), S' ⊆ S → + RectangleIntegral' (fun s ↦ ∑ p ∈ S', c p / (s - p)) z w = + ∑ p ∈ S', c p := by + intro S' hS' + revert hS' + refine Finset.induction_on S' ?_ ?_ + · intro _ + simp [RectangleIntegral', RectangleIntegral, HIntegral, VIntegral] + · intro a S' ha ih hS' + obtain ⟨haFin, hSsub⟩ := Finset.insert_subset_iff.mp hS' + have hterm_border : + RectangleBorderIntegrable (fun s ↦ c a / (s - a)) z w := + by simpa using h_partial_border ({a} : Finset ℂ) (Finset.singleton_subset_iff.mpr haFin) + have hfun : + (fun s ↦ ∑ p ∈ insert a S', c p / (s - p)) = + (fun s ↦ c a / (s - a)) + + (fun s ↦ ∑ p ∈ S', c p / (s - p)) := by + funext s; simp [Finset.sum_insert, ha] + have h_add_primed : + RectangleIntegral' ((fun s ↦ c a / (s - a)) + (fun s ↦ ∑ p ∈ S', c p / (s - p))) z w = + RectangleIntegral' (fun s ↦ c a / (s - a)) z w + + RectangleIntegral' (fun s ↦ ∑ p ∈ S', c p / (s - p)) z w := by + unfold RectangleIntegral' + rw [RectangleBorderIntegrable.add hterm_border (h_partial_border S' hSsub), smul_add] + rw [hfun, h_add_primed, h_term_integral haFin, ih hSsub, Finset.sum_insert ha] + exact h_partial_integral S (by intro p hp; exact hp) + +-- Splits the integral of `fNF` into the integral of its holomorphic part and its principal part. +private lemma toMeromorphicNFOn_add_integral {f : ℂ → ℂ} {z w : ℂ} + (f_mero : MeromorphicOn f (Rectangle z w)) + (f_no_poles_boundary : Disjoint (RectangleBorder z w) {z | meromorphicOrderAt f z < 0}) + (f_poles_finite : (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}).Finite) + (f_simple_poles : HasSimplePolesOn f (Rectangle z w)) : + RectangleIntegral' (toMeromorphicNFOn f (Rectangle z w)) z w = + RectangleIntegral' (toMeromorphicNFOn (toMeromorphicNFOn f (Rectangle z w) - + fun s ↦ ∑ p ∈ f_poles_finite.toFinset, residue (toMeromorphicNFOn f (Rectangle z w)) p / + (s - p)) (Rectangle z w)) z w + + RectangleIntegral' (fun s ↦ ∑ p ∈ f_poles_finite.toFinset, residue (toMeromorphicNFOn f + (Rectangle z w)) p / (s - p)) z w := by + let R : Set ℂ := Rectangle z w + let poles : Set ℂ := R ∩ {u | meromorphicOrderAt f u < 0} + let polesFin : Finset ℂ := f_poles_finite.toFinset + let fNF : ℂ → ℂ := toMeromorphicNFOn f R + let principalPart : ℂ → ℂ := fun s ↦ ∑ p ∈ polesFin, residue fNF p / (s - p) + let holoPart : ℂ → ℂ := toMeromorphicNFOn (fNF - principalPart) R + have h_holoPart_border : RectangleBorderIntegrable holoPart z w := + (holoPart_holomorphicOn f_mero f_simple_poles f_poles_finite).rectangleBorderIntegrable + have h_fNF_eq : + Set.EqOn fNF (holoPart + principalPart) (RectangleBorder z w) := by + intro s hs + have hsR : s ∈ R := rectangleBorder_subset_rectangle z w hs + have hsnp : s ∉ poles := fun hsp => Set.disjoint_right.mp f_no_poles_boundary hsp.2 hs + have hraw_analytic : AnalyticAt ℂ (fNF - principalPart) s := by + have h_fNF_nonneg : 0 ≤ meromorphicOrderAt fNF s := by + rw [show meromorphicOrderAt fNF s = meromorphicOrderAt f s by + simpa [fNF] using + (meromorphicOrderAt_toMeromorphicNFOn (f := f) (U := R) f_mero hsR)] + exact le_of_not_gt fun hsneg => hsnp ⟨hsR, hsneg⟩ + exact sub_principalPart_analyticAt_of_not_mem_poles + (by simpa [fNF] using meromorphicNFOn_toMeromorphicNFOn (f := f) (U := R) hsR) + (fun h => hsnp (by simpa [polesFin, poles] using h)) + h_fNF_nonneg + have hs_eq : holoPart s = (fNF - principalPart) s := by + rw [show holoPart = toMeromorphicNFOn (fNF - principalPart) R by rfl] + have h_fNF_mero : MeromorphicOn fNF R := by + simpa [fNF] using (meromorphicNFOn_toMeromorphicNFOn (f := f) (U := R)).meromorphicOn + have hf_sub_mero : MeromorphicOn (fNF - principalPart) R := + h_fNF_mero.sub principalPart_meromorphicOn + rw [toMeromorphicNFOn_eq_toMeromorphicNFAt (f := fNF - principalPart) (U := R) hf_sub_mero + hsR] + exact congr_fun (toMeromorphicNFAt_eq_self.2 hraw_analytic.meromorphicNFAt) s + calc + fNF s = (fNF - principalPart) s + principalPart s := by simp + _ = holoPart s + principalPart s := by rw [← hs_eq] + rw [RectangleIntegral'_congr h_fNF_eq, RectangleIntegral', + RectangleBorderIntegrable.add h_holoPart_border + (principalPart_borderIntegrable f_no_poles_boundary f_poles_finite), smul_add] + +/-- The Residue Theorem on a rectangle for functions with simple poles. -/ +lemma RectangleIntegral'_eq_sumResiduesIn {f : ℂ → ℂ} {z w : ℂ} + (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : z.im ≤ w.im) + (f_mero : MeromorphicOn f (Rectangle z w)) + (f_no_poles_boundary : Disjoint (RectangleBorder z w) {z | meromorphicOrderAt f z < 0}) + (f_poles_finite : (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}).Finite) + (f_simple_poles : HasSimplePolesOn f (Rectangle z w)) : + RectangleIntegral' f z w = sumResiduesIn f (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}) + := by + let R : Set ℂ := Rectangle z w + let poles : Set ℂ := R ∩ {u | meromorphicOrderAt f u < 0} + let polesFin : Finset ℂ := f_poles_finite.toFinset + let fNF : ℂ → ℂ := toMeromorphicNFOn f R + let principalPart : ℂ → ℂ := fun s ↦ ∑ p ∈ polesFin, residue fNF p / (s - p) + let holoPart : ℂ → ℂ := toMeromorphicNFOn (fNF - principalPart) R + have h_residue_congr : sumResiduesIn f poles = sumResiduesIn fNF poles := by + rw [sumResiduesIn, sumResiduesIn] + apply tsum_congr + intro p + exact (residue_toMeromorphicNFOn_eq_residue p.2.1 f_mero f_simple_poles p.2.2).symm + have h_principalPart_integral : RectangleIntegral' principalPart z w = sumResiduesIn fNF poles + := by + have h_sum : RectangleIntegral' principalPart z w = ∑ p ∈ polesFin, residue fNF p := by + apply rectangleIntegral'_sum_div_sub zRe_le_wRe zIm_le_wIm + · intro p hp + dsimp [polesFin, poles, R] at hp + simp only [Finset.mem_coe, Set.Finite.mem_toFinset] at hp + exact hp.1 + · exact Disjoint.mono_right (by rw [f_poles_finite.coe_toFinset]; exact + Set.inter_subset_right) f_no_poles_boundary + rw [h_sum] + have h_eq_poles : poles = ↑polesFin := by + dsimp [poles, polesFin, R] + exact f_poles_finite.coe_toFinset.symm + rw [sumResiduesIn, h_eq_poles, + tsum_fintype (f := fun p : (polesFin : Set ℂ) => residue fNF p), + ← Finset.sum_coe_sort polesFin]; rfl + calc + RectangleIntegral' f z w = RectangleIntegral' fNF z w := + rectangleIntegral'_toMeromorphicNFOn_eq f_mero + _ = RectangleIntegral' holoPart z w + RectangleIntegral' principalPart z w := + toMeromorphicNFOn_add_integral f_mero f_no_poles_boundary f_poles_finite f_simple_poles + _ = 0 + sumResiduesIn fNF poles := by + rw [h_principalPart_integral] + rw [RectangleIntegral', + (holoPart_holomorphicOn f_mero f_simple_poles f_poles_finite).vanishesOnRectangle + subset_rfl] + simp + _ = sumResiduesIn fNF poles := by simp + _ = sumResiduesIn f poles := h_residue_congr.symm + +lemma residue_eq_zero_of_not_pole_of_meromorphicAt {F : ℂ → ℂ} {s : ℂ} + (hs_mero : MeromorphicAt F s) (hs_not_pole : 0 ≤ meromorphicOrderAt F s) : + residue F s = 0 := by + apply residue_eq_of_tendsto + obtain ⟨c, hc⟩ := tendsto_nhds_of_meromorphicOrderAt_nonneg hs_mero hs_not_pole + have hsub : Filter.Tendsto (fun z : ℂ ↦ z - s) (nhdsWithin s {s}ᶜ) (nhds 0) := + tendsto_sub_nhds_zero_iff.mpr (tendsto_id.mono_left nhdsWithin_le_nhds) + simpa using hsub.mul hc + +lemma sumResiduesIn_inter_eq_of_set_eq {F : ℂ → ℂ} {Rn S2 P : Set ℂ} + (h_set_eq : Rn ∩ P = S2 ∩ P) + (h_residue_zero : ∀ s ∈ S2, s ∉ P → residue F s = 0) : + sumResiduesIn F (Rn ∩ P) = sumResiduesIn F S2 := by + rw [sumResiduesIn, sumResiduesIn, tsum_subtype, tsum_subtype] + apply tsum_congr + intro s + by_cases hs_S2 : s ∈ S2 + · by_cases hs_pole : s ∈ P + · have hs_rect_pole : s ∈ Rn ∩ P := h_set_eq.symm ▸ ⟨hs_S2, hs_pole⟩ + simp [hs_S2, hs_rect_pole] + · have hs_not_rect_pole : s ∉ Rn ∩ P := fun hs => hs_pole hs.2 + have hres0 : residue F s = 0 := h_residue_zero s hs_S2 hs_pole + simp [hs_S2, hs_not_rect_pole, hres0] + · have hs_not_rect_pole : s ∉ Rn ∩ P := fun hs => hs_S2 (h_set_eq ▸ hs).1 + simp [hs_S2, hs_not_rect_pole] + +end IwaniecLinearSievePNT diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/StrongPNT.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/StrongPNT.lean new file mode 100644 index 000000000..eb46f659a --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/StrongPNT.lean @@ -0,0 +1,2754 @@ +/- +Copyright (c) 2026 PrimeNumberTheoremAnd contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: PrimeNumberTheoremAnd contributors +-/ + +module + +public import Mathlib.Analysis.CStarAlgebra.Classes +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.MediumPNT +import Mathlib.Algebra.Order.Star.Real +import Mathlib.Analysis.Complex.BorelCaratheodory +import Mathlib.Analysis.Complex.HasPrimitives +import Mathlib.MeasureTheory.Order.Group.Lattice +import Mathlib.NumberTheory.LSeries.Nonvanishing +import Mathlib.RingTheory.SimpleRing.Principal + +/-! +Adapted from PrimeNumberTheoremAnd revision +`127b50e33f6033e2147921167a117af96d9ba4ea`, via Jason Davies's +Iwaniec linear sieve snapshot `c8d01549d2ae640b36ec198c1f0f6495f1b036cf` +(both Apache-2.0). Blueprint-only machinery is omitted. + +Supporting lemmas for Iwaniec's sieve and its prime-number-theorem input. +-/ + +@[expose] public section + +namespace IwaniecLinearSievePNT + + + +open Nat Filter Topology Set Function Complex Real ComplexConjugate MeasureTheory + +open ArithmeticFunction (vonMangoldt) + +local notation (name := mellintransform2) "𝓜" => mellin + +local notation "Λ" => vonMangoldt + +local notation "ζ" => riemannZeta + +local notation "ζ'" => deriv ζ + +local notation "ψ" => ChebyshevPsi + +--open scoped ArithmeticFunction + + + +/- +An application of the Maximum modulus principle. +This is standard in the literature. +-/ +lemma _root_.AnalyticOn.norm_le_of_norm_le_on_sphere {C r R : ℝ} {f : ℂ → ℂ} {w : ℂ} + (hyp_r : r ≤ R) + (analytic : AnalyticOn ℂ f (Metric.closedBall 0 R)) + (cond : ∀ z ∈ Metric.sphere 0 r, ‖f z‖ ≤ C) + (wInS : w ∈ Metric.closedBall 0 r) : + ‖f w‖ ≤ C := by + apply Complex.norm_le_of_forall_mem_frontier_norm_le + (U := Metric.closedBall 0 r) Metric.isBounded_closedBall + · apply DifferentiableOn.diffContOnCl + rw [Metric.closure_closedBall] + exact AnalyticOn.differentiableOn + (AnalyticOn.mono analytic + (Metric.closedBall_subset_closedBall hyp_r)) + · rw [frontier_closedBall'] + exact cond + · rw [Metric.closure_closedBall] + exact wInS + + + +/- +An application of + \begin{verbatim} + Complex.borelCaratheodory_zero. + \end{verbatim} +This is standard in the literature. +-/ +theorem borelCaratheodory' {M r R : ℝ} {f : ℂ → ℂ} {z : ℂ} + (Mpos : 0 < M) (Rpos : 0 < R) (hyp_r : r < R) + (analytic : AnalyticOn ℂ f (Metric.ball 0 R)) + (zeroAtZero : f 0 = 0) + (realPartBounded : ∀ z ∈ Metric.ball 0 R, (f z).re ≤ M) + (hyp_z : z ∈ Metric.closedBall 0 r) : + ‖f z‖ ≤ (2 * M * r) / (R - r) := by + have h_borelCaratheodory : ∀ ε > 0, ‖f z‖ ≤ (2 * (M + ε) * ‖z‖) / (R - ‖z‖) := by + intro ε εpos; + apply Complex.borelCaratheodory_zero; + exacts [by linarith, analytic.differentiableOn, + fun z hz => by rw [Set.mem_ofPred_eq]; linarith [realPartBounded z hz], + Rpos, by exact Metric.mem_ball.mpr (lt_of_le_of_lt (Metric.mem_closedBall.mp hyp_z) hyp_r), + zeroAtZero] + have h_limit : ‖f z‖ ≤ (2 * M * ‖z‖) / (R - ‖z‖) := by + have h_limit : Filter.Tendsto (fun ε => (2 * (M + ε) * ‖z‖) / (R - ‖z‖)) + (nhdsWithin 0 (Set.Ioi 0)) (nhds ((2 * M * ‖z‖) / (R - ‖z‖))) := by + refine tendsto_nhdsWithin_of_tendsto_nhds (Continuous.tendsto' ?_ _ _ (by ring_nf)) + exact Continuous.div_const + ((continuous_const.mul (continuous_const.add continuous_id)).mul continuous_const) _ + refine le_of_tendsto_of_tendsto tendsto_const_nhds h_limit ?_ + exact Filter.eventually_of_mem self_mem_nhdsWithin fun ε hε => h_borelCaratheodory ε hε + rw [mem_closedBall_iff_norm, sub_zero] at hyp_z + refine le_trans h_limit ?_; + gcongr + exact mul_nonneg (mul_nonneg (zero_le_two) (le_of_lt Mpos)) (le_trans (norm_nonneg z) hyp_z) + + + +/- + This upstreamed from https://github.com/math-inc/strongpnt/tree/main +-/ + + + +/- +Let $f$ be analytic on $|z|\leq R$. For any $z$ with $|z|\leq r$ and any $r'$ + with $0 < r < r' < R$ we have + $$f'(z)=\frac{1}{2\pi i}\oint_{|w|=r'}\frac{f(w)}{(w-z)^2}\,dw=\frac{1}{2\pi} + \int_0^{2\pi}\frac{r'e^{it}\,f(r'e^{it})}{(r'e^{it}-z)^2}\,dt.$$ +This is just Cauchy's integral formula for derivatives. +-/ +lemma cauchy_formula_deriv {r r' R : ℝ} {f : ℂ → ℂ} {z : ℂ} + (r_lt_r' : r < r') (r'_lt_R : r' < R) + (hf_on_ball : DifferentiableOn ℂ f (Metric.ball 0 R)) + (hz : z ∈ Metric.closedBall 0 r) : + deriv f z = (1 / (2 * Real.pi * I)) • ∮ w in C(0, r'), (w - z)⁻¹ ^ 2 • f w := by + have hz_in_ball : z ∈ Metric.ball 0 r' := + Metric.mem_ball.mpr <| (Metric.mem_closedBall.mp hz).trans_lt r_lt_r' + simp [← Complex.two_pi_I_inv_smul_circleIntegral_sub_sq_inv_smul_of_differentiable + Metric.isOpen_ball (Metric.closedBall_subset_ball r'_lt_R) hf_on_ball hz_in_ball] + + + +/- +Let $R,\,M>0$ and $0 < r < r' < R$. Let $f$ be analytic on $|z|\leq R$ such that + $f(0)=0$ and suppose $\Re f(z)\leq M$ for all $|z|\leq R$. Then we have that + $$|f'(z)|\leq\frac{2M(r')^2}{(R-r')(r'-r)^2}$$ + for all $|z|\leq r$. +By Lemma \ref{cauchy_formula_deriv} we know that + $$f'(z)=\frac{1}{2\pi i}\oint_{|w|=r'}\frac{f(w)}{(w-z)^2}\,dw + =\frac{1}{2\pi }\int_0^{2\pi}\frac{r'e^{it}\,f(r'e^{it})}{(r'e^{it}-z)^2}\,dt.$$ + Thus, + \begin{equation}\label{pickupPoint1} + |f'(z)|=\left|\frac{1}{2\pi}\int_0^{2\pi} + \frac{r'e^{it}\,f(r'e^{it})}{(r'e^{it}-z)^2}\,dt\right| + \leq\frac{1}{2\pi}\int_0^{2\pi} + \left|\frac{r'e^{it}\,f(r'e^{it})}{(r'e^{it}-z)^2}\right|\,dt. + \end{equation} + Now applying Theorem \ref{borelCaratheodory'}, and noting that + $r'-r\leq|r'e^{it}-z|$, we have that + $$\left|\frac{r'e^{it}\,f(r'e^{it})}{(r'e^{it}-z)^2}\right| + \leq\frac{2M(r')^2}{(R-r')(r'-r)^2}.$$ + Substituting this into Equation (\ref{pickupPoint1}) and evaluating the integral + completes the proof. +-/ +lemma DerivativeBound {M r r' R : ℝ} {f : ℂ → ℂ} {z : ℂ} + (Mpos : 0 < M) (pos_r : 0 < r) (r_lt_r' : r < r') (r'_lt_R : r' < R) + (analytic_f : AnalyticOn ℂ f (Metric.ball 0 R)) + (f_zero_at_zero : f 0 = 0) + (re_f_le_M : ∀ z ∈ Metric.ball 0 R, (f z).re ≤ M) + (z_in_r : z ∈ Metric.closedBall 0 r) : + ‖(deriv f) z‖ ≤ 2 * M * (r') ^ 2 / ((R - r') * (r' - r) ^ 2) := by + rw [cauchy_formula_deriv r_lt_r' r'_lt_R analytic_f.differentiableOn z_in_r, one_div] + grw [circleIntegral.norm_two_pi_i_inv_smul_integral_le_of_norm_le_const (by linarith) + (C := 2 * M * r' / ((R - r') * (r' - r) ^ 2))] + · exact le_of_eq (by ring) + · intro z' hz' + rw [smul_eq_mul, norm_mul] + grw[borelCaratheodory' Mpos (by grind) r'_lt_R analytic_f f_zero_at_zero re_f_le_M + (Metric.sphere_subset_closedBall hz')] + suffices ‖(z' - z)⁻¹ ^ 2‖ ≤ 1 / (r' - r) ^ 2 by + grw [this] + · exact le_of_eq (by field) + · refine mul_nonneg (mul_nonneg ?_ ?_) (inv_nonneg.mpr ?_) <;> linarith + have hdist : r' - r ≤ ‖z' - z‖ := by + simp only [mem_sphere_iff_norm, sub_zero, Metric.mem_closedBall, + dist_zero_right] at hz' z_in_r + rw [← hz'] + exact le_trans (by linarith) (norm_sub_norm_le z' z) + rw [norm_pow, norm_inv, one_div, inv_pow] + gcongr + + + +/- +Let $R,\,M>0$. Let $f$ be analytic on $|z|\leq R$ such that $f(0)=0$ and suppose + $\Re f(z)\leq M$ for all $|z|\leq R$. Then for any $0 < r < R$, + $$|f'(z)|\leq\frac{16MR^2}{(R-r)^3}$$ + for all $|z|\leq r$. +Using Lemma \ref{DerivativeBound} with $r'=(R+r)/2$, and noting that $r < R$, + we have that + $$|f'(z)|\leq\frac{4M(R+r)^2}{(R-r)^3}\leq\frac{16MR^2}{(R-r)^3}.$$ +-/ +theorem BorelCaratheodoryDeriv {M r R : ℝ} {f : ℂ → ℂ} {z : ℂ} + (Mpos : 0 < M) (rpos : 0 < r) (hyp_r : r < R) + (analytic_f : AnalyticOn ℂ f (Metric.ball 0 R)) + (zeroAtZero : f 0 = 0) + (realPartBounded : ∀ z ∈ Metric.ball 0 R, (f z).re ≤ M) + (hyp_z : z ∈ Metric.closedBall 0 r) : + ‖deriv f z‖ ≤ 16 * M * R ^ 2 / (R - r) ^ 3 := by + have hr' : 2 * M * ((R + r) / 2) ^ 2 / ((R - (R + r) / 2) * ((R + r) / 2 - r) ^ 2) = + 4 * M * (R + r) ^ 2 / (R - r) ^ 3 := by + rw [div_eq_div_iff (mul_ne_zero (by linarith) (pow_ne_zero _ (by linarith))) + (pow_ne_zero _ (by linarith))] + ring + calc ‖deriv f z‖ + _ ≤ 4 * M * (R + r) ^ 2 / (R - r) ^ 3 := hr' ▸ + DerivativeBound Mpos rpos (by linarith) (by linarith) + analytic_f zeroAtZero realPartBounded hyp_z + _ ≤ 16 * M * R ^ 2 / (R - r) ^ 3 := by + have : 16 * M * R ^ 2 = 4 * M * (2 * R) ^ 2 := by ring_nf + rw [this]; bound + + + +/- +\begin{definition}[TaxicabIntegral]\label{TaxicabIntegral} + Let $0 < R$. Let $f:\overline{\mathbb{D}_R}\to\mathbb{C}$ be analytic on neighborhoods of points + in $\overline{\mathbb{D}_R}$. Define the functon $I_f:\mathbb{D}_R\to\mathbb{C}$ by + $$I_f(z)=z\int_0^1f(tz)\,dt.$$ +\end{definition} +-/ + + + +/- +Let $0 deriv B z / B z; + have hf : AnalyticOnNhd ℂ f (Metric.ball 0 R) := + (BanalyticOnNhdOfDR.deriv.mono Metric.ball_subset_closedBall).div + (BanalyticOnNhdOfDR.mono Metric.ball_subset_closedBall) + (fun z hz => Bnonzero z <| Metric.ball_subset_closedBall hz) + obtain ⟨J, hJ⟩ := DifferentiableOn.isExactOn_ball hf.differentiableOn + refine ⟨fun z ↦ J z - J 0, fun z hz ↦ (hJ z hz).sub_const _, by simp, ?_⟩ + set H : ℂ → ℂ := fun z => Complex.exp (J z - J 0) / B z + have hJB_deriv : ∀ z ∈ Metric.ball 0 R, HasDerivAt (fun z ↦ J z - J 0) (f z) z := + fun z hz ↦ (hJ z hz).sub_const _ + have hH_deriv : ∀ z ∈ Metric.ball 0 R, HasDerivAt H 0 z := by + intro z hz + have := (Complex.hasDerivAt_exp _).comp z (hJB_deriv z hz) + convert! this.div (BanalyticOnNhdOfDR.differentiableOn.differentiableAt + (Metric.closedBall_mem_nhds_of_mem hz) |>.hasDerivAt) + (Bnonzero z <| Metric.ball_subset_closedBall hz) using 1 + ring_nf!; grind + have hH_const : ∀ z ∈ Metric.ball 0 R, H z = H 0 := by + intro z hz + have h_diffOn : DifferentiableOn ℂ H (Metric.ball 0 R) := + fun z hz ↦ (hH_deriv z hz).differentiableAt.differentiableWithinAt + refine Convex.is_const_of_fderivWithin_eq_zero (convex_ball 0 R) h_diffOn ?_ hz + (Metric.mem_ball_self (Metric.pos_of_mem_ball hz)) + intro x hx + rw [fderivWithin_of_isOpen Metric.isOpen_ball hx, + ← ContinuousLinearMap.toSpanSingleton_zero] + exact (hH_deriv x hx).hasFDerivAt.fderiv + have h_exp_re : ∀ z ∈ Metric.ball 0 R, Real.exp (J z - J 0).re = ‖B z‖ / ‖B 0‖ := by + intro z hz + have hc := hH_const z hz + simp only [H, sub_self, Complex.exp_zero, one_div] at hc + rw [div_eq_iff (Bnonzero z (Metric.ball_subset_closedBall hz)), mul_comm] at hc + rw [← Complex.norm_exp, ← norm_div, div_eq_mul_inv] + exact enorm_eq_iff_norm_eq.mp (congrArg enorm hc) + intro z hz + have hBz := Bnonzero z (Metric.ball_subset_closedBall hz) + have hB0 := Bnonzero 0 (by norm_num; linarith) + rw [← Real.log_div (norm_ne_zero_iff.mpr hBz) (norm_ne_zero_iff.mpr hB0), + ← h_exp_re z hz, Real.log_exp] + have hmem : ∀ z, z ∈ Metric.ball (0 : ℂ) r → z ∈ Metric.closedBall (0 : ℂ) R := by + intro z hz + apply Metric.mem_closedBall.mpr + rw [Metric.mem_ball] at hz + linarith + refine ⟨J_B, fun z hz => ?_, hJB.2.1, fun z hz => ?_, hJB.2.2⟩ + · exact DifferentiableOn.analyticAt + (fun w hw ↦ (hJB.1 w hw).differentiableAt.differentiableWithinAt) + (IsOpen.mem_nhds Metric.isOpen_ball hz) + · exact (hJB.1 z (Metric.closedBall_subset_ball r_lt_R hz)).deriv + + + +/- +A wrapper of the above theorem that will be useful later on. +See above. +-/ +theorem LogOfAnalyticFunction' {r' r R : ℝ} {B : ℂ → ℂ} + (r'_pos : 0 < r') (r'_lt_r : r' < r) (r_lt_R : r < R) + (BanalyticOnNhdOfDR : AnalyticOnNhd ℂ B (Metric.closedBall (0 : ℂ) R)) + (Bnonzero : ∀ z ∈ Metric.closedBall (0 : ℂ) r, B z ≠ 0) : + ∃ (J_B : ℂ → ℂ), (AnalyticOnNhd ℂ J_B (Metric.ball 0 r)) ∧ + (J_B 0 = 0) ∧ + (∀ z ∈ Metric.closedBall 0 r', (deriv J_B) z = (deriv B) z / (B z)) ∧ + (∀ z ∈ Metric.ball 0 r, Real.log ‖B z‖ - Real.log ‖B 0‖ = (J_B z).re) := by + have BanalyticOnNhdOfDr : AnalyticOnNhd ℂ B (Metric.closedBall (0 : ℂ) r) := + BanalyticOnNhdOfDR.mono (Metric.closedBall_subset_closedBall r_lt_R.le) + exact LogOfAnalyticFunction r'_pos r'_lt_r BanalyticOnNhdOfDr Bnonzero + + + +/- +Let $R>0$ and $f:\mathbb{C}\to\mathbb{C}$. Define the set of zeros + $\mathcal{K}_f(R)=\{\rho\in\mathbb{C}:|\rho|\leq R,\,f(\rho)=0\}$. +-/ +/-- The zeros of `f` in the closed disk of radius `R` about the origin. -/ +def SetOfZeros (R : ℝ) (f : ℂ → ℂ) : Set ℂ := {ρ : ℂ | ‖ρ‖ ≤ R ∧ f ρ = 0} + + + +lemma finiteSetOfZeros_mono {r : ℝ} {f : ℂ → ℂ} + (r_lt_one : r < 1) + (finiteZeros : (SetOfZeros 1 f).Finite) : + (SetOfZeros r f).Finite := by + apply Set.Finite.subset finiteZeros + unfold SetOfZeros + refine ofPred_subset_ofPred.mpr ?_ + intro z hz + exact ⟨by linarith, hz.2⟩ + + + +/- +\begin{definition}[ZeroOrder]\label{ZeroOrder} + Let $f:\mathbb{C}\to\mathbb{C}$. + We define $m_f(\rho)$ as the order of the zero $\rho$ w.r.t $f$. +\end{definition} + In LEAN, this corresponds exactly with analyticOrderAt/analyticOrderNatAt. +-/ + + + +/- +Let $f:\mathbb{C}\to\mathbb{C}$ and $\rho\in\mathbb{C}$. Then there exists $h_\rho$ such that + $$f(z)=(z-\rho)^{m_f(\rho)}\,h_\rho(z).$$ + In LEAN, this corresponds exactly with (-.analyticOrderAt-ne-top.mp -).choose, + but this serves as a wrapper of that with the necessary conditions. +-/ +open Classical in +/-- The analytic factor remaining after removing the zero at `z`, evaluated at `z`. -/ +noncomputable def ZeroFactor (f : ℂ → ℂ) (z : ℂ) : ℂ := + if h1 : AnalyticAt ℂ f z then + if h2 : analyticOrderAt f z ≠ ⊤ then + (h1.analyticOrderAt_ne_top.mp h2).choose z + else 0 + else 0 + + + +/- +Let $f:\mathbb{C}\to\mathbb{C}$ be analytic on $\overline{\mathbb{D}_1}$ with $f(0)\neq 0$. + For all $\rho\in\mathcal{K}_f(R)$ with $R<1$ there exists $h_\rho(z)$ such that + $h_\rho(z)$ is analytic at $\rho$, $h_\rho(\rho)\neq 0$, and + $f(z)=(z-\rho)^{m_f(\rho)}\,h_\rho(z)$. +Since $f$ is analytic on neighborhoods of points in $\overline{\mathbb{D}_1}$ we know + that there exists a series expansion about $\rho$: + $$f(z)=\sum_{0\leq n}a_n\,(z-\rho)^n.$$ + Now if we let $m$ be the smallest number such that $a_m\neq 0$, then + $$f(z)=\sum_{0\leq n}a_n\,(z-\rho)^n=\sum_{m\leq n}a_n\,(z-\rho)^n + =(z-\rho)^m\sum_{m\leq n}a_n\,(z-\rho)^{n-m}=(z-\rho)^m\,h_\rho(z).$$ + Trivially, $h_\rho(z)$ is analytic at $\rho$ (we have written down the series + expansion); now note that + $$h_\rho(\rho)=\sum_{m\leq n}a_n(\rho-\rho)^{n-m}=\sum_{m\leq n}a_n0^{n-m}=a_m\neq 0.$$ +-/ +lemma ZeroFactorization {R : ℝ} {f : ℂ → ℂ} {ρ : ℂ} + (RleOne : R < 1) + (hfAnalytic : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) 1)) + (hf_neq_zero_at_zero : f 0 ≠ 0) + (hρ : ρ ∈ SetOfZeros R f) : + ∃ h_ρ : ℂ → ℂ, AnalyticAt ℂ h_ρ ρ ∧ h_ρ ρ ≠ 0 ∧ ZeroFactor f ρ = h_ρ ρ ∧ + f =ᶠ[nhds ρ] fun z ↦ (z - ρ) ^ analyticOrderNatAt f ρ * h_ρ z := by + have zero_mem_closedBall : 0 ∈ Metric.closedBall (0 : ℂ) 1 := by + rw[mem_closedBall_iff_norm, sub_zero, norm_zero] + exact zero_le_one + have ρ_mem_closedBall : ρ ∈ Metric.closedBall (0 : ℂ) 1 := by + rw[mem_closedBall_iff_norm, sub_zero] + linarith[hρ.1] + have orderAtZeroIsZero : analyticOrderAt f 0 = 0 := by + rw[analyticOrderAt_eq_zero] + exact Or.symm (Decidable.not_or_of_imp fun a a_1 ↦ hf_neq_zero_at_zero a) + have finiteOrder : analyticOrderAt f ρ ≠ ⊤ := by + refine AnalyticOnNhd.analyticOrderAt_ne_top_of_isPreconnected hfAnalytic + (Metric.isPreconnected_closedBall) zero_mem_closedBall ρ_mem_closedBall + (lt_top_iff_ne_top.mp ?_) + rw[orderAtZeroIsZero] + exact ENat.top_pos + have AnalyticAt_ρ : AnalyticAt ℂ f ρ := by exact (hfAnalytic ρ ρ_mem_closedBall) + obtain ⟨h_ρ, h_ρ_neq_zero_at_zero, f_eq⟩ := + (AnalyticAt_ρ.analyticOrderAt_ne_top.mp finiteOrder).choose_spec + set g := (AnalyticAt_ρ.analyticOrderAt_ne_top.mp finiteOrder).choose + refine ⟨g, h_ρ, h_ρ_neq_zero_at_zero, ?_, f_eq⟩ + simp only [ZeroFactor, AnalyticAt_ρ, ↓reduceDIte, ne_eq, finiteOrder, not_false_eq_true, + smul_eq_mul, g] + + + +/- +Let $0 < r < 1$, and $f:\mathbb{C}\to\mathbb{C}$ be analytic on $\overline{\mathbb{D}_1}$ with + $f(0)\neq 0$. We define a function $C_f:\mathbb{C}\to\mathbb{C}$ as follows. This function is + constructed by dividing $f(z)$ by a polynomial whose roots are the zeros of $f$ inside + $\overline{\mathbb{D}_r}$. + $$C_f(z)=\begin{cases} + \displaystyle\frac{f(z)}{\prod_{\rho\in\mathcal{K}_f(r)}(z-\rho)^{m_f(\rho)}} + \qquad\text{for }z\not\in\mathcal{K}_f(r) \\ + \displaystyle\frac{h_z(z)}{\prod_{\rho\in\mathcal{K}_f(r)\setminus\{z\}} + (z-\rho)^{m_f(\rho)}}\qquad\text{for }z\in\mathcal{K}_f(r) + \end{cases}$$ + where $h_z(z)$ comes from Lemma \ref{ZeroFactorization}. +-/ +open Classical in +/-- The analytic function obtained by removing the zeros of `f` in the disk of radius `r`. -/ +noncomputable def Cf (r : ℝ) (f : ℂ → ℂ) (z : ℂ) : ℂ := + if finite_zeros_mono : (SetOfZeros r f).Finite then + if _ : z ∈ SetOfZeros r f then + ZeroFactor f z / ∏ ρ ∈ (finite_zeros_mono.toFinset \ {z}), (z - ρ) ^ (analyticOrderNatAt f ρ) + else + f z / ∏ ρ ∈ (finite_zeros_mono.toFinset), (z - ρ) ^ (analyticOrderNatAt f ρ) + else 1 + + + +lemma analyticAt_finset_prod_sub_pow (s : Finset ℂ) (g : ℂ → ℕ) (w : ℂ) : + AnalyticAt ℂ (fun z => ∏ ρ ∈ s, (z - ρ) ^ g ρ) w := by + induction s using Finset.induction with + | empty => + simp only [Finset.prod_empty] + exact analyticAt_const + | @insert a s' hne ih => + have : (fun z => ∏ ρ ∈ insert a s', (z - ρ) ^ g ρ) = + fun z => (z - a) ^ g a * ∏ ρ ∈ s', (z - ρ) ^ g ρ := + funext fun z => Finset.prod_insert hne + rw [this] + exact ((analyticAt_id.sub analyticAt_const).pow _).mul ih + + + +/- +If $f:\mathbb{C}\to\mathbb{C}$ is analytic on $\overline{\mathbb{D}_1}$ then so too is $C_f$. +Look at the definition of $C_f$ and apply ZeroFactorization. +-/ +lemma CfAnalytic {r R : ℝ} {f : ℂ → ℂ} + (r_lt_R : r < R) (R_lt_one : R < 1) + (hfAnalytic : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) 1)) + (hf_neq_zero_at_zero : f 0 ≠ 0) : + AnalyticOnNhd ℂ (Cf r f) (Metric.closedBall (0 : ℂ) R) := by + classical + intro w hw + unfold Cf + by_cases finite_zeros_mono : (SetOfZeros r f).Finite + · simp only [finite_zeros_mono, ↓reduceDIte] + by_cases w_in_zeros : w ∈ SetOfZeros r f + · obtain ⟨hW, hhWanalytic, hhWne_zero, hhWeq⟩ := + ZeroFactorization (by linarith) + (hfAnalytic.mono (Metric.closedBall_subset_closedBall (by linarith))) hf_neq_zero_at_zero + w_in_zeros + have h_eq : ∀ᶠ z in nhds w, + (if h : z ∈ SetOfZeros r f then ZeroFactor f z / ∏ ρ ∈ finite_zeros_mono.toFinset \ {z}, + (z - ρ) ^ analyticOrderNatAt f ρ else f z / ∏ ρ ∈ finite_zeros_mono.toFinset, + (z - ρ) ^ analyticOrderNatAt f ρ) = + hW z / ∏ ρ ∈ finite_zeros_mono.toFinset \ {w}, (z - ρ) ^ analyticOrderNatAt f ρ := by + filter_upwards [hhWeq.2, hhWanalytic.continuousAt.eventually_ne hhWne_zero] with z hz hz' + by_cases h : z = w + · subst h + rw [dite_eq_left w_in_zeros] + congr 1 + exact hhWeq.1 + · have z_not_in : z ∉ SetOfZeros r f := by + intro hmem + have hfz : f z = 0 := hmem.2 + rw [hz] at hfz + exact absurd hfz (mul_ne_zero (pow_ne_zero _ (sub_ne_zero_of_ne h)) hz') + rw [dite_eq_right z_not_in, hz] + have hw_mem : w ∈ finite_zeros_mono.toFinset := + finite_zeros_mono.mem_toFinset.mpr w_in_zeros + rw [Finset.prod_eq_prod_sdiff_singleton_mul hw_mem + (fun ρ => (z - ρ) ^ analyticOrderNatAt f ρ)] + rw [mul_comm ((z - w) ^ analyticOrderNatAt f w) (hW z)] + rw [mul_div_mul_right _ _ (pow_ne_zero _ (sub_ne_zero_of_ne h))] + apply hhWanalytic.div _ _ |> fun h => h.congr _; + · use fun z => ∏ ρ ∈ finite_zeros_mono.toFinset \ { w }, ( z - ρ ) ^ analyticOrderNatAt f ρ; + · exact analyticAt_finset_prod_sub_pow _ _ _ + · simp only [Finset.prod_eq_zero_iff, ne_eq, pow_eq_zero_iff', Finset.mem_sdiff, and_imp, + Finite.mem_toFinset, Finset.mem_singleton, not_exists, not_and, Decidable.not_not] + intro x _ h_ne_w + exact fun h_eq_w => absurd (sub_eq_zero.mp h_eq_w).symm h_ne_w + · filter_upwards [ h_eq ] with z hz using hz.symm + · apply AnalyticAt.congr _ _ + · exact fun z => f z / ∏ ρ ∈ finite_zeros_mono.toFinset, ( z - ρ ) ^ analyticOrderNatAt f ρ + · refine AnalyticAt.div ?_ ?_ ?_ + · exact hfAnalytic w ( Metric.mem_closedBall.mpr <| le_trans hw.out <| by linarith ) + · exact analyticAt_finset_prod_sub_pow _ _ _ + · simp only [ ne_eq, Finset.prod_eq_zero_iff, Finite.mem_toFinset, pow_eq_zero_iff', + sub_eq_zero, ↓existsAndEq, true_and, not_and, Decidable.not_not] + exact fun h => absurd h w_in_zeros + · filter_upwards [IsOpen.mem_nhds (isOpen_compl_iff.mpr finite_zeros_mono.isClosed) + w_in_zeros] with z hz + split_ifs with h + · exact absurd h hz + · rfl + · simp only [finite_zeros_mono, ↓reduceDIte] + exact analyticAt_const + + + +/- +Let $0 < r < R < 1$, and $f:\mathbb{C}\to\mathbb{C}$ be analytic $\overline{\mathbb{D}_1}$ with + $f(0)\neq 0$. We define a function $B_f:\mathbb{C}\to\mathbb{C}$ as follows. + $$B_f(z)=C_f(z)\prod_{\rho\in\mathcal{K}_f(r)} + \left(R-\frac{z\overline{\rho}}{R}\right)^{m_f(\rho)}$$ +-/ +open Classical in +/-- The zero-removed function multiplied by the reflected zero factors at radius `R`. -/ +noncomputable def BlaschkeB (r R : ℝ) (f : ℂ → ℂ) (z : ℂ) : ℂ := + if finite_zeros_mono : (SetOfZeros r f).Finite then (Cf r f) z * + (∏ ρ ∈ finite_zeros_mono.toFinset, (R - z * (conj ρ) / R) ^ (analyticOrderNatAt f ρ)) + else 1 + + + +/- +If $f:\mathbb{C}\to\mathbb{C}$ is analytic on $\overline{\mathbb{D}_R}$ then so too is $B_f$. +Expand out $B_f$ as a product, and observe that each part is analytic on + $\overline{\mathbb{D}_R}$. +-/ +lemma BlaschkeAnalytic {r R : ℝ} {f : ℂ → ℂ} + (r_pos : 0 < r) (r_lt_R : r < R) (R_lt_one : R < 1) + (finiteZeros : (SetOfZeros 1 f).Finite) + (hfAnalytic : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) 1)) + (hf_neq_zero_at_zero : f 0 ≠ 0) : + AnalyticOnNhd ℂ (BlaschkeB r R f) (Metric.closedBall (0 : ℂ) R) := by + have R_pos : 0 < R := lt_trans r_pos r_lt_R + have r_lt_one : r < 1 := lt_trans r_lt_R R_lt_one + unfold BlaschkeB + by_cases finite_zeros_mono : (SetOfZeros r f).Finite + · simp only [finite_zeros_mono, ↓reduceDIte] + refine AnalyticOnNhd.mul (CfAnalytic r_lt_R R_lt_one hfAnalytic hf_neq_zero_at_zero) + (Finset.analyticOnNhd_fun_prod (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset ?_) + intro w hw + refine AnalyticOnNhd.fun_pow + (AnalyticOnNhd.sub analyticOnNhd_const + (AnalyticOnNhd.div (AnalyticOnNhd.mul analyticOnNhd_id analyticOnNhd_const) + analyticOnNhd_const ?_)) _ + intro w' hw' + exact_mod_cast ne_of_gt R_pos + · simp only [finite_zeros_mono, ↓reduceDIte] + exact analyticOnNhd_const + + + +/- +Let $0 < r < R<1$, and $f:\mathbb{C}\to\mathbb{C}$ be analytic on $\overline{\mathbb{D}_1}$ with + $f(0)\neq 0$. Then + $$|B_f(0)|=|f(0)|\prod_{\rho\in\mathcal{K}_f(r)} + \left(\frac{R}{|\rho|}\right)^{m_f(\rho)}.$$ +Since $f(0)\neq 0$, we know that $0\not\in\mathcal{K}_f(r)$. Thus, + $$C_f(0)=\frac{f(0)}{\displaystyle\prod_{\rho\in\mathcal{K}_f(r)}(-\rho)^{m_f(\rho)}}.$$ + Thus, substituting this into Definition \ref{BlaschkeB}, + $$|B_f(0)|=|C_f(0)|\prod_{\rho\in\mathcal{K}_f(r)}R^{m_f(\rho)} + =|f(0)|\prod_{\rho\in\mathcal{K}_f(r)}\left(\frac{R}{|\rho|}\right)^{m_f(\rho)}.$$ +-/ +lemma BlaschkeOfZero {r R : ℝ} {f : ℂ → ℂ} + (r_pos : 0 < r) (r_lt_one : r < 1) (r_lt_R : r < R) + (finiteZeros : (SetOfZeros 1 f).Finite) + (hf_neq_zero_at_zero : f 0 ≠ 0) : + ‖BlaschkeB r R f 0‖ = ‖f 0‖ * + (∏ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + (R / ‖ρ‖) ^ (analyticOrderNatAt f ρ)) := by + have zero_not_zero : ¬(0 ∈ SetOfZeros r f) := by + apply notMem_ofPred_iff.mpr + simp only [norm_zero, not_and] + intro r + exact mem_support.mp hf_neq_zero_at_zero + unfold BlaschkeB Cf + simp only [finiteSetOfZeros_mono r_lt_one finiteZeros, zero_not_zero, ↓reduceDIte, zero_sub, + zero_mul, zero_div, sub_zero, Complex.norm_mul, Complex.norm_div, norm_prod, norm_pow, norm_neg, + norm_real, norm_eq_abs] + rw[div_eq_mul_inv, mul_assoc, abs_of_pos (by linarith)] + refine (mul_right_inj' (norm_ne_zero_iff.mpr hf_neq_zero_at_zero)).mpr ?_ + rw[← Finset.prod_inv_distrib, ← Finset.prod_mul_distrib] + simp only [div_eq_inv_mul, mul_pow, inv_pow] + + + +/- +Let $0 < r < R<1$, and $f:\mathbb{C}\to\mathbb{C}$ be analytic on $\overline{\mathbb{D}_1}$ with + $f(0)\neq 0$. Then + $$|f(0)|\leq|B_f(0)|.$$ +Applying lemma \ref{BlaschkeOfZero} we know that + $$|B_f(0)|=|f(0)|\prod_{\rho\in\mathcal{K}_f(r)} + \left(\frac{R}{|\rho|}\right)^{m_f(\rho)}.$$ + Note that for all $\rho\in\mathcal{K}_f(r)$ that $1 hw_not_in (h ▸ hw'_in))) + rw[Bf_eq_f_at_w] + exact fz_bound w (le_of_eq hw) + + + +/- +Let $0 < r < R<1$ and $f:\overline{\mathbb{D}_1}\to\mathbb{C}$ be analytic on + neighborhoods of points in $\overline{\mathbb{D}_1}$ with $f(0)\neq 0$. Then $B_f(z)\neq 0$ + for all $z\in\overline{\mathbb{D}_r}$. +Suppose that $z\in\mathcal{K}_f(r)$. Then we have that + $$C_f(z)=\frac{h_z(z)}{\displaystyle\prod_{\rho\in\mathcal{K}_f(r)\setminus\{z\}} + (z-\rho)^{m_f(\rho)}}.$$ + where $h_z(z)\neq 0$ according to Lemma \ref{ZeroFactorization}. Thus, substituting + this into Definition \ref{BlaschkeB}, + \begin{equation}\label{pickupPoint2} + |B_f(z)|=|h_z(z)|\cdot\left|R-\frac{|z|^2}{R}\right|^{m_f(z)} + \prod_{\rho\in\mathcal{K}_f(r)\setminus\{z\}} + \left|\frac{R-z\overline{\rho}/R}{z-\rho}\right|^{m_f(\rho)}. + \end{equation} + Trivially, $|h_z(z)|\neq 0$. Now note that + $$\left|R-\frac{|z|^2}{R}\right|=0\implies|z|=R.$$ + However, this is a contradiction because $z\in\overline{\mathbb{D}_r}$ tells us that + $|z|\leq r < R$. Similarly, note that + $$\left|\frac{R-z\overline{\rho}/R}{z-\rho}\right|=0\implies|z|=\frac{R^2}{|\overline{\rho}|}.$$ + However, this is also a contradiction because $\rho\in\mathcal{K}_f(r)$ tells us that + $R < R^2/|\overline{\rho}|=|z|$, but $z\in\overline{\mathbb{D}_r}$ tells us that + $|z|\leq r < R$. So, we know that + $$\left|R-\frac{|z|^2}{R}\right|\neq 0\qquad\text{and}\qquad + \left|\frac{R-z\overline{\rho}/R}{z-\rho}\right|\neq 0 + \quad\text{for all}\quad\rho\in\mathcal{K}_f(r)\setminus\{z\}.$$ + Applying this to Equation (\ref{pickupPoint2}) we have that $|B_f(z)|\neq 0$. + So, $B_f(z)\neq 0$. + Now suppose that $z\not\in\mathcal{K}_f(r)$. Then we have that + $$C_f(z)=\frac{f(z)}{\displaystyle\prod_{\rho\in\mathcal{K}_f(r)}(z-\rho)^{m_f(\rho)}}.$$ + Thus, substituting this into Definition \ref{BlaschkeB}, + \begin{equation}\label{pickupPoint3} + |B_f(z)|=|f(z)|\prod_{\rho\in\mathcal{K}_f(r)} + \left|\frac{R-z\overline{\rho}/R}{z-\rho}\right|^{m_f(\rho)}. + \end{equation} + We know that $|f(z)|\neq 0$ since $z\not\in\mathcal{K}_f(r)$. Now note that + $$\left|\frac{R-z\overline{\rho}/R}{z-\rho}\right|=0\implies|z|=\frac{R^2}{|\overline{\rho}|}.$$ + However, this is a contradiction because $\rho\in\mathcal{K}_f(r)$ tells us that + $R < R^2/|\overline{\rho}|=|z|$, but $z\in\overline{\mathbb{D}_r}$ tells us that + $|z|\leq r < R$. So, we know that + $$\left|\frac{R-z\overline{\rho}/R}{z-\rho}\right|\neq 0 + \quad\text{for all}\quad\rho\in\mathcal{K}_f(r).$$ + Applying this to Equation (\ref{pickupPoint3}) we have that $|B_f(z)|\neq 0$. + So, $B_f(z)\neq 0$. + We have shown that $B_f(z)\neq 0$ for both $z\in\mathcal{K}_f(r)$ and + $z\not\in\mathcal{K}_f(r)$, so the result follows. +-/ +lemma BlaschkeNonzero {r R : ℝ} {f : ℂ → ℂ} + (r_pos : 0 < r) (r_lt_R : r < R) (R_lt_one : R < 1) + (finiteZeros : (SetOfZeros 1 f).Finite) + (hfAnalytic : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) 1)) + (hf_neq_zero_at_zero : f 0 ≠ 0) : + ∀ z ∈ Metric.closedBall (0 : ℂ) r, BlaschkeB r R f z ≠ 0 := by + have r_lt_one : r < 1 := lt_trans r_lt_R R_lt_one + have R_pos : 0 < R := lt_trans r_pos r_lt_R + intro z hz + have hz_norm_le_r : ‖z‖ ≤ r := by rwa [mem_closedBall_iff_norm, sub_zero] at hz + have hz_norm_lt_R : ‖z‖ < R := by linarith + let hFin := finiteSetOfZeros_mono r_lt_one finiteZeros + have hBProd : ∏ ρ ∈ hFin.toFinset, + (↑R - z * (starRingEnd ℂ) ρ / ↑R) ^ analyticOrderNatAt f ρ ≠ 0 := by + apply Finset.prod_ne_zero_iff.mpr + intro ρ hρ + apply pow_ne_zero + norm_num [ sub_eq_zero, Complex.ext_iff ]; + simp only [SetOfZeros, Finite.mem_toFinset, mem_ofPred_eq] at hρ + rw [ eq_div_iff ] <;> norm_num [ Complex.normSq, Complex.norm_def ] at *; + · rw [Real.sqrt_lt' (by linarith)] at hz_norm_lt_R + rw [ Real.sqrt_le_iff ] at hρ + refine fun h => absurd h ?_ + nlinarith [sq_nonneg ( z.re - ρ.re ), sq_nonneg ( z.im - ρ.im ), + mul_lt_mul_of_pos_left r_lt_R R_pos] + · linarith + unfold BlaschkeB Cf + by_cases z_in_zeros : z ∈ SetOfZeros r f + · simp only [hFin, z_in_zeros, ↓reduceDIte] + obtain ⟨_, _, hne, heq⟩ := ZeroFactorization (by linarith) + (hfAnalytic.mono (Metric.closedBall_subset_closedBall (by linarith))) hf_neq_zero_at_zero + z_in_zeros + rw [heq.1] + refine mul_ne_zero (div_ne_zero hne (Finset.prod_ne_zero_iff.mpr fun ρ hρ => + pow_ne_zero _ (sub_ne_zero.mpr fun h => + (Finset.mem_sdiff.mp hρ).2 (Finset.mem_singleton.mpr h.symm)))) hBProd + · simp only [hFin, z_in_zeros, ↓reduceDIte] + refine mul_ne_zero (div_ne_zero (fun hfz => z_in_zeros ⟨hz_norm_le_r, hfz⟩) + (Finset.prod_ne_zero_iff.mpr fun ρ hρ => + pow_ne_zero _ (sub_ne_zero.mpr fun h => z_in_zeros (h ▸ hFin.mem_toFinset.mp hρ)))) hBProd + + + +/- +Let $0< r < R<1$. If $f:\mathbb{C}\to\mathbb{C}$ is a function analytic on + neighborhoods of points in $\overline{\mathbb{D}_1}$ with $f(0)=1$ and $|f(z)|\leq B$ + for $|z|\leq R$, then + $$\sum_{\rho\in\mathcal{K}_f(r)}m_f(\rho)\leq\frac{\log B}{\log(R/r)}.$$ +Since $f(0)=1$, by Lemma \ref{BlaschkeOfZero} we know that + $$|B_f(0)| + =|f(0)|\prod_{\rho\in\mathcal{K}_f(r)}\left(\frac{R}{|\rho|}\right)^{m_f(\rho)} + =\prod_{\rho\in\mathcal{K}_f(r)}\left(\frac{R}{|\rho|}\right)^{m_f(\rho)}.$$ + Thus, substituting this into Definition \ref{BlaschkeB}, + $$(R/r)^{\sum_{\rho\in\mathcal{K}_f(r)}m_f(\rho)} + =\prod_{\rho\in\mathcal{K}_f(r)}\left(\frac{R}{r}\right)^{m_f(\rho)} + \leq\prod_{\rho\in\mathcal{K}_f(r)}\left(\frac{R}{|\rho|}\right)^{m_f(\rho)} + =|B_f(0)|\leq B$$ + whereby Lemma \ref{DiskBound} we know that $|B_f(z)|\leq B$ for all $|z|\leq R$. + Taking the logarithm of both sides and rearranging gives the desired result. +-/ +theorem ZerosBound {B r R : ℝ} {f : ℂ → ℂ} + (r_pos : 0 < r) (r_lt_one : r < 1) (r_lt_R : r < R) (R_lt_one : R < 1) + (hfAnalytic : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) 1)) (hf0_eq_one : f 0 = 1) + (finiteZeros : (SetOfZeros 1 f).Finite) (fz_bound : ∀ z : ℂ, ‖z‖ ≤ R → ‖f z‖ ≤ B) : + ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, analyticOrderNatAt f ρ ≤ + 1 / Real.log (R / r) * Real.log B := by + have R_pos : 0 < R := lt_trans r_pos r_lt_R + have hf0_ne_zero : f 0 ≠ 0 := by rw [hf0_eq_one]; exact one_ne_zero + have blaschke_eq := BlaschkeOfZero r_pos r_lt_one r_lt_R finiteZeros hf0_ne_zero + rw[hf0_eq_one, norm_one, one_mul] at blaschke_eq + rw [one_div, inv_mul_eq_div, + le_div_iff₀ (Real.log_pos (by simp only [lt_div_iff₀ r_pos, one_mul, r_lt_R])), ← Real.log_pow] + refine Real.log_le_log (pow_pos (div_pos R_pos r_pos) _) ?_ + calc (R / r) ^ ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, analyticOrderNatAt f ρ + = ∏ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + (R / r) ^ analyticOrderNatAt f ρ := by + rw [Finset.prod_pow_eq_pow_sum] + _ ≤ ∏ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + (R / ‖ρ‖) ^ analyticOrderNatAt f ρ := by + apply Finset.prod_le_prod₀ + · intro ρ _ + exact pow_nonneg (div_nonneg (le_of_lt R_pos) (le_of_lt r_pos)) _ + · intro ρ hρ + have hρ_mem := (finiteSetOfZeros_mono r_lt_one finiteZeros).mem_toFinset.mp hρ + refine pow_le_pow_left₀ (div_nonneg (le_of_lt R_pos) (le_of_lt r_pos)) ?_ _ + refine div_le_div_of_nonneg_left (le_of_lt R_pos) (norm_pos_iff.mpr ?_) (hρ_mem.1) + rintro rfl + exact hf0_ne_zero hρ_mem.2 + _ ≤ B := by + rw[← blaschke_eq] + exact DiskBound r_pos r_lt_R R_lt_one finiteZeros hfAnalytic + hf0_ne_zero fz_bound (Metric.mem_closedBall_self (le_of_lt R_pos)) + + + +/- +Let $0 < r < R<1$. If $f:\mathbb{C}\to\mathbb{C}$ is a function analytic on + neighborhoods of points in $\overline{\mathbb{D}_1}$ with $f(0)=1$, define + $L_f(z)=J_{B_f}(z)$ where $J$ is from Theorem \ref{LogOfAnalyticFunction} and $B_f$ + is from Definition \ref{BlaschkeB}. +-/ +/-- An analytic logarithm of `BlaschkeB` on the smaller disk. -/ +noncomputable def JBlaschke {r' r R : ℝ} {f : ℂ → ℂ} + (r'_pos : 0 < r') (r'_lt_r : r' < r) (r_pos : 0 < r) (r_lt_R : r < R) (R_lt_one : R < 1) + (hfAnalytic : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) 1)) (hf0_eq_one : f 0 = 1) + (finiteZeros : (SetOfZeros 1 f).Finite) + (z : ℂ) : ℂ := (LogOfAnalyticFunction' r'_pos r'_lt_r r_lt_R + (BlaschkeAnalytic + r_pos r_lt_R R_lt_one finiteZeros hfAnalytic (hf0_eq_one ▸ one_ne_zero)) + (BlaschkeNonzero + r_pos r_lt_R R_lt_one finiteZeros hfAnalytic (hf0_eq_one ▸ one_ne_zero))).choose z + + + +/- +Let $B>1$ and $0 < r' < r < R<1$. If $f:\mathbb{C}\to\mathbb{C}$ is a function analytic + on neighborhoods of points in $\overline{\mathbb{D}_1}$ with $f(0)=1$ and $|f(z)|\leq B$ + for all $|z|\leq R$, then for all $|z|\leq r'$ + $$|L_f'(z)|\leq\frac{16\log(B)\,r^2}{(r-r')^3}.$$ +By Lemma \ref{DiskBound} we immediately know that $|B_f(z)|\leq B$ for all $|z|\leq R$. + Now since $L_f=J_{B_f}$ by Definition \ref{JBlaschke}, by Theorem + \ref{LogOfAnalyticFunction} we know that + $$L_f(0)=0\qquad\text{and}\qquad + \Re L_f(z)=\log|B_f(z)|-\log|B_f(0)|\leq\log|B_f(z)|\leq\log B$$ + for all $|z|\leq r$. Note that in the above + $$0=\log|f(0)|\leq\log|B_f(0)|$$ + because of Lemma \ref{norm_fOfZero_le_norm_BlaschkeOfZero}. So by + Theorem \ref{BorelCaratheodoryDeriv}, it follows that + $$|L_f'(z)|\leq\frac{16\log(B)\,r^2}{(r-r')^3}$$ + for all $|z|\leq r'$. +-/ +theorem JBlaschkeDerivBound {B r' r R : ℝ} {f : ℂ → ℂ} {z : ℂ} + (one_lt_B : 1 < B) + (r'_pos : 0 < r') (r'_lt_r : r' < r) (r_pos : 0 < r) (r_lt_R : r < R) (R_lt_one : R < 1) + (hfAnalytic : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) 1)) (hf0_eq_one : f 0 = 1) + (finiteZeros : (SetOfZeros 1 f).Finite) (fz_bound : ∀ z : ℂ, ‖z‖ ≤ R → ‖f z‖ ≤ B) + (hz : z ∈ Metric.closedBall (0 : ℂ) r') : + ‖deriv (JBlaschke r'_pos r'_lt_r r_pos r_lt_R R_lt_one hfAnalytic hf0_eq_one finiteZeros) z‖ + ≤ 16 * Real.log (B) * r ^ 2 / (r - r') ^ 3 := by + have r_pos : 0 < r := lt_trans r'_pos r'_lt_r + let blaschkeAnalytic := BlaschkeAnalytic r_pos r_lt_R R_lt_one finiteZeros hfAnalytic + (hf0_eq_one ▸ one_ne_zero) + let blaschkeNonzero := BlaschkeNonzero r_pos r_lt_R R_lt_one finiteZeros hfAnalytic + (hf0_eq_one ▸ one_ne_zero) + let logOfAnalytic := LogOfAnalyticFunction' r'_pos r'_lt_r r_lt_R blaschkeAnalytic blaschkeNonzero + set JB := logOfAnalytic.choose with JB_def + obtain ⟨JB_Analytic, JB_0_eq_0, deriv_JB_eq, JB_re⟩ := logOfAnalytic.choose_spec + rw [← JB_def] at JB_Analytic JB_0_eq_0 deriv_JB_eq JB_re + have JB_def' : JB = + (JBlaschke r'_pos r'_lt_r r_pos r_lt_R R_lt_one hfAnalytic hf0_eq_one finiteZeros) := by + unfold JBlaschke + rw [← JB_def] + rw[← JB_def'] + refine BorelCaratheodoryDeriv (Real.log_pos one_lt_B) r'_pos r'_lt_r (JB_Analytic.analyticOn) + JB_0_eq_0 ?_ hz + intro w hw + rw[← JB_re w hw] + have hwr : w ∈ Metric.closedBall (0 : ℂ) r := by exact Metric.ball_subset_closedBall hw + have hlog : 0 ≤ Real.log ‖BlaschkeB r R f 0‖ := by + rw [← Real.log_one] + apply Real.log_le_log zero_lt_one + rw [← norm_one (α := ℂ), ← hf0_eq_one] + exact norm_fOfZero_le_norm_BlaschkeOfZero r_pos r_lt_R R_lt_one finiteZeros + (hf0_eq_one ▸ one_ne_zero) + suffices h : Real.log ‖BlaschkeB r R f w‖ ≤ Real.log B by linarith + exact Real.log_le_log (norm_pos_iff.mpr (blaschkeNonzero w hwr)) + (DiskBound r_pos r_lt_R R_lt_one finiteZeros hfAnalytic (hf0_eq_one ▸ one_ne_zero) fz_bound + (Metric.closedBall_subset_closedBall r_lt_R.le hwr)) + + + +/- +Let $B>1$ and $0 < r' < r < R' < R<1$. If $f:\mathbb{C}\to\mathbb{C}$ is a function + analytic on neighborhoods of points in $\overline{\mathbb{D}_1}$ with $f(0)=1$ and + $|f(z)|\leq B$ for all $|z|\leq R$, then for all + $z\in\overline{\mathbb{D}_{r'}}\setminus\mathcal{K}_f(R')$ we have + $$\left|\frac{f'}{f}(z)-\sum_{\rho\in\mathcal{K}_f(r)}\frac{m_f(\rho)}{z-\rho}\right| + \leq\left(\frac{16r^2}{(r-r')^3}+\frac{1}{(R^2/R'-R')\,\log(R/R')}\right)\log B.$$ +Since $z\in\overline{\mathbb{D}_{r'}}\setminus\mathcal{K}_f(R')$ we know that + $z\not\in\mathcal{K}_f(R')$; thus, by Definition \ref{CFunction} we know that + $$C_f(z)=\frac{f(z)}{\displaystyle\prod_{\rho\in\mathcal{K}_f(r)}(z-\rho)^{m_f(\rho)}}.$$ + Substituting this into Definition \ref{BlaschkeB} we have that + $$B_f(z)=f(z)\prod_{\rho\in\mathcal{K}_f(r)} + \left(\frac{R-z\overline{\rho}/R}{z-\rho}\right)^{m_f(\rho)}.$$ + Taking the complex logarithm of both sides we have that + $$\mathrm{Log}\,B_f(z)=\mathrm{Log}\,f(z) + +\sum_{\rho\in\mathcal{K}_f(r)}m_f(\rho)\,\mathrm{Log}(R-z\overline{\rho}/R) + -\sum_{\rho\in\mathcal{K}_f(r)}m_f(\rho)\,\mathrm{Log}(z-\rho).$$ + Taking the derivative of both sides we have that + $$\frac{B_f'}{B_f}(z)=\frac{f'}{f}(z) + +\sum_{\rho\in\mathcal{K}_f(r)}\frac{m_f(\rho)}{z-R^2/\overline{\rho}} + -\sum_{\rho\in\mathcal{K}_f(r)}\frac{m_f(\rho)}{z-\rho}.$$ + By Definition \ref{JBlaschke} and Theorem \ref{LogOfAnalyticFunction}, + since $L_f(z)=J_{B_f}(z)$ we have $L_f'(z)=J'_{B_f}(z)=(B_f'/B_f)(z)$. Thus, + $$\frac{f'}{f}(z)-\sum_{\rho\in\mathcal{K}_f(r)}\frac{m_f(\rho)}{z-\rho} + =L_f'(z)-\sum_{\rho\in\mathcal{K}_f(r)}\frac{m_f(\rho)}{z-R^2/\overline{\rho}}.$$ + Now since $z\in\overline{\mathbb{D}_{r'}}\subseteq\overline{\mathbb{D}_{R'}}$ and + $\rho\in\mathcal{K}_f(r)\subseteq\mathcal{K}_f(R')$, we know that + $R^2/R'-R'\leq|z-R^2/\overline{\rho}|$. Thus by the triangle inequality we have + $$\left|\frac{f'}{f}(z)-\sum_{\rho\in\mathcal{K}_f(r)}\frac{m_f(\rho)}{z-\rho}\right| + \leq|L_f'(z)|+\left(\frac{1}{R^2/R'-R'}\right)\sum_{\rho\in\mathcal{K}_f(r)}m_f(\rho).$$ + Now by Theorem \ref{ZerosBound} and \ref{JBlaschkeDerivBound} we get our desired result + with a little algebraic manipulation. +-/ +theorem FinalBound {B r' r R' R : ℝ} {f : ℂ → ℂ} {z : ℂ} + (one_lt_B : 1 < B) (r'_pos : 0 < r') (r'_lt_r : r' < r) (r_lt_one : r < 1) (r_lt_R' : r < R') + (R'_lt_R : R' < R) (R_lt_one : R < 1) + (hfAnalytic : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) 1)) (hf0_eq_one : f 0 = 1) + (finiteZeros : (SetOfZeros 1 f).Finite) (fz_bound : ∀ z : ℂ, ‖z‖ ≤ R → ‖f z‖ ≤ B) + (hz : z ∈ Metric.closedBall (0 : ℂ) r' \ SetOfZeros R' f) : + ‖(deriv f z / f z) - ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + analyticOrderNatAt f ρ / (z - ρ)‖ ≤ + (16 * r ^ 2 / (r - r') ^ 3 + 1 / ((R ^ 2 / R' - R') * Real.log (R / R'))) * Real.log B := by + classical + have r'_lt_one : r' < 1 := lt_trans r'_lt_r r_lt_one + have r_pos : 0 < r := lt_trans r'_pos r'_lt_r + have R'_pos : 0 < R' := lt_trans r_pos r_lt_R' + have R_pos : 0 < R := lt_trans R'_pos R'_lt_R + have r_lt_R : r < R := lt_trans r_lt_R' R'_lt_R + have r'_lt_R : r' < R := lt_trans r'_lt_r r_lt_R + have rFiniteZeros: (SetOfZeros r f).Finite := finiteSetOfZeros_mono r_lt_one finiteZeros + have zNotInZeros : ¬(z ∈ SetOfZeros r f) := (fun hmem => hz.2 ⟨hmem.1.trans r_lt_R'.le, hmem.2⟩) + have z_norm : ‖z‖ ≤ r' := by simpa [Metric.mem_closedBall, dist_zero_right] using hz.1 + have ρ_mem : ∀ ρ ∈ rFiniteZeros.toFinset, ‖ρ‖ ≤ r ∧ f ρ = 0 := + fun ρ hρ => rFiniteZeros.mem_toFinset.mp hρ + have ρ_ne_zero : ∀ ρ ∈ rFiniteZeros.toFinset, ρ ≠ 0 := + fun ρ hρ h => one_ne_zero (hf0_eq_one ▸ h ▸ (ρ_mem ρ hρ).2) + have blaschke_sub_ne : ∀ ρ ∈ rFiniteZeros.toFinset, + (↑R : ℂ) - z * (starRingEnd ℂ) ρ / ↑R ≠ 0 := by + intro ρ hρ h + have : ‖z * (starRingEnd ℂ) ρ / (↑R : ℂ)‖ < R := by + rw [norm_div, Complex.norm_real, Real.norm_eq_abs, abs_of_pos R_pos, div_lt_iff₀ R_pos, + norm_mul, norm_conj] + exact mul_lt_mul (z_norm.trans_lt r'_lt_R) ((ρ_mem ρ hρ).1.trans_lt r_lt_R).le + (norm_pos_iff.mpr (ρ_ne_zero ρ hρ)) R_pos.le + rw [← sub_eq_zero.mp h] at this + simp [Complex.norm_real, abs_of_pos R_pos] at this + have fz_ne : f z ≠ 0 := fun h => zNotInZeros ⟨z_norm.trans r'_lt_r.le, h⟩ + have blaschke_prod_ne : ∀ ρ ∈ rFiniteZeros.toFinset, + ((↑R : ℂ) - z * (starRingEnd ℂ) ρ / ↑R) ^ analyticOrderNatAt f ρ ≠ 0 := + fun ρ hρ => pow_ne_zero _ (blaschke_sub_ne ρ hρ) + have hDiff_blaschke : ∀ ρ ∈ rFiniteZeros.toFinset, + DifferentiableAt ℂ + (fun w => ((↑R : ℂ) - w * (starRingEnd ℂ) ρ / ↑R) ^ analyticOrderNatAt f ρ) z := fun ρ _ => + ((differentiableAt_const _).sub ((differentiableAt_id.mul_const _).div_const _)).pow _ + have hDiff_sub : ∀ ρ ∈ rFiniteZeros.toFinset, + DifferentiableAt ℂ (fun w => (w - (ρ : ℂ)) ^ analyticOrderNatAt f ρ) z := fun ρ _ => + (differentiableAt_id.sub (differentiableAt_const _)).pow _ + have hpos : 0 < R ^ 2 / R' - R' := by + rw [sub_pos, lt_div_iff₀ R'_pos, ← sq] + apply pow_lt_pow_left₀ R'_lt_R R'_pos.le two_ne_zero + have LfBound := JBlaschkeDerivBound one_lt_B r'_pos r'_lt_r r_pos r_lt_R R_lt_one hfAnalytic + hf0_eq_one finiteZeros fz_bound hz.1 + have zerosBound : ↑(∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + analyticOrderNatAt f ρ) ≤ 1 / Real.log (R / R') * Real.log B := by + apply (ZerosBound r_pos r_lt_one r_lt_R R_lt_one hfAnalytic + hf0_eq_one finiteZeros fz_bound).trans + refine mul_le_mul_of_nonneg_right (one_div_le_one_div_of_le ?_ ?_) + (Real.log_nonneg (le_of_lt one_lt_B)) + · rw [← Real.log_one, Real.log_lt_log_iff zero_lt_one (div_pos R_pos R'_pos), one_lt_div R'_pos] + exact R'_lt_R + · rw [Real.log_le_log_iff (div_pos R_pos R'_pos) (div_pos R_pos r_pos)] + exact div_le_div_of_nonneg_left (le_of_lt R_pos) r_pos (le_of_lt r_lt_R') + suffices h1 : ‖deriv f z / f z - ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + ↑(analyticOrderNatAt f ρ) / (z - ρ)‖ ≤ + ‖deriv (JBlaschke r'_pos r'_lt_r r_pos r_lt_R R_lt_one hfAnalytic hf0_eq_one finiteZeros) z‖ + + 1 / (R ^ 2 / R' - R') * ↑(∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + analyticOrderNatAt f ρ) by + calc ‖deriv f z / f z - ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + ↑(analyticOrderNatAt f ρ) / (z - ρ)‖ + ≤ ‖deriv (JBlaschke r'_pos r'_lt_r r_pos r_lt_R R_lt_one hfAnalytic hf0_eq_one finiteZeros) z‖ + + 1 / (R ^ 2 / R' - R') * ↑(∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + analyticOrderNatAt f ρ) := h1 + _ ≤ 16 * Real.log B * r ^ 2 / (r - r') ^ 3 + + 1 / (R ^ 2 / R' - R') * (1 / Real.log (R / R') * Real.log B) := by + linarith [mul_le_mul_of_nonneg_left zerosBound (div_nonneg zero_le_one (le_of_lt hpos))] + _ = (16 * r ^ 2 / (r - r') ^ 3 + 1 / ((R ^ 2 / R' - R') * Real.log (R / R'))) * Real.log B := by + field_simp + suffices h2 : deriv f z / f z - ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + ↑(analyticOrderNatAt f ρ) / (z - ρ) = + deriv (JBlaschke r'_pos r'_lt_r r_pos r_lt_R R_lt_one hfAnalytic hf0_eq_one finiteZeros) z + - ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + ↑(analyticOrderNatAt f ρ) / (z - R ^ 2 / conj ρ) by + rw [h2, sub_eq_add_neg] + apply norm_add_le_of_le (le_rfl) + simp only [norm_neg, cast_sum, Finset.mul_sum, one_div_mul_eq_div] + apply (norm_sum_le _ _).trans (Finset.sum_le_sum (fun ρ hρ => ?_)) + rw [norm_div, RCLike.norm_natCast] + apply div_le_div_of_nonneg_left (Nat.cast_nonneg _) hpos + simp only [Set.mem_sdiff, Metric.mem_closedBall, dist_zero_right, SetOfZeros, + Finite.mem_toFinset, mem_ofPred_eq] at hρ hz + rw [norm_sub_rev] + calc R ^ 2 / R' - R' + ≤ ‖↑R ^ 2 / conj ρ‖ - ‖z‖ := by + refine sub_le_sub ?_ (hz.1.trans (r'_lt_r.le.trans r_lt_R'.le)) + rw [norm_div, norm_pow, norm_real, norm_eq_abs, abs_of_nonneg (le_of_lt R_pos)] + apply div_le_div_of_nonneg_left (sq_nonneg R) + (norm_pos_iff.mpr (star_ne_zero.mpr (fun h => one_ne_zero (hf0_eq_one ▸ h ▸ hρ.2)))) + rw [norm_star] + linarith [hρ.1] + _ ≤ ‖↑R ^ 2 / conj ρ - z‖ := norm_sub_norm_le _ _ + suffices h3 : deriv (BlaschkeB r R f) z / BlaschkeB r R f z = deriv f z / f z + + ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + ↑(analyticOrderNatAt f ρ) / (z - R ^ 2 / conj ρ) + - ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + ↑(analyticOrderNatAt f ρ) / (z - ρ) by + let blaschkeAnalytic := BlaschkeAnalytic r_pos r_lt_R R_lt_one finiteZeros hfAnalytic + (hf0_eq_one ▸ one_ne_zero) + let blaschkeNonzero := BlaschkeNonzero r_pos r_lt_R R_lt_one finiteZeros hfAnalytic + (hf0_eq_one ▸ one_ne_zero) + let logAnalytic := LogOfAnalyticFunction' r'_pos r'_lt_r r_lt_R blaschkeAnalytic blaschkeNonzero + set JB := logAnalytic.choose with JB_def + obtain ⟨JB_Analytic, JB_0_eq_0, deriv_JB_eq, JB_re⟩ := logAnalytic.choose_spec + rw [← JB_def] at JB_Analytic JB_0_eq_0 deriv_JB_eq JB_re + have JB_def' : JB = + (JBlaschke r'_pos r'_lt_r r_pos r_lt_R R_lt_one hfAnalytic hf0_eq_one finiteZeros) := by + unfold JBlaschke + rw [JB_def] + rw [eq_sub_iff_add_eq, sub_add_eq_add_sub, ← h3, ← JB_def', eq_comm] + exact deriv_JB_eq z hz.1 + suffices h4 : BlaschkeB r R f z = f z * + ∏ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + ((R - z * conj ρ / R) / (z - ρ)) ^ (analyticOrderNatAt f ρ) by + have sum1 : ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + logDeriv (fun z ↦ (R - z * conj ρ / R) ^ ↑(analyticOrderNatAt f ρ)) z = + ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + ↑(analyticOrderNatAt f ρ) / (z - R ^ 2 / conj ρ) := by + refine Finset.sum_congr rfl (fun ρ hρ => ?_) + rw [← logDeriv_pow, logDeriv_fun_pow, logDeriv_fun_pow, logDeriv_id', mul_eq_mul_left_iff] + · left + simp only [logDeriv, Pi.div_apply] + rw [deriv_fun_sub (differentiableAt_const _) ?_, deriv_div_const, + deriv_mul_const (differentiableAt_fun_id)] + · simp only [deriv_const', deriv_id'', one_mul, zero_sub] + rw [div_eq_div_iff (blaschke_sub_ne ρ hρ), one_mul, neg_mul, mul_sub, mul_div, neg_sub, + mul_comm _ z, ← mul_div_assoc, sub_left_inj] + · field_simp + exact mul_div_cancel_left₀ _ (star_ne_zero.mpr (ρ_ne_zero ρ hρ)) + · intro h; apply blaschke_sub_ne ρ hρ + have hconj : (starRingEnd ℂ) ρ ≠ 0 := star_ne_zero.mpr (ρ_ne_zero ρ hρ) + have hR : (↑R : ℂ) ≠ 0 := Complex.ofReal_ne_zero.mpr (ne_of_gt R_pos) + rw [sub_eq_zero.mp h, div_mul_cancel₀ _ hconj, sq, mul_div_cancel_right₀ _ hR, sub_self] + · simp only [differentiableAt_fun_id, differentiableAt_const, DifferentiableAt.fun_mul, + DifferentiableAt.div_const] + · simp only [differentiableAt_fun_id] + · simp only [differentiableAt_const, DifferentiableAt.fun_sub_iff_right, + differentiableAt_fun_id, DifferentiableAt.fun_mul, DifferentiableAt.div_const] + have sum2 : ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + logDeriv (fun z ↦ (z - ρ) ^ ↑(analyticOrderNatAt f ρ)) z = + ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + ↑(analyticOrderNatAt f ρ) / (z - ρ) := by + refine Finset.sum_congr rfl (fun ρ _ => ?_) + have : (fun z ↦ (z - ρ) ^ analyticOrderNatAt f ρ) = + (fun x ↦ x ^ analyticOrderNatAt f ρ) ∘ (fun z ↦ z - ρ) := by rfl + rw[← logDeriv_pow, this, logDeriv_comp] + · simp only [logDeriv_pow, differentiableAt_fun_id, differentiableAt_const, deriv_fun_sub, + deriv_id'', deriv_const', sub_zero, mul_one] + · simp only [differentiableAt_fun_id, DifferentiableAt.fun_pow] + · simp only [differentiableAt_fun_id, differentiableAt_const, DifferentiableAt.fun_sub] + unfold BlaschkeB Cf + simp only [rFiniteZeros, ↓reduceDIte, dite_eq_ite, ite_mul, ← logDeriv_apply, ← sum1, ← sum2] + rw [← logDeriv_fun_prod blaschke_prod_ne hDiff_blaschke, + ← logDeriv_fun_prod ?_ hDiff_sub, + ← logDeriv_mul _ fz_ne (Finset.prod_ne_zero_iff.mpr blaschke_prod_ne) + ((hfAnalytic z (Metric.closedBall_subset_closedBall r'_lt_one.le hz.1)).differentiableAt) + (DifferentiableAt.fun_finsetProd hDiff_blaschke), + ← logDeriv_div _ ?_ ?_ ?_ (DifferentiableAt.fun_finsetProd hDiff_sub)] + · have h_eq : ∀ᶠ w in nhds z, (if w ∈ SetOfZeros r f then + (ZeroFactor f w / ∏ ρ ∈ rFiniteZeros.toFinset \ {w}, (w - ρ) ^ analyticOrderNatAt f ρ) * + ∏ ρ ∈ rFiniteZeros.toFinset, (R - w * (starRingEnd ℂ) ρ / R) ^ analyticOrderNatAt f ρ + else (f w / ∏ ρ ∈ rFiniteZeros.toFinset, (w - ρ) ^ analyticOrderNatAt f ρ) * + ∏ ρ ∈ rFiniteZeros.toFinset, (R - w * (starRingEnd ℂ) ρ / R) ^ analyticOrderNatAt f ρ) = + (f w * ∏ ρ ∈ rFiniteZeros.toFinset, + (R - w * (starRingEnd ℂ) ρ / R) ^ analyticOrderNatAt f ρ) / ∏ ρ ∈ rFiniteZeros.toFinset, + (w - ρ) ^ analyticOrderNatAt f ρ := by + filter_upwards [(isOpen_compl_iff.mpr rFiniteZeros.isClosed).mem_nhds zNotInZeros] + with w hw using by rw [ite_eq_right hw]; ring + simp only [logDeriv, Pi.div_apply] + congr 1 + · apply Filter.EventuallyEq.deriv_eq h_eq + · convert h_eq.self_of_nhds using 1 + · exact mul_ne_zero fz_ne (Finset.prod_ne_zero_iff.mpr blaschke_prod_ne) + · simp only [ne_eq, Finset.prod_eq_zero_iff, Finite.mem_toFinset, pow_eq_zero_iff', + sub_eq_zero, ↓existsAndEq, zNotInZeros, true_and, false_and, not_false_eq_true] + · exact DifferentiableAt.mul + (hfAnalytic z (Metric.closedBall_subset_closedBall r'_lt_one.le hz.1)).differentiableAt + (DifferentiableAt.fun_finsetProd hDiff_blaschke) + · exact (fun ρ hρ => pow_ne_zero _ (sub_ne_zero.mpr fun h => + zNotInZeros (h ▸ rFiniteZeros.mem_toFinset.mp hρ))) + simp only [BlaschkeB, Cf, rFiniteZeros, ↓reduceDIte, zNotInZeros, div_mul_eq_mul_div, + mul_div_assoc, ← Finset.prod_div_distrib, div_pow] + + + +/- API analogous to HasProd.norm, Multipliable.norm, Multipliable.norm-tprod -/ + +variable {α R : Type*} [SeminormedCommRing R] [NormMulClass R] [NormOneClass R] + {f : α → R} {x : R} + +lemma _root_.HasProd.nnnorm (hfx : HasProd f x) : HasProd (‖f ·‖₊) ‖x‖₊ := by + simp only [HasProd, ← nnnorm_prod, SummationFilter.unconditional_filter] at ⊢ hfx + exact hfx.nnnorm + +theorem _root_.Multipliable.nnnorm (hf : Multipliable f) : Multipliable (‖f ·‖₊) := + let ⟨x, hx⟩ := hf; ⟨‖x‖₊, hx.nnnorm⟩ + +lemma _root_.Multipliable.nnnorm_tprod (hf : Multipliable f) : ‖∏' i, f i‖₊ = ∏' i, ‖f i‖₊ := + hf.hasProd.nnnorm.tprod_eq.symm + + + +/- +For all $t\in\mathbb{R}$ one has + $$|\zeta(3/2+it)|\geq\frac{\zeta(3)}{\zeta(3/2)}.$$ +From the Euler product expansion of $\zeta$, we have that for $\Re s>1$ + $$\zeta(s)=\prod_p\frac{1}{1-p^{-s}}.$$ + Thus, we have that + $$\frac{\zeta(2s)}{\zeta(s)}=\prod_p\frac{1-p^{-s}}{1-p^{-2s}}=\prod_p\frac{1}{1+p^{-s}}.$$ + Now note that $|1-p^{-(3/2+it)}|\leq 1+|p^{-(3/2+it)}|=1+p^{-3/2}$. Thus, + $$|\zeta(3/2+it)|=\prod_p\frac{1}{|1-p^{-(3/2+it)}|} + \geq\prod_p\frac{1}{1+p^{-3/2}}=\frac{\zeta(3)}{\zeta(3/2)}$$ + for all $t\in\mathbb{R}$ as desired. +-/ +lemma ZetaFixedLowerBound (t : ℝ) : + ‖ζ (3/2 + I * t)‖₊ ≥ ‖ζ 3 / ζ (3 / 2)‖₊ := by + have mp : ∀ {s : ℂ}, 1 < s.re → Multipliable fun p : Primes ↦ (1 - (p : ℂ) ^ (-s))⁻¹ := by + intro s hs + exact ⟨ζ s, riemannZeta_eulerProduct_hasProd hs⟩ + have h₁ : 1 < ((3 : ℂ) / 2).re := by norm_num + have h₂ : 1 < (3 : ℂ).re := by norm_num + have h₃ : 1 < (3 / 2 + I * (t : ℂ)).re := by norm_num + rw [nnnorm_div, ge_iff_le, + div_le_iff₀ (nnnorm_pos.mpr (riemannZeta_ne_zero_of_one_le_re (by norm_num))), + ← riemannZeta_eulerProduct_tprod h₁, ← riemannZeta_eulerProduct_tprod h₂, + ← riemannZeta_eulerProduct_tprod h₃, (mp h₁).nnnorm_tprod, (mp h₂).nnnorm_tprod, + (mp h₃).nnnorm_tprod, ← (mp h₃).nnnorm.tprod_mul (mp h₁).nnnorm] + refine (mp h₂).nnnorm.tprod_le_tprod (fun p ↦ ?_) ((mp h₃).nnnorm.mul (mp h₁).nnnorm) + simp only [nnnorm_inv, ← mul_inv] + have hfact : ‖1 - (p : ℂ) ^ (-3 : ℂ)‖₊ = + ‖1 + (p : ℂ) ^ ((-3 : ℂ) / 2)‖₊ * ‖1 - (p : ℂ) ^ (-((3 : ℂ) / 2))‖₊ := by + rw [← nnnorm_mul]; congr 1; ring_nf; rw [← Complex.cpow_nat_mul]; ring_nf + have hne : ∀ {s : ℂ}, 1 < s.re → (1 - (p : ℂ) ^ (-s)) ≠ 0 := + fun hs ↦ Complex.one_sub_prime_cpow_ne_zero p.2 hs + rw [inv_le_inv₀, hfact] + · apply _root_.mul_le_mul_left + rw [← norm_toNNReal, ← norm_toNNReal] + apply Real.toNNReal_le_toNNReal + calc ‖1 - (p : ℂ) ^ (-(3 / 2 + I * ↑t))‖ + ≤ 1 + ‖(p : ℂ) ^ (-(3 / 2 + I * ↑t))‖ := by + rw [← Complex.norm_of_nonneg zero_le_one]; exact norm_sub_le _ _ + _ = ‖1 + (p : ℂ) ^ (-(3 : ℂ) / 2)‖ := by + have : 0 ≤ 1 + (p : ℝ) ^ (-(3 : ℝ) / 2) := + by linarith [Real.rpow_nonneg (cast_nonneg' ↑p) (-3 / 2)] + simp only [Complex.norm_natCast_cpow_of_pos (Nat.Prime.pos p.2), add_re, neg_re, mul_re, + I_re, ofReal_re, zero_mul, I_im, ofReal_im, mul_zero, sub_self, div_ofNat_re, re_ofNat, + neg_div', add_zero] + rw [← Real.norm_of_nonneg this, ← Complex.norm_real, Complex.ofReal_add, + Complex.ofReal_cpow (cast_nonneg' ↑p)] + push_cast; rfl + · exact norm_pos_iff.mpr (hne h₂) + · exact mul_pos (norm_pos_iff.mpr (hne h₃)) (norm_pos_iff.mpr (hne h₁)) + + + +/- +Let + $$\zeta_1(s)=1+\frac{1}{s-1}-s\int_1^\infty\{x\}\,x^{-s}\,\frac{dx}{x}.$$ +-/ +/-- The integral continuation of zeta to positive real part, with its pole at `1` separated. -/ +noncomputable def riemannZeta1 (s : ℂ) := 1 + 1 / (s - 1) - s * ∫ u in Ioi (1 : ℝ), + (Int.fract u : ℝ) * (u : ℂ) ^ (-s - 1) + +local notation "ζ₁" => riemannZeta1 + + + +/- +We have that + $$\zeta_1(s)=\zeta_0(1,s)$$ + where $\zeta_0(1,s)$ comes from Definition \ref{riemannZeta0}. +Note that + $$\zeta_0(1,s)=1+\frac{-1}{1-s}+\frac{-1}{2}+ + s\int_1^\infty\frac{\lfloor x\rfloor+1/2-x}{x^{s+1}}\,dx.$$ + With minor simplifications we have + $$\zeta_0(1,s)=1+\frac{1}{s-1}-\frac{1}{2}+ + \frac{s}{2}\int_1^\infty x^{-s-1}\,dx-s\int_1^\infty\{x\}\,x^{-s-1}\,dx.$$ + The first integral evaluates to $1/s$ (when $0<\mathfrak{R}s$), so this term when multiplied + by the $s/2$ cancels with the $-1/2$. This exactly gives $\zeta_1$. +-/ +lemma Zeta1AltFormula {s : ℂ} (hs : 0 < s.re) : + ζ₁ s = riemannZeta0 1 s := by + have := Int.self_sub_floor (R := ℝ) + have s_ne_zero : s ≠ 0 := by + intro h; have : s.re = 0 := by simp only [h, zero_re] + linarith + simp only [riemannZeta1, riemannZeta0, Finset.sum_range_succ, Finset.sum_range_zero, div_zero, + CharP.cast_eq_zero, zero_add, cast_one, one_cpow, ne_eq, one_ne_zero, not_false_eq_true, + div_self, Complex.zero_cpow s_ne_zero, zero_add, ← div_neg_eq_neg_div', neg_sub, Int.fract] + rw [sub_eq_add_neg, ← mul_neg, ← MeasureTheory.integral_neg] + nth_rewrite 2 [add_assoc] + rw [add_left_cancel_iff, neg_sub_left, add_comm 1 s] + simp only [← neg_mul, ← Complex.ofReal_neg, neg_sub, div_eq_mul_inv, one_mul, add_sub_right_comm, + add_mul, ← Complex.cpow_neg, neg_add, ← sub_eq_add_neg] + rw [MeasureTheory.integral_add, MeasureTheory.integral_const_mul, + integral_Ioi_cpow_of_lt _ zero_lt_one] + · push_cast; simp only [inv_neg, sub_add_cancel, one_cpow, + neg_div_neg_eq, one_div, mul_add, ← mul_assoc, mul_right_comm, mul_inv_cancel₀ s_ne_zero] + norm_num + · simp only [neg_re, one_re, sub_re] + linarith + · refine MeasureTheory.Integrable.mono' (integrableOn_Ioi_rpow_of_lt (by linarith) (by linarith)) + ?_ ?_ (g := fun u => u ^ ( -s.re - 1 )) + · apply Measurable.aestronglyMeasurable + refine Measurable.mul ?_ (Complex.measurable_ofReal.pow_const _) + exact (Measurable.of_discrete.comp Int.measurable_floor).sub Complex.measurable_ofReal + · filter_upwards [MeasureTheory.ae_restrict_mem measurableSet_Ioi] with x hx + norm_num [Complex.norm_cpow_eq_rpow_re_of_pos ( zero_lt_one.trans hx )] + apply mul_le_of_le_one_left (Real.rpow_nonneg (by linarith [hx.out]) _) + norm_cast; rw [← norm_neg, neg_sub, ← Int.fract, Real.norm_of_nonneg (Int.fract_nonneg _)] + exact (Int.fract_lt_one _).le + · refine MeasureTheory.Integrable.mono' (integrableOn_Ioi_rpow_of_lt (by linarith) (by linarith)) + ?_ ?_ (g := fun u => u ^ ( -s.re - 1 )) + · apply Measurable.aestronglyMeasurable + exact measurable_const.mul (Complex.measurable_ofReal.pow_const _) + · filter_upwards [MeasureTheory.ae_restrict_mem measurableSet_Ioi] with x hx + norm_num [Complex.norm_cpow_eq_rpow_re_of_pos ( zero_lt_one.trans hx )] + exact mul_le_of_le_one_left (Real.rpow_nonneg (by linarith [hx.out]) _) (one_half_lt_one).le + + + +/- +We have that + $$\zeta(s)=\zeta_1(s)$$ + for all $s\in S$ with $S=\{s\in\mathbb{C}:0<\mathfrak{R}s,\,s\neq 1\}$. +This immediately follows from Lemmas \ref{Zeta1AltFormula} and \ref{Zeta0EqZeta}. +-/ +lemma ZetaAltFormula {s : ℂ} (hs : 0 < s.re) (hs' : s ≠ 1) : + ζ s = ζ₁ s:= by + rw [Zeta1AltFormula hs, ← Zeta0EqZeta zero_lt_one hs hs'] + + + +/- +For all $s\in\mathbb{C}$ with $|s|\leq 1$ and $t\in\mathbb{R}$ with $|t|\geq 2$, we have that + $$|\zeta(s+3/2+it)|\leq 7+2\,|t|.$$ +For the sake of clearer proof writing let $z=s+3/2+it$. Since $|s|\leq 1$ we know that + $1/2\leq\mathfrak{R}z$; additionally, as $|t|\geq 2$, we know $1\leq|\mathfrak{I}z|$. + So, $z\in S$. Thus, from Lemma \ref{ZetaAltFormula} we know that + $$|\zeta(z)|\leq 1+\frac{1}{|z-1|} + +|z|\cdot\left|\int_1^\infty\{x\}\,x^{-z}\,\frac{dx}{x}\right|$$ + by applying the triangle inequality. Now note that $|z-1|\geq 1$. Likewise, + $$|z|\cdot\left|\int_1^\infty\{x\}\,x^{-z}\,\frac{dx}{x}\right| + \leq|z|\int_1^\infty|\{x\}\,x^{-z-1}|\,dx + \leq|z|\int_1^\infty x^{-\Re z-1}\,dx=\frac{|z|}{\Re z}\leq 2\,|z|.$$ + Thus we have that, + $$|\zeta(s+3/2+it)|=|\zeta(z)|\leq 1+1+2\,|z|=2+2\,|s+3/2+it| + \leq2+2\,|s|+3+2\,|it|\leq 7+2\,|t|.$$ +-/ +theorem GlobalBound + {s : ℂ} (hs : ‖s‖ ≤ 1) {t : ℝ} (ht : |t| ≥ 2) : + ‖ζ (s + 3 / 2 + I * t)‖ ≤ 7 + 2 * |t| := by + have sReLB : -1 ≤ s.re := by linarith [abs_le.mp ((Complex.abs_re_le_norm s).trans hs)] + have hz : s + 3 / 2 + I * ↑t ∈ {s | 0 < s.re ∧ s ≠ 1} := by + simp only [ne_eq, Complex.ext_iff, one_re, one_im, not_and, mem_ofPred_eq, add_re, div_ofNat_re, + re_ofNat, mul_re, I_re, ofReal_re, zero_mul, I_im, ofReal_im, mul_zero, sub_self, add_zero, + add_im, div_ofNat_im, im_ofNat, zero_div, mul_im, one_mul, zero_add] + refine ⟨by linarith, fun hs => ?_⟩ + cases abs_cases t <;> linarith [abs_le.mp (Complex.abs_re_le_norm s), + abs_le.mp (Complex.abs_im_le_norm s)] + have leadingTerms : ‖1 + 1 / (s + 3 / 2 + I * ↑t - 1)‖ ≤ 2 := by + rw [← one_add_one_eq_two (R := ℝ)] + apply norm_add_le_of_le (norm_one.le) + rw [norm_div, norm_one, div_le_one (norm_pos_iff.mpr (sub_ne_zero.mpr hz.2))] + simp only [norm_def, normSq, MonoidWithZeroHom.coe_mk, ZeroHom.coe_mk, sqrt_le_one, sub_re, + add_re, div_ofNat_re, re_ofNat, mul_re, I_re, ofReal_re, zero_mul, I_im, ofReal_im, mul_zero, + sub_self, add_zero, one_re, sub_im, add_im, div_ofNat_im, im_ofNat, zero_div, mul_im, one_mul, + zero_add, one_im, sub_zero, one_le_sqrt] at ⊢ hs + cases abs_cases t <;> nlinarith [sq_nonneg (s.re + 1 / 2), sq_nonneg (s.im + t - 1), + sq_nonneg (s.im + t + 1)] + have domBound {x : ℝ} (hu : x ∈ Ioi 1) : |Int.fract x| * ‖(x : ℂ) ^ (-(s + 3 / 2 + I * ↑t) - 1)‖ + ≤ x ^ (-(s.re + 3 / 2) - 1) := by + rw [mem_Ioi] at hu + rw [Complex.norm_cpow_eq_rpow_re_of_pos (by linarith)] + simp only [neg_add_rev, sub_re, add_re, neg_re, mul_re, I_re, ofReal_re, zero_mul, I_im, one_re, + ofReal_im, mul_zero, sub_self, neg_zero, div_ofNat_re, re_ofNat, zero_add, Int.abs_fract] + refine mul_le_of_le_one_left (by apply Real.rpow_nonneg (by linarith)) ((Int.fract_lt_one x).le) + have domIntegral : Integrable (fun x : ℝ => x ^ (-(s.re + 3 / 2) - 1)) + (volume.restrict (Set.Ioi 1)) := integrableOn_Ioi_rpow_of_lt (by linarith) zero_lt_one + have hint : ‖∫ (u : ℝ) in Ioi 1, (↑(Int.fract u) : ℂ) * (u : ℂ) ^ (-(s + 3 / 2 + I * ↑t) - 1)‖ + ≤ 1 / (s.re + 3 / 2) := by + refine (MeasureTheory.norm_integral_le_integral_norm _).trans ?_ + have hI := integral_Ioi_rpow_of_lt (a := -(s.re + 3 / 2) - 1) (by linarith) one_pos + simp only [sub_add_cancel, one_rpow, neg_div_neg_eq] at hI + simp only [Complex.norm_mul, norm_real, norm_eq_abs, ← hI] + refine integral_mono_ae (domIntegral.mono' (((measurable_fract.abs).mul + ((Complex.measurable_ofReal.pow_const _).norm)).aestronglyMeasurable) ?_) domIntegral + (by filter_upwards [self_mem_ae_restrict measurableSet_Ioi] with x hx using domBound hx) + filter_upwards [ae_restrict_mem measurableSet_Ioi] with x hx + rw [norm_mul, norm_eq_abs, abs_abs, norm_norm] + exact domBound hx + have z_norm : ‖s + 3 / 2 + I * ↑t‖ ≤ 5 / 2 + |t| := by + have It_norm : ‖I * (↑t : ℂ)‖ = |t| := + by rw [norm_mul, norm_I, one_mul, Complex.norm_real, Real.norm_eq_abs] + have threeHalves_norm : ‖(3 / 2 : ℂ)‖ = 3 / 2 := + by rw [norm_div, Complex.norm_ofNat, Complex.norm_ofNat] + apply le_trans + (norm_add_le_of_le (norm_add_le_of_le hs (le_of_eq threeHalves_norm)) (le_of_eq It_norm)) + linarith + have hmul : ‖(s + 3 / 2 + I * ↑t) * ∫ (u : ℝ) in Ioi 1, + (↑(Int.fract u) : ℂ) * (u : ℂ) ^ (-(s + 3 / 2 + I * ↑t) - 1)‖ ≤ 5 + 2 * |t| := by + rw [norm_mul] + have hinv : (1 : ℝ) / (s.re + 3 / 2) ≤ 2 := by rw [div_le_iff₀ (by linarith)]; linarith + apply le_trans + (mul_le_mul z_norm (hint.trans hinv) (norm_nonneg _) (by linarith [abs_nonneg t])) + linarith + rw [ZetaAltFormula hz.1 hz.2] + exact (norm_sub_le_of_le leadingTerms hmul).trans (by linarith) + + + +/- +If $a,b\in\mathbb{R}$ with $1 ((n + 2 : ℝ) ^ c)⁻¹) := by + exact_mod_cast (summable_nat_add_iff 2).2 (Real.summable_nat_rpow_inv.2 hc) + simp only [zeta_rw (hb.trans hab), rpow_eq_pow, one_div, norm_real, norm_eq_abs, zeta_rw hb, + gt_iff_lt] + repeat rw [abs_of_nonneg] + · rw [tsum_eq_zero_add' (f := fun n : ℕ => (_ ^ a)⁻¹), + tsum_eq_zero_add' (f := fun n : ℕ => (_ ^ b)⁻¹)] + · simp only [CharP.cast_eq_zero, zero_add, one_rpow, inv_one, cast_add, cast_one, + add_lt_add_iff_left, add_assoc, one_add_one_eq_two] + have h : ∀ n : ℕ, ((n + 2 : ℝ) ^ a)⁻¹ < ((n + 2 : ℝ) ^ b)⁻¹ := fun _ => + inv_strictAnti₀ (Real.rpow_pos_of_pos (by positivity) b) + (Real.rpow_lt_rpow_of_exponent_lt (by linarith) hab) + exact Summable.tsum_strict_mono (hsum (hb.trans hab)) (hsum hb) + (Pi.lt_def.mpr ⟨fun n => (h n).le, 0, h 0⟩) + · push_cast; simpa [add_assoc, one_add_one_eq_two] using hsum hb + · push_cast; simpa [add_assoc, one_add_one_eq_two] using hsum (hb.trans hab) + all_goals exact tsum_nonneg fun n => inv_nonneg.mpr (rpow_nonneg (by positivity) _) + + + +/- API for analyticOrderNatAt -/ +lemma analyticOrderNatAt_fun_div_const {c z : ℂ} {f : ℂ → ℂ} + (hc : c ≠ 0) (hfAnalytic : AnalyticAt ℂ f z) : + analyticOrderNatAt (fun z => f z / c) z = analyticOrderNatAt f z := by + simp only [analyticOrderNatAt, div_eq_inv_mul, ← Pi.mul_def] + rw [analyticOrderAt_mul analyticAt_const hfAnalytic, analyticOrderAt_eq_zero.mpr, zero_add] + exact .inr (inv_ne_zero hc) + + + +/- +Let $t\in\mathbb{R}$ with $|t|\geq 2$ and $0 < r' < r < R' < R<1$. If + $f(z)=\zeta(z+3/2+it)$, then for all + $z\in\overline{\mathbb{D}_{r'}}\setminus\mathcal{K}_f(R')$ we have that + $$\left|\frac{f'}{f}(z)-\sum_{\rho\in\mathcal{K}_f(r)}\frac{m_f(\rho)}{z-\rho}\right| + \ll\left(\frac{16r^2}{(r-r')^3}+\frac{1}{(R^2/R'-R')\,\log(R/R')}\right)\log|t|.$$ +Let $g(z)=\zeta(z+3/2+it)/\zeta(3/2+it)$. Note that $g(0)=1$ and for $|z|\leq R$ + $$|g(z)|=\frac{|\zeta(z+3/2+it)|}{|\zeta(3/2+it)|} + \leq\frac{\zeta(3/2)}{\zeta(3)}\cdot(7+2\,|t|)\leq\frac{13\,\zeta(3/2)}{3\,\zeta(3)}\,|t|$$ + by Theorems \ref{ZetaFixedLowerBound} and \ref{GlobalBound}. Thus by Theorem + \ref{FinalBound} we have that + $$\left|\frac{g'}{g}(z)-\sum_{\rho\in\mathcal{K}_g(r)}\frac{m_g(\rho)}{z-\rho}\right| + \leq\left(\frac{16r^2}{(r-r')^3}+\frac{1}{(R^2/R'-R')\,\log(R/R')}\right) + \left(\log|t|+\log\left(\frac{13\,\zeta(3/2)}{3\,\zeta(3)}\right)\right).$$ + Now note that $f'/f=g'/g$, $\mathcal{K}_f(r)=\mathcal{K}_g(r)$, and + $m_g(\rho)=m_f(\rho)$ for all $\rho\in\mathcal{K}_f(r)$. Thus we have that, + $$\left|\frac{f'}{f}(z)-\sum_{\rho\in\mathcal{K}_f(r)}\frac{m_f(\rho)}{z-\rho}\right| + \ll\left(\frac{16r^2}{(r-r')^3}+\frac{1}{(R^2/R'-R')\,\log(R/R')}\right)\log|t|$$ + where the implied constant $C$ is taken to be + $$C\geq 1+\frac{\log(11\,\zeta(3/2)/\zeta(3))}{\log 2}.$$ +-/ +theorem LogDerivZetaFinalBound {r' r R' R : ℝ} (r'_pos : 0 < r') (r'_lt_r : r' < r) + (r_lt_one : r < 1) (r_lt_R' : r < R') (R'_lt_R : R' < R) (R_lt_one : R < 1) : + ∃ (C : ℝ), C > 0 ∧ + ∀ (t : ℝ), |t| ≥ 2 → + let f : ℂ → ℂ := fun z ↦ ζ (z + 3 / 2 + I * (t : ℂ)); + (finiteZeros : (SetOfZeros 1 f).Finite) → + ∀ (z : ℂ), z ∈ Metric.closedBall (0 : ℂ) r' \ SetOfZeros R' f → + ‖(deriv f z / f z) - ∑ ρ ∈ (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset, + analyticOrderNatAt f ρ / (z - ρ)‖ ≤ (16 * r ^ 2 / (r - r') ^ 3 + + 1 / ((R ^ 2 / R' - R') * Real.log (R / R'))) * (C * Real.log |t|) := by + have one_lt_zeta_div : (1 : ℝ) < ‖ζ ((3 / 2) : ℝ)‖₊ / ‖ζ (3 : ℝ)‖₊ := by + rw [coe_nnnorm, coe_nnnorm, + one_lt_div (norm_pos_iff.mpr (riemannZeta_ne_zero_of_one_lt_re (by norm_num)))] + exact norm_zeta_strict_mono_ofReal (by linarith) (by linarith) + have hzd : (1 : ℝ) < (‖ζ (3 / 2)‖₊ / ‖ζ 3‖₊ : ℝ) := by + simpa only [ofReal_div, ofReal_ofNat] using one_lt_zeta_div + set C : ℝ := 1 + Real.log (11 * (‖ζ (3 / 2)‖₊ / ‖ζ 3‖₊)) / Real.log 2 with C_def + refine ⟨C, ?_, ?_⟩ + · rw [C_def, Real.log_mul (Ne.symm (OfNat.zero_ne_ofNat 11)) (by linarith)] + exact add_pos zero_lt_one + (div_pos (add_pos (Real.log_pos one_lt_ofNat) (Real.log_pos hzd)) (Real.log_pos one_lt_two)) + · intro t ht f finiteZeros z hz + set g : ℂ → ℂ := f / (fun z ↦ f 0) with g_def + have g_def' : g = fun z ↦ f z / f 0 := rfl + set B : ℝ := (7 + 2 * |t|) * (‖ζ (3 / 2)‖₊ / ‖ζ 3‖₊) with B_def + have one_lt_B : 1 < B := one_lt_mul (by linarith) hzd + have one_le_C : (1 : ℝ) ≤ 11 * (‖ζ (3 / 2)‖₊ / ‖ζ 3‖₊) := (one_lt_mul (by linarith) hzd).le + have f0nonzero : ¬f 0 = 0 := by + simp only [f, zero_add] + exact riemannZeta_ne_zero_of_one_lt_re (by norm_num) + have ifInStripNotOne {z : ℂ} (hnorm: ‖z‖ ≤ 1) : (z.re + 3 / 2 = 1 → ¬z.im + t = 0) := by + rw [← sq_le_one_iff₀ (norm_nonneg _), ← Complex.normSq_eq_norm_sq, + Complex.normSq_apply] at hnorm + intro hre him + have hre' : z.re = -(1/2 : ℝ) := by linarith + have him' : z.im = -t := by linarith + simp only [hre', him', neg_mul_neg] at hnorm + rw [← abs_two, ge_iff_le, ← sq_le_sq] at ht + nlinarith [hnorm, ht] + have gAnalytic : AnalyticOnNhd ℂ g (Metric.closedBall (0 : ℂ) 1) := by + simp only [g_def, f, zero_add] + intro z hz; rw [Metric.mem_closedBall, _root_.dist_zero_right] at hz + refine AnalyticAt.div_const + (AnalyticAt.comp (AnalyticAt.comp (analyticAt_riemannZeta ?_) analyticAt_id) + (AnalyticAt.add (AnalyticAt.add analyticAt_id analyticAt_const) analyticAt_const)) + simp only [Pi.add_apply, id_eq, ne_eq, Complex.ext_iff, add_re, div_ofNat_re, re_ofNat, + mul_re, I_re, ofReal_re, zero_mul, I_im, ofReal_im, mul_zero, sub_self, add_zero, one_re, + add_im, div_ofNat_im, im_ofNat, zero_div, mul_im, one_mul, zero_add, one_im, not_and] + exact ifInStripNotOne hz + have g0_eq_one : g 0 = 1 := by + simp only [g_def, Pi.div_apply, ne_eq, f0nonzero, not_false_eq_true, div_self] + have gFiniteZeros : (SetOfZeros 1 g).Finite := by + simp only [SetOfZeros, g_def, Pi.div_apply, div_eq_zero_iff, + or_iff_left f0nonzero] at ⊢ finiteZeros + exact finiteZeros + have gBound : ∀ z : ℂ, ‖z‖ ≤ R → ‖g z‖ ≤ B := by + intro z' hz' + simp only [B_def, g_def, f, zero_add, Pi.div_apply, Complex.norm_div] + rw [div_eq_mul_one_div] + refine mul_le_mul (GlobalBound (le_trans hz' R_lt_one.le) ht) ?_ + (one_div_nonneg.mpr (norm_nonneg _)) (by linarith) + rw [one_div_le (norm_pos_iff.mpr (riemannZeta_ne_zero_of_one_lt_re (by norm_num))), one_div, + inv_div, ← toReal_coe_nnnorm, ENNReal.coe_toReal, ← NNReal.coe_div, ← nnnorm_div] + · exact_mod_cast ZetaFixedLowerBound t + · simp only [coe_nnnorm, ← norm_div, norm_pos_iff, div_ne_zero_iff] + exact ⟨riemannZeta_ne_zero_of_one_lt_re (by norm_num), + riemannZeta_ne_zero_of_one_lt_re (by norm_num)⟩ + have ghz : z ∈ Metric.closedBall (0 : ℂ) r' \ SetOfZeros R' g := by + simp only [Set.mem_sdiff, Metric.mem_closedBall, _root_.dist_zero_right, SetOfZeros, + mem_ofPred_eq, not_and, g_def, Pi.div_apply, div_eq_zero_iff, not_or] at ⊢ hz + exact ⟨hz.1, fun hz' => ⟨hz.2 hz', f0nonzero⟩⟩ + have gFinalBound := FinalBound one_lt_B r'_pos r'_lt_r r_lt_one r_lt_R' R'_lt_R R_lt_one + gAnalytic g0_eq_one gFiniteZeros gBound ghz + have gFiniteZeros' : (finiteSetOfZeros_mono r_lt_one gFiniteZeros).toFinset = + (finiteSetOfZeros_mono r_lt_one finiteZeros).toFinset := by + simp only [SetOfZeros, g_def, Pi.div_apply, div_eq_zero_iff, or_iff_left f0nonzero] + suffices h1 : Real.log B ≤ C * Real.log |t| by + refine le_trans (le_of_eq ?_) (gFinalBound.trans ?_) + · apply congrArg norm + rw [gFiniteZeros'] + congr 1 + · simp only [g_def', deriv_div_const, div_div_div_cancel_right₀ f0nonzero] + · refine Finset.sum_congr rfl fun ρ hρ => ?_ + rw [div_left_inj', Nat.cast_inj, g_def', analyticOrderNatAt_fun_div_const f0nonzero] + · simp only [f] + refine AnalyticAt.comp (analyticAt_riemannZeta ?_) + (AnalyticAt.add (AnalyticAt.add analyticAt_id analyticAt_const) + (AnalyticAt.mul analyticAt_const analyticAt_const)) + simp only [SetOfZeros, Complex.ext_iff, zero_re, zero_im, Finite.mem_toFinset, add_re, + mem_ofPred_eq, ne_eq, div_ofNat_re, re_ofNat, mul_re, I_re, ofReal_re, zero_mul, + I_im, ofReal_im, mul_zero, sub_self, add_zero, one_re, add_im, div_ofNat_im, im_ofNat, + zero_div, mul_im, one_mul, zero_add, one_im, not_and] at ⊢ hρ + exact ifInStripNotOne (le_trans hρ.1 r_lt_one.le) + · simp only [SetOfZeros, Set.mem_sdiff, Metric.mem_closedBall, _root_.dist_zero_right, + mem_ofPred_eq, not_and, Finite.mem_toFinset] at hz hρ + intro h; rw [sub_eq_zero] at h; rw [h] at hz + exact (hz.2 (le_trans hρ.1 r_lt_R'.le)) hρ.2 + · refine mul_le_mul (by rfl) h1 (Real.log_nonneg one_lt_B.le) + (add_nonneg (div_nonneg (mul_nonneg (ofNat_nonneg' _) (sq_nonneg _)) + (pow_nonneg (sub_nonneg.mpr r'_lt_r.le) _)) + (div_nonneg zero_le_one (mul_nonneg (sub_nonneg.mpr ?_) + (Real.log_nonneg ((one_le_div (by linarith)).mpr R'_lt_R.le))))) + rw [le_div_iff₀ (by linarith)]; nlinarith + rw [add_mul, one_mul, div_mul_eq_mul_div, mul_div_assoc] + suffices h2 : Real.log B ≤ Real.log |t| + Real.log (11 * (↑‖ζ (3 / 2)‖₊ / ↑‖ζ 3‖₊)) by + exact le_trans h2 ((add_le_add_iff_left _).mpr (le_mul_of_one_le_right + (Real.log_nonneg one_le_C) ((one_le_div (Real.log_pos one_lt_two)).mpr + (log_le_log zero_lt_two (RCLike.ofReal_le_ofReal.mp ht))))) + rw [← Real.log_mul (by linarith) (by linarith), + log_le_log_iff (by linarith) (mul_pos (by linarith) (by linarith))] + simp only [← mul_assoc, B_def, coe_nnnorm] + exact mul_le_mul_of_nonneg_right (by linarith) (div_nonneg (norm_nonneg _) (norm_nonneg _)) + + + +/- +For all $|t|\geq 2$, if $f(z)=\zeta(z+3/2+it)$, then $f(z)$ has a finite number of zeros in + $\overline{\mathbb{D}_1}$. +If we suppose the opposite, i.e. that there are an infinite number of zeros in this region, then + $f\equiv 0$ by the identity theorem. This is a contradiction, so the statement must be true. +-/ +lemma ZetaShiftFiniteZeros {t : ℝ} (ht : |t| ≥ 2) + {f : ℂ → ℂ} (hf : f = fun z ↦ ζ (z + 3 / 2 + I * t)) : (SetOfZeros 1 f).Finite := by + by_contra hinf; rw [Set.not_finite] at hinf + have zerosSubset : SetOfZeros 1 f ⊆ Metric.closedBall (0 : ℂ) 1 := fun _ hx => by + simpa only [Metric.mem_closedBall, dist_zero_right] using hx.1 + obtain ⟨x, hxK, hacc⟩ := + hinf.exists_accPt_of_subset_isCompact (isCompact_closedBall 0 1) zerosSubset + have hfAnalytic : AnalyticOnNhd ℂ f (Metric.ball (0 : ℂ) 2) := by + intro z hz; simp only [Metric.mem_ball, Complex.dist_eq, sub_zero] at hz + simp only [hf, add_assoc] + refine AnalyticAt.fun_comp (analyticAt_riemannZeta fun h => ?_) + (analyticAt_id.fun_add analyticAt_const) + have him : z.im = -t := by + have := congr_arg Complex.im h; simp only [add_im, div_ofNat_im, im_ofNat, zero_div, mul_im, + I_re, ofReal_im, mul_zero, I_im, ofReal_re, one_mul, zero_add, one_im] at this + linarith + have abs_z_im := Complex.abs_im_le_norm z + rw [him, abs_neg] at abs_z_im + linarith + have hfeq : Set.EqOn f 0 (Metric.ball (0 : ℂ) 2) := by + refine AnalyticOnNhd.eqOn_zero_of_preconnected_of_mem_closure hfAnalytic + Metric.isPreconnected_ball (z₀ := x) ?_ ?_ + · simp only [Metric.mem_ball, Metric.mem_closedBall, dist_zero_right] at hxK ⊢ + linarith + · simp only [mem_closure_iff_clusterPt, ← accPt_principal_iff_clusterPt] + exact hacc.mono (principal_mono.mpr fun _ h => h.2) + have hne : f 0 ≠ 0 := by + simp only [hf, zero_add, ne_eq] + exact riemannZeta_ne_zero_of_one_lt_re (by norm_num) + exact hne (hfeq (Metric.mem_ball_self (by linarith))) + + + +/- +Let $\mathcal{Z}_t=\{\rho\in\mathbb{C}:\zeta(\rho)=0,\,|\rho-(3/2+it)|\leq 3/4\}$. +-/ +/-- The zeros of zeta within distance `3 / 4` of `3 / 2 + I * t`. -/ +def ZeroWindow (t : ℝ) : Set ℂ := {ρ : ℂ | ζ ρ = 0 ∧ ‖ρ - (3 / 2 + I * t)‖ ≤ 3 / 4} + + + +/- API for analyticOrderNatAt -/ +lemma analyticOrderNatAt_fun_comp_add_left (g : ℂ → ℂ) (c z : ℂ) : + analyticOrderNatAt (fun z : ℂ => g (c + z)) z = analyticOrderNatAt g (c + z) := by + have asComp : analyticOrderAt (g ∘ fun z : ℂ => c + z) z = analyticOrderAt g (c + z) := by + apply analyticOrderAt_comp_of_deriv_ne_zero (AnalyticAt.add analyticAt_const analyticAt_id) + simp only [differentiableAt_const, differentiableAt_id, deriv_add, deriv_const', deriv_id', + zero_add, ne_eq, one_ne_zero, not_false_eq_true] + simp only [analyticOrderNatAt, ← asComp, comp_def] + +lemma analyticOrderNatAt_fun_comp_add_right (g : ℂ → ℂ) (c z : ℂ) : + analyticOrderNatAt (fun z : ℂ => g (z + c)) z = analyticOrderNatAt g (z + c) := by + have asComp : analyticOrderAt (g ∘ fun z : ℂ => z + c) z = analyticOrderAt g (z + c) := by + apply analyticOrderAt_comp_of_deriv_ne_zero (AnalyticAt.add analyticAt_id analyticAt_const) + simp only [differentiableAt_const, differentiableAt_id, deriv_add, deriv_const', deriv_id', + ne_eq, add_zero, one_ne_zero, not_false_eq_true] + simp only [analyticOrderNatAt, ← asComp, comp_def] + + + +/- +For all $\delta\in (0,1)$ and $t\in\mathbb{R}$ with $|t|\geq 2$ we have + $$\left|\frac{\zeta'}{\zeta}(1+\delta+it) + -\sum_{\rho\in\mathcal{Z}_t}\frac{m_\zeta(\rho)}{1+\delta+it-\rho}\right|\ll\log|t|.$$ +We apply Theorem \ref{LogDerivZetaFinalBound} where $r'=2/3$, $r=3/4$, $R'=4/5$, and + $R=5/6$. Thus, for all $z\in\overline{\mathbb{D}_{2/3}}\setminus\mathcal{K}_f(4/5)$ + we have that + $$\left|\frac{\zeta'}{\zeta}(z+3/2+it) + -\sum_{\rho\in\mathcal{K}_f(3/4)}\frac{m_f(\rho)}{z-\rho}\right|\ll\log|t|$$ + where $f(z)=\zeta(z+3/2+it)$ for $t\in\mathbb{R}$ with $|t|\geq 2$. Now if we let + $z=-1/2+\delta$, then $z\in(-1/2,1/2)\subseteq\overline{\mathbb{D}_{2/3}}$. + Additionally, $f(z)=\zeta(1+\delta+it)$, where $1+\delta+it$ lies in the zero-free + region where $\sigma>1$. Thus, $z\not\in\mathcal{K}_f(4/5)$. So, + $$\left|\frac{\zeta'}{\zeta}(1+\delta+it) + -\sum_{\rho\in\mathcal{K}_f(3/4)}\frac{m_f(\rho)}{-1/2+\delta-\rho}\right| + \ll\log|t|.$$ + But now note that if $\rho\in\mathcal{K}_f(3/4)$, then $\zeta(\rho+3/2+it)=0$ and + $|\rho|\leq 3/4$. Thus, $\rho+3/2+it\in\mathcal{Z}_t$ (the argument works in reverse as well). + Additionally, note that $m_f(\rho)=m_\zeta(\rho+3/2+it)$. So changing variables using these + facts gives us that + $$\left|\frac{\zeta'}{\zeta}(1+\delta+it) + -\sum_{\rho\in\mathcal{Z}_t}\frac{m_\zeta(\rho)}{1+\delta+it-\rho}\right| + \ll\log|t|.$$ +-/ +lemma SumBoundI : + ∃ (C : ℝ), C > 0 ∧ + ∀ (δ : ℝ), δ ∈ Ioo 0 1 → + ∀ (t : ℝ), |t| ≥ 2 → + ∀ (finiteZeros : (ZeroWindow t).Finite), + ‖ζ' (1 + δ + I * t) / ζ (1 + δ + I * t) - ∑ ρ ∈ finiteZeros.toFinset, + analyticOrderNatAt ζ ρ / (1 + δ + I * t - ρ)‖ ≤ C * Real.log |t| := by + let r' : ℝ := 2 / 3 + let r : ℝ := 3 / 4 + let R' : ℝ := 4 / 5 + let R : ℝ := 5 / 6 + have r'_pos : 0 < r' := by norm_num + have r'_lt_r : r' < r := by norm_num + have r_lt_one : r < 1 := by norm_num + have r_lt_R' : r < R' := by norm_num + have R'_lt_R : R' < R := by norm_num + have R_lt_one : R < 1 := by norm_num + obtain ⟨C, hC, LogDerivBound⟩ := + LogDerivZetaFinalBound r'_pos r'_lt_r r_lt_one r_lt_R' R'_lt_R R_lt_one + refine ⟨(16 * r ^ 2 / (r - r') ^ 3 + 1 / ((R ^ 2 / R' - R') * Real.log (R / R'))) * C, + by positivity, ?_⟩ + intro δ hd t ht finiteZeros + have LogDerivBound := LogDerivBound t ht + extract_lets f at LogDerivBound + have finiteZeros' : (SetOfZeros 1 f).Finite := by + apply ZetaShiftFiniteZeros ht + simp only [f] + have hd' : ‖(δ : ℂ) - 1 / 2‖ < 1 / 2 := by + obtain ⟨d0, d1⟩ := hd + simp only [← Complex.ofReal_one, ← Complex.ofReal_ofNat, ← Complex.ofReal_div, + ← Complex.ofReal_sub, Complex.norm_real, Real.norm_eq_abs, abs_lt] + exact ⟨by linarith, by linarith⟩ + set z : ℂ := δ - 1 / 2 with hz + have hz' : z ∈ Metric.closedBall (0 : ℂ) r' \ SetOfZeros R' f := by + simp only [SetOfZeros, f, Set.mem_sdiff, Metric.mem_closedBall, dist_zero_right, mem_ofPred_eq, + not_and] + refine ⟨le_of_lt (lt_trans hd' (by linarith)), fun _ => riemannZeta_ne_zero_of_one_lt_re ?_⟩ + simp only [add_re, div_ofNat_re, re_ofNat, mul_re, I_re, ofReal_re, zero_mul, I_im, ofReal_im, + mul_zero, sub_self, add_zero] + linarith [abs_lt.mp (lt_of_le_of_lt (Complex.abs_re_le_norm z) hd')] + have LogDerivBound := LogDerivBound finiteZeros' z hz' + refine le_trans (le_of_eq ?_) (LogDerivBound.trans (by rw [mul_assoc])) + apply congrArg norm + congr 1 + · simp only [f, hz, add_assoc, deriv_comp_add_const] + ring_nf + · simp only [f, hz] + refine Finset.sum_nbij' (fun ρ => ρ - (3 / 2 + I * t)) (fun ρ => ρ + (3 / 2 + I * t)) + (fun ρ hρ => ?_) (fun ρ hρ => ?_) (fun ρ hρ => by ring_nf) (fun ρ hρ => by ring_nf) + (fun ρ hρ => ?_) + · simp only [Set.Finite.mem_toFinset, SetOfZeros, ZeroWindow, Set.mem_ofPred_eq] at hρ ⊢ + refine ⟨?_, ?_⟩ + · simp only [r, hρ.2] + · simp only [add_assoc, sub_add_cancel, hρ.1] + · simp only [Set.Finite.mem_toFinset, SetOfZeros, ZeroWindow, Set.mem_ofPred_eq] at hρ ⊢ + refine ⟨?_, ?_⟩ + · simp only [← add_assoc, hρ.2] + · simp only [add_sub_cancel_right, r, hρ.1] + · ring_nf + rw [mul_comm, analyticOrderNatAt_fun_comp_add_left] + ring_nf + + + +/- +For all $\delta\in (0,1)$ and $t\in\mathbb{R}$ with $|t|\geq 2$ we have + $$-\Re \left(\frac{\zeta'}{\zeta}(1+\delta+2it)\right)\ll\log|t|.$$ +Note that, for $\rho\in\mathcal{Z}_{2t}$ + \begin{align*} + \Re \left(\frac{1}{1+\delta+2it-\rho}\right) + &=\Re \left(\frac{1+\delta-2it-\overline{\rho}} + {(1+\delta+2it-\rho)(1+\delta-2it-\overline{\rho})}\right) \\ + &=\frac{\Re (1+\delta-2it-\overline{\rho})}{|1+\delta+2it-\rho|^2} + =\frac{1+\delta-\Re \rho}{(1+\delta-\Re \rho)^2+(2t-\mathfrak{I}\rho)^2}. + \end{align*} + Now since $\rho\in\mathcal{Z}_{2t}$, we have that $|\rho-(3/2+2it)|\leq 3/4$. So, + we have $\Re \rho\in[3/4,9/4]$ and $\mathfrak{I}\rho\in[2t-3/4,2t+3/4]$. Additionally, + we know that $\zeta(\rho)=0$. This implies the stronger condition that $\Re \rho\in[3/4,1]$. + Thus, + $$\delta\leq 1+\delta-\Re \rho\qquad\text{and}\qquad + (1+\delta-\Re \rho)^2+(2t-\mathfrak{I}\rho)^2\leq 25/16+9/16=17/8.$$ + Which implies that + \begin{equation}\label{pickupPoint4} + 0<\frac{8}{17}\,\delta + \leq\frac{1+\delta-\Re \rho}{(1+\delta-\Re \rho)^2+(2t-\mathfrak{I}\rho)^2} + =\Re \left(\frac{1}{1+\delta+2it-\rho}\right). + \end{equation} + Note that, from Lemma \ref{SumBoundI}, we have + $$\sum_{\rho\in\mathcal{Z}_{2t}}m_\zeta(\rho)\, + \Re \left(\frac{1}{1+\delta+2it-\rho}\right) + -\Re \left(\frac{\zeta'}{\zeta}(1+\delta+2it)\right) + \leq\left|\frac{\zeta'}{\zeta}(1+\delta+2it) + -\sum_{\rho\in\mathcal{Z}_{2t}}\frac{m_\zeta(\rho)}{1+\delta+2it-\rho}\right| + \ll\log|2t|.$$ + Since $m_\zeta(\rho)\geq 0$ for all $\rho\in\mathcal{Z}_{2t}$, the inequality from + Equation (\ref{pickupPoint4}) tells us that by subtracting the sum from both sides + we have + $$-\Re \left(\frac{\zeta'}{\zeta}(1+\delta+2it)\right)\ll\log|2t|.$$ + Noting that $\log|2t|=\log(2)+\log|t|\leq2\log|t|$ completes the proof. +-/ +lemma ShiftTwoBound : + ∃ (C : ℝ), C > 0 ∧ + ∀ (δ : ℝ), δ ∈ Ioo 0 1 → + ∀ (t : ℝ), |t| ≥ 2 → + (ZeroWindow (2 * t)).Finite → + -(ζ' (1 + δ + 2 * I * t) / ζ (1 + δ + 2 * I * t)).re ≤ C * log |t| := by + obtain ⟨C, hC, SumBound⟩ := SumBoundI + refine ⟨C * 2, by positivity, ?_⟩ + intro δ hd t ht finiteZeros + suffices h1 : -(ζ' (1 + δ + 2 * I * t) / ζ (1 + δ + 2 * I * t)).re ≤ C * log |2 * t| by + refine le_trans h1 ?_ + rw [mul_assoc C, abs_mul, Real.log_mul (by norm_num) (by linarith [ht]), two_mul] + exact mul_le_mul (by rfl) (add_le_add (log_le_log (by norm_num) (by norm_num [ht])) (by rfl)) + (add_nonneg (Real.log_nonneg (by norm_num)) (Real.log_nonneg (by linarith [ht]))) hC.le + have ht' : |2 * t| ≥ 2 := by + simp only [abs_mul, abs_ofNat, ofNat_pos, le_mul_iff_one_le_right] + linarith + have SumBound := SumBound δ hd _ ht' finiteZeros; rw [← Complex.norm_neg', neg_sub] at SumBound + refine le_trans ?_ (le_trans (Complex.re_le_norm _) SumBound) + simp only [ofReal_mul, ofReal_ofNat, sub_re, re_sum, ← mul_assoc, mul_comm] + rw [sub_eq_add_neg, le_add_iff_nonneg_left] + refine Finset.sum_nonneg (fun ρ hρ => ?_); simp only [ZeroWindow, ofReal_mul, ofReal_ofNat, + Finite.mem_toFinset, mem_ofPred_eq] at hρ + have hρ_re: ρ.re ≤ 1 := by + by_contra hre; simp only [not_le] at hre + exact riemannZeta_ne_zero_of_one_lt_re hre hρ.1 + simp only [div_re, natCast_re, sub_re, add_re, one_re, ofReal_re, mul_re, I_re, zero_mul, I_im, + ofReal_im, mul_zero, sub_self, re_ofNat, mul_im, ← sq, ne_eq, OfNat.ofNat_ne_zero, + not_false_eq_true, zero_pow, one_mul, zero_add, im_ofNat, add_zero, normSq_apply, sub_im, + add_im, one_im, natCast_im, zero_div] + exact div_nonneg (mul_nonneg (cast_nonneg' _) (by linarith [hd.1])) + (add_nonneg (sq_nonneg _) (sq_nonneg _)) + + + +/- +There exists $C>0$ such that for all $\delta\in(0,1)$ and $t\in\mathbb{R}$ with + $|t|\geq 2$; if $\zeta(\rho)=0$ with $\rho=\sigma+it$, then + $$-\Re \left(\frac{\zeta'}{\zeta}(1+\delta+it)\right) + \leq -\frac{1}{1+\delta-\sigma}+C\log|t|.$$ +Note that for $\rho'\in\mathcal{Z}_t$ + \begin{align*} + \mathfrak{R}\left(\frac{1}{1+\delta+it-\rho'}\right)&=\mathfrak{R}\left( + \frac{1+\delta-it-\overline{\rho'}}{(1+\delta+it-\rho')(1+\delta-it-\overline{\rho'})}\right) + \\ + &=\frac{\mathfrak{R}(1+\delta-it-\overline{\rho'})}{|1+\delta+it-\rho'|^2} + =\frac{1+\delta-\mathfrak{R}\rho'}{(1+\delta-\mathfrak{R}\rho')^2+(t-\mathfrak{I}\rho')^2}. + \end{align*} + Now since $\rho'\in\mathcal{Z}_t$, we have that $|\rho'-(3/2+it)|\leq 3/4$. So, we have + $\mathfrak{R}\rho'\in[3/4,9/4]$ and $\mathfrak{I}\rho'\in[t-3/4,t+3/4]$. Additionally, we know + that $\zeta(\rho')=0$. This implies the stronger condition that $\mathfrak{R}\rho'\in[3/4,1]$. + Thus, + $$\delta\leq 1+\delta-\mathfrak{R}\rho' + \qquad\text{and}\qquad + (1+\delta-\mathfrak{R}\rho')^2+(t-\mathfrak{I}\rho')^2\leq 25/16+9/16=17/8.$$ + Which implies that + \begin{equation}\label{pickupPoint5} + 0<\frac{8}{17}\,\delta\leq\frac{1+\delta-\mathfrak{R}\rho'}{(1+\delta-\mathfrak{R}\rho')^2 + +(t-\mathfrak{I}\rho')^2}=\mathfrak{R}\left(\frac{1}{1+\delta+it-\rho'}\right). + \end{equation} + Note that, from Lemma \ref{SumBoundI}, we have + $$\sum_{\rho'\in\mathcal{Z}_t}m_\zeta(\rho')\,\mathfrak{R}\left( + \frac{1}{1+\delta+it-\rho'}\right)-\mathfrak{R}\left( + \frac{\zeta'}{\zeta}(1+\delta+it)\right)\leq + \left|\frac{\zeta'}{\zeta}(1+\delta+it) + -\sum_{\rho'\in\mathcal{Z}_t}\frac{m_\zeta(\rho')}{1+\delta+it-\rho'}\right|\ll\log|t|.$$ + Now we proceed via cases. If $\rho\in\mathcal{Z}_t$, then + $\mathcal{Z}_t=\rho\sqcup(\mathcal{Z}_t\setminus\rho)$ and the inequality from Equation + (\ref{pickupPoint5}) tells us that by subtracting the sum over all + $\rho'\in\mathcal{Z}_t\setminus\{\rho\}$ from both sides we have + $$\frac{m_\zeta(\rho)}{\mathfrak{R}(1+\delta+it-\rho)} + -\mathfrak{R}\left(\frac{\zeta'}{\zeta}(1+\delta+it)\right)\ll\log|t|.$$ + But of course we have that $\mathfrak{R}(1+\delta+it-\rho)=1+\delta-\sigma$. So subtracting this + term from both sides and recalling the implied constant we have + $$-\mathfrak{R}\left(\frac{\zeta'}{\zeta}(1+\delta+it)\right)\leq + -\frac{m_\zeta(\rho)}{1+\delta-\sigma}+C\log|t|.$$ + We have that $\sigma\leq 1$ since $\zeta$ is zero free on the right half plane $\sigma>1$. Thus, + $0<1+\delta-\sigma$. Noting this in combination with the fact that $1\leq m_\zeta(\rho)$ gives + us that + $$-\mathfrak{R}\left(\frac{\zeta'}{\zeta}(1+\delta+it)\right)\leq + -\frac{m_\zeta(\rho)}{1+\delta-\sigma}+C\log|t|\leq-\frac{1}{1+\delta-\rho}+(7+C)\log|t|.$$ + Now if $\rho\not\in\mathcal{Z}_t$, then $|\sigma-3/2|=|\rho-(3/2+it)|>3/4$ since + $\zeta(\rho)=0$. Additionally, $\sigma\leq 1$ since $\zeta(\rho)=0$, thus + $3/2-\sigma=|\sigma-3/2|>3/4$. So it follows that + $$\frac{1}{1+\delta-\sigma}<4<7\log 2\leq 7\log|t|.$$ + Thus, by subtracting the sum over $\rho'\in\mathcal{Z}_t$ from both sides we have + $$-\mathfrak{R}\left(\frac{\zeta'}{\zeta}(1+\delta+it)\right)\leq + C\log|t|\leq-\frac{1}{1+\delta-\rho}+(7+C)\log|t|.$$ +-/ +lemma ShiftOneBound : + ∃ (C : ℝ), C > 0 ∧ + ∀ (δ : ℝ), δ ∈ Ioo 0 1 → + ∀ (t : ℝ), |t| ≥ 2 → + (ZeroWindow t).Finite → + ∀ (ρ : ℂ), ζ ρ = 0 → + t = ρ.im → + -(ζ' (1 + δ + I * t) / ζ (1 + δ + I * t)).re ≤ C * Real.log |t| - 1 / (1 + δ - ρ.re) := by + obtain ⟨C, hC, SumBound⟩ := SumBoundI + refine ⟨7 + C, by linarith, ?_⟩ + intro δ hd t ht finiteZeros ρ hρzero hρim + have SumBound := SumBound δ hd t ht finiteZeros; rw [← Complex.norm_neg', neg_sub] at SumBound + have SumBound := le_trans (Complex.re_le_norm _) SumBound + have hρre : ρ.re < 1 := lt_of_not_ge fun h => riemannZeta_ne_zero_of_one_le_re h hρzero + have ρ_ne_one : ρ ≠ 1 := by rintro rfl; simp only [one_re, lt_self_iff_false] at hρre + have analyticOnNhdZeta : AnalyticOnNhd ℂ ζ {z : ℂ | z ≠ 1} := by + intro z hz; simp only [ne_eq, mem_ofPred_eq] at hz + exact DifferentiableOn.analyticAt (s := {z : ℂ | z ≠ 1}) + (fun z' hz' => (differentiableAt_riemannZeta hz').differentiableWithinAt) + ((isOpen_ne).mem_nhds hz) + have hTermNonneg {ρ' : ℂ} (hρ' : ρ' ∈ finiteZeros.toFinset) : + 0 ≤ ((analyticOrderNatAt ζ ρ') / (1 + ↑δ + I * ↑t - ρ')).re := by + simp only [div_re, natCast_re, add_re, one_re, ofReal_re, sub_re, mul_re, I_re, zero_mul, I_im, + ofReal_im, mul_zero, sub_self, natCast_im, add_im, one_im, add_zero, sub_im, mul_im, + one_mul, zero_add, zero_div] + refine div_nonneg (mul_nonneg (by positivity) ?_) (normSq_nonneg _) + by_contra h; push Not at h + simp only [ZeroWindow, Finite.mem_toFinset, mem_ofPred_eq] at hρ' + exact riemannZeta_ne_zero_of_one_le_re (by linarith [hd.1]) hρ'.1 + by_cases hρZt : ρ ∈ finiteZeros.toFinset + · have obvious : C * log |t| ≤ (7 + C) * log |t| := mul_le_mul (by linarith) (by rfl) + (Real.log_nonneg (by linarith)) (by linarith) + have SumBound := le_trans SumBound obvious + rw [← Finset.insert_erase hρZt, ← Finset.singleton_union, ← Finset.sdiff_singleton_eq_erase, + Finset.sum_union (by simp), Finset.sum_singleton] at SumBound + simp only [sub_re, add_re, re_sum, add_sub_assoc] at SumBound + rw [div_re] at SumBound + simp only [natCast_re, add_re, one_re, ofReal_re, sub_re, mul_re, I_re, zero_mul, I_im, add_im, + ofReal_im, mul_zero, sub_self, zero_sub, natCast_im, one_im, add_zero, sub_im, mul_im, ← hρim, + one_mul, zero_add, zero_div, normSq_apply, mul_div_assoc, div_self_mul_self', + ← one_div] at SumBound + refine le_sub_left_of_add_le (le_trans (add_le_add ?_ ?_) SumBound) + · rw [← mul_div_assoc, mul_one] + refine div_le_div_of_nonneg_right ?_ (by linarith [hd.1]) + simp only [one_le_cast, Nat.one_le_iff_ne_zero, analyticOrderNatAt, ne_eq, ENat.toNat_eq_zero, + analyticOrderAt_eq_zero, analyticOrderAt_eq_top, not_or, not_not] + refine ⟨⟨DifferentiableOn.analyticAt (s := {z : ℂ | z ≠ 1}) + (fun z hz => (differentiableAt_riemannZeta hz).differentiableWithinAt) + ((isOpen_ne).mem_nhds ρ_ne_one), hρzero⟩, + (fun h => riemannZeta_ne_zero_of_one_le_re (s := 2) (by norm_num) + (AnalyticOnNhd.eqOn_zero_of_preconnected_of_eventuallyEq_zero analyticOnNhdZeta (z₀ := ρ) + ((isConnected_compl_singleton_of_one_lt_rank ?_ 1).isPreconnected) ?_ ?_ ?_))⟩ + · simp only [rank_real_complex, one_lt_ofNat] + · simp only [ne_eq, mem_ofPred_eq, ρ_ne_one, not_false_eq_true] + · simp only [EventuallyEq, Pi.zero_apply, h] + · simp only [ne_eq, mem_ofPred_eq, OfNat.ofNat_ne_one, not_false_eq_true] + · simp only [← add_sub_assoc, neg_le_sub_iff_le_add, le_add_iff_nonneg_left] + refine Finset.sum_nonneg (fun ρ' hρ' => hTermNonneg ?_) + simp only [Finset.mem_sdiff] at hρ' + exact hρ'.1 + · have logBound : -(ζ' (1 + ↑δ + I * ↑t) / ζ (1 + ↑δ + I * ↑t)).re ≤ C * Real.log |t| := by + refine le_trans ?_ SumBound + rw [sub_eq_add_neg, add_re, neg_re, re_sum, le_add_iff_nonneg_left] + exact Finset.sum_nonneg (fun ρ' hρ' => hTermNonneg hρ') + have invBound : 1 / (1 + δ - ρ.re) ≤ 7 * Real.log |t| := by + suffices h1 : 1 / (1 + δ - ρ.re) ≤ 4 by + have explicitEstimate : 4 ≤ 7 * Real.log 2 := by linarith [Real.log_two_gt_d9] + exact le_trans h1 (le_trans explicitEstimate ((mul_le_mul_iff_of_pos_left ofNat_pos').mpr + (Real.log_le_log ofNat_pos' ht))) + simp only [ZeroWindow, Finite.mem_toFinset, mem_ofPred_eq, hρzero, true_and, not_le] at hρZt + rw [← Complex.re_add_im ρ, hρim] at hρZt + ring_nf at hρZt + have : - (3 : ℂ) / 2 + ρ.re = (((ρ.re - 3 / 2) : ℝ) : ℂ) := by + simp only [ofReal_sub, ofReal_div, ofReal_ofNat, neg_add_eq_sub, neg_div, neg_add_eq_sub] + rw [this, Complex.norm_real, Real.norm_eq_abs] at hρZt + have hρreImproved : ρ.re < 3 / 4 := by rcases lt_abs.mp hρZt with _ | _ <;> linarith + rw [one_div_le (by linarith [hd.1]) four_pos] + linarith [hd.1] + linarith + + + +/- +For all $\delta\in(0,1)$ we have + $$-\Re \left(\frac{\zeta'}{\zeta}(1+\delta)\right)\leq\frac{1}{\delta}+O(1).$$ +From Theorem \ref{riemannZetaLogDerivResidue} we know that + $$-\frac{\zeta'}{\zeta}(s)=\frac{1}{s-1}+O(1).$$ + Changing variables $s\mapsto 1+\delta$ and applying the triangle inequality we have that + $$-\Re \left(\frac{\zeta'}{\zeta}(1+\delta)\right)\leq\left| + -\frac{\zeta'}{\zeta}(1+\delta)\right|\leq\frac{1}{\delta}+O(1).$$ +-/ +lemma ShiftZeroBound : + ∃ (C : ℝ), C ≥ 1 ∧ + ∀ (δ : ℝ), δ ∈ Ioo 0 1 → + -(ζ' (1 + δ) / ζ (1 + δ)).re ≤ 1 / δ + C := by + have zetaAnalyticOnNhd : AnalyticOnNhd ℂ ζ {(1 : ℂ)}ᶜ := DifferentiableOn.analyticOnNhd + (fun _ hs => (differentiableAt_riemannZeta hs).differentiableWithinAt) isOpen_compl_singleton + have oneAddContinuous : Continuous (fun x : ℝ => (1 + (x : ℂ))) := + Continuous.add continuous_const continuous_ofReal + have ShiftZeroBoundNear : + ∃ (C r : ℝ), r ∈ Ioo 0 1 ∧ + ∀ (δ : ℝ), δ ∈ Ioo 0 r → + -(ζ' (1 + δ) / ζ (1 + δ)).re ≤ 1 / δ + C := by + obtain ⟨C, hC⟩ := riemannZetaLogDerivResidueBigO.bound + rcases Metric.mem_nhdsWithin_iff.mp hC with ⟨ε, εpos, hε⟩ + refine ⟨C, min ε (1 / 2), ⟨?_, fun δ δrange => ?_⟩⟩ + · simp only [one_div, mem_Ioo, lt_inf_iff, inv_pos, ofNat_pos, and_true, inf_lt_iff] + exact ⟨εpos, Or.inr two_inv_lt_one⟩ + · have δin : ((1 : ℂ) + δ) ∈ Metric.ball 1 ε ∩ {1}ᶜ := by + simp only [mem_inter_iff, Metric.mem_ball, dist_self_add_left, norm_real, norm_eq_abs, + mem_compl_iff, mem_singleton_iff, add_eq_left, ofReal_eq_zero, abs_lt] + exact ⟨⟨by linarith [δrange.1], by linarith [δrange.2, min_le_left ε (1 / 2)]⟩, + by linarith [δrange.1]⟩ + have reBound := (Complex.re_le_norm _).trans (hε δin) + simp only [Pi.sub_apply, Pi.div_apply, Pi.neg_apply, add_sub_cancel_left, sub_re, inv_re, + ofReal_re, normSq_ofReal, div_self_mul_self', Pi.one_apply, norm_one, mul_one, + tsub_le_iff_right] at reBound + simp only [one_div, ← Complex.neg_re, ← neg_div, add_comm _ C, reBound] + obtain ⟨C₀, r, rIn, boundNear⟩ := ShiftZeroBoundNear + have ShiftZeroBoundCompact : + ∃ (C : ℝ), ∀ (δ : ℝ), δ ∈ Icc r 1 → + -(ζ' (1 + δ) / ζ (1 + δ)).re ≤ 1 / δ + C := by + simp only [← sub_le_iff_le_add', ← Complex.neg_re] + refine ⟨_, fun δ hδ => le_csSup (IsCompact.bddAbove (isCompact_Icc.image_of_continuousOn ?_)) + (Set.mem_image_of_mem _ hδ)⟩ + refine ContinuousOn.add (Complex.continuous_re.comp_continuousOn + (ContinuousOn.neg (ContinuousOn.div (ContinuousOn.comp zetaAnalyticOnNhd.deriv.continuousOn + (by apply fun x hx => oneAddContinuous.continuousOn) ?_) + (ContinuousOn.comp zetaAnalyticOnNhd.continuousOn + (by apply fun x hx => oneAddContinuous.continuousOn) ?_) + (fun x hx => riemannZeta_ne_zero_of_one_lt_re ?_)))) (ContinuousOn.neg + (ContinuousOn.div continuousOn_const continuousOn_id ?_)) + · simp only [MapsTo, mem_Icc, mem_compl_iff, mem_singleton_iff, add_eq_left, + ofReal_eq_zero, and_imp] + exact fun x hx _ => by linarith [rIn.1, hx] + · simp only [MapsTo, mem_Icc, mem_compl_iff, mem_singleton_iff, add_eq_left, + ofReal_eq_zero, and_imp] + exact fun x hx _ => by linarith [rIn.1, hx] + · simp only [add_re, one_re, ofReal_re, lt_add_iff_pos_right] + linarith [rIn.1, hx.1] + · simp only [ne_eq] + exact fun x hx => by linarith [rIn.1, hx.1] + obtain ⟨C₁, boundCompact⟩ := ShiftZeroBoundCompact + refine ⟨1 + max |C₀| |C₁|, ?_, fun δ δrange => ?_⟩ + · simp only [ge_iff_le, le_add_iff_nonneg_right, le_sup_iff, abs_nonneg, or_self] + · by_cases δ_lt_r : δ < r + · have δIn : δ ∈ Ioo 0 r := by simp only [mem_Ioo, δrange.1, δ_lt_r, and_self] + apply le_trans (boundNear δ δIn) + simp only [one_div, add_le_add_iff_left] + linarith [le_abs_self C₀, le_max_left |C₀| |C₁|] + · have δIn : δ ∈ Icc r 1 := by + simp only [mem_Icc, δrange.2.le, ← not_lt, δ_lt_r, not_false_eq_true, and_self] + apply le_trans (boundCompact δ δIn) + simp only [one_div, add_le_add_iff_left] + linarith [le_abs_self C₁, le_max_right |C₀| |C₁|] + + + +/- +The series + $$\sum_{n=1}^\infty\frac{\Lambda(n)}{n^s}$$ + converges when $1<\mathfrak{R}(s)$. +We know that $\Lambda(n)$ is $O(n^\varepsilon)$ since it is bounded above by $\log(n)$. Thus, + $$\left|\sum_{n=1}^\infty\frac{\Lambda(n)}{n^s}\right|\leq + \sum_{n=1}^\infty\left|\frac{\Lambda(n)}{n^s}\right|\ll + \sum_{n=1}^\infty\frac{1}{n^{\mathfrak{R}(s)-\varepsilon}}.$$ + Since $\varepsilon$ can be arbitrarily small, we know the left hand side converges by the + $p$-test. +-/ +lemma vonMangoldtLSeriesSummable {s : ℂ} (hs : 1 < s.re) : + Summable (fun n : ℕ => (Λ n : ℂ) / (n : ℂ) ^ s) := by + refine (ArithmeticFunction.LSeriesSummable_vonMangoldt hs).congr (fun n => ?_) + by_cases heq0 : n = 0 <;> simp only [LSeries.term, heq0, ↓reduceIte, ArithmeticFunction.map_zero, + ofReal_zero, CharP.cast_eq_zero, zero_div] + + + +/- +For all $|t|\geq 2$, $\mathcal{Z}(t)$ contains a finite number of points. +If we suppose the opposite, i.e. that there are an infinite number of zeta zeros in this region, + then $\zeta\equiv 0$ by the identity theorem. This is a contradiction, so the statement must be + true. +-/ +lemma ZeroWindowFinite {t : ℝ} (ht : |t| ≥ 2) : (ZeroWindow t).Finite := by + by_contra hinf; rw [Set.not_finite] at hinf + have zerosSubset : ZeroWindow t ⊆ Metric.closedBall (3 / 2 + I * t) (3 / 4) := fun _ hx => by + simpa only [dist_eq_norm, Metric.mem_closedBall, ge_iff_le] using hx.2 + obtain ⟨x, hxK, hacc⟩ := + hinf.exists_accPt_of_subset_isCompact (isCompact_closedBall (3 / 2 + I * t) (3 / 4)) zerosSubset + have hfAnalytic : AnalyticOnNhd ℂ ζ (Metric.ball (3 / 2 + I * t) 1) := by + intro z hz; simp only [Metric.mem_ball, Complex.dist_eq] at hz + have him : |z.im| > 1 := by + have := abs_lt.mp (lt_of_le_of_lt (Complex.abs_im_le_norm (z - (3 / 2 + I * ↑t))) hz) + simp only [sub_im, add_im, div_ofNat_im, im_ofNat, zero_div, mul_im, I_re, ofReal_im, + mul_zero, I_im, ofReal_re, one_mul, zero_add, neg_lt_sub_iff_lt_add] at this + simp only [gt_iff_lt, lt_abs] + by_cases tpos : 0 < t + · rw [abs_of_pos tpos] at ht + exact Or.inl (by linarith) + · rw [abs_of_nonpos (not_lt.mp tpos)] at ht + exact Or.inr (by linarith) + refine analyticAt_riemannZeta (fun h => ?_) + simp only [h, one_im, gt_iff_lt, abs_zero] at him + linarith + have hfeq : Set.EqOn ζ 0 (Metric.ball (3 / 2 + I * t) 1) := by + refine AnalyticOnNhd.eqOn_zero_of_preconnected_of_mem_closure hfAnalytic + Metric.isPreconnected_ball (z₀ := x) ?_ ?_ + · simp only [Metric.mem_ball, Metric.mem_closedBall] at hxK ⊢ + linarith + · simp only [mem_closure_iff_clusterPt, ← accPt_principal_iff_clusterPt] + refine hacc.mono (principal_mono.mpr fun _ h => h.1) + have hne : ζ (3 / 2 + I * t) ≠ 0 := by + exact riemannZeta_ne_zero_of_one_lt_re (by norm_num) + exact hne (hfeq (Metric.mem_ball_self (by linarith))) + + + +/- +There exists a constant $0 < E<1/14$ such that for all $\rho=\sigma+it$ with $\zeta(\rho)=0$ + and $|t|\geq 2$, one has + $$\sigma\leq 1-\frac{E}{\log|t|}.$$ +From Theorem \ref{LogDerivativeDirichlet} when $\Re s>1$ we have + $$-\frac{\zeta'}{\zeta}(s)=\sum_{1\leq n}\frac{\Lambda(n)}{n^s}.$$ + Thus, + $$-3\,\frac{\zeta'}{\zeta}(1+\delta) + -4\,\frac{\zeta'}{\zeta}(1+\delta+it) + -\frac{\zeta'}{\zeta}(1+\delta+2it) + =\sum_{1\leq n}\Lambda(n)\,n^{-(1+\delta)}\left(3+4n^{-it}+n^{-2it}\right).$$ + Now applying Euler's identity + \begin{align*} + -3\,\Re \left(\frac{\zeta'}{\zeta}(1+\delta)\right)& + -4\,\Re \left(\frac{\zeta'}{\zeta}(1+\delta+it)\right) + -\Re \left(\frac{\zeta'}{\zeta}(1+\delta+2it)\right) \\ + &\qquad\qquad\qquad=\sum_{1\leq n}\Lambda(n)\,n^{-(1+\delta)} + \left(3+4\cos(-t\log n)+\cos(-2t\log n)\right) + \end{align*} + Since + $$3+4\cos(-t\log n)+\cos(-2t\log n)=2\,(1+\cos(-t\log n))^2\geq 0,$$ + we know that the series on the right hand side is bounded below by $0$, + and by Lemmas \ref{ShiftTwoBound}, \ref{ShiftOneBound}, and \ref{ShiftZeroBound} + we have an upper bound on the left hand side. So, + $$0\leq\frac{3}{\delta}+3A-\frac{4}{1+\delta-\sigma}+4B\log|t|+C\log|t|$$ + where $A$, $B$, and $C$ are the implied constants coming from Lemmas + \ref{ShiftZeroBound}, \ref{ShiftOneBound}, and \ref{ShiftTwoBound} respectively. + By choosing $D\geq 5A+4B+C\geq 3A/\log 2+4B+C$ we have + $$\frac{4}{1+\delta-\sigma}\leq\frac{3}{\delta}+D\log|t|$$ + by some manipulation. Now if we choose $\delta=(2D\log|t|)^{-1}$ then we have + $$\frac{4}{1-\sigma+1/(2D\log|t|)}\leq7D\log|t|.$$ + So with some manipulation we have that + $$\sigma\leq 1-\frac{1}{14D\log|t|}.$$ + This is exactly the desired result with the constant $E=(14D)^{-1}$. Since + $D\geq 5A+4B+C\geq 1$ we have that $E\in(0,1/14)$. +-/ +theorem ZeroInequality : ∃ (E : ℝ), E ∈ Ioo (0 : ℝ) (1 / 14 : ℝ) ∧ + ∀ (ρ : ℂ), ζ ρ = 0 → + ∀ (σ : ℝ), σ = ρ.re → + ∀ (t : ℝ), t = ρ.im → |t| ≥ 2 → + σ ≤ 1 - E / log |t| := by + obtain ⟨A, Age, ShiftZero⟩ := ShiftZeroBound + obtain ⟨B, Bpos, ShiftOne⟩ := ShiftOneBound + obtain ⟨C, Cpos, ShiftTwo⟩ := ShiftTwoBound + set D : ℝ := 5 * A + 4 * B + C with D_def + set E : ℝ := (14 * D)⁻¹ with E_def + have Dge1 : 1 ≤ D := by linarith + refine ⟨E, ⟨?_, ?_⟩, fun ρ hρzero σ ρre t ρim ht => ?_⟩ + · rw [E_def, mul_inv_rev, mul_pos_iff_of_pos_right (inv_pos.mpr ofNat_pos'), inv_pos] + linarith + · rw [E_def, one_div, inv_lt_inv₀ (by linarith) (by linarith)] + linarith + · set δ : ℝ := 1 / (2 * D * Real.log |t|) with δ_def + have δrange : δ ∈ Ioo 0 1 := by + simp only [mem_Ioo, δ_def, one_div_pos] + rw [div_lt_one (by nlinarith [Real.log_le_log zero_lt_two ht, Real.log_two_gt_d9])] + exact ⟨by nlinarith [Real.log_le_log zero_lt_two ht, Real.log_two_gt_d9], + by nlinarith [Real.log_le_log zero_lt_two ht, Real.log_two_gt_d9]⟩ + have hugeEq : + 3 * (-ζ' (1 + δ) / ζ (1 + δ)) + + 4 * (-ζ' (1 + δ + I * t) / ζ (1 + δ + I * t)) + + (-ζ' (1 + δ + 2 * I * t) / ζ (1 + δ + 2 * I * t)) + = ∑' (n : ℕ), Λ (n) * n ^ (-(1 : ℂ) - δ) + * ((3 : ℂ) + 4 * n ^ (-I * t) + n ^ (-2 * I * t)) := by + rw [LogDerivativeDirichlet (s := 1 + δ) (by simp [δrange.1]), + LogDerivativeDirichlet (s := 1 + δ + I * t) (by simp [δrange.1]), + LogDerivativeDirichlet (s := 1 + δ + 2 * I * t) (by simp [δrange.1])] + simp only [← tsum_mul_left, ← neg_add', mul_add]; repeat rw [← Summable.tsum_add] + · congr 1; funext n; by_cases heq0 : n = 0 + · simp only [heq0, ArithmeticFunction.map_zero, ofReal_zero, CharP.cast_eq_zero, + zero_div, mul_zero, add_zero, neg_add_rev, zero_mul, neg_mul] + · simp only [div_eq_mul_inv, mul_assoc, neg_mul] + congr 2 + · simp only [← cpow_neg, neg_add_rev] + ring_nf + · simp only [← cpow_neg, neg_add_rev] + rw [cpow_add _ _ ((cast_ne_zero (R := ℂ)).mpr heq0), mul_comm] + ring_nf + · simp only [← cpow_neg, neg_add_rev] + rw [cpow_add _ _ ((cast_ne_zero (R := ℂ)).mpr heq0), mul_comm] + · refine Summable.add (Summable.mul_left _ (vonMangoldtLSeriesSummable ?_)) + (Summable.mul_left _ (vonMangoldtLSeriesSummable ?_)) + · simp only [add_re, one_re, ofReal_re, lt_add_iff_pos_right, δrange.1] + · simp only [add_re, one_re, ofReal_re, mul_re, I_re, zero_mul, I_im, ofReal_im, mul_zero, + sub_self, add_zero, lt_add_iff_pos_right, δrange.1] + · refine vonMangoldtLSeriesSummable ?_ + simp only [add_re, one_re, ofReal_re, mul_re, re_ofNat, I_re, mul_zero, im_ofNat, I_im, + mul_one, sub_self, zero_mul, mul_im, add_zero, ofReal_im, lt_add_iff_pos_right, δrange.1] + · refine Summable.mul_left _ (vonMangoldtLSeriesSummable ?_) + simp only [add_re, one_re, ofReal_re, lt_add_iff_pos_right, δrange.1] + · refine Summable.mul_left _ (vonMangoldtLSeriesSummable ?_) + simp only [add_re, one_re, ofReal_re, mul_re, I_re, zero_mul, I_im, ofReal_im, mul_zero, + sub_self, add_zero, lt_add_iff_pos_right, δrange.1] + have hugeEqRe : + 3 * -(ζ' (1 + δ) / ζ (1 + δ)).re + + 4 * -(ζ' (1 + δ + I * t) / ζ (1 + δ + I * t)).re + + -(ζ' (1 + δ + 2 * I * t) / ζ (1 + δ + 2 * I * t)).re + = 2 * ∑' (n : ℕ), Λ (n) * n ^ (-1 - δ) * (1 + Real.cos (-t * Real.log n)) ^ 2 := by + have re_eq := congr_arg Complex.re hugeEq + simp only [add_re, mul_re, re_ofNat, im_ofNat, zero_mul, sub_zero, neg_mul, neg_div, + Complex.neg_re] at re_eq + rw [re_eq, Complex.re_tsum, ← tsum_mul_left] + · refine tsum_congr (fun n => ?_) + by_cases heq0 : n = 0 + · simp [heq0] + · repeat rw [Complex.cpow_def_of_ne_zero (cast_ne_zero (R := ℂ).mpr heq0)] + simp only [← natCast_log, mul_neg, mul_re, ofReal_re, exp_re, sub_re, neg_re, one_re, + ofReal_im, sub_im, neg_im, one_im, neg_zero, sub_self, mul_zero, sub_zero, mul_im, + zero_mul, add_zero, Real.cos_zero, mul_one, exp_im, Real.sin_zero, add_re, re_ofNat, + I_re, I_im, one_mul, zero_add, Real.exp_zero, Real.cos_neg, im_ofNat, Real.sin_neg, + add_im, neg_mul, add_sq, one_pow, Real.cos_sq, one_div] + rw [← Real.rpow_def_of_pos (Nat.cast_pos.mpr (Nat.pos_of_ne_zero heq0))] + ring_nf + · simp only [mul_add, mul_assoc]; ring_nf + refine Summable.add (Summable.add (Summable.mul_right _ ?_) (Summable.mul_right _ ?_)) ?_ + · refine (ArithmeticFunction.LSeriesSummable_vonMangoldt + (s := 1 + δ) (by simp [δrange.1])).congr (fun n => ?_) + by_cases heq0 : n = 0 + · simp only [heq0, LSeries.term_zero, ArithmeticFunction.map_zero, ofReal_zero, + CharP.cast_eq_zero, zero_mul] + · simp only [ne_eq, heq0, not_false_eq_true, LSeries.term_of_ne_zero] + rw [div_eq_mul_inv, ← Complex.cpow_neg, neg_add'] + · refine (ArithmeticFunction.LSeriesSummable_vonMangoldt + (s := 1 + δ + I * t) (by simp [δrange.1])).congr (fun n => ?_) + by_cases heq0 : n = 0 + · simp only [heq0, LSeries.term_zero, ArithmeticFunction.map_zero, ofReal_zero, + CharP.cast_eq_zero, zero_mul] + · simp only [ne_eq, heq0, not_false_eq_true, LSeries.term_of_ne_zero] + rw [div_eq_mul_inv, ← Complex.cpow_neg, neg_add, + Complex.cpow_add _ _ ((cast_ne_zero (R := ℂ)).mpr heq0)] + ring_nf + · refine (ArithmeticFunction.LSeriesSummable_vonMangoldt + (s := 1 + δ + 2 * I * t) (by simp [δrange.1])).congr (fun n => ?_) + by_cases heq0 : n = 0 + · simp only [heq0, LSeries.term_zero, ArithmeticFunction.map_zero, ofReal_zero, + CharP.cast_eq_zero, zero_mul] + · simp only [ne_eq, heq0, not_false_eq_true, LSeries.term_of_ne_zero] + rw [div_eq_mul_inv, ← Complex.cpow_neg, neg_add, + Complex.cpow_add _ _ ((cast_ne_zero (R := ℂ)).mpr heq0)] + ring_nf + have ZeroWindowOneFinite : (ZeroWindow t).Finite := ZeroWindowFinite ht + have ZeroWindowTwoFinite : (ZeroWindow (2 * t)).Finite := by + apply ZeroWindowFinite + simp only [abs_mul, abs_ofNat, ge_iff_le, ofNat_pos, le_mul_iff_one_le_right] + linarith + have ShiftZero := ShiftZero δ δrange + have ShiftOne := ShiftOne δ δrange t ht ZeroWindowOneFinite ρ hρzero ρim + have ShiftTwo := ShiftTwo δ δrange t ht ZeroWindowTwoFinite + suffices h1 : 4 / (1 + δ - σ) ≤ 3 / δ + D * Real.log |t| by + simp only [δ_def, div_eq_mul_inv, mul_inv_rev, one_mul, inv_inv] at h1 + rw [mul_inv_le_iff₀] at h1 + · ring_nf at h1; field_simp at h1; ring_nf at h1; field_simp at h1 + rw [mul_div_cancel_left₀ _ + (Real.log_ne_zero_of_pos_of_ne_one (by linarith) (by linarith))] at h1 + rw [E_def, ← inv_mul', le_sub_comm, + inv_le_iff_one_le_mul₀' (mul_pos (by linarith) (Real.log_pos (by linarith)))] + linarith + · rw [add_sub_right_comm] + apply add_pos_of_nonneg_of_pos + · by_contra hσ; simp only [sub_nonneg, not_le, ρre] at hσ + exact (riemannZeta_ne_zero_of_one_lt_re hσ) hρzero + · exact mul_pos (inv_pos.mpr (Real.log_pos (by linarith))) (by positivity) + suffices h2 : 0 ≤ 3 / δ + 3 * A - 4 / (1 + δ - σ) + 4 * B * Real.log |t| + C * Real.log |t| by + simp only [sub_eq_neg_add, add_assoc, le_neg_add_iff_add_le, add_zero, ge_iff_le] at ⊢ h2 + apply le_trans h2 + simp only [← add_assoc, D_def, add_mul, add_le_add_iff_right, add_le_add_iff_left] + nlinarith [Real.log_le_log zero_lt_two ht, Real.log_two_gt_d9] + calc 0 ≤ 2 * ∑' (n : ℕ), Λ (n) * n ^ (-1 - δ) * (1 + Real.cos (-t * Real.log n)) ^ 2 := by + rw [mul_nonneg_iff_of_pos_left two_pos] + exact tsum_nonneg (fun n => mul_nonneg (mul_nonneg ArithmeticFunction.vonMangoldt_nonneg + (Real.rpow_nonneg (Nat.cast_nonneg n) _)) (sq_nonneg _)) + _ = 3 * -(ζ' (1 + δ) / ζ (1 + δ)).re + + 4 * -(ζ' (1 + δ + I * t) / ζ (1 + δ + I * t)).re + + -(ζ' (1 + δ + 2 * I * t) / ζ (1 + δ + 2 * I * t)).re := + hugeEqRe.symm + _ ≤ 3 / δ + 3 * A - 4 / (1 + δ - σ) + 4 * B * Real.log |t| + C * Real.log |t| := by + rw [← ρre] at ShiftOne + ring_nf at ShiftZero ShiftOne ShiftTwo ⊢ + linarith + + + +/-- A positive constant in the zero-free-region inequality `ZeroInequality`. -/ +noncomputable def E : ℝ := ZeroInequality.choose +lemma EinIoo : E ∈ Ioo (0 : ℝ) (1 / 14 : ℝ) := ZeroInequality.choose_spec.1 +theorem ZeroInequalitySpec : ∀ (ρ : ℂ), ζ ρ = 0 → + ∀ (σ : ℝ), σ = ρ.re → + ∀ (t : ℝ), t = ρ.im → |t| ≥ 2 → + σ ≤ 1 - E / log |t| := ZeroInequality.choose_spec.2 + + + +/- +Let $\delta_t=E/\log|t|$ where $E$ is the constant coming from Theorem \ref{ZeroInequality}. +-/ +/-- The width `E / log |t|` of the zero-free region at height `t`. -/ +noncomputable def DeltaT (t : ℝ) : ℝ := E / log |t| + + + +/- +For all $t\in\mathbb{R}$ with $|t|\geq 2$ we have that $$\delta_t<1/9.$$ +Note that $\delta_t=E/\log|t|$ where $E$ is the implied constant from + Lemma \ref{ZeroInequality}. But we know that $E=(14D)^{-1}$ where $D\geq 5A+4B+C$ + where $A$, $B$, and $C$ are the constants coming from + Lemmas \ref{ShiftZeroBound}, \ref{ShiftOneBound}, and \ref{ShiftTwoBound} respectively. Thus, + $$E\leq\frac{1}{14\,(5A+4B+C)}.$$ + But note that $A\geq 1$, $B>0$, and $C>0$ by Lemmas \ref{ShiftZeroBound}, \ref{ShiftOneBound}, + and \ref{ShiftTwoBound} respectively. So, by a very lazy estimate we have $E\leq 1/14$. Thus, + $$\delta_t=\frac{E}{\log|t|}\leq\frac{1}{14\,\log2}<\frac{1}{9}.$$ +-/ +lemma DeltaRange : ∀ (t : ℝ), + |t| ≥ 2 → + DeltaT t < (1 : ℝ) / 9 := by + intro t ht + rw [DeltaT, div_lt_div_iff₀ (Real.log_pos (by linarith)) (ofNat_pos'), one_mul] + exact lt_of_lt_of_le (by linarith [EinIoo.2, Real.log_two_gt_d9]) (Real.log_le_log zero_lt_two ht) + + + +/- +For all $t\in\mathbb{R}$ with $|t|\geq 2$ and $z=\sigma+it$ + where $1-\delta_t/3\leq\sigma\leq 3/2$, we have that + $$\left|\frac{\zeta'}{\zeta}(z) + -\sum_{\rho\in\mathcal{Z}_t}\frac{m_\zeta(\rho)}{z-\rho}\right|\ll\log|t|.$$ +By Lemma \ref{DeltaRange} we have that + $$-29/54<-1/2-\delta_t/3\leq\sigma-3/2\leq0.$$ + We apply Theorem \ref{LogDerivZetaFinalBound} where $r'=2/3$, $r=3/4$, $R'=4/5$, and $R=5/6$. + Thus for all $z\in\overline{\mathbb{D}_{2/3}}\setminus\mathcal{K}_f(4/5)$ we have that + $$\left|\frac{\zeta'}{\zeta}(z+3/2+it) + -\sum_{\rho\in\mathcal{K}_f(3/4)}\frac{m_f(\rho)}{z-\rho}\right|\ll\log|t|$$ + where $f(z)=\zeta(z+3/2+it)$ for $t\in\mathbb{R}$ with $|t|\geq 2$. + Now if we let $z=\sigma-3/2$, then $z\in(-29/54,0)\subseteq\overline{\mathbb{D}_{2/3}}$. + Additionally, $f(z)=\zeta(\sigma+it)$, where $\sigma+it$ lies in the zero free region given by + Lemma \ref{ZeroInequality} since $\sigma\geq 1-\delta_t/3\geq 1-\delta_t$. + Thus, $z\not\in\mathcal{K}_f(4/5)$. So, + $$\left|\frac{\zeta'}{\zeta}(\sigma+it) + -\sum_{\rho\in\mathcal{K}_f(3/4)}\frac{m_f(\rho)}{\sigma-3/2-\rho}\right|\ll\log|t|.$$ + But now note that if $\rho\in\mathcal{K}_f(3/4)$, then $\zeta(\rho+3/2+it)=0$ + and $|\rho|\leq 3/4$ (and the argument works in reverse). Additionally, note that + $m_f(\rho)=m_\zeta(\rho+3/2+it)$. So changing variables using these facts gives us that + $$\left|\frac{\zeta'}{\zeta}(\sigma+it) + -\sum_{\rho\in\mathcal{Z}_t}\frac{m_\zeta(\rho)}{\sigma+it-\rho}\right|\ll\log|t|.$$ +-/ +lemma SumBoundII : + ∃ (C : ℝ), C > 0 ∧ + ∀ (t : ℝ), |t| ≥ 2 → + ∀ (z : ℂ), (hzIm : t = z.im) → (hzRe : z.re ∈ Icc (1 - DeltaT t / 3) (3 / 2)) → + ∀ (finiteZeros : (ZeroWindow t).Finite), + ‖ζ' (z) / ζ (z) - ∑ ρ ∈ finiteZeros.toFinset, + analyticOrderNatAt ζ ρ / (z - ρ)‖ ≤ C * Real.log |t| := by + let r' : ℝ := 2 / 3 + let r : ℝ := 3 / 4 + let R' : ℝ := 4 / 5 + let R : ℝ := 5 / 6 + have r'_pos : 0 < r' := by norm_num + have r'_lt_r : r' < r := by norm_num + have r_lt_one : r < 1 := by norm_num + have r_lt_R' : r < R' := by norm_num + have R'_lt_R : R' < R := by norm_num + have R_lt_one : R < 1 := by norm_num + obtain ⟨C, hC, LogDerivBound⟩ := + LogDerivZetaFinalBound r'_pos r'_lt_r r_lt_one r_lt_R' R'_lt_R R_lt_one + refine ⟨(16 * r ^ 2 / (r - r') ^ 3 + 1 / ((R ^ 2 / R' - R') * Real.log (R / R'))) * C, + by positivity, ?_⟩ + intro t ht z hzIm hzRe finiteZeros + have LogDerivBound := LogDerivBound t ht + extract_lets f at LogDerivBound + have finiteZeros' : (SetOfZeros 1 f).Finite := by + apply ZetaShiftFiniteZeros ht + simp only [f] + have hz : I * t + z.re = z := by + rw [← Complex.re_add_im z] + simp only [hzIm, add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + add_zero, mul_comm, add_comm] + set Z : ℂ := z.re - 3 / 2 with hZ + have hZ' : Z ∈ Metric.closedBall (0 : ℂ) r' \ SetOfZeros R' f := by + simp only [SetOfZeros, f, Set.mem_sdiff, Metric.mem_closedBall, dist_zero_right, mem_ofPred_eq, + not_and, hZ] + ring_nf + refine ⟨?_, fun _ => ?_⟩ + · suffices h1 : ‖-3 / 2 + z.re‖ ≤ r' by exact_mod_cast h1 + rw [Real.norm_eq_abs, abs_le] + exact ⟨by linarith [hzRe.1, DeltaRange t ht], by linarith [hzRe.2]⟩ + · rw [add_comm, hz] + by_contra zZetaZero + suffices h1 : 1 - E / Real.log |t| < 1 - DeltaT t / 3 by + linarith [hzRe.1, ZeroInequalitySpec z zZetaZero z.re rfl t hzIm ht] + simp only [DeltaT, sub_lt_sub_iff_left] + exact _root_.div_lt_self (_root_.div_pos EinIoo.1 (Real.log_pos (by linarith))) one_lt_ofNat + have LogDerivBound := LogDerivBound finiteZeros' Z hZ' + refine le_trans (le_of_eq ?_) (LogDerivBound.trans (by rw [mul_assoc])) + apply congrArg norm + congr 1 + · simp only [f, hZ, add_assoc, deriv_comp_add_const] + ring_nf + rw [add_comm, hz] + · simp only [f] + refine Finset.sum_nbij' (fun ρ => ρ - (3 / 2 + I * t)) (fun ρ => ρ + (3 / 2 + I * t)) + (fun ρ hρ => ?_) (fun ρ hρ => ?_) (fun ρ hρ => by ring_nf) (fun ρ hρ => by ring_nf) + (fun ρ hρ => ?_) + · simp only [Set.Finite.mem_toFinset, SetOfZeros, ZeroWindow, Set.mem_ofPred_eq] at hρ ⊢ + refine ⟨?_, ?_⟩ + · simp only [r, hρ.2] + · simp only [add_assoc, sub_add_cancel, hρ.1] + · simp only [Set.Finite.mem_toFinset, SetOfZeros, ZeroWindow, Set.mem_ofPred_eq] at hρ ⊢ + refine ⟨?_, ?_⟩ + · simp only [← add_assoc, hρ.2] + · simp only [add_sub_cancel_right, r, hρ.1] + · ring_nf + simp only [add_assoc _ _ (I * t), add_comm _ (I * t), ← add_assoc _ (I * t) _] + rw [mul_comm, analyticOrderNatAt_fun_comp_add_left, hZ] + ring_nf + simp only [add_assoc, hz, neg_add_eq_sub ρ z, mul_comm] + + + +/- +Let $t\in\mathbb{R}$ with $|t|\geq 3$ and $z=\sigma+it$ where $1-\delta_t/3\leq\sigma\leq 3/2$. + Additionally, let $\rho\in\mathcal{Z}_t$. Then we have that + $$|z-\rho|\geq\delta_t/6.$$ +Let $\rho=\sigma'+it'$ and note that since $\rho\in\mathcal{Z}_t$, we have $t'\in(t-3/4,t+3/4)$. + Thus, if $t>1$ we have + $$\log|t'|\leq\log|t+3/4|\leq\log|2t|=\log 2+\log|t|\leq 2\log|t|.$$ + And otherwise if $t<-1$ we have + $$\log|t'|\leq\log|t-3/4|\leq\log|2t|=\log 2+\log|t|\leq 2\log|t|.$$ + So by taking reciprocals and multiplying through by a constant we have + that $\delta_t\leq2\delta_{t'}$. Now note that since $\rho\in\mathcal{Z}_t$ + we know that $\sigma'\leq 1-\delta_{t'}$ by Theorem \ref{ZeroInequality} + (here we use the fact that $|t|\geq 3$ to give us that $|t'|\geq 2$). Thus, + $$\delta_t/6\leq\delta_{t'}-\delta_t/3 + =1-\delta_t/3-(1-\delta_{t'})\leq\sigma-\sigma'\leq|z-\rho|.$$ +-/ +lemma GapSize (t : ℝ) (ht : |t| ≥ 3) + (z : ℂ) (hzRe : z.re ∈ Icc (1 - DeltaT t / 3) (3 / 2)) + (ρ : ℂ) (hρ : ρ ∈ ZeroWindow t) : + ‖z - ρ‖ ≥ DeltaT t / 6 := by + simp only [ZeroWindow, mem_ofPred_eq] at hρ + have := abs_sub_abs_le_abs_sub t ρ.im; rw [abs_sub_comm] at this + have ρImDiffBound : |ρ.im - t| ≤ 3 / 4 := by + have h := Complex.abs_im_le_norm (ρ - (3 / 2 + I * t)) + simp only [sub_im, add_im, div_ofNat_im, im_ofNat, zero_div, mul_im, I_re, ofReal_im, mul_zero, + I_im, ofReal_re, one_mul, zero_add] at h + exact h.trans hρ.2 + have ρImAbsUpperBound : Real.log |ρ.im| ≤ 2 * Real.log |t| := by + have moveTwo : Real.log (2 * |t|) ≤ 2 * Real.log |t| := by + rw [← Real.log_rpow (by linarith)] + have := mul_le_mul_of_nonneg_right ht (abs_nonneg t); rw [← sq, ← Real.rpow_two] at this + exact Real.log_le_log (by linarith) (by linarith) + refine le_trans (Real.log_le_log (by linarith) ?_) moveTwo + linarith [abs_sub_abs_le_abs_sub ρ.im t] + have deltaRelation : DeltaT t ≤ 2 * (DeltaT ρ.im) := by + simp only [DeltaT, mul_div, mul_comm] + rw [div_le_div_iff₀ (Real.log_pos (by linarith)) (Real.log_pos (by linarith)), mul_assoc] + nlinarith [EinIoo.1, EinIoo.2] + have hρRe := ZeroInequalitySpec ρ hρ.1 ρ.re rfl ρ.im rfl (by linarith); rw [← DeltaT] at hρRe + calc DeltaT t / 6 ≤ (1 - DeltaT t / 3) - (1 - DeltaT ρ.im) := by linarith + _ ≤ z.re - ρ.re := by linarith [hzRe.1, hρRe] + _ = (z - ρ).re := by rw [Complex.sub_re] + _ ≤ ‖z - ρ‖ := Complex.re_le_norm _ + + + +/- +There exists a constant $F\in(0,1/42)$ such that + for all $t\in\mathbb{R}$ with $|t|\geq 3$ one has + $$1-\frac{F}{\log|t|}\leq\sigma\leq 3/2 + \implies\left|\frac{\zeta'}{\zeta}(\sigma+it)\right|\ll\log^2|t|$$ + where the implied constant is uniform in $\sigma$. +Take $F=E/3$ where $E$ comes from Theorem \ref{ZeroInequality}. + Then we have that $\sigma\geq 1-\delta_t/3$. So, we apply Lemma \ref{SumBoundII}, + which gives us that + $$\left|\frac{\zeta'}{\zeta}(z) + -\sum_{\rho\in\mathcal{Z}_t}\frac{m_\zeta(\rho)}{z-\rho}\right|\ll\log|t|.$$ + Using the reverse triangle inequality and rearranging, we have that + $$\left|\frac{\zeta'}{\zeta}(z)\right| + \leq\sum_{\rho\in\mathcal{Z}_t}\frac{m_\zeta(\rho)}{|z-\rho|}+C\,\log|t|$$ + where $C$ is the implied constant in Lemma \ref{SumBoundII}. + Now applying Lemma \ref{GapSize} we have that + $$\left|\frac{\zeta'}{\zeta}(z)\right| + \leq\frac{6}{\delta_t}\sum_{\rho\in\mathcal{Z}_t}m_\zeta(\rho)+C\,\log|t|.$$ + Now let $f(z)=\zeta(z+3/2+it)/\zeta(3/2+it)$ with $\rho=\rho'+3/2+it$. + Then if $\rho\in\mathcal{Z}_t$ we have that + $$0=\zeta(\rho)=\zeta(\rho'+3/2+it)=f(\rho')$$ + with the same multiplicity of zero, that is $m_\zeta(\rho)=m_f(\rho')$. + And also if $\rho\in\mathcal{Z}_t$ then + $$3/4\geq|\rho-(3/2+it)|=|\rho'|.$$ + Thus we change variables to have that + $$\left|\frac{\zeta'}{\zeta}(z)\right| + \leq\frac{6}{\delta_t}\sum_{\rho'\in\mathcal{K}_f(3/4)}m_f(\rho')+C\,\log|t|.$$ + Now note that $f(0)=1$ and for $|z|\leq 5/6$ we have + $$|f(z)|=\frac{|\zeta(z+3/2+it)|}{|\zeta(3/2+it)|} + \leq\frac{\zeta(3/2)}{\zeta(3)}\cdot(7+2\,|t|)\leq\frac{13\,\zeta(3/2)}{3\,\zeta(3)}\,|t|$$ + by Theorems \ref{ZetaFixedLowerBound} and \ref{GlobalBound}. + Thus by Theorem \ref{ZerosBound} we have that + $$\sum_{\rho'\in\mathcal{K}_f(3/4)}m_f(\rho') + \leq\frac{\log|t|+\log(13\,\zeta(3/2)/(3\,\zeta(3)))}{\log((5/6)/(3/4))}\leq D\log|t|$$ + where $D$ is taken to be sufficiently large. + Recall, by definition that, $\delta_t=E/\log|t|$ with $E$ coming from + Theorem \ref{ZeroInequality}. By using this fact and the above, we have that + $$\left|\frac{\zeta'}{\zeta}(z)\right|\ll\log^2|t|+\log|t|$$ + where the implied constant is taken to be bigger than $6D/E+C$. + We know that the RHS is bounded above by $\ll\log^2|t|$; so the result follows. +-/ +lemma LogDerivZetaUniformLogSquaredBoundStrip : ∃ (F : ℝ) (_ : F = E / 3) + (C : ℝ) (_ : 0 < C), + ∀ (t : ℝ), 3 ≤ |t| → + ∀ (σ : ℝ), σ ∈ Set.Icc (1 - F / Real.log |t|) (3 / 2) → + ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ ≤ C * (Real.log |t|) ^ 2 := by + obtain ⟨C, Cpos, SumBoundII⟩ := SumBoundII + set d : ℝ := ‖13 * ζ (3 / 2) / (3 * ζ 3)‖ with hd + have d_gt_one : 1 < d := by + simp only [hd, Complex.norm_div, Complex.norm_mul, Complex.norm_ofNat] + rw [one_lt_div] + · refine mul_lt_mul (by linarith) ?_ ?_ (ofNat_nonneg' _) + · have ζNormLe := norm_zeta_strict_mono_ofReal (a := 3) (b := (3 / 2)) + simp only [half_lt_self_iff, ofNat_pos, ofReal_ofNat, ofReal_div, forall_const] at ζNormLe + refine le_of_lt (ζNormLe (by linarith)) + · simp only [norm_pos_iff, ne_eq] + exact riemannZeta_ne_zero_of_one_lt_re (by norm_num) + · simp only [ofNat_pos, mul_pos_iff_of_pos_left, norm_pos_iff, ne_eq] + exact riemannZeta_ne_zero_of_one_lt_re (by norm_num) + set D : ℝ := (1 + Real.log d / Real.log 3) / Real.log (10 / 9) with hD + have Dpos : D > 0 := by + rw [hD, add_div] + refine add_pos ?_ (_root_.div_pos (_root_.div_pos (Real.log_pos d_gt_one) (Real.log_pos + one_lt_ofNat)) + (Real.log_pos ?_)) + · rw [one_div_pos] + exact Real.log_pos (by norm_num) + · rw [one_lt_div ofNat_pos'] + linarith + refine ⟨E / 3, rfl, ⟨6 * D / E + C, + add_pos (mul_pos (mul_pos ofNat_pos' Dpos) (inv_pos.mpr EinIoo.1)) Cpos, ?_⟩⟩ + intro t ht σ hσ + set r : ℝ := 3 / 4 with rwr + set R : ℝ := 5 / 6 with rwR + have R_over_r : R / r = 10 / 9 := by norm_num + have r_pos : 0 < r := by norm_num + have r_lt_one : r < 1 := by norm_num + have r_lt_R : r < R := by norm_num + have R_lt_one : R < 1 := by norm_num + set B : ℝ := d * |t| with hB + set g : ℂ → ℂ := fun z ↦ ζ (z + 3 / 2 + I * t) with hg + set f : ℂ → ℂ := fun z ↦ g z / ζ (3 / 2 + I * t) with hf + have fAnalytic : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) 1) := by + intro z hz; simp only [Metric.mem_closedBall, dist_zero_right] at hz + simp only [hf, hg] + refine AnalyticAt.div_const (AnalyticAt.comp (DifferentiableOn.analyticAt (s := {z : ℂ | z ≠ 1}) + (fun z' hz' => (differentiableAt_riemannZeta hz').differentiableWithinAt) + ((isOpen_ne).mem_nhds ?_)) (AnalyticAt.add (AnalyticAt.add analyticAt_id analyticAt_const) + analyticAt_const)) + simp only [ne_eq, Pi.add_apply, id_eq, mem_ofPred_eq] + by_contra h; rw [Complex.ext_iff] at h + obtain ⟨_, hIm⟩ := h; simp only [add_im, div_ofNat_im, im_ofNat, zero_div, add_zero, mul_im, + I_re, ofReal_im, mul_zero, I_im, ofReal_re, one_mul, zero_add, one_im] at hIm + rw [add_eq_zero_iff_eq_neg] at hIm + have h := Complex.abs_im_le_norm z; rw [hIm, abs_neg] at h + linarith + have zetaThreeHalfNonzero : ¬ζ (3 / 2 + I * ↑t) = 0 := by + exact riemannZeta_ne_zero_of_one_lt_re (by norm_num) + have f0_1 : f 0 = 1 := by + simp only [hg, hf, zero_add, div_self_eq_one₀, ne_eq, zetaThreeHalfNonzero, not_false_eq_true] + have finiteSetOf0s : (SetOfZeros 1 f).Finite := by + have gFiniteSetOf0s := ZetaShiftFiniteZeros (t := t) (by linarith) hg + simp only [SetOfZeros, hf, div_eq_zero_iff, zetaThreeHalfNonzero, or_false] at gFiniteSetOf0s ⊢ + exact gFiniteSetOf0s + have rFinite0s:= finiteSetOfZeros_mono r_lt_one finiteSetOf0s + have finite0s := ZeroWindowFinite (t := t) (by linarith) + have fz_bound : ∀ z : ℂ, ‖z‖ ≤ R → ‖f z‖ ≤ B := by + intro z hz + simp only [hf, hg, Complex.norm_div, hB, hd, Complex.norm_mul, Complex.norm_ofNat] + rw [mul_comm 3 _, div_mul_eq_div_mul_one_div, mul_comm _ |t|, mul_comm _ (1 / 3), ← mul_div, + ← mul_assoc, ← mul_assoc] + refine mul_le_mul (le_trans (GlobalBound (s := z) (t := t) (by linarith) (by linarith)) (by + linarith)) ?_ (inv_nonneg.mpr (Complex.norm_nonneg _)) (by linarith) + rw [← inv_le_inv₀ (_root_.div_pos (norm_pos_iff.mpr (riemannZeta_ne_zero_of_one_lt_re (by + norm_num))) + (norm_pos_iff.mpr (riemannZeta_ne_zero_of_one_lt_re (by norm_num)))) (inv_pos.mpr + (norm_pos_iff.mpr zetaThreeHalfNonzero)), inv_div, inv_inv] + have zetaLowerBound := ZetaFixedLowerBound t + simp only [nnnorm_div, ge_iff_le] at zetaLowerBound + exact_mod_cast zetaLowerBound + have ZerosBound := ZerosBound r_pos r_lt_one r_lt_R R_lt_one fAnalytic f0_1 finiteSetOf0s fz_bound + rw [hB, one_div_mul_eq_div, cast_sum, R_over_r, + Real.log_mul (by linarith) (by linarith), add_div] at ZerosBound + have ZerosBound : ∑ ρ ∈ finite0s.toFinset, ↑(analyticOrderNatAt ζ ρ) ≤ Real.log |t| * D := by + rw [mul_comm, Finset.sum_nbij' (t := rFinite0s.toFinset) (g := fun ρ ↦ ↑(analyticOrderNatAt f + ρ)) + (fun ρ => ρ - (3 / 2 + I * t)) (fun ρ => ρ + (3 / 2 + I * t))] + · apply le_trans ZerosBound + rw [hd, div_mul_eq_mul_div, add_mul, one_mul, add_div, add_comm, add_le_add_iff_left] + gcongr + rw [div_mul_eq_mul_div, le_div_iff₀ (Real.log_pos one_lt_ofNat)] + exact mul_le_mul_of_nonneg_left (Real.log_le_log three_pos ht) (Real.log_nonneg d_gt_one.le) + · simp only [ZeroWindow, Finite.mem_toFinset, mem_ofPred_eq, SetOfZeros, and_imp, rwr, hf, hg] + ring_nf + intro z hzZero hzBound + simp only [_root_.mul_eq_zero, inv_eq_zero, zetaThreeHalfNonzero, or_false] + exact ⟨hzBound, hzZero⟩ + · simp only [SetOfZeros, Finite.mem_toFinset, mem_ofPred_eq, ZeroWindow, add_sub_cancel_right, + and_imp, rwr, hf, hg] + ring_nf + intro z hzBound hzZero + simp only [_root_.mul_eq_zero, inv_eq_zero, zetaThreeHalfNonzero, or_false] at hzZero + exact ⟨hzZero, hzBound⟩ + · simp only [Finite.mem_toFinset, implies_true, sub_add_cancel] + · simp only [Finite.mem_toFinset, implies_true, add_sub_cancel_right] + · simp only [ZeroWindow, Finite.mem_toFinset, mem_ofPred_eq, hf, hg, Nat.cast_inj, and_imp] + intro z hzZero hzBound + rw [analyticOrderNatAt_fun_div_const zetaThreeHalfNonzero] + · simp only [add_assoc, analyticOrderNatAt_fun_comp_add_right, sub_add_cancel] + · apply AnalyticAt.comp (DifferentiableOn.analyticAt (s := {z : ℂ | z ≠ 1}) + (fun z' hz' => (differentiableAt_riemannZeta hz').differentiableWithinAt) + ((isOpen_ne).mem_nhds ?_)) + (AnalyticAt.add (AnalyticAt.add analyticAt_id analyticAt_const) analyticAt_const) + simp only [ne_eq, Pi.add_apply, id_eq, mem_ofPred_eq]; ring_nf + by_contra z1 + simp [z1] at hzBound; ring_nf at hzBound + have h := Complex.abs_im_le_norm (-1 / 2 - I * t); simp only [sub_im, div_ofNat_im, neg_im, + one_im, neg_zero, zero_div, mul_im, I_re, ofReal_im, mul_zero, I_im, ofReal_re, one_mul, + zero_add, zero_sub, abs_neg] at h + linarith + set z : ℂ := σ + t * I with hz + have zIm : t = z.im := by + simp only [hz, add_im, ofReal_im, mul_im, ofReal_re, I_im, mul_one, I_re, mul_zero, add_zero, + zero_add] + have zRe : z.re ∈ Icc (1 - DeltaT t / 3) (3 / 2) := by + simp only [hz, DeltaT, div_right_comm, add_re, ofReal_re, mul_re, I_re, zero_mul, I_im, + ofReal_im, mul_zero, sub_self, add_zero, hσ] + have one_le_logt : 1 ≤ Real.log |t| := by + rw [← Real.log_exp 1] + apply Real.log_le_log (Real.exp_pos _) + linarith [Real.exp_one_lt_three] + calc ‖ζ' z / ζ z‖ ≤ _ := norm_le_norm_sub_add _ (∑ ρ ∈ finite0s.toFinset, analyticOrderNatAt ζ ρ + / (z - ρ)) + _ ≤ ‖∑ ρ ∈ finite0s.toFinset, ↑(analyticOrderNatAt ζ ρ) / (z - ρ)‖ + C * Real.log |t| := by + linarith [SumBoundII t (by linarith) z zIm zRe finite0s] + _ ≤ ∑ ρ ∈ finite0s.toFinset, ↑(analyticOrderNatAt ζ ρ) / ‖z - ρ‖ + C * Real.log |t| := by + rw [add_le_add_iff_right] + apply norm_sum_le_of_le + intro ρ hρ + simp only [Complex.norm_div, RCLike.norm_natCast, Std.le_refl] + _ ≤ (6 / DeltaT t) * ∑ ρ ∈ finite0s.toFinset, ↑(analyticOrderNatAt ζ ρ) + C * Real.log |t| := by + rw [add_le_add_iff_right, Finset.mul_sum] + apply Finset.sum_le_sum + intro ρ hρ; rw [Finite.mem_toFinset] at hρ + rw [mul_comm, mul_div, ← div_div_eq_mul_div] + refine div_le_div_of_nonneg_left (cast_nonneg' _) ?_ (GapSize t ht z zRe ρ hρ) + simp only [DeltaT, ofNat_pos, div_pos_iff_of_pos_right] + refine _root_.div_pos EinIoo.1 (Real.log_pos ?_) + linarith + _ ≤ 6 * D / E * Real.log |t| ^ 2 + C * Real.log |t| := by + simp only [DeltaT, add_le_add_iff_right, ← div_mul, mul_comm] + field_simp + exact div_le_div_of_nonneg_right ZerosBound EinIoo.1.le + _ ≤ _ := by + simp only [add_mul, add_le_add_iff_left] + refine mul_le_mul_of_nonneg_left ?_ Cpos.le + nlinarith [one_le_logt] + + + +/-- The zero-free-strip constant used in the uniform log-squared bound. -/ +noncomputable def F : ℝ := LogDerivZetaUniformLogSquaredBoundStrip.choose +lemma Fequ : F = E / 3 := LogDerivZetaUniformLogSquaredBoundStrip.choose_spec.1 +lemma FinIoo : F ∈ Ioo (0 : ℝ) (1 / 42 : ℝ) := by + simp only [one_div, Fequ, mem_Ioo, EinIoo.1, div_pos_iff_of_pos_left, ofNat_pos, true_and] + linarith [EinIoo.2] +lemma LogDerivZetaUniformLogSquaredBoundStripSpec : ∃ (C : ℝ) (_ : 0 < C), + ∀ (t : ℝ), 3 ≤ |t| → + ∀ (σ : ℝ), σ ∈ Set.Icc (1 - F / Real.log |t|) (3 / 2) → + ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ ≤ C * (Real.log |t|) ^ 2 := + LogDerivZetaUniformLogSquaredBoundStrip.choose_spec.2 +lemma FLogTtoDeltaT : ∀ (t : ℝ), + DeltaT t / 3 = F / Real.log |t| := fun _ ↦ by simp [DeltaT, Fequ]; ring + + + +/- +There exists a uniform constant $C$ such that for $z=\sigma+it$ one has + $$3/2\leq\sigma\implies\left|\frac{\zeta'}{\zeta}(z)\right|\leq C.$$ +Note that + $$\left|\frac{\zeta'}{\zeta}(z)\right|=\left|\sum_{n=1}^\infty\frac{\Lambda(n)}{n^z}\right|\leq + \sum_{n=1}^\infty\frac{\Lambda(n)}{|n^z|}=\sum_{n=1}^\infty\frac{\Lambda(n)}{n^\sigma}\leq + \sum_{n=1}^\infty\frac{\Lambda(n)}{n^{3/2}}<\infty$$ + by \ref{vonMangoldtLSeriesSummable}. +-/ +lemma LogDerivZetaBdd_of_Re_ge_three_halves : + ∃ C, ∀ (s : ℂ), 3/2 ≤ s.re → ‖deriv riemannZeta s / riemannZeta s‖ ≤ C := by + have threeHalvesRe : 1 < ((3 / 2) : ℂ).re := by norm_num + have h_sum_converges : Summable (fun n : ℕ ↦ vonMangoldt n / (n : ℝ) ^ (3 / 2 : ℝ)) := by + apply Complex.summable_ofReal.mp + convert (vonMangoldtLSeriesSummable threeHalvesRe) using 2 with n + rw [ofReal_div, Complex.ofReal_cpow, ofReal_natCast, ofReal_div, ofReal_ofNat 3, ofReal_ofNat 2] + exact cast_nonneg' n + have h_log_deriv_sum : ∀ s : ℂ, 3 / 2 ≤ s.re → + deriv riemannZeta s / riemannZeta s = -∑' n : ℕ, (vonMangoldt n : ℂ) / (n : ℂ) ^ s := by + intro s hs; have h := LogDerivativeDirichlet s (by grind); linear_combination -h + have h_triangle : ∀ s : ℂ, + ‖∑' n : ℕ, (vonMangoldt n : ℂ) / (n : ℂ) ^ s‖ ≤ + ∑' n : ℕ, ‖(vonMangoldt n : ℂ) / (n : ℂ) ^ s‖ := fun s ↦ by + by_cases h : Summable fun n ↦ (ArithmeticFunction.vonMangoldt n : ℂ) / (n : ℂ) ^ s + · exact norm_tsum_le_tsum_norm h.norm + · simp only [tsum_eq_zero_of_not_summable h, norm_zero] + exact tsum_nonneg fun _ ↦ by positivity + have h_norm_summand : ∀ s : ℂ, 3 / 2 ≤ s.re → ∀ n : ℕ, + ‖(vonMangoldt n : ℂ) / (n : ℂ) ^ s‖ ≤ (vonMangoldt n : ℝ) / (n : ℝ) ^ (3 / 2 : ℝ) := by + intro s hs n + by_cases hn : n = 0 <;> simp_all [Complex.norm_cpow_of_ne_zero] + ring_nf; norm_num + rw [abs_of_nonneg ArithmeticFunction.vonMangoldt_nonneg] + exact mul_le_mul_of_nonneg_left (inv_anti₀ (by positivity) + (Real.rpow_le_rpow_of_exponent_le (mod_cast Nat.one_le_iff_ne_zero.mpr hn) hs)) + ArithmeticFunction.vonMangoldt_nonneg + refine ⟨∑' n : ℕ, (ArithmeticFunction.vonMangoldt n : ℝ) / (n : ℝ) ^ (3 / 2 : ℝ), + fun s hs ↦ ?_⟩ + have hSum : Summable fun n ↦ ‖(vonMangoldt n : ℂ) / (n : ℂ) ^ s‖ := + Summable.of_nonneg_of_le (fun n ↦ by positivity) + (fun n ↦ h_norm_summand s hs n) h_sum_converges + simpa [neg_div, h_log_deriv_sum s hs] using (h_triangle s).trans + (hSum.tsum_le_tsum (fun n ↦ h_norm_summand s hs n) h_sum_converges) + + + +/- +There exists a constant $F\in(0,1/42)$ such that for all $t\in\mathbb{R}$ with $|t|\geq 3$ one has + $$1-\frac{F}{\log|t|}\leq\sigma\implies + \left|\frac{\zeta'}{\zeta}(\sigma+it)\right|\ll\log^2|t|$$ + where the implied constant is uniform in $\sigma$. +Put the previous two Lemmas together. +-/ +theorem LogDerivZetaUniformLogSquaredBound : ∃ (C : ℝ) (_ : 0 < C), + ∀ (σ t : ℝ), 3 < |t| → σ ∈ Set.Ici (1 - F / Real.log |t|) → + ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ ≤ C * Real.log |t| ^ (2 : ℝ) := by + obtain ⟨C1, hC1⟩ := LogDerivZetaUniformLogSquaredBoundStripSpec + obtain ⟨C2, hC2⟩ := LogDerivZetaBdd_of_Re_ge_three_halves + have hC2pos := (norm_nonneg _).trans (hC2 2 (by norm_num)) + use max C1 C2, lt_max_of_lt_left hC1.1 + intro σ t ht hσ + by_cases hσ' : σ ≤ 3 / 2 + · apply (hC1.2 t (by grind) σ ⟨hσ, hσ'⟩).trans + gcongr + · exact le_max_left _ _ + · simp only [log_abs, rpow_ofNat, Std.le_refl] + · refine (hC2 _ ?_).trans ?_ + · norm_num; linarith + · nth_rewrite 1 [← mul_one C2, ← mul_one 1, ← sq] + refine mul_le_mul (le_max_right _ _) ?_ (sq_nonneg _) ?_ + · rw [one_pow, rpow_ofNat, one_le_sq_iff_one_le_abs, abs_of_pos (Real.log_pos (by + linarith)), Real.le_log_iff_exp_le (by linarith)] + linarith [Real.exp_one_lt_d9] + · linarith [le_max_right C1 C2] + + + +/-- A wrapper for the above theorem -/ +lemma LogDerivZetaBndUnif12 : LogDerivZetaBndUnifGenProp 1 2 := by + refine ⟨F, ⟨FinIoo.1, by linarith [FinIoo.2]⟩, ?_⟩ + simp only [rpow_one] + apply LogDerivZetaUniformLogSquaredBound + + + +-- analouge from ZetaBounds +lemma ZetaZeroFree1 : + ZetaZeroFreeGenProp 1 := by + refine ⟨F, ⟨FinIoo.1, by linarith [FinIoo.2]⟩, ?_⟩ + intro σ t ht hσ + by_contra h + have ZeroInequalityThing := ZeroInequalitySpec (σ + t * I) h + simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + add_zero, add_im, mul_im, zero_add, ge_iff_le, forall_eq] at ZeroInequalityThing + have contra := hσ.1; rw [Fequ] at contra + have contra := le_trans contra (ZeroInequalityThing (by linarith)) + have log_pos : 0 < Real.log |t| := by exact Real.log_pos (by linarith) + rw [rpow_one, sub_le_sub_iff_left, div_div, div_le_div_iff_of_pos_left EinIoo.1 log_pos (mul_pos + three_pos (Real.log_pos (lt_trans one_lt_ofNat ht)))] at contra + linarith + + + +-- analouge from ZetaBounds +theorem LogDerivZetaHolcLargeT1 : LogDerivZetaHolcLargeTGenProp 1 := by + exact LogDerivZetaHolcLargeTGen ZetaZeroFree1 zero_lt_one + + + +-- analouge from MediumPNT +lemma LogDerivZetaBoundedAndHolo12 : LogDerivZetaBoundedAndHoloGenProp 1 2 := by + exact LogDerivZetaBoundedAndHoloGen LogDerivZetaBndUnif12 LogDerivZetaHolcLargeT1 + + + +/- +We have + $$\sum_{n \leq x}\Lambda(n)=x+O(x \exp(-c(\log x)^{1/2})).$$ +This follows as a corollary of + Theorems \ref{GenStrengthPNT} and \ref{LogDerivZetaUniformLogSquaredBound}. +-/ +theorem StrongPNT : ∃ c > 0, + (ψ - id) =O[atTop] + fun (x : ℝ) ↦ x * Real.exp (-c * (Real.log x) ^ ((1 : ℝ) / 2)) := by + have := GenStrengthPNT LogDerivZetaBoundedAndHolo12 (by linarith) (by linarith); ring_nf at this + simpa only [gt_iff_lt, one_div, neg_mul] using this + +end IwaniecLinearSievePNT diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaBounds.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaBounds.lean new file mode 100644 index 000000000..f7a543218 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaBounds.lean @@ -0,0 +1,3487 @@ +/- +Copyright (c) 2026 PrimeNumberTheoremAnd contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: PrimeNumberTheoremAnd contributors +-/ + +module + +public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.ResidueCalcOnRectangles +public import Mathlib.NumberTheory.Harmonic.Defs +public import Mathlib.NumberTheory.LSeries.RiemannZeta +import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.Auxiliary +import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.EulerMaclaurin +import LeanPool.MooreBound.PrimeNumberTheoremAnd.Fourier +import LeanPool.MooreBound.PrimeNumberTheoremAnd.Mathlib.Analysis.SpecialFunctions.Log.Basic +import Mathlib.MeasureTheory.Function.Floor +import Mathlib.MeasureTheory.Order.Group.Lattice +import Mathlib.NumberTheory.Harmonic.Bounds +import Mathlib.NumberTheory.LSeries.Nonvanishing + +/-! +Adapted from PrimeNumberTheoremAnd revision +`127b50e33f6033e2147921167a117af96d9ba4ea`, via Jason Davies's +Iwaniec linear sieve snapshot `c8d01549d2ae640b36ec198c1f0f6495f1b036cf` +(both Apache-2.0). Blueprint-only machinery is omitted. + +Supporting lemmas for Iwaniec's sieve and its prime-number-theorem input. +-/ + +@[expose] public section + +namespace IwaniecLinearSievePNT + + +open MooreBound + +open Complex Topology Filter Interval Set Asymptotics + +lemma div_cpow_eq_cpow_neg (a x s : ℂ) : a / x ^ s = a * x ^ (-s) := by + rw [div_eq_mul_inv, cpow_neg] + +lemma one_div_cpow_eq_cpow_neg (x s : ℂ) : 1 / x ^ s = x ^ (-s) := by + convert div_cpow_eq_cpow_neg 1 x s using 1; simp + +lemma div_rpow_eq_rpow_neg (a x s : ℝ) (hx : 0 ≤ x) : a / x ^ s = a * x ^ (-s) := by + rw [div_eq_mul_inv, Real.rpow_neg hx] + +lemma div_rpow_neg_eq_rpow_div {x y s : ℝ} (hx : 0 ≤ x) (hy : 0 ≤ y) : + x ^ (-s) / y ^ (-s) = (y / x) ^ s := by + rw [div_eq_mul_inv, Real.rpow_neg hx, Real.rpow_neg hy, Real.div_rpow hy hx]; field_simp + +lemma div_rpow_eq_rpow_div_neg {x y s : ℝ} (hx : 0 ≤ x) (hy : 0 ≤ y) : + x ^ s / y ^ s = (y / x) ^ (-s) := by + convert div_rpow_neg_eq_rpow_div (s := -s) hx hy using 1; simp only [neg_neg] + +local notation (name := riemannzeta) "ζ" => riemannZeta +local notation (name := derivriemannzeta) "ζ'" => deriv riemannZeta + +/- +We record here some prelimiaries about the zeta function and general +holomorphic functions. +-/ +/- +If a function $f$ is holomorphic in a neighborhood of $p$ and + $\lim_{s\to p} (s-p)f(s) = A$, then + $f(s) = \frac{A}{s-p} + O(1)$ near $p$. +The function $(s - p)\cdot f(s)$ bounded, so by Theorem + \ref{existsDifferentiableOn_of_bddAbove}, there is a holomorphic function, $g$, say, so that + $(s-p)f(s) = g(s)$ in a neighborhood of $s=p$, and $g(p)=A$. Now because $g$ is holomorphic, + near $s=p$, we have $g(s)=A+O(s-p)$. Then when you divide by $(s-p)$, you get + $f(s) = A/(s-p) + O(1)$. +-/ +theorem ResidueOfTendsTo {f : ℂ → ℂ} {p : ℂ} {U : Set ℂ} + (hU : U ∈ 𝓝 p) + (hf : HolomorphicOn f (U \ {p})) + {A : ℂ} + (h_limit : Tendsto (fun s ↦ (s - p) * f s) (𝓝[≠] p) (𝓝 A)) : + ∃ V ∈ 𝓝 p, + BddAbove (norm ∘ (f - fun s ↦ A * (s - p)⁻¹) '' (V \ {p})) := by + -- Step 1. `(s-p) f s` is bounded on some punctured nbhd `V`. + have h_event : ∀ᶠ s in 𝓝[≠] p, ‖(s - p) * f s - A‖ < 1 := by + simp_rw [← dist_eq_norm_sub] + exact h_limit.eventually (Metric.ball_mem_nhds _ (by norm_num)) + have h_event_nhds : + ∀ᶠ s in 𝓝 p, s ≠ p → ‖(s - p) * f s - A‖ < 1 := by + exact (eventually_nhdsWithin_iff).1 h_event + rcases (eventually_nhds_iff.1 h_event_nhds) with ⟨V₀, hV₀_mem, hV₀_prop⟩ + have h_bound : + ∀ s, s ∈ V₀ \ {p} → ‖(s - p) * f s‖ ≤ ‖A‖ + 1 := by + intro s hs + rcases hs with ⟨hV₀, hsne⟩ + calc ‖(s - p) * f s‖ = ‖((s - p) * f s - A) + A‖ := by + ring_nf + _ ≤ ‖(s - p) * f s - A‖ + ‖A‖ := norm_add_le ((s - p) * f s - A) A + _ ≤ 1 + ‖A‖ := add_le_add_left (le_of_lt (hV₀_mem s hV₀ hsne)) ‖A‖ + _ = ‖A‖ + 1 := add_comm 1 ‖A‖ + have h_bdd : + BddAbove (norm ∘ (fun s ↦ (s - p) * f s) '' (V₀ \ {p})) := by + refine ⟨‖A‖ + 1, ?_⟩ + rintro _ ⟨s, hs, rfl⟩ + exact h_bound s hs + -- From now on work inside `W = V₀ ∩ U`, still a nbhd of `p`. + set W : Set ℂ := V₀ ∩ U with hW_def + have hW_mem : (W : Set ℂ) ∈ 𝓝 p := inter_mem (IsOpen.mem_nhds hV₀_prop.1 hV₀_prop.2) hU + have h_subset_V₀ : (W \ {p}) ⊆ (V₀ \ {p}) := by + intro z hz; exact ⟨hz.1.1, hz.2⟩ + have h_prod_holo : HolomorphicOn (fun z ↦ (z - p) * f z) (W \ {p}) := by + have h_id : HolomorphicOn (fun z : ℂ ↦ z - p) (W \ {p}) := + Differentiable.differentiableOn (Differentiable.sub_const differentiable_fun_id p) + have hfW : HolomorphicOn f (W \ {p}) := by + apply hf.mono + exact Set.sdiff_subset_sdiff_left inter_subset_right + simpa using! h_id.mul hfW + have h_bdd_W : BddAbove (norm ∘ (fun s ↦ (s - p) * f s) '' (W \ {p})) := + h_bdd.mono (image_mono h_subset_V₀) + -- Step 2. Extend the product across `p`; obtain holomorphic `g`. + obtain ⟨g, hg_holo, hg_eq⟩ := + existsDifferentiableOn_of_bddAbove hW_mem h_prod_holo h_bdd_W + have h_event_eq : + (fun z ↦ g z) =ᶠ[𝓝[≠] p] fun z ↦ (z - p) * f z := by + have hW_diff_mem : (W \ {p} : Set ℂ) ∈ 𝓝[≠] p := + sdiff_mem_nhdsWithin_compl hW_mem {p} + exact (hg_eq.eventuallyEq_of_mem hW_diff_mem).symm + have h_tendsto_gA : Tendsto g (𝓝[≠] p) (𝓝 A) := + h_limit.congr' (id (EventuallyEq.symm h_event_eq)) + have hpW : p ∈ W := by + exact mem_of_mem_nhds hW_mem + have h_cont_g : ContinuousAt g p := by + apply (hg_holo.continuousOn.continuousWithinAt hpW).continuousAt hW_mem + have h_tendsto_gp : Tendsto g (𝓝[≠] p) (𝓝 (g p)) := + h_cont_g.tendsto.mono_left inf_le_left + have g_p_eq : g p = A := + tendsto_nhds_unique' (NormedField.nhdsNE_neBot p) h_tendsto_gp h_tendsto_gA + let q : ℂ → ℂ := fun z ↦ (g z - A) / (z - p) + have h_deriv : HasDerivAt g (deriv g p) p := by + exact DifferentiableOn.hasDerivAt hg_holo hW_mem + have h_q_limit : Tendsto q (𝓝[≠] p) (𝓝 (deriv g p)) := by + rw [hasDerivAt_iff_tendsto_slope] at h_deriv + unfold slope at h_deriv + simp only [vsub_eq_sub, smul_eq_mul, inv_mul_eq_div, g_p_eq] at h_deriv + exact h_deriv + have h_event_q : ∀ᶠ z in 𝓝[≠] p, ‖q z - deriv g p‖ < 1 := by + simp_rw [← dist_eq_norm_sub] + exact h_q_limit.eventually (Metric.ball_mem_nhds _ (by norm_num)) + have h_event_q_nhds : ∀ᶠ z in 𝓝 p, z ≠ p → ‖q z - deriv g p‖ < 1 := by + simpa using (eventually_nhdsWithin_iff).1 h_event_q + rcases (eventually_nhds_iff.1 h_event_q_nhds) with + ⟨V₁, hV₁_mem, hV₁_prop⟩ + have h_q_bound : + ∀ z, z ∈ V₁ \ {p} → ‖q z‖ ≤ ‖deriv g p‖ + 1 := by + intro z hz + rcases hz with ⟨hV₁, hz_ne⟩ + calc ‖q z‖ = ‖(q z - deriv g p) + (deriv g p)‖ := by + ring_nf + _ ≤ ‖q z - deriv g p‖ + ‖deriv g p‖ := norm_add_le (q z - deriv g p) (deriv g p) + _ ≤ 1 + ‖deriv g p‖ := add_le_add_left (le_of_lt (hV₁_mem z hV₁ hz_ne)) ‖deriv g p‖ + _ = ‖deriv g p‖ + 1 := add_comm 1 ‖deriv g p‖ + -- Step 4. Relate `f` to `q` and pass the bound. + have h_eq_diff : + EqOn (fun z ↦ f z - A * (z - p)⁻¹) q (W \ {p}) := by + intro z hz + simp only + have hz_ne : (z - p) ≠ 0 := sub_ne_zero.mpr hz.2 + have hgz : g z = (z - p) * f z := by + exact id (EqOn.symm hg_eq) hz + simp only [hgz, q] + field_simp + apply IsBigO_to_BddAbove + rw [isBigO_iff] + use ‖deriv g p‖ + 1 + apply eventually_nhdsWithin_iff.mpr + filter_upwards [IsOpen.mem_nhds hV₁_prop.1 hV₁_prop.2, hW_mem] with z hV₁ hW z_ne_p + specialize h_eq_diff ⟨ hW, z_ne_p⟩ + simp only [Pi.sub_apply, Pi.one_apply, one_mem, CStarRing.norm_of_mem_unitary, + mul_one] at h_eq_diff ⊢ + rw [h_eq_diff] + exact h_q_bound _ ⟨hV₁, z_ne_p⟩ + + + + +theorem analyticAt_riemannZeta {s : ℂ} (s_ne_one : s ≠ 1) : + AnalyticAt ℂ riemannZeta s := by + apply Complex.analyticAt_iff_eventually_differentiableAt.mpr + filter_upwards [eventually_ne_nhds s_ne_one] with z hz using differentiableAt_riemannZeta hz + +theorem differentiableAt_deriv_riemannZeta {s : ℂ} (s_ne_one : s ≠ 1) : + DifferentiableAt ℂ ζ' s := by + exact (analyticAt_riemannZeta s_ne_one).deriv.differentiableAt + + +/- +The Riemann zeta function $\zeta(s)$ has a simple pole at $s=1$ with residue $1$. In particular, + the function $\zeta(s) - \frac{1}{s-1}$ is bounded in a neighborhood of $s=1$. +From \texttt{riemannZeta\_residue\_one} (in Mathlib), we know that + $(s-1)\zeta(s)$ goes to $1$ as $s\to1$. Now apply Theorem \ref{ResidueOfTendsTo}. + (This can also be done using $\zeta_0$ below, which is expressed as + $1/(s-1)$ plus things that are holomorphic for $\Re(s)>0$...) +-/ +theorem riemannZetaResidue : + ∃ U ∈ 𝓝 1, BddAbove (norm ∘ (ζ - (fun s ↦ (s - 1)⁻¹)) '' (U \ {1})) := by + have zeta_holc : HolomorphicOn ζ (univ \ {1}) := by + intro y hy + exact DifferentiableAt.differentiableWithinAt <| differentiableAt_riemannZeta hy.2 + convert ResidueOfTendsTo univ_mem zeta_holc riemannZeta_residue_one using 6 + simp + + +-- Main theorem: if functions agree on a punctured set, their derivatives agree there too +theorem deriv_eqOn_of_eqOn_punctured (f g : ℂ → ℂ) (U : Set ℂ) (p : ℂ) + (hU_open : IsOpen U) + (h_eq : EqOn f g (U \ {p})) : + EqOn (deriv f) (deriv g) (U \ {p}) := by + intro x hx + apply EventuallyEq.deriv_eq + filter_upwards [IsOpen.mem_nhds (hU_open.sdiff isClosed_singleton) hx] with t ht using h_eq ht + +/- New two theorems to be proven -/ +theorem analytic_deriv_bounded_near_point + (f : ℂ → ℂ) {U : Set ℂ} {p : ℂ} (hU : IsOpen U) (hp : p ∈ U) (hf : HolomorphicOn f U) : + (deriv f) =O[𝓝[≠] p] (1 : ℂ → ℂ) := by + have U_in_filter : U ∈ 𝓝 p := by + exact IsOpen.mem_nhds hU hp + have T := (analyticOn_iff_differentiableOn hU).mpr hf + have T2 : ContDiffOn ℂ 1 f U := + DifferentiableOn.contDiffOn hf hU + have T3 : ContinuousOn (fun x ↦ ((deriv f) x)) U := by + apply T2.continuousOn_deriv_of_isOpen hU (by simp) + have T4 := T3.continuousAt U_in_filter + have T5 : (deriv f) =O[𝓝 p] (1 : ℂ → ℂ) := + T4.norm.isBoundedUnder_le.isBigO_one ℂ + exact Asymptotics.IsBigO.mono T5 inf_le_left + +theorem derivative_const_plus_product {g : ℂ → ℂ} (A p x : ℂ) (hg : DifferentiableAt ℂ g x) : + deriv ((fun _ ↦ A) + g * fun s ↦ s - p) x = deriv g x * (x - p) + g x := by + rw [deriv_add (by fun_prop) (by fun_prop), deriv_const, deriv_mul hg (by fun_prop)] + simp + +lemma deriv_inv_sub {x p : ℂ} (hp : x ≠ p) : + deriv (fun z => (z - p)⁻¹) x = -((x - p) ^ 2)⁻¹ := by + rw [deriv_fun_inv'' (by fun_prop) (by grind)] + simp + field + +-- Alternative cleaner proof using more direct approach +theorem deriv_f_minus_A_inv_sub_clean (f : ℂ → ℂ) (A x p : ℂ) + (hf : DifferentiableAt ℂ f x) (hp : x ≠ p) : + deriv (f - (fun z ↦ A * (z - p)⁻¹)) x = deriv f x + A * ((x - p) ^ 2)⁻¹ := by + have h1 : DifferentiableAt ℂ (fun z => (z - p)⁻¹) x := by + fun_prop (disch := grind) + rw [deriv_sub hf (h1.const_mul A), deriv_const_mul A h1, deriv_inv_sub hp] + ring + +/- +If a function $f$ has a simple pole at a point $p$ with residue $A \neq 0$, then + $f$ is nonzero in a punctured neighborhood of $p$. +We know that $f(s) = \frac{A}{s-p} + O(1)$ near $p$, so we can write + $$f(s) = \left(f(s) - \frac{A}{s-p}\right) + \frac{A}{s-p}.$$ + The first term is bounded, say by $M$, and the second term goes to $\infty$ as $s \to p$. + Therefore, there exists a neighborhood $V$ of $p$ such that for all $s \in V \setminus \{p\}$, + we have $f(s) \neq 0$. +-/ +theorem nonZeroOfBddAbove {f : ℂ → ℂ} {p : ℂ} {U : Set ℂ} + (U_in_nhds : U ∈ 𝓝 p) {A : ℂ} (A_ne_zero : A ≠ 0) + (f_near_p : BddAbove (norm ∘ (f - fun s ↦ A * (s - p)⁻¹) '' (U \ {p}))) : + ∃ V ∈ 𝓝 p, IsOpen V ∧ ∀ s ∈ V \ {p}, f s ≠ 0 := by + -- Step 1: Rewrite f as the sum of two parts + have h_decomp : ∀ s, f s = (f s - A * (s - p)⁻¹) + A * (s - p)⁻¹ := by + intro s + ring + -- Get a bound for the first summand + obtain ⟨M, hM⟩ := f_near_p + -- Step 2: The second summand A * (s - p)⁻¹ goes to ∞ as s → p + -- We need to find a neighborhood where |A * (s - p)⁻¹| > M + 1 + have A_norm_pos : 0 < ‖A‖ := norm_pos_iff.mpr A_ne_zero + -- Choose δ such that for |s - p| < δ, we have |A * (s - p)⁻¹| > M + 1 + let δ := ‖A‖ / (‖M‖ + 1) + have δ_pos : 0 < δ := by + refine div_pos A_norm_pos (add_pos_of_nonneg_of_pos (norm_nonneg M) one_pos) + -- Find an open neighborhood V contained in both U and the δ-ball around p + obtain ⟨V, hV_open, hV_mem, hV_sub⟩ : ∃ V, IsOpen V ∧ p ∈ V ∧ V ⊆ U ∩ Metric.ball p δ := by + -- rw [mem_nhds_iff] at U_in_nhds + obtain ⟨W, hW_sub, hW_open, hW_mem⟩ := mem_nhds_iff.mp U_in_nhds + let V := W ∩ Metric.ball p δ + have VNp : V ∈ 𝓝 p := (𝓝 p).inter_mem (IsOpen.mem_nhds hW_open hW_mem) + (Metric.ball_mem_nhds p δ_pos) + exact ⟨V, IsOpen.inter hW_open Metric.isOpen_ball, mem_of_mem_nhds VNp, + inter_subset_inter_left _ hW_sub⟩ + use V, mem_nhds_iff.mpr ⟨V, subset_refl V, hV_open, hV_mem⟩, hV_open + -- Show f ≠ 0 on V + intro s hs + have hs_in_U : s ∈ U := hV_sub hs.1 |>.1 + have hs_near_p : dist s p < δ := hV_sub hs.1 |>.2 + have hs_ne_p : s ≠ p := hs.2 + -- Step 3: Therefore the sum of the two terms has large norm + rw [h_decomp s] + -- The first summand is bounded + have bound_first : ‖f s - A * (s - p)⁻¹‖ ≤ M := by + apply hM + exact ⟨s, ⟨hs_in_U, hs_ne_p⟩, rfl⟩ + -- The second summand has large norm + have large_second : ‖M‖ + 1 < ‖A * (s - p)⁻¹‖ := by + rw [norm_mul, norm_inv, ← div_eq_mul_inv] + rw [lt_div_iff₀ (norm_pos_iff.mpr (sub_ne_zero.mpr hs_ne_p))] + rw [mul_comm, ← lt_div_iff₀ (add_pos_of_nonneg_of_pos (norm_nonneg M) one_pos)] + rw [dist_eq_norm_sub] at hs_near_p + exact hs_near_p + -- Step 4: Therefore the sum is nonzero near p + by_contra h_zero + -- If f s = 0, then the two summands are negatives of each other + rw [add_eq_zero_iff_eq_neg] at h_zero + rw [h_zero, norm_neg] at bound_first + -- But this contradicts our bounds + have : ‖M‖ + 1 < ‖M‖ := (lt_of_lt_of_le (lt_of_lt_of_le large_second bound_first) + (Real.le_norm_self M)) + norm_num at this + +/- The set should be open so that f'(p) = O(1) for all p ∈ U -/ +theorem logDerivResidue' {f : ℂ → ℂ} {p : ℂ} {U : Set ℂ} + (U_is_open : IsOpen U) + (non_zero : ∀ x ∈ U \ {p}, f x ≠ 0) + (holc : HolomorphicOn f (U \ {p})) + (U_in_nhds : U ∈ 𝓝 p) {A : ℂ} (A_ne_zero : A ≠ 0) + (f_near_p : BddAbove (norm ∘ (f - fun s ↦ A * (s - p)⁻¹) '' (U \ {p}))) : + (deriv f * f⁻¹ + (fun s ↦ (s - p)⁻¹)) =O[𝓝[≠] p] (1 : ℂ → ℂ) := by + have simpleHolo : HolomorphicOn (fun s ↦ A / (s - p)) (U \ {p}) := by + apply DifferentiableOn.mono (t := {p}ᶜ) + · apply DifferentiableOn.div + · exact differentiableOn_const _ + · exact DifferentiableOn.sub differentiableOn_id (differentiableOn_const _) + · exact fun x hx => by rw [sub_ne_zero]; exact hx + · rintro s ⟨_, hs⟩; exact hs + have f_minus_pole_is_holomorphic : HolomorphicOn (f - (fun s ↦ A * (s - p)⁻¹)) (U \ {p}) := by + exact (DifferentiableOn.sub_iff_right holc).mpr simpleHolo + let ⟨g, ⟨g_is_holomorphic, g_is_f_minus_pole⟩⟩ := existsDifferentiableOn_of_bddAbove + U_in_nhds f_minus_pole_is_holomorphic f_near_p + /- TODO: Assert that the derivatives match too -/ + let h := (fun _ ↦ A) + g * (fun (s : ℂ) ↦ (s - p)) + have linear_is_holomorphic : HolomorphicOn (fun (s : ℂ ) ↦ (s - p)) U := by + exact DifferentiableOn.sub_const differentiableOn_id p + have h_is_holomorphic : HolomorphicOn h U := by + have T := DifferentiableOn.mul g_is_holomorphic linear_is_holomorphic + exact DifferentiableOn.const_add A T + have h_continuous : ContinuousOn h U := + by exact DifferentiableOn.continuousOn h_is_holomorphic + have deriv_h_identity : ∀x ∈ (U \ {p}), (deriv h) x = f x + (deriv f x) * (x - p) := by + intro x x_in_u_not_p + have x_in_u : x ∈ U := by exact Set.mem_of_mem_sdiff x_in_u_not_p + have x_not_p : x ≠ p := by + exact ((Set.mem_sdiff x).mp x_in_u_not_p).2 + have weird : U ∈ 𝓝 x := by + exact IsOpen.mem_nhds (U_is_open) (x_in_u) + rw [derivative_const_plus_product, ← g_is_f_minus_pole x_in_u_not_p, + ← deriv_eqOn_of_eqOn_punctured _ _ U p U_is_open g_is_f_minus_pole x_in_u_not_p, + deriv_f_minus_A_inv_sub_clean] + · simp only [Pi.sub_apply] + have := sub_ne_zero_of_ne x_not_p + field_simp + ring + · apply holc.differentiableAt + exact Filter.inter_mem weird <| compl_singleton_mem_nhds x_not_p + · exact x_not_p + · exact g_is_holomorphic.differentiableAt weird + have h_identity : ∀x ∈ (U \ {p}), h x = (f x) * (x - p) := by + intro x x_in_u_not_p + have hyp_x_not_p : x ≠ p := by + exact ((Set.mem_sdiff x).mp x_in_u_not_p).2 + simp only [h, Pi.add_apply, Pi.mul_apply] + rw [← g_is_f_minus_pole x_in_u_not_p] + simp only [Pi.sub_apply] + field [sub_ne_zero.mpr hyp_x_not_p] + have log_deriv_f_plus_pole_equal_log_deriv_h : + EqOn (deriv f * f⁻¹ + fun s ↦ (s - p)⁻¹) ((deriv h) * h⁻¹) (U \ {p}) := by + simp only [Set.mem_sdiff, mem_singleton_iff, ne_eq, and_imp, Function.comp_apply, Pi.sub_apply, + DifferentiableOn.sub_iff_right, differentiableOn_const, DifferentiableOn.fun_sub_iff_left, + holc] at * + intro x hyp_x + have x_not_p : x ≠ p := by + exact ((Set.mem_sdiff x).mp hyp_x).2 + have x_in_u : x ∈ U := by exact Set.mem_of_mem_sdiff hyp_x + simp only [Pi.add_apply, Pi.mul_apply, Pi.inv_apply] + rw [deriv_h_identity _ x_in_u x_not_p, h_identity _ x_in_u x_not_p] + /- This is just an identity at this point -/ + field [sub_ne_zero.mpr x_not_p, non_zero x (x_in_u) x_not_p] + have h_inv_bounded : + h⁻¹ =O[𝓝[≠] p] (1 : ℂ → ℂ) := by + have : ContinuousAt h⁻¹ p := by + apply ContinuousOn.continuousAt h_continuous U_in_nhds |>.inv₀ + simp [h, A_ne_zero] + exact Asymptotics.IsBigO.mono (this.norm.isBoundedUnder_le.isBigO_one ℂ) inf_le_left + have h_deriv_bounded : + (deriv h) =O[𝓝[≠] p] (1 : ℂ → ℂ) := + analytic_deriv_bounded_near_point h U_is_open + (by exact mem_of_mem_nhds U_in_nhds) h_is_holomorphic + have h_log_deriv_bounded : + ((deriv h) * h⁻¹) =O[𝓝[≠] p] (1 : ℂ → ℂ) := by + have T := Asymptotics.IsBigO.mul h_deriv_bounded h_inv_bounded + exact IsBigO.of_const_mul_right T + have u_not_p_in_filter : U \ {p} ∈ 𝓝[≠] p := by + exact sdiff_mem_nhdsWithin_compl U_in_nhds {p} + have T := Set.EqOn.eventuallyEq_of_mem log_deriv_f_plus_pole_equal_log_deriv_h u_not_p_in_filter + exact EventuallyEq.trans_isBigO T h_log_deriv_bounded + + +/- +If $f$ is holomorphic in a neighborhood of $p$, and there is a simple pole at $p$, then $f'/ + f$ has a simple pole at $p$ with residue $-1$: + $$ \frac{f'(s)}{f(s)} = \frac{-1}{s - p} + O(1).$$ +Using Theorem \ref{existsDifferentiableOn_of_bddAbove}, there is a function $g$ holomorphic + near $p$, for which $f(s) = A/(s-p) + g(s) = h(s)/ (s-p)$. Here $h(s):= A + g(s)(s-p)$ which + is nonzero in a neighborhood of $p$ (since $h$ goes to $A$ which is nonzero). + Then $f'(s) = (h'(s)(s-p) - h(s))/(s-p)^2$, and we can compute the quotient: + $$ + \frac{f'(s)}{f(s)}+1/(s-p) = \frac{h'(s)(s-p) - h(s)}{h(s)} \cdot \frac{1}{(s-p)}+1/(s-p) + = + \frac{h'(s)}{h(s)}. + $$ + Since $h$ is nonvanishing near $p$, this remains bounded in a neighborhood of $p$. +-/ +theorem logDerivResidue {f : ℂ → ℂ} {p : ℂ} {U : Set ℂ} + (non_zero : ∀ x ∈ U \ {p}, f x ≠ 0) + (holc : HolomorphicOn f (U \ {p})) + (U_in_nhds : U ∈ 𝓝 p) {A : ℂ} (A_ne_zero : A ≠ 0) + (f_near_p : BddAbove (norm ∘ (f - fun s ↦ A * (s - p)⁻¹) '' (U \ {p}))) : + (deriv f * f⁻¹ + (fun s ↦ (s - p)⁻¹)) =O[𝓝[≠] p] (1 : ℂ → ℂ) := + by + let ⟨U', ⟨a,b,c⟩⟩ := mem_nhds_iff.mp U_in_nhds + have W : (U' \ {p}) ⊆ U' := by + exact Set.sdiff_subset + have T : (U' \ {p}) ⊆ (U \ {p}) := by + exact Set.sdiff_subset_sdiff a (subset_refl _) + refine logDerivResidue' b ?_ ?_ (IsOpen.mem_nhds b c) A_ne_zero ?_ + · intro x hyp_x + exact non_zero x <| T hyp_x + · exact DifferentiableOn.mono holc T + · exact (f_near_p.mono (image_mono (Set.sdiff_subset_sdiff a (subset_refl _)))) + + + +/- +If $f$ is bounded above in a punctured neighborhood of $p$, then $f$ is $O(1)$ in that + neighborhood. +Elementary. +-/ +lemma BddAbove_to_IsBigO {f : ℂ → ℂ} {p : ℂ} + {U : Set ℂ} (hU : U ∈ 𝓝 p) (bdd : BddAbove (norm ∘ f '' (U \ {p}))) : + f =O[𝓝[≠] p] (1 : ℂ → ℂ) := by + dsimp [BddAbove, upperBounds] at bdd + rcases bdd with ⟨C, hC⟩ + have h : ∀ x ∈ U \ {p}, ‖f x‖ ≤ C := by + intro x hx + have fx_is_norm : ‖f x‖ ∈ norm ∘ f ''(U \ {p}) := by + exact ⟨x, hx, rfl⟩ + exact hC fx_is_norm + rw [Asymptotics.isBigO_iff] + use C + rw [eventually_nhdsWithin_iff] + simp only [Set.mem_sdiff, mem_singleton_iff, and_imp, mem_compl_iff, Pi.one_apply, one_mem, + CStarRing.norm_of_mem_unitary, mul_one] at h ⊢ + filter_upwards [hU] using h + + +theorem logDerivResidue'' {f : ℂ → ℂ} {p : ℂ} {U : Set ℂ} + (non_zero : ∀ x ∈ U \ {p}, f x ≠ 0) + (holc : HolomorphicOn f (U \ {p})) + (U_in_nhds : U ∈ 𝓝 p) {A : ℂ} (A_ne_zero : A ≠ 0) + (f_near_p : BddAbove (norm ∘ (f - fun s ↦ A * (s - p)⁻¹) '' (U \ {p}))) : + ∃ V ∈ 𝓝 p, BddAbove (norm ∘ (deriv f * f⁻¹ + (fun s ↦ (s - p)⁻¹)) '' (V \ {p})) := by + apply IsBigO_to_BddAbove + exact logDerivResidue non_zero holc U_in_nhds A_ne_zero f_near_p + +/- +Let's also record that if a function $f$ has a simple pole at $p$ with residue $A$, and $g$ is +holomorphic near $p$, then the residue of $f \cdot g$ is $A \cdot g(p)$. +-/ + +/- +If $f$ has a simple pole at $p$ with residue $A$, and $g$ is holomorphic near $p$, then the + residue of $f \cdot g$ at $p$ is $A \cdot g(p)$. That is, we assume that + $$ + f(s) = \frac{A}{s - p} + O(1)$$ + near $p$, and that $g$ is holomorphic near $p$. Then + $$ + f(s) \cdot g(s) = \frac{A \cdot g(p)}{s - p} + O(1).$$ +Elementary calculation. + $$ + f(s) * g(s) - \frac{A * g(p)}{s - p} = + \left(f(s) * g(s) - \frac{A * g(s)}{s - p}\right) + + \left(\frac{A * g(s) - A * g(p)}{s - p}\right). + $$ + The first term is $g(s)(f(s) - \frac{A}{s - p})$, which is bounded near $p$ by the assumption + on $f$ + and the fact that $g$ is holomorphic near $p$. + The second term is $A$ times the log derivative of $g$ at $p$, which is bounded by the assumption + that $g$ is holomorphic. +-/ +theorem ResidueMult {f g : ℂ → ℂ} {p : ℂ} {U : Set ℂ} + (g_holc : HolomorphicOn g U) (U_in_nhds : U ∈ 𝓝 p) {A : ℂ} + (f_near_p : (f - (fun s ↦ A * (s - p)⁻¹)) =O[𝓝[≠] p] (1 : ℂ → ℂ)) : + (f * g - (fun s ↦ A * g p * (s - p)⁻¹)) =O[𝓝[≠] p] (1 : ℂ → ℂ) := by + -- Add and subtract a term + have : (f * g - fun s ↦ A * g p * (s - p)⁻¹) + = (f - A • fun s ↦ (s - p)⁻¹) * g + fun s ↦ (A * (g s - g p) / (s - p)) := by + ext; simp; ring + -- Apply to goal + rw[this] + have p_in_U : p ∈ U := mem_of_mem_nhds U_in_nhds + refine Asymptotics.IsBigO.add ?_ ?_ + · rw[← mul_one (1 : ℂ → ℂ)] + refine Asymptotics.IsBigO.mul f_near_p ?_ + -- Show g is bounded near p + have g_cont : ContinuousAt g p := by + -- g is holomorphic on U, p ∈ U, so g is continuous at p + exact (g_holc.continuousOn.continuousWithinAt p_in_U).continuousAt U_in_nhds + -- Use continuity to get boundedness + have := g_cont.norm.isBoundedUnder_le.isBigO_one ℂ + exact IsBigO.mono this inf_le_left + · -- Show that (fun s ↦ A * (g s - g p) / (s - p)) =O[𝓝[≠] p] 1 + suffices (fun s ↦ A * ((s - p)⁻¹ * (g s - g p))) =O[𝓝[≠] p] 1 by + convert! this using 2 + rw[div_eq_mul_inv] + ring + apply Asymptotics.IsBigO.const_mul_left + -- g is differentiable at p since it's holomorphic on U + have g_diff : HasDerivAt g (deriv g p) p := + (DifferentiableOn.differentiableAt g_holc U_in_nhds).hasDerivAt + rw [hasDerivAt_iff_isLittleO] at g_diff + apply Asymptotics.IsLittleO.isBigO at g_diff + have : (fun x' ↦ deriv g p * (x' - p)) =O[𝓝 p] fun x' ↦ x' - p := by + apply Asymptotics.IsBigO.const_mul_left + exact Asymptotics.isBigO_refl (fun x ↦ x - p) (𝓝 p) + have h1 := g_diff.add this + have h2 : (fun x ↦ g x - g p) =O[𝓝 p] fun x' ↦ x' - p := by + convert! h1 using 2 + simp + ring + refine (Asymptotics.isBigO_mul_iff_isBigO_div ?_).mpr ?_ + · filter_upwards [self_mem_nhdsWithin] with x hx + simp only [mem_compl_iff, mem_singleton_iff] at hx + exact inv_ne_zero (sub_ne_zero.mpr hx) + · simp only [div_inv_eq_mul] + refine Asymptotics.IsBigO.mono ?_ inf_le_left + simpa + + +/- +As a corollary, the log derivative of the Riemann zeta function has a simple pole at $s=1$: +-/ +/- +The log derivative of the Riemann zeta function $\zeta(s)$ has a simple pole at $s=1$ with + residue $-1$: $-\frac{\zeta'(s)}{\zeta(s)} - \frac{1}{s-1} = O(1)$. +This follows from Theorem \ref{logDerivResidue} and Theorem \ref{riemannZetaResidue}. +-/ +theorem riemannZetaLogDerivResidue : + ∃ U ∈ 𝓝 1, BddAbove (norm ∘ (-(ζ' / ζ) - (fun s ↦ (s - 1)⁻¹)) '' (U \ {1})) := by + obtain ⟨U,U_in_nhds, hU⟩ := riemannZetaResidue + have hU' : BddAbove (norm ∘ (ζ - fun s ↦ 1 * (s - 1)⁻¹) '' (U \ {1})) := by + simp only [Function.comp_apply, Pi.sub_apply, one_mul] at hU ⊢ + exact hU + obtain ⟨V,V_in_nhds, V_is_open, hV⟩ := nonZeroOfBddAbove U_in_nhds one_ne_zero hU' + let W := V ∩ interior U + have hW : ∀ s ∈ W \ {1}, ζ s ≠ 0 := by + intro s hs + have s_in_V_diff : s ∈ V \ {1} := ⟨hs.1.1, hs.2⟩ + exact hV s s_in_V_diff + have ζ_holc: HolomorphicOn ζ (W \ {1}) := by + intro y hy + simp only [Set.mem_sdiff, mem_singleton_iff] at hy + refine DifferentiableAt.differentiableWithinAt ?_ + apply differentiableAt_riemannZeta hy.2 + have W_in_nhds : W ∈ 𝓝 1 := by + refine inter_mem V_in_nhds ?_ + exact interior_mem_nhds.mpr U_in_nhds + have := logDerivResidue'' hW ζ_holc W_in_nhds one_ne_zero + have HW : BddAbove (norm ∘ (ζ - fun s ↦ (s - 1)⁻¹) '' (W \ {1})) := by + obtain ⟨c, hc⟩ := bddAbove_def.mp hU + apply bddAbove_def.mpr + use c + rintro y ⟨x, x_in_W, fxy⟩ + apply hc + exact ⟨x, ⟨interior_subset x_in_W.1.2, x_in_W.2⟩, fxy⟩ + simp only [one_mul] at this + have aux: ∀ a, ‖-(deriv ζ a / ζ a) - (a - 1)⁻¹‖ = ‖(deriv ζ a / ζ a) + (a - 1)⁻¹‖ := by + intro a + calc ‖-(deriv ζ a / ζ a) - (a - 1)⁻¹‖ + = ‖-((deriv ζ a / ζ a) + (a - 1)⁻¹)‖ := by ring_nf + _ = ‖(deriv ζ a / ζ a) + (a - 1)⁻¹‖ := by rw [norm_neg] + simp only [Function.comp_apply, Pi.sub_apply] at hU + simp only [Function.comp_apply, Pi.sub_apply, Pi.neg_apply, Pi.div_apply, aux] + apply this HW + + +theorem riemannZetaLogDerivResidueBigO : + (-ζ' / ζ - fun z ↦ (z - 1)⁻¹) =O[nhdsWithin 1 {1}ᶜ] (1 : ℂ → ℂ) := by + obtain ⟨U, hU, bdd⟩ := riemannZetaLogDerivResidue + convert BddAbove_to_IsBigO hU bdd using 2 + rw [neg_div] + +/- +For any natural $N\ge1$, we define + $$ + \zeta_0(N,s) := + \sum_{1\le n \le N} \frac1{n^s} + + + \frac{- N^{1-s}}{1-s} + \frac{-N^{-s}}{2} + s \int_N^\infty \frac{\lfloor x\rfloor + 1/2 - + x}{x^{s+1}} \, dx + $$ +-/ +/-- The Euler-Maclaurin representation of zeta with a cutoff at `N`. -/ +noncomputable def riemannZeta0 (N : ℕ) (s : ℂ) : ℂ := + (∑ n ∈ Finset.range (N + 1), 1 / (n : ℂ) ^ s) + + (- N ^ (1 - s)) / (1 - s) + (- N ^ (-s)) / 2 + + s * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) / (x : ℂ) ^ (s + 1) + +/-- We use `ζ` to denote the Rieman zeta function and `ζ₀` to denote the alternative Rieman zeta +function. -/ +local notation (name := riemannzeta0) "ζ₀" => riemannZeta0 + +lemma riemannZeta0_apply (N : ℕ) (s : ℂ) : ζ₀ N s = + (∑ n ∈ Finset.range (N + 1), 1 / (n : ℂ) ^ s) + + ((- N ^ (1 - s)) / (1 - s) + (- N ^ (-s)) / 2 + + s * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-(s + 1))) := by + simp_rw [riemannZeta0, div_cpow_eq_cpow_neg]; ring + +-- move near `Real.differentiableAt_rpow_const_of_ne` +lemma _root_.Real.differentiableAt_cpow_const_of_ne (s : ℂ) {x : ℝ} (xpos : 0 < x) : + DifferentiableAt ℝ (fun (x : ℝ) ↦ (x : ℂ) ^ s) x := by + apply DifferentiableAt.comp_ofReal (e := fun z ↦ z ^ s) + apply DifferentiableAt.cpow (by simp) (by simp) (by simp [xpos]) + +lemma _root_.Complex.one_div_cpow_eq {s : ℂ} {x : ℝ} (x_ne : x ≠ 0) : + 1 / (x : ℂ) ^ s = (x : ℂ) ^ (-s) := by + refine (eq_one_div_of_mul_eq_one_left ?_).symm + rw [← cpow_add _ _ <| mod_cast x_ne, neg_add_cancel, cpow_zero] + +/- +Let $a < b$, and let $\phi$ be continuously differentiable on $[a, b]$. + Then + \[ + \sum_{a < n \le b} \phi(n) = \int_a^b \phi(x) \, dx + + \left(\lfloor b \rfloor + \frac{1}{2} - b\right) \phi(b) + - \left(\lfloor a \rfloor + \frac{1}{2} - a\right) \phi(a) + - \int_a^b \left(\lfloor x \rfloor + \frac{1}{2} - x\right) \phi'(x) \, dx. + \] +This is first order Euler-Maclaurin. +-/ +lemma sum_eq_int_deriv {φ : ℝ → ℂ} {a b : ℝ} (apos : 0 ≤ a) (a_lt_b : a < b) + (φDiff : ∀ x ∈ [[a, b]], HasDerivAt φ (deriv φ x) x) + (derivφCont : ContinuousOn (deriv φ) [[a, b]]) : + ∑ n ∈ Finset.Ioc ⌊a⌋₊ ⌊b⌋₊, φ n = + (∫ x in a..b, φ x) + (⌊b⌋₊ + 1 / 2 - b) * φ b - (⌊a⌋₊ + 1 / 2 - a) * φ a + - ∫ x in a..b, (⌊x⌋ + 1 / 2 - x) * deriv φ x := by + rw [uIcc_of_le a_lt_b.le] at φDiff + convert sum_eq_integral_add_integral_deriv apos a_lt_b.le (fun t ht ↦ (φDiff t + ht).differentiableAt) derivφCont using 1 + unfold B1 + push_cast + suffices ∫ (x : ℝ) in a..b, (↑⌊x⌋ + 1 / 2 - ↑x) * deriv φ x = -∫ (t : ℝ) in a..b, deriv φ t * + (↑t - ↑⌊t⌋₊ - 1 / 2) by + rw [this] + ring_nf! + rw [← intervalIntegral.integral_neg] + refine intervalIntegral.integral_congr fun x hx ↦ ?_ + rw [uIcc_of_le a_lt_b.le, mem_Icc] at hx + rw [← Int.natCast_floor_eq_floor (by linarith)] + norm_cast + push_cast + ring + + +lemma xpos_of_uIcc {a b : ℕ} (ha : a ∈ Ioo 0 b) {x : ℝ} (x_in : x ∈ [[(a : ℝ), b]]) : + 0 < x := by + rw [uIcc_of_le (by exact_mod_cast ha.2.le), mem_Icc] at x_in + linarith [(by exact_mod_cast ha.1 : (0 : ℝ) < a)] + +lemma ZetaSum_aux1₁ {a b : ℕ} {s : ℂ} (s_ne_one : s ≠ 1) (ha : a ∈ Ioo 0 b) : + (∫ (x : ℝ) in a..b, 1 / (x : ℂ) ^ s) = + (b ^ (1 - s) - a ^ (1 - s)) / (1 - s) := by + convert integral_cpow (a := a) (b := b) (r := -s) ?_ using 1 + · refine intervalIntegral.integral_congr fun x hx ↦ one_div_cpow_eq ?_ + exact (xpos_of_uIcc ha hx).ne' + · norm_cast; ring_nf + · right; refine ⟨(by grind), ?_⟩ + exact fun hx ↦ (lt_self_iff_false 0).mp <| xpos_of_uIcc ha hx + +lemma ZetaSum_aux1φDiff {s : ℂ} {x : ℝ} (xpos : 0 < x) : + HasDerivAt (fun (t : ℝ) ↦ 1 / (t : ℂ) ^ s) (deriv (fun (t : ℝ) ↦ 1 / (t : ℂ) ^ s) x) x := by + exact hasDerivAt_deriv_iff.mpr <| + DifferentiableAt.div (differentiableAt_const _) + (Real.differentiableAt_cpow_const_of_ne s xpos) (by simp [cpow_eq_zero_iff, xpos.ne']) + +lemma ZetaSum_aux1φderiv {s : ℂ} (s_ne_zero : s ≠ 0) {x : ℝ} (xpos : 0 < x) : + deriv (fun (t : ℝ) ↦ 1 / (t : ℂ) ^ s) x = (fun (x : ℝ) ↦ -s * (x : ℂ) ^ (-(s + 1))) x := by + let r := -s - 1 + have r_add1_ne_zero : r + 1 ≠ 0 := fun hr ↦ by simp [neg_ne_zero.mpr s_ne_zero, r] at hr + have r_ne_neg1 : r ≠ -1 := fun hr ↦ (hr ▸ r_add1_ne_zero) <| by norm_num + have hasDeriv := hasDerivAt_ofReal_cpow_const' xpos.ne' r_ne_neg1 + have := hasDeriv.deriv ▸ deriv_const_mul (-s) (hasDeriv).differentiableAt + convert! this using 2 + · ext y + by_cases y_zero : (y : ℂ) = 0 + · simp only [y_zero, ne_eq, s_ne_zero, not_false_eq_true, zero_cpow, div_zero, + r_add1_ne_zero, zero_div, mul_zero] + · have : (y : ℂ) ^ s ≠ 0 := fun hy ↦ y_zero ((cpow_eq_zero_iff _ _).mp hy).1 + simp only [one_div, sub_add_cancel, cpow_neg, neg_mul, r] + field_simp + · simp only [r] + ring_nf + +lemma ZetaSum_aux1derivφCont {s : ℂ} (s_ne_zero : s ≠ 0) {a b : ℕ} (ha : a ∈ Ioo 0 b) : + ContinuousOn (deriv (fun (t : ℝ) ↦ 1 / (t : ℂ) ^ s)) [[a, b]] := by + have : EqOn _ (fun (t : ℝ) ↦ -s * (t : ℂ) ^ (-(s + 1))) [[a, b]] := + fun x hx ↦ ZetaSum_aux1φderiv s_ne_zero <| xpos_of_uIcc ha hx + refine continuous_ofReal.continuousOn.cpow_const ?_ |>.const_smul (c := -s) |>.congr this + exact fun x hx ↦ ofReal_mem_slitPlane.mpr <| xpos_of_uIcc ha hx + +/- +Let $0 < a < b$ be natural numbers and $s\in \C$ with $s \ne 1$ and $s \ne 0$. + Then + \[ + \sum_{a < n \le b} \frac{1}{n^s} = \frac{b^{1-s} - a^{1-s}}{1-s} + \frac{b^{-s}-a^{-s}}{2} + + s \int_a^b \frac{\lfloor x\rfloor + 1/2 - x}{x^{s+1}} \, dx. + \] +Apply Lemma \ref{sum_eq_int_deriv} to the function $x \mapsto x^{-s}$. +-/ +lemma ZetaSum_aux1 {a b : ℕ} {s : ℂ} (s_ne_one : s ≠ 1) (s_ne_zero : s ≠ 0) (ha : a ∈ Ioo 0 b) : + ∑ n ∈ Finset.Ioc a b, 1 / (n : ℂ) ^ s = + (b ^ (1 - s) - a ^ (1 - s)) / (1 - s) + 1 / 2 * (1 / b ^ (s)) - 1 / 2 * (1 / a ^ s) + + s * ∫ x in a..b, (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-(s + 1)) := by + let φ := fun (x : ℝ) ↦ 1 / (x : ℂ) ^ s + let φ' := fun (x : ℝ) ↦ -s * (x : ℂ) ^ (-(s + 1)) + have xpos : ∀ x ∈ [[(a : ℝ), b]], 0 < x := fun x hx ↦ xpos_of_uIcc ha hx + have φDiff : ∀ x ∈ [[(a : ℝ), b]], HasDerivAt φ (deriv φ x) x := + fun x hx ↦ ZetaSum_aux1φDiff (xpos x hx) + have φderiv : ∀ x ∈ [[(a : ℝ), b]], deriv φ x = φ' x := by + exact fun x hx ↦ ZetaSum_aux1φderiv s_ne_zero (xpos x hx) + have derivφCont : ContinuousOn (deriv φ) [[a, b]] := ZetaSum_aux1derivφCont s_ne_zero ha + convert sum_eq_int_deriv (by linarith) (by exact_mod_cast ha.2) φDiff derivφCont using 1 + · congr <;> simp only [Nat.floor_natCast] + · rw [Nat.floor_natCast, Nat.floor_natCast, ← intervalIntegral.integral_const_mul] + simp_rw [mul_div, ← mul_div, φ, ZetaSum_aux1₁ s_ne_one ha] + conv => rhs; rw [sub_eq_add_neg] + congr; any_goals norm_cast; simp only [one_div, add_sub_cancel_left] + rw [← intervalIntegral.integral_neg, intervalIntegral.integral_congr] + simp only [φ, one_div] at φderiv + intro x hx; simp_rw [φderiv x hx, φ']; ring_nf + +lemma ZetaSum_aux1_1' {a b x : ℝ} (apos : 0 < a) (hx : x ∈ Icc a b) : 0 < x := + lt_of_lt_of_le apos hx.1 + +lemma ZetaSum_aux1_1 {a b x : ℝ} (apos : 0 < a) (a_lt_b : a < b) (hx : x ∈ [[a, b]]) : 0 < x := + lt_of_lt_of_le apos (uIcc_of_le a_lt_b.le ▸ hx).1 + +lemma ZetaSum_aux1_2 {a b : ℝ} {c : ℝ} (apos : 0 < a) (a_lt_b : a < b) + (h : c ≠ 0 ∧ 0 ∉ [[a, b]]) : + ∫ (x : ℝ) in a..b, 1 / x ^ (c+1) = (a ^ (-c) - b ^ (-c)) / c := by + rw [(by ring : (a ^ (-c) - b ^ (-c)) / c = (b ^ (-c) - a ^ (-c)) / (-c))] + have := integral_rpow (a := a) (b := b) (r := -c-1) (Or.inr ⟨by simp [h.1], h.2⟩) + simp only [sub_add_cancel] at this + rw [← this] + apply intervalIntegral.integral_congr + intro x hx + have : 0 ≤ x := (ZetaSum_aux1_1 apos a_lt_b hx).le + simp [div_rpow_eq_rpow_neg _ _ _ this, sub_eq_add_neg, add_comm] + +lemma ZetaSum_aux1_3 (x : ℝ) : ‖(⌊x⌋ + 1/2 - x)‖ ≤ 1/2 := + abs_le.mpr ⟨(by linarith [Int.lt_floor_add_one x]), (by linarith [Int.floor_le x])⟩ + +lemma ZetaSum_aux1_4' (x : ℝ) (hx : 0 < x) (s : ℂ) : + ‖(⌊x⌋ + 1 / 2 - (x : ℝ)) / (x : ℂ) ^ (s + 1)‖ = + ‖⌊x⌋ + 1 / 2 - x‖ / x ^ ((s + 1).re) := by + simp_rw [norm_div, Complex.norm_cpow_eq_rpow_re_of_pos hx, ← norm_real] + simp + +lemma ZetaSum_aux1_4 {a b : ℝ} (apos : 0 < a) (a_lt_b : a < b) {s : ℂ} : + ∫ (x : ℝ) in a..b, ‖(↑⌊x⌋ + (1 : ℝ) / 2 - ↑x) / (x : ℂ) ^ (s + 1)‖ = + ∫ (x : ℝ) in a..b, |⌊x⌋ + 1 / 2 - x| / x ^ (s + 1).re := by + apply intervalIntegral.integral_congr + exact fun x hx ↦ ZetaSum_aux1_4' x (ZetaSum_aux1_1 apos a_lt_b hx) s + +lemma ZetaSum_aux1_5a {a b : ℝ} (apos : 0 < a) {s : ℂ} (x : ℝ) + (h : x ∈ Icc a b) : |↑⌊x⌋ + 1 / 2 - x| / x ^ (s.re + 1) ≤ 1 / x ^ (s.re + 1) := by + apply div_le_div_of_nonneg_right _ _ + · exact le_trans (ZetaSum_aux1_3 x) (by norm_num) + · apply Real.rpow_nonneg <| le_of_lt (ZetaSum_aux1_1' apos h) + +lemma ZetaSum_aux1_5b {a b : ℝ} (apos : 0 < a) (a_lt_b : a < b) {s : ℂ} (σpos : 0 < s.re) : + IntervalIntegrable (fun u ↦ 1 / u ^ (s.re + 1)) MeasureTheory.volume a b := by + refine continuousOn_const.div ?_ ?_ |>.intervalIntegrable_of_Icc (le_of_lt a_lt_b) + · exact continuousOn_id.rpow_const fun x hx ↦ Or.inl (ne_of_gt <| ZetaSum_aux1_1' apos hx) + · exact fun x hx h ↦ by rw [Real.rpow_eq_zero] at h <;> linarith [ZetaSum_aux1_1' apos hx] + +open MeasureTheory in +lemma measurable_floor_add_half_sub : Measurable fun (u : ℝ) ↦ ↑⌊u⌋ + 1 / 2 - u := by + refine Measurable.add ?_ measurable_const |>.sub measurable_id + exact Measurable.comp (by exact fun _ _ ↦ trivial) Int.measurable_floor + +open MeasureTheory in +lemma ZetaSum_aux1_5c {a b : ℝ} {s : ℂ} : + let g : ℝ → ℝ := fun u ↦ |↑⌊u⌋ + 1 / 2 - u| / u ^ (s.re + 1); + AEStronglyMeasurable g + (Measure.restrict volume (Ι a b)) := by + intro + refine (Measurable.div ?_ <| measurable_id.pow_const _).aestronglyMeasurable + exact continuous_abs.measurable.comp measurable_floor_add_half_sub + +lemma ZetaSum_aux1_5d {a b : ℝ} (apos : 0 < a) (a_lt_b : a < b) {s : ℂ} (σpos : 0 < s.re) : + IntervalIntegrable (fun u ↦ |↑⌊u⌋ + 1 / 2 - u| / u ^ (s.re + 1)) MeasureTheory.volume a b := by + set g : ℝ → ℝ := (fun u ↦ |↑⌊u⌋ + 1 / 2 - u| / u ^ (s.re + 1)) + apply ZetaSum_aux1_5b apos a_lt_b σpos |>.mono_fun ZetaSum_aux1_5c ?_ + filter_upwards with x + simp only [Real.norm_eq_abs, one_div, norm_inv, abs_div, _root_.abs_abs] + conv => rw [div_eq_mul_inv, ← one_div]; rhs; rw [← one_mul |x ^ (s.re + 1)|⁻¹] + refine mul_le_mul ?_ (le_refl _) (by simp) <| by norm_num + exact le_trans (ZetaSum_aux1_3 x) <| by norm_num + +lemma ZetaSum_aux1_5 {a b : ℝ} (apos : 0 < a) (a_lt_b : a < b) {s : ℂ} (σpos : 0 < s.re) : + ∫ (x : ℝ) in a..b, |⌊x⌋ + 1 / 2 - x| / x ^ (s.re + 1) ≤ + ∫ (x : ℝ) in a..b, 1 / x ^ (s.re + 1) := by + apply intervalIntegral.integral_mono_on (le_of_lt a_lt_b) ?_ ?_ + · exact ZetaSum_aux1_5a apos + · exact ZetaSum_aux1_5d apos a_lt_b σpos + · exact ZetaSum_aux1_5b apos a_lt_b σpos + +/- +For any $0 < a < b$ and $s \in \C$ with $\sigma=\Re(s)>0$, + $$ + \int_a^b \left|\frac{\lfloor x\rfloor + 1/2 - x}{x^{s+1}} \, dx\right| + \le \frac{a^{-\sigma}-b^{-\sigma}}{\sigma}. + $$ +Apply the triangle inequality + $$ + \left|\int_a^b \frac{\lfloor x\rfloor + 1/2 - x}{x^{s+1}} \, dx\right| + \le \int_a^b \frac{1}{x^{\sigma+1}} \, dx, + $$ + and evaluate the integral. +-/ +lemma ZetaBnd_aux1a {a b : ℝ} (apos : 0 < a) (a_lt_b : a < b) {s : ℂ} (σpos : 0 < s.re) : + ∫ x in a..b, ‖(⌊x⌋ + 1 / 2 - x) / (x : ℂ) ^ (s + 1)‖ ≤ + (a ^ (-s.re) - b ^ (-s.re)) / s.re := by + calc + _ = ∫ x in a..b, |(⌊x⌋ + 1 / 2 - x)| / x ^ (s+1).re := ZetaSum_aux1_4 apos a_lt_b + _ ≤ ∫ x in a..b, 1 / x ^ (s.re + 1) := ZetaSum_aux1_5 apos a_lt_b σpos + _ = (a ^ (-s.re) - b ^ (-s.re)) / s.re := ?_ + refine ZetaSum_aux1_2 (c := s.re) apos a_lt_b ⟨ne_of_gt σpos, ?_⟩ + exact fun h ↦ (lt_self_iff_false 0).mp <| ZetaSum_aux1_1 apos a_lt_b h + +lemma _root_.Finset.Ioc_eq_Ico (M N : ℕ) : Finset.Ioc N M = Finset.Ico (N + 1) (M + 1) := by + ext a; simp only [Finset.mem_Ioc, Finset.mem_Ico]; constructor <;> intro ⟨h₁, h₂⟩ <;> omega + +lemma _root_.Finset.Ioc_eq_Icc (M N : ℕ) : Finset.Ioc N M = Finset.Icc (N + 1) M := by + ext a; simp only [Finset.mem_Ioc, Finset.mem_Icc]; constructor <;> intro ⟨h₁, h₂⟩ <;> omega + +lemma _root_.Finset.Icc_eq_Ico (M N : ℕ) : Finset.Icc N M = Finset.Ico N (M + 1) := by + ext a; simp only [Finset.mem_Icc, Finset.mem_Ico]; constructor <;> intro ⟨h₁, h₂⟩ <;> omega + +lemma finsetSum_tendsto_tsum {N : ℕ} {f : ℕ → ℂ} (hf : Summable f) : + Tendsto (fun (k : ℕ) ↦ ∑ n ∈ Finset.Ico N k, f n) atTop (𝓝 (∑' (n : ℕ), f (n + N))) := by + have := Summable.hasSum_iff_tendsto_nat hf (m := ∑' (n : ℕ), f n) |>.mp hf.hasSum + have const := tendsto_const_nhds (α := ℕ) (x := ∑ i ∈ Finset.range N, f i) (f := atTop) + have := Filter.Tendsto.sub this const + rw [← hf.sum_add_tsum_nat_add N, add_comm, add_sub_cancel_right] at this + apply this.congr' + filter_upwards [Filter.mem_atTop (N + 1)] + intro M hM + rw [Finset.sum_Ico_eq_sub] + linarith + +lemma _root_.Complex.cpow_tendsto {s : ℂ} (s_re_gt : 1 < s.re) : + Tendsto (fun (x : ℕ) ↦ (x : ℂ) ^ (1 - s)) atTop (𝓝 0) := by + have one_sub_s_re_ne : (1 - s).re ≠ 0 := by simp only [sub_re, one_re]; linarith + rw [tendsto_zero_iff_norm_tendsto_zero] + simp_rw [Complex.norm_natCast_cpow_of_re_ne_zero _ (one_sub_s_re_ne)] + rw [(by simp only [sub_re, one_re, neg_sub] : (1 - s).re = - (s - 1).re)] + apply (tendsto_rpow_neg_atTop _).comp tendsto_natCast_atTop_atTop; simp [s_re_gt] + +lemma _root_.Complex.cpow_inv_tendsto {s : ℂ} (hs : 0 < s.re) : + Tendsto (fun (x : ℕ) ↦ ((x : ℂ) ^ s)⁻¹) atTop (𝓝 0) := by + rw [tendsto_zero_iff_norm_tendsto_zero] + simp_rw [norm_inv, Complex.norm_natCast_cpow_of_re_ne_zero _ <| ne_of_gt hs] + apply Filter.Tendsto.inv_tendsto_atTop + exact (tendsto_rpow_atTop hs).comp tendsto_natCast_atTop_atTop + +lemma ZetaSum_aux2a : ∃ C, ∀ (x : ℝ), ‖⌊x⌋ + 1 / 2 - x‖ ≤ C := by + use 1 / 2; exact ZetaSum_aux1_3 + +lemma ZetaSum_aux3 {N : ℕ} {s : ℂ} (s_re_gt : 1 < s.re) : + Tendsto (fun k ↦ ∑ n ∈ Finset.Ioc N k, 1 / (n : ℂ) ^ s) atTop + (𝓝 (∑' (n : ℕ), 1 / (n + N + 1 : ℂ) ^ s)) := by + let f := fun (n : ℕ) ↦ 1 / (n : ℂ) ^ s + have hf := summable_one_div_nat_cpow.mpr s_re_gt + simp_rw [Finset.Ioc_eq_Ico] + convert finsetSum_tendsto_tsum (f := fun n ↦ f (n + 1)) (N := N) ?_ using 1 + · ext k + rw [Finset.sum_Ico_add'] + · congr; ext n; simp only [one_div, Nat.cast_add, Nat.cast_one, f] + · rwa [summable_nat_add_iff (k := 1)] + +lemma integrableOn_of_Zeta0_fun {N : ℕ} (N_pos : 0 < N) {s : ℂ} (s_re_gt : 0 < s.re) : + MeasureTheory.IntegrableOn (fun (x : ℝ) ↦ (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-(s + 1))) (Ioi N) + MeasureTheory.volume := by + obtain ⟨c, hc⟩ := ZetaSum_aux2a + apply MeasureTheory.Integrable.bdd_mul (c := c) ?_ ?_ + · apply MeasureTheory.ae_of_all + convert hc; simp only [← Complex.norm_real]; simp + · apply integrableOn_Ioi_cpow_iff (by positivity) |>.mpr (by simp [s_re_gt]) + · refine Measurable.add ?_ measurable_const |>.sub (by fun_prop) |>.aestronglyMeasurable + exact Measurable.comp (by exact fun _ _ ↦ trivial) Int.measurable_floor + +/- +Let $N$ be a natural number and $s\in \C$, $\Re(s)>1$. + Then + \[ + \sum_{N < n} \frac{1}{n^s} = \frac{- N^{1-s}}{1-s} + \frac{-N^{-s}}{2} + + s \int_N^\infty \frac{\lfloor x\rfloor + 1/2 - x}{x^{s+1}} \, dx. + \] +Apply Lemma \ref{ZetaSum_aux1} with $a=N$ and $b\to \infty$. +-/ +lemma ZetaSum_aux2 {N : ℕ} (N_pos : 0 < N) {s : ℂ} (s_re_gt : 1 < s.re) : + ∑' (n : ℕ), 1 / (n + N + 1 : ℂ) ^ s = + (- N ^ (1 - s)) / (1 - s) - N ^ (-s) / 2 + + s * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-(s + 1)) := by + have s_ne_zero : s ≠ 0 := fun hs ↦ by linarith [zero_re ▸ hs ▸ s_re_gt] + have s_ne_one : s ≠ 1 := fun hs ↦ (lt_self_iff_false _).mp <| one_re ▸ hs ▸ s_re_gt + apply tendsto_nhds_unique (X := ℂ) (Y := ℕ) (l := atTop) + (f := fun k ↦ ((k : ℂ) ^ (1 - s) - (N : ℂ) ^ (1 - s)) / (1 - s) + + 1 / 2 * (1 / ↑k ^ s) - 1 / 2 * (1 / ↑N ^ s) + + s * ∫ (x : ℝ) in (N : ℝ)..k, (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-(s + 1))) + (b := (- N ^ (1 - s)) / (1 - s) - N ^ (-s) / 2 + + s * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-(s + 1))) + · apply Filter.Tendsto.congr' + (f₁ := fun (k : ℕ) ↦ ∑ n ∈ Finset.Ioc N k, 1 / (n : ℂ) ^ s) (l₁ := atTop) + · apply Filter.eventually_atTop.mpr + use N + 1 + intro k hk + exact ZetaSum_aux1 (a := N) (b := k) s_ne_one s_ne_zero ⟨N_pos, hk⟩ + · exact ZetaSum_aux3 s_re_gt + · apply (Tendsto.sub ?_ ?_).add (Tendsto.const_mul _ ?_) + · rw [(by ring : -↑N ^ (1 - s) / (1 - s) = (0 - ↑N ^ (1 - s)) / (1 - s) + 0)] + apply cpow_tendsto s_re_gt |>.sub_const _ |>.div_const _ |>.add + simp_rw [mul_comm_div, one_mul, one_div, (by congr; ring : 𝓝 (0 : ℂ) = 𝓝 ((0 : ℂ) / 2))] + apply Tendsto.div_const <| cpow_inv_tendsto (by positivity) + · simp_rw [mul_comm_div, one_mul, one_div, cpow_neg]; exact tendsto_const_nhds + · exact MeasureTheory.intervalIntegral_tendsto_integral_Ioi (a := N) + (b := (fun (n : ℕ) ↦ (n : ℝ))) + (integrableOn_of_Zeta0_fun N_pos <| by positivity) tendsto_natCast_atTop_atTop + +open MeasureTheory in +/- +For any $N\ge1$ and $s = \sigma + tI \in \C$, $\sigma > 0$, + $$ + \left| \int_N^\infty \frac{\lfloor x\rfloor + 1/2 - x}{x^{s+1}} \, dx \right| + \le \frac{N^{-\sigma}}{\sigma}. + $$ +Apply Lemma \ref{ZetaBnd_aux1a} with $a=N$ and $b\to \infty$. +-/ +lemma ZetaBnd_aux1b (N : ℕ) (Npos : 1 ≤ N) {σ t : ℝ} (σpos : 0 < σ) : + ‖∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) / (x : ℂ) ^ ((σ + t * I) + 1)‖ + ≤ N ^ (-σ) / σ := by + apply le_trans (by apply norm_integral_le_integral_norm) + apply le_of_tendsto (x := atTop (α := ℝ)) (f := fun (t : ℝ) ↦ ∫ (x : ℝ) in N..t, + ‖(⌊x⌋ + 1 / 2 - x) / (x : ℂ) ^ (σ + t * I + 1)‖) ?_ ?_ + · apply intervalIntegral_tendsto_integral_Ioi (μ := volume) (l := atTop) (b := id) + (f := fun (x : ℝ) ↦ ‖(⌊x⌋ + 1 / 2 - x) / (x : ℂ) ^ (σ + t * I + 1)‖) N ?_ ?_ |>.congr' ?_ + · filter_upwards [Filter.mem_atTop ((N : ℝ))] + intro u hu + simp only [id_eq, intervalIntegral.integral_of_le hu, norm_div] + apply setIntegral_congr_fun (by simp) + intro x hx; beta_reduce + iterate 2 (rw [norm_cpow_eq_rpow_re_of_pos (by linarith [hx.1])]) + simp + · apply IntegrableOn.integrable ?_ |>.norm + convert! integrableOn_of_Zeta0_fun (s := σ + t * I) Npos (by simp [σpos]) using 1 + simp_rw [div_eq_mul_inv, cpow_neg] + · exact fun ⦃_⦄ a ↦ a + · filter_upwards [mem_atTop (N + 1 : ℝ)] with t ht + have : (N ^ (-σ) - t ^ (-σ)) / σ ≤ N ^ (-σ) / σ := + div_le_div_iff_of_pos_right σpos |>.mpr (by simp [Real.rpow_nonneg (by linarith)]) + apply le_trans ?_ this + convert! ZetaBnd_aux1a (a := N) (b := t) (by positivity) (by linarith) ?_ <;> simp [σpos] + +/- +For any $N\ge1$ and $s = \sigma + tI \in \C$, $\sigma=\in(0,2], 2 < |t|$, + $$ + \left| s\int_N^\infty \frac{\lfloor x\rfloor + 1/2 - x}{x^{s+1}} \, dx \right| + \le 2 |t| \frac{N^{-\sigma}}{\sigma}. + $$ +Apply Lemma \ref{ZetaBnd_aux1b} and estimate $|s|\ll |t|$. +-/ +lemma ZetaBnd_aux1 (N : ℕ) (Npos : 1 ≤ N) {σ t : ℝ} (hσ : σ ∈ Ioc 0 2) (ht : 2 ≤ |t|) : + ‖(σ + t * I) * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) / (x : ℂ) ^ ((σ + t * I) + 1)‖ + ≤ 2 * |t| * N ^ (-σ) / σ := by + rw [norm_mul, mul_div_assoc] + rw [Set.mem_Ioc] at hσ + apply mul_le_mul ?_ (ZetaBnd_aux1b N Npos hσ.1) (norm_nonneg _) (by positivity) + refine le_trans (by apply norm_add_le) ?_ + simp only [Complex.norm_of_nonneg hσ.1.le, Complex.norm_mul, norm_real, Real.norm_eq_abs, norm_I, + mul_one] + linarith [hσ.2] + +/- +Big-Oh version of Lemma \ref{ZetaBnd_aux1}. +-/ +/- +For any $N\ge1$ and $s = \sigma + tI \in \C$, $\sigma=\in(0,2], 2 < |t|$, + $$ + \left| s\int_N^\infty \frac{\lfloor x\rfloor + 1/2 - x}{x^{s+1}} \, dx \right| + \ll |t| \frac{N^{-\sigma}}{\sigma}. + $$ +Apply Lemma \ref{ZetaBnd_aux1b} and estimate $|s|\ll |t|$. +-/ +lemma ZetaBnd_aux1p (N : ℕ) (Npos : 1 ≤ N) {σ : ℝ} (hσ : σ ∈ Ioc 0 2) : + (fun (t : ℝ) ↦ + ‖(σ + t * I) * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) / (x : ℂ) ^ ((σ + t * I) + 1)‖) + =O[Filter.principal {t | 2 ≤ |t|}] fun t ↦ |t| * N ^ (-σ) / σ := by + rw [Asymptotics.IsBigO_def] + use 2 + rw [Asymptotics.isBigOWith_principal] + intro t ht + simp only [mem_ofPred_eq] at ht + rw [norm_norm, norm_mul, mul_div_assoc, norm_mul] + have : 2 * (‖|t|‖ * ‖↑N ^ (-σ) / σ‖) = (2 * |t|) * ((N : ℝ) ^ (-σ) / σ) := by + simp only [Real.norm_eq_abs, _root_.abs_abs, norm_div] + have : σ ≠ 0 := by linarith [hσ.1] + field_simp + rw [abs_of_pos hσ.1] + have : 0 < (N : ℝ) ^ (-σ) := by + refine Real.rpow_pos_of_pos ?_ _ + positivity + rw [abs_of_pos this] + ring + rw [this] + apply mul_le_mul ?_ (ZetaBnd_aux1b N Npos hσ.1) (norm_nonneg _) (by positivity) + refine le_trans (by apply norm_add_le) ?_ + simp only [norm_real, norm_mul, norm_I, mul_one, Complex.norm_of_nonneg hσ.1.le, Real.norm_eq_abs] + linarith [hσ.2] + +lemma isOpen_aux : IsOpen {z : ℂ | z ≠ 1 ∧ 0 < z.re} := by + refine IsOpen.inter isOpen_ne ?_ + exact isOpen_lt (g := fun (z : ℂ) ↦ z.re) (by continuity) (by continuity) + +open MeasureTheory in +lemma integrable_log_over_pow {r : ℝ} (rneg : r < 0) {N : ℕ} (Npos : 0 < N) : + IntegrableOn (fun (x : ℝ) ↦ ‖x ^ (r - 1)‖ * ‖Real.log x‖) <| Ioi N := by + apply IntegrableOn.mono_set (hst := Set.Ioi_subset_Ici <| le_refl (N : ℝ)) + apply LocallyIntegrableOn.integrableOn_of_isBigO_atTop (g := fun x ↦ x ^ (r / 2 - 1)) + · apply ContinuousOn.abs ?_ |>.mul ?_ |>.locallyIntegrableOn (by simp) + · apply ContinuousOn.rpow (by fun_prop) (by fun_prop) + intro x hx; left; contrapose! Npos with h; exact_mod_cast h ▸ mem_Ici.mp hx + · apply continuous_id.continuousOn.log ?_ |>.abs + intro x hx; simp only [id_eq]; contrapose! Npos with h; exact_mod_cast h ▸ mem_Ici.mp hx + · have := isLittleO_log_rpow_atTop (r := -r / 2) (by linarith) |>.isBigO + rw [Asymptotics.isBigO_iff_eventually, Filter.eventually_atTop] at this + obtain ⟨C, hC⟩ := this + have hh := hC C (by simp) + rw [Asymptotics.isBigO_atTop_iff_eventually_exists] + have := Filter.eventually_atTop.mp hh + obtain ⟨x₀, hx₀ ⟩ := this + filter_upwards [hh, Filter.mem_atTop x₀, Filter.mem_atTop 1] + intro x hx x_gt x_pos + use C + intro y hy + simp only [norm_mul, Real.norm_eq_abs, _root_.abs_abs] + simp only [Real.norm_eq_abs] at hx + have y_pos : 0 < y := by linarith + have : y ^ (r / 2 - 1) = y ^ (r - 1) * y ^ (-r / 2) := by + rw [← Real.rpow_add y_pos]; ring_nf + rw [this, abs_mul] + have y_gt : y ≥ x₀ := by linarith + have := hx₀ y y_gt + simp only [Real.norm_eq_abs] at this + rw [← mul_assoc, mul_comm C, mul_assoc] + exact mul_le_mul_of_nonneg_left (hbc := this) (a := |y ^ (r - 1)|) (ha := by simp) + · have := integrableOn_Ioi_rpow_iff (s := r / 2 - 1) (t := N) (by simp [Npos]) |>.mpr + (by linarith [rneg]) + exact integrableOn_Ioi_iff_integrableAtFilter_atTop_nhdsWithin.mp this |>.1 + +open MeasureTheory in +lemma integrableOn_of_Zeta0_fun_log {N : ℕ} (Npos : 0 < N) {s : ℂ} (s_re_gt : 0 < s.re) : + IntegrableOn (fun (x : ℝ) ↦ (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-(s + 1)) * (-Real.log x)) (Ioi N) + volume := by + simp_rw [mul_assoc] + obtain ⟨c, hc⟩ := ZetaSum_aux2a + apply Integrable.bdd_mul (c := c) ?_ ?_ ?_ + · simp only [neg_add_rev, mul_neg, add_comm, ← sub_eq_add_neg] + apply integrable_norm_iff ?_ |>.mp ?_ |>.neg + · apply ContinuousOn.mul ?_ ?_ |>.aestronglyMeasurable (by simp) + · intro x hx + apply ContinuousWithinAt.cpow ?_ continuous_const.continuousWithinAt ?_ + · exact RCLike.continuous_ofReal.continuousWithinAt + · simp only [ofReal_mem_slitPlane]; linarith [mem_Ioi.mp hx] + · apply RCLike.continuous_ofReal.continuousOn.comp ?_ (mapsTo_image _ _) + refine continuous_id.continuousOn.log ?_ + intro x hx; simp only [id_eq]; linarith [mem_Ioi.mp hx] + · simp only [norm_mul, norm_real] + have := integrable_log_over_pow (r := -s.re) (by linarith) Npos + apply IntegrableOn.congr_fun this ?_ (by simp) + intro x hx + simp only [mul_eq_mul_right_iff, norm_eq_zero, Real.log_eq_zero] + left + have xpos : 0 < x := by linarith [mem_Ioi.mp hx] + simp [norm_cpow_eq_rpow_re_of_pos xpos, Real.abs_rpow_of_nonneg xpos.le, + abs_eq_self.mpr xpos.le] + · apply Measurable.add ?_ measurable_const |>.sub (by fun_prop) |>.aestronglyMeasurable + exact Measurable.comp (fun _ _ ↦ trivial) Int.measurable_floor + · apply MeasureTheory.ae_of_all + convert hc with _ x; simp only [← Complex.norm_real]; simp + +open MeasureTheory in +lemma hasDerivAt_Zeta0Integral {N : ℕ} (Npos : 0 < N) {s : ℂ} (hs : s ∈ {s | 0 < s.re}) : + HasDerivAt (fun z ↦ ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-z - 1)) + (∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (- s - 1) * (- Real.log x)) s := by + simp only [mem_ofPred_eq] at hs + set f : ℝ → ℂ := fun x ↦ (⌊x⌋ : ℂ) + 1 / 2 - x + set F : ℂ → ℝ → ℂ := fun s x ↦ (x : ℂ) ^ (- s - 1) * f x + set F' : ℂ → ℝ → ℂ := fun s x ↦ (x : ℂ) ^ (- s - 1) * (- Real.log x) * f x + set ε := s.re / 2 + have ε_pos : 0 < ε := by aesop + set bound : ℝ → ℝ := fun x ↦ |x ^ (- s.re / 2 - 1)| * |Real.log x| + let μ : Measure ℝ := volume.restrict (Ioi (N : ℝ)) + have hF_meas : ∀ᶠ (z : ℂ) in 𝓝 s, AEStronglyMeasurable (F z) μ := by + have : {z : ℂ | 0 < z.re} ∈ 𝓝 s := by + rw [mem_nhds_iff] + refine ⟨{z | 0 < z.re}, fun ⦃a⦄ a ↦ a, isOpen_lt continuous_const Complex.continuous_re, hs⟩ + filter_upwards [this] with z hz + convert! integrableOn_of_Zeta0_fun Npos hz |>.aestronglyMeasurable using 1 + simp only [F, f]; ext x; ring_nf + have hF_int : Integrable (F s) μ := by + convert! integrableOn_of_Zeta0_fun Npos hs |>.integrable using 1 + simp only [F, f]; ext x; ring_nf + have hF'_meas : AEStronglyMeasurable (F' s) μ := by + convert! integrableOn_of_Zeta0_fun_log Npos hs |>.aestronglyMeasurable using 1 + simp only [F', f]; ext x; ring_nf + have IoiSubIoi1 : (Ioi (N : ℝ)) ⊆ {x | 1 < x} := + fun x hx ↦ lt_of_le_of_lt (by simp only [Nat.one_le_cast]; omega) <| mem_Ioi.mp hx + have measSetIoi1 : MeasurableSet {x : ℝ | 1 < x} := (isOpen_lt' 1).measurableSet + have h_bound1 : + ∀ᵐ (x : ℝ) ∂volume.restrict {x | 1 < x}, ∀ z ∈ Metric.ball s ε, ‖F' z x‖ ≤ bound x := by + filter_upwards [self_mem_ae_restrict measSetIoi1] with x hx + intro z hz + simp only [F', f, bound] + calc _ = ‖(x : ℂ) ^ (-z - 1)‖ * ‖-(Real.log x)‖ * ‖(⌊x⌋ + 1 / 2 - x)‖ := by + simp only [mul_neg, one_div, neg_mul, norm_neg, norm_mul, norm_real, Real.norm_eq_abs, + ← (by simp : (((⌊x⌋ + 2⁻¹ - x) : ℝ) : ℂ) = (⌊x⌋ : ℂ) + 2⁻¹ - ↑x), + Complex.norm_real] + _ = ‖x ^ (-z.re - 1)‖ * ‖-(Real.log x)‖ * ‖(⌊x⌋ + 1 / 2 - x)‖ := ?_ + _ = |x ^ (-z.re - 1)| * |(Real.log x)| * |(⌊x⌋ + 1 / 2 - x)| := by simp + _ ≤ _ := ?_ + · congr! 2 + simp only [Real.norm_eq_abs, norm_cpow_eq_rpow_re_of_pos (by linarith), + sub_re, neg_re, one_re] + apply abs_eq_self.mpr ?_ |>.symm + positivity + · rw [mul_comm, ← mul_assoc] + apply mul_le_mul_of_nonneg_right ?_ <| abs_nonneg _ + simp only [Metric.mem_ball, ε, Complex.dist_eq] at hz + apply le_trans (b := 1 * |x ^ (-z.re - 1)|) + · apply mul_le_mul_of_nonneg_right (le_trans (ZetaSum_aux1_3 _) (by norm_num)) <| abs_nonneg _ + · simp_rw [one_mul, Real.abs_rpow_of_nonneg (by linarith : 0 ≤ x)] + apply Real.rpow_le_rpow_of_exponent_le <| le_abs.mpr (by left; exact hx.le) + have := abs_le.mp <| le_trans (abs_re_le_norm (z-s)) hz.le + simp only [sub_re, neg_le_sub_iff_le_add, tsub_le_iff_right] at this + linarith [this.1] + have h_bound : ∀ᵐ x ∂μ, ∀ z ∈ Metric.ball s ε, ‖F' z x‖ ≤ bound x := by + apply ae_restrict_of_ae_restrict_of_subset IoiSubIoi1 + exact h_bound1 + have bound_integrable : Integrable bound μ := by + simp only [bound] + convert! integrable_log_over_pow (r := -s.re / 2) (by linarith) Npos using 0 + have h_diff : ∀ᵐ x ∂μ, ∀ z ∈ Metric.ball s ε, HasDerivAt (fun w ↦ F w x) (F' z x) z := by + simp only [F, F', f] + apply ae_restrict_of_ae_restrict_of_subset IoiSubIoi1 + filter_upwards [h_bound1, self_mem_ae_restrict measSetIoi1] with x _ one_lt_x + intro z hz + convert! HasDerivAt.mul_const (c := fun (w : ℂ) ↦ (x : ℂ) ^ (-w-1)) + (c' := (x : ℂ) ^ (-z-1) * -Real.log x) (d := (⌊x⌋ : ℝ) + 1 / 2 - x) ?_ using 1 + convert! HasDerivAt.comp (h := fun w ↦ -w-1) (h' := -1) (h₂ := fun w ↦ x ^ w) + (h₂' := x ^ (-z-1) * Real.log x) (x := z) ?_ ?_ using 0 + · simp only [mul_neg, mul_one]; congr! 2 + · convert! HasDerivAt.const_cpow (c := (x : ℂ)) (f := fun w ↦ w) (f' := 1) (x := -z-1) + (hasDerivAt_id _) ?_ using 1 + · simp only [mul_one, mul_eq_mul_left_iff, cpow_eq_zero_iff, ofReal_eq_zero, ne_eq] + left + rw [Complex.ofReal_log] + linarith + · right + intro h + simp only [Metric.mem_ball, ε, Complex.dist_eq, + neg_eq_iff_eq_neg.mp <| sub_eq_zero.mp h] at hz + have := (abs_le.mp <| le_trans (abs_re_le_norm (-1-s)) hz.le).1 + simp only [sub_re, neg_re, one_re, neg_le_sub_iff_le_add, le_neg_add_iff_add_le] at this + linarith + · apply hasDerivAt_id _ |>.neg |>.sub_const + convert! (hasDerivAt_integral_of_dominated_loc_of_deriv_le (F := F) (F' := F') (x₀ := s) + (s := Metric.ball s ε) (bound := bound) (μ := μ) (Metric.ball_mem_nhds s ε_pos) + hF_meas hF_int hF'_meas h_bound bound_integrable h_diff).2 using 3 + · ext a; simp only [one_div, F, f]; ring_nf + · simp only [one_div, mul_neg, neg_mul, neg_inj, F', f]; ring_nf + +/-- The differentiated Euler-Maclaurin expression for `riemannZeta0`. -/ +noncomputable def ζ₀' (N : ℕ) (s : ℂ) : ℂ := + ∑ n ∈ Finset.range (N + 1), -1 / (n : ℂ) ^ s * Real.log n + + (-N ^ (1 - s) / (1 - s) ^ 2 + Real.log N * N ^ (1 - s) / (1 - s)) + + Real.log N * N ^ (-s) / 2 + + (1 * (∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (- s - 1)) + + s * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (- s - 1) * (- Real.log x)) + +lemma HasDerivAt_neg_cpow_over2 {N : ℕ} (Npos : 0 < N) (s : ℂ) : + HasDerivAt (fun x : ℂ ↦ -(N : ℂ) ^ (-x) / 2) (-((- Real.log N) * (N : ℂ) ^ (-s)) / 2) s := by + convert! hasDerivAt_neg' s |>.const_cpow (c := N) (by aesop) |>.neg |>.div_const _ using 1 + simp [mul_comm] + +lemma HasDerivAt_cpow_over_var (N : ℕ) {z : ℂ} (z_ne_zero : z ≠ 0) : + HasDerivAt (fun z ↦ -(N : ℂ) ^ z / z) + (((N : ℂ) ^ z / z ^ 2) - (Real.log N * N ^ z / z)) z := by + simp_rw [div_eq_mul_inv] + convert! HasDerivAt.mul (c := fun z ↦ - (N : ℂ) ^ z) (d := fun z ↦ z⁻¹) + (c' := - (N : ℂ) ^ z * Real.log N) + (d' := - (z ^ 2)⁻¹) ?_ ?_ using 1 + · simp only [natCast_log, neg_mul, mul_neg, neg_neg] + ring_nf + · simp only [natCast_log, neg_mul] + apply HasDerivAt.neg + convert! HasDerivAt.const_cpow (c := (N : ℂ)) (f := id) (f' := 1) (x := z) (hasDerivAt_id z) + (by simp [z_ne_zero]) using 1 + simp only [id_eq, mul_one] + · exact hasDerivAt_inv z_ne_zero + +lemma HasDerivAtZeta0 {N : ℕ} (Npos : 0 < N) {s : ℂ} (reS_pos : 0 < s.re) (s_ne_one : s ≠ 1) : + HasDerivAt (ζ₀ N) (ζ₀' N s) s := by + unfold riemannZeta0 ζ₀' + apply HasDerivAt.fun_sum ?_ |>.add ?_ |>.add ?_ |>.add ?_ + · intro n _ + convert! hasDerivAt_neg' s |>.const_cpow (c := n) (by aesop) using 1 + all_goals (ring_nf; simp [cpow_neg]) + · convert! HasDerivAt.comp (h₂ := fun z ↦ -(N : ℂ) ^ z / z) (h := fun z ↦ 1 - z) (h' := -1) + (h₂' := ((N : ℂ) ^ (1 - s) / (1 - s) ^ 2 - Real.log (N : ℝ) * (N : ℂ) ^ (1 - s) / (1 - s))) + (x := s) ?_ ?_ using 1 + · ring_nf + · exact HasDerivAt_cpow_over_var N (by rw [sub_ne_zero]; exact s_ne_one.symm) + · convert! hasDerivAt_const s _ |>.sub (hasDerivAt_id _) using 1; simp + · convert! HasDerivAt_neg_cpow_over2 Npos s using 1; simp only [natCast_log, neg_mul, neg_neg] + · simp_rw [div_cpow_eq_cpow_neg, neg_add, ← sub_eq_add_neg] + convert! hasDerivAt_id s |>.mul <| hasDerivAt_Zeta0Integral Npos reS_pos using 1 + +/- +For any $N\ge1$, the function $\zeta_0(N,s)$ is holomorphic on $\{s\in \C\mid \Re(s)>0 ∧ s \ne 1\}$. +The function $\zeta_0(N,s)$ is a finite sum of entire functions, plus an integral + that's absolutely convergent on $\{s\in \C\mid \Re(s)>0 ∧ s \ne 1\}$ by Lemma \ref{ZetaBnd_aux1b}. +-/ +lemma HolomorphicOn_riemannZeta0 {N : ℕ} (N_pos : 0 < N) : + HolomorphicOn (ζ₀ N) {s : ℂ | s ≠ 1 ∧ 0 < s.re} := + fun _ ⟨hs₁, hs₂⟩ ↦ (HasDerivAtZeta0 N_pos hs₂ hs₁).differentiableAt.differentiableWithinAt + +-- MOVE TO MATHLIB near `differentiableAt_riemannZeta` +lemma HolomorphicOn_riemannZeta : + HolomorphicOn ζ {s : ℂ | s ≠ 1} := by + intro z hz + simp only [mem_ofPred_eq] at hz + exact (differentiableAt_riemannZeta hz).differentiableWithinAt + +/- +The set $\{s\in \C\mid \Re(s)>0 ∧ s \ne 1\}$ is path-connected. +Construct explicit paths from $2$ to any point, either a line segment or two joined ones. +-/ +lemma isPathConnected_aux : IsPathConnected {z : ℂ | z ≠ 1 ∧ 0 < z.re} := by + use (2 : ℂ) + constructor + · simp + intro w hw; simp only [ne_eq, mem_ofPred_eq] at hw + by_cases w_im : w.im = 0 + · apply JoinedIn.trans (y := 1 + I) + · let f : ℝ → ℂ := fun t ↦ (1 + I) * t + 2 * (1 - t) + have cont : Continuous f := by continuity + apply JoinedIn.ofLine cont.continuousOn (by simp [f]) (by simp [f]) + simp only [unitInterval, ne_eq, image_subset_iff, preimage_ofPred_eq, add_re, mul_re, one_re, + I_re, add_zero, ofReal_re, one_mul, add_im, one_im, I_im, zero_add, ofReal_im, mul_zero, + sub_zero, re_ofNat, sub_re, im_ofNat, sub_im, sub_self, f] + intro x hx; simp only [mem_Icc] at hx + refine ⟨?_, by linarith⟩ + intro h + rw [Complex.ext_iff] at h; simp [(by apply And.right; simpa [w_im] using h : x = 0)] at h + · let f : ℝ → ℂ := fun t ↦ w * t + (1 + I) * (1 - t) + have cont : Continuous f := by continuity + apply JoinedIn.ofLine cont.continuousOn (by simp [f]) (by simp [f]) + simp only [unitInterval, ne_eq, image_subset_iff, preimage_ofPred_eq, add_re, mul_re, + ofReal_re, ofReal_im, mul_zero, sub_zero, one_re, I_re, add_zero, sub_re, one_mul, add_im, + one_im, I_im, zero_add, sub_im, sub_self, f] + intro x hx; simp only [mem_Icc] at hx + simp only [mem_ofPred_eq] + constructor + · intro h + refine hw.1 ?_ + rw [Complex.ext_iff] at h + have : x = 1 := by linarith [(by apply And.right; simpa [w_im] using h : 1 - x = 0)] + rw [Complex.ext_iff, one_re, one_im]; exact ⟨by simpa [this, w_im] using h, w_im⟩ + · by_cases hxx : x = 0 + · simp only [hxx]; linarith + · have : 0 < x := lt_of_le_of_ne hx.1 (Ne.symm hxx) + have : 0 ≤ 1 - x := by linarith + have := hw.2 + positivity + · let f : ℝ → ℂ := fun t ↦ w * t + 2 * (1 - t) + have cont : Continuous f := by continuity + apply JoinedIn.ofLine cont.continuousOn (by simp [f]) (by simp [f]) + simp only [unitInterval, ne_eq, image_subset_iff, preimage_ofPred_eq, add_re, mul_re, ofReal_re, + ofReal_im, mul_zero, sub_zero, re_ofNat, sub_re, one_re, im_ofNat, sub_im, one_im, sub_self, + f] + intro x hx; simp only [mem_Icc] at hx + constructor + · intro h + rw [Complex.ext_iff] at h; + simp [(by apply And.right; simpa [w_im] using h : x = 0)] at h + · by_cases hxx : x = 0 + · simp only [hxx]; linarith + · have : 0 < x := lt_of_le_of_ne hx.1 (Ne.symm hxx) + have : 0 ≤ 1 - x := by linarith + have := hw.2 + positivity + +/- +For $\Re(s)>0$, $s\ne1$, and for any $N$, + $$ + \zeta_0(N,s) = \zeta(s). + $$ +Use Lemma \ref{ZetaSum_aux2} and the Definition \ref{riemannZeta0}. +-/ +lemma Zeta0EqZeta {N : ℕ} (N_pos : 0 < N) {s : ℂ} (reS_pos : 0 < s.re) (s_ne_one : s ≠ 1) : + ζ₀ N s = riemannZeta s := by + let f := riemannZeta + let g := ζ₀ N + let U := {z : ℂ | z ≠ 1 ∧ 0 < z.re} + have f_an : AnalyticOnNhd ℂ f U := by + apply (HolomorphicOn_riemannZeta.analyticOnNhd isOpen_ne).mono + simp only [ne_eq, ofPred_subset_ofPred, and_imp, U] + exact fun a ha _ ↦ ha + have g_an : AnalyticOnNhd ℂ g U := (HolomorphicOn_riemannZeta0 N_pos).analyticOnNhd isOpen_aux + have preconU : IsPreconnected U := by + apply IsConnected.isPreconnected + apply (IsOpen.isConnected_iff_isPathConnected isOpen_aux).mpr isPathConnected_aux + have h2 : (2 : ℂ) ∈ U := by simp [U] + have s_mem : s ∈ U := by simp [U, reS_pos, s_ne_one] + convert (AnalyticOnNhd.eqOn_of_preconnected_of_eventuallyEq f_an g_an preconU h2 ?_ s_mem).symm + have u_mem : {z : ℂ | 1 < z.re} ∈ 𝓝 (2 : ℂ) := by + apply mem_nhds_iff.mpr + use {z : ℂ | 1 < z.re} + simp only [ofPred_subset_ofPred, imp_self, forall_const, mem_ofPred_eq, re_ofNat, + Nat.one_lt_ofNat, and_true, true_and] + exact isOpen_lt (by continuity) (by continuity) + filter_upwards [u_mem] + intro z hz + simp only [f,g, zeta_eq_tsum_one_div_nat_cpow hz, riemannZeta0_apply] + nth_rewrite 2 [neg_div] + rw [← sub_eq_add_neg, ← ZetaSum_aux2 N_pos hz, + ← (summable_one_div_nat_cpow.mpr hz).sum_add_tsum_nat_add (N + 1)] + norm_cast + +lemma DerivZeta0EqDerivZeta {N : ℕ} (N_pos : 0 < N) {s : ℂ} (reS_pos : 0 < s.re) + (s_ne_one : s ≠ 1) : + deriv (ζ₀ N) s = ζ' s := by + let U := {z : ℂ | z ≠ 1 ∧ 0 < z.re} + have {x : ℂ} (hx : x ∈ U) : ζ₀ N x = ζ x := by + simp only [mem_ofPred_eq, U] at hx; exact Zeta0EqZeta (N := N) N_pos hx.2 hx.1 + refine deriv_eqOn isOpen_aux ?_ (by simp [s_ne_one, reS_pos]) + intro x hx + have hζ := HolomorphicOn_riemannZeta.mono (by aesop)|>.hasDerivAt (s := U) <| + isOpen_aux.mem_nhds hx + exact hζ.hasDerivWithinAt.congr (fun y hy ↦ this hy) (this hx) + +lemma le_trans₄ {α : Type*} [Preorder α] {a b c d : α} : a ≤ b → b ≤ c → c ≤ d → a ≤ d := + fun hab hbc hcd ↦ le_trans (le_trans hab hbc) hcd + +lemma lt_trans₄ {α : Type*} [Preorder α] {a b c d : α} : a < b → b < c → c < d → a < d := + fun hab hbc hcd ↦ lt_trans (lt_trans hab hbc) hcd + +lemma norm_add₅_le {E : Type*} [SeminormedAddGroup E] (a : E) (b : E) (c : E) (d : E) (e : E) : + ‖a + b + c + d + e‖ ≤ ‖a‖ + ‖b‖ + ‖c‖ + ‖d‖ + ‖e‖ := by + apply le_trans <| norm_add_le (a + b + c + d) e + simp only [add_le_add_iff_right]; apply norm_add₄_le + +lemma norm_add₆_le {E : Type*} [SeminormedAddGroup E] (a : E) (b : E) (c : E) (d : E) (e : E) + (f : E) : + ‖a + b + c + d + e + f‖ ≤ ‖a‖ + ‖b‖ + ‖c‖ + ‖d‖ + ‖e‖ + ‖f‖ := by + apply le_trans <| norm_add_le (a + b + c + d + e) f + simp only [add_le_add_iff_right]; apply norm_add₅_le + +lemma mul_le_mul₃ {α : Type*} {a b c d e f : α} [MulZeroClass α] [Preorder α] [PosMulMono α] + [MulPosMono α] (h₁ : a ≤ b) (h₂ : c ≤ d) (h₃ : e ≤ f) (c0 : 0 ≤ c) (b0 : 0 ≤ b) + (e0 : 0 ≤ e) : a * c * e ≤ b * d * f := by + apply mul_le_mul (mul_le_mul h₁ h₂ c0 b0) h₃ e0 <| mul_nonneg b0 <| le_trans c0 h₂ + +/- +Given $n ≤ t$ and $\sigma$ with $1-A/\log t \le \sigma$, we have + that + $$ + |n^{-s}| \le n^{-1} e^A. + $$ +Use $|n^{-s}| = n^{-\sigma} + = e^{-\sigma \log n} + \le + \exp(-\left(1-\frac{A}{\log t}\right)\log n) + \le + n^{-1} e^A$, + since $n\le t$. +-/ +lemma ZetaBnd_aux2 {n : ℕ} {t A σ : ℝ} (Apos : 0 < A) (σpos : 0 < σ) (n_le_t : n ≤ |t|) + (σ_ge : (1 : ℝ) - A / Real.log |t| ≤ σ) : + ‖(n : ℂ) ^ (-(σ + t * I))‖ ≤ (n : ℝ)⁻¹ * Real.exp A := by + set s := σ + t * I + by_cases n0 : n = 0 + · simp_rw [n0, CharP.cast_eq_zero, inv_zero, zero_mul] + rw [Complex.zero_cpow ?_] + · simp + · exact fun h ↦ σpos.ne' <| zero_eq_neg.mp <| zero_re ▸ h ▸ (by simp [s]) + have n_gt_0 : 0 < n := Nat.pos_of_ne_zero n0 + have n_gt_0' : (0 : ℝ) < (n : ℝ) := Nat.cast_pos.mpr n_gt_0 + have n_ge_1 : 1 ≤ (n : ℝ) := Nat.one_le_cast.mpr <| Nat.succ_le_of_lt n_gt_0 + calc + _ = |((n : ℝ) ^ (-σ))| := ?_ + _ ≤ Real.exp (Real.log n * -σ) := Real.abs_rpow_le_exp_log_mul (n : ℝ) (-σ) + _ ≤ Real.exp (Real.log n * -(1 - A / Real.log t)) := ?_ + _ ≤ Real.exp (- Real.log n + A) := Real.exp_le_exp_of_le ?_ + _ ≤ _ := by rw [Real.exp_add, Real.exp_neg, Real.exp_log n_gt_0'] + · have : ‖(n : ℂ) ^ (-s)‖ = n ^ (-s.re) := norm_cpow_eq_rpow_re_of_pos n_gt_0' (-s) + rw [this, abs_eq_self.mpr <| Real.rpow_nonneg n_gt_0'.le _]; simp [s] + · apply Real.exp_le_exp_of_le <| mul_le_mul_of_nonneg_left _ <| Real.log_nonneg n_ge_1 + rw [neg_sub, neg_le_sub_iff_le_add, add_comm, ← Real.log_abs]; linarith + · simp only [neg_sub, le_neg_add_iff_add_le] + ring_nf + conv => rw [mul_comm, ← mul_assoc, ← Real.log_abs]; rhs; rw [← one_mul A] + gcongr + by_cases ht1 : |t| = 1 + · simp [ht1] + apply (inv_mul_le_iff₀ ?_).mpr + · convert! Real.log_le_log n_gt_0' n_le_t using 1; rw [mul_one] + · exact Real.log_pos <| lt_of_le_of_ne (le_trans n_ge_1 n_le_t) <| fun t ↦ ht1 (t.symm) + +lemma logt_gt_one {t : ℝ} (t_ge : 3 ≤ t) : 1 < Real.log t := + (Real.lt_log_iff_exp_lt (by linarith)).mpr (by linarith [Real.exp_one_lt_d9]) + +lemma UpperBnd_aux {A σ t : ℝ} (hA : A ∈ Ioc 0 (1 / 2)) (t_gt : 3 < |t|) + (σ_ge : 1 - A / Real.log |t| ≤ σ) : + let N := ⌊|t|⌋₊; + 0 < N ∧ N ≤ |t| ∧ 1 < Real.log |t| ∧ 1 - A < σ ∧ 0 < σ ∧ σ + t * I ≠ 1 := by + intro N + have Npos : 0 < N := Nat.floor_pos.mpr (by linarith) + have N_le_t : N ≤ |t| := Nat.floor_le <| abs_nonneg _ + have logt_gt := logt_gt_one t_gt.le + have σ_gt : 1 - A < σ := by + apply lt_of_lt_of_le ((sub_lt_sub_iff_left (a := 1)).mpr ?_) σ_ge + exact (div_lt_iff₀ (by linarith)).mpr <| lt_mul_right hA.1 logt_gt + refine ⟨Npos, N_le_t, logt_gt, σ_gt, by linarith [hA.2], ?_⟩ + contrapose! t_gt + simp only [Complex.ext_iff, add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, add_zero, one_re, add_im, mul_im, zero_add, one_im] at t_gt + norm_num [t_gt.2] + +lemma UpperBnd_aux2 {A σ t : ℝ} (t_ge : 3 < |t|) (σ_ge : 1 - A / Real.log |t| ≤ σ) : + |t| ^ (1 - σ) ≤ Real.exp A := by + have : |t| ^ (1 - σ) ≤ |t| ^ (A / Real.log |t|) := + Real.rpow_le_rpow_of_exponent_le (by linarith) (by linarith) + apply le_trans this ?_ + conv => lhs; lhs; rw [← Real.exp_log (by linarith : 0 < |t|)] + rw [div_eq_mul_inv, Real.rpow_mul (by positivity), ← Real.exp_mul, ← Real.exp_mul, mul_comm, + ← mul_assoc, inv_mul_cancel₀, one_mul] + apply Real.log_ne_zero.mpr; split_ands <;> linarith + +lemma riemannZeta0_zero_aux (N : ℕ) (Npos : 0 < N) : + ∑ x ∈ Finset.Ico 0 N, ((x : ℝ))⁻¹ = ∑ x ∈ Finset.Ico 1 N, ((x : ℝ))⁻¹ := by + have : Finset.Ico 1 N ⊆ Finset.Ico 0 N := by + intro x hx + simp only [Finset.mem_Ico, Nat.Ico_zero_eq_range, Finset.mem_range] at hx ⊢ + exact hx.2 + rw [← Finset.sum_sdiff (s₁ := Finset.Ico 1 N) (s₂ := Finset.Ico 0 N) this] + have : Finset.Ico 0 N \ Finset.Ico 1 N = Finset.range 1 := by + ext a + simp only [Nat.Ico_zero_eq_range, Finset.mem_sdiff, Finset.mem_range, Finset.mem_Ico, not_and, + not_lt, Finset.range_one, Finset.mem_singleton] + exact ⟨fun _ ↦ by omega, fun ha ↦ ⟨by simp [ha, Npos], by omega⟩⟩ + rw [this]; simp + +lemma UpperBnd_aux3 {A C σ t : ℝ} (hA : A ∈ Ioc 0 (1 / 2)) + (σ_ge : 1 - A / Real.log |t| ≤ σ) (t_gt : 3 < |t|) (hC : 2 ≤ C) : let N := ⌊|t|⌋₊; + ‖∑ n ∈ Finset.range (N + 1), (n : ℂ) ^ (-(σ + t * I))‖ ≤ + Real.exp A * C * Real.log |t| := by + intro N + obtain ⟨Npos, N_le_t, _, _, σPos, _⟩ := UpperBnd_aux hA t_gt σ_ge + have logt_gt := logt_gt_one t_gt.le + have (n : ℕ) (hn : n ∈ Finset.range (N + 1)) := ZetaBnd_aux2 (n := n) hA.1 σPos ?_ σ_ge + · replace := norm_sum_le_of_le (Finset.range (N + 1)) this + rw [← Finset.sum_mul, mul_comm _ (Real.exp A)] at this + rw [mul_assoc] + apply le_trans this <| (mul_le_mul_iff_right₀ A.exp_pos).mpr ?_ + have : 1 + Real.log (N : ℝ) ≤ C * Real.log |t| := by + by_cases hN : N = 1 + · simp only [hN, Nat.cast_one, Real.log_one, add_zero] + have : 2 * 1 ≤ C * Real.log |t| := mul_le_mul hC logt_gt.le (by linarith) (by linarith) + linarith + · rw [(by ring : C * Real.log |t| = Real.log |t| + (C - 1) * Real.log |t|), + ← one_mul <| Real.log (N: ℝ)] + apply add_le_add logt_gt.le + refine mul_le_mul (by linarith) ?_ (by positivity) (by linarith) + exact Real.log_le_log (by positivity) N_le_t + refine le_trans ?_ this + convert! harmonic_eq_sum_Icc ▸ harmonic_le_one_add_log N + · simp only [Rat.cast_sum, Rat.cast_inv, Rat.cast_natCast, Finset.range_eq_Ico] + rw [riemannZeta0_zero_aux (N + 1) (by linarith)]; congr! 1 + · simp only [Finset.mem_range] at hn + linarith [(by exact_mod_cast (by omega : n ≤ N) : (n : ℝ) ≤ N)] + +lemma _root_.Nat.self_div_floor_bound {t : ℝ} (t_ge : 1 ≤ |t|) : let N := ⌊|t|⌋₊; + (|t| / N) ∈ Icc 1 2 := by + intro N + have Npos : 0 < N := Nat.floor_pos.mpr (by linarith) + have N_le_t : N ≤ |t| := Nat.floor_le <| abs_nonneg _ + constructor + · apply le_div_iff₀ (by simp [Npos]) |>.mpr; simp [N_le_t] + · apply div_le_iff₀ (by positivity) |>.mpr + suffices |t| < N + 1 by linarith [(by exact_mod_cast (by omega) : 1 ≤ (N : ℝ))] + apply Nat.lt_floor_add_one + +lemma UpperBnd_aux5 {σ t : ℝ} (t_ge : 3 < |t|) (σ_le : σ ≤ 2) : (|t| / ⌊|t|⌋₊) ^ σ ≤ 4 := by + obtain ⟨h₁, h₂⟩ := Nat.self_div_floor_bound (by linarith) + calc _ ≤ ((|t| / ↑⌊|t|⌋₊) ^ (2 : ℝ)) := by gcongr + _ ≤ (2 : ℝ) ^ (2 : ℝ) := by gcongr + _ = 4 := by norm_num + +lemma UpperBnd_aux6 {σ t : ℝ} (t_ge : 3 < |t|) (hσ : σ ∈ Ioc (1 / 2) 2) + (neOne : σ + t * I ≠ 1) (Npos : 0 < ⌊|t|⌋₊) (N_le_t : ⌊|t|⌋₊ ≤ |t|) : + ⌊|t|⌋₊ ^ (1 - σ) / ‖1 - (σ + t * I)‖ ≤ |t| ^ (1 - σ) * 2 ∧ + ⌊|t|⌋₊ ^ (-σ) / 2 ≤ |t| ^ (1 - σ) ∧ ⌊|t|⌋₊ ^ (-σ) / σ ≤ 8 * |t| ^ (-σ) := by + have bnd := UpperBnd_aux5 t_ge hσ.2 + have bnd' : (|t| / ⌊|t|⌋₊) ^ σ ≤ 2 * |t| := by linarith + split_ands + · apply (div_le_iff₀ <| norm_pos_iff.mpr <| sub_ne_zero_of_ne neOne.symm).mpr + conv => rw [mul_assoc]; rhs; rw [mul_comm] + apply (div_le_iff₀ <| Real.rpow_pos_of_pos (by linarith) _).mp + rw [div_rpow_eq_rpow_div_neg (by positivity) (by positivity), neg_sub] + refine le_trans₄ ?_ bnd' ?_ + · exact Real.rpow_le_rpow_of_exponent_le (one_le_div (by positivity) |>.mpr N_le_t) (by simp) + · apply (mul_le_mul_iff_right₀ (by norm_num)).mpr; simpa using abs_im_le_norm (1 - (σ + t * I)) + · apply div_le_iff₀ (by norm_num) |>.mpr + rw [Real.rpow_sub (by linarith), Real.rpow_one, div_mul_eq_mul_div, mul_comm] + apply div_le_iff₀ (by positivity) |>.mp + convert! bnd' using 1 + rw [← Real.rpow_neg (by linarith), div_rpow_neg_eq_rpow_div (by positivity) (by positivity)] + · apply div_le_iff₀ (by linarith [hσ.1]) |>.mpr + rw [mul_assoc, mul_comm, mul_assoc] + apply div_le_iff₀' (by positivity) |>.mp + apply le_trans ?_ (by linarith [hσ.1] : 4 ≤ σ * 8) + convert! bnd using 1; exact div_rpow_neg_eq_rpow_div (by positivity) (by positivity) + +lemma ZetaUpperBnd' {A σ t : ℝ} (hA : A ∈ Ioc 0 (1 / 2)) (t_gt : 3 < |t|) + (hσ : σ ∈ Icc (1 - A / Real.log |t|) 2) : + let C := Real.exp A * (5 + 8 * 2); -- the 2 comes from ZetaBnd_aux1 + let N := ⌊|t|⌋₊; + let s := σ + t * I; + ‖∑ n ∈ Finset.range (N + 1), 1 / (n : ℂ) ^ s‖ + ‖(N : ℂ) ^ (1 - s) / (1 - s)‖ + + ‖(N : ℂ) ^ (-s) / 2‖ + + ‖s * ∫ (x : ℝ) in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) / (x : ℂ) ^ (s + 1)‖ + ≤ C * Real.log |t| := by + intros C N s + obtain ⟨Npos, N_le_t, logt_gt, σ_gt, σPos, neOne⟩ := UpperBnd_aux hA t_gt hσ.1 + replace σ_gt : 1 / 2 < σ := by linarith [hA.2] + calc + _ ≤ Real.exp A * 2 * Real.log |t| + ‖N ^ (1 - s) / (1 - s)‖ + ‖(N : ℂ) ^ (-s) / 2‖ + + ‖s * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) / (x : ℂ) ^ (s + 1)‖ := ?_ + _ ≤ Real.exp A * 2 * Real.log |t| + ‖N ^ (1 - s) / (1 - s)‖ + ‖(N : ℂ) ^ (-s) / 2‖ + + 2 * |t| * N ^ (-σ) / σ := ?_ + _ = Real.exp A * 2 * Real.log |t| + N ^ (1 - σ) / ‖(1 - s)‖ + N ^ (-σ) / 2 + + 2 * |t| * N ^ (-σ) / σ := ?_ + _ ≤ Real.exp A * 2 * Real.log |t| + |t| ^ (1 - σ) * 2 + + |t| ^ (1 - σ) + 2 * |t| * (8 * |t| ^ (-σ)) := ?_ + _ = Real.exp A * 2 * Real.log |t| + (3 + 8 * 2) * |t| ^ (1 - σ) := ?_ + _ ≤ Real.exp A * 2 * Real.log |t| + (3 + 8 * 2) * Real.exp A * 1 := ?_ + _ ≤ Real.exp A * 2 * Real.log |t| + (3 + 8 * 2) * Real.exp A * Real.log |t| := ?_ + _ = _ := by ring + · simp only [add_le_add_iff_right, one_div_cpow_eq_cpow_neg] + convert UpperBnd_aux3 (C := 2) hA hσ.1 t_gt le_rfl using 1 + · simp only [add_le_add_iff_left]; exact ZetaBnd_aux1 N (by linarith) ⟨σPos, hσ.2⟩ (by linarith) + · simp only [norm_div, RCLike.norm_ofNat, s] + congr <;> (convert norm_natCast_cpow_of_pos Npos _; simp) + · have ⟨h₁, h₂, h₃⟩ := UpperBnd_aux6 t_gt ⟨σ_gt, hσ.2⟩ neOne Npos N_le_t + gcongr + rw [mul_div_assoc] + gcongr + · ring_nf; conv => lhs; rhs; lhs; rw [mul_comm |t|] + rw [← Real.rpow_add_one (by positivity)]; ring_nf + · simp only [Real.log_abs, add_le_add_iff_left, mul_one] + exact mul_le_mul_iff_right₀ (by positivity) |>.mpr <| UpperBnd_aux2 t_gt hσ.1 + · simp only [add_le_add_iff_left] + apply mul_le_mul_iff_right₀ (by norm_num [Real.exp_pos]) |>.mpr <| logt_gt.le + +/- +For any $s = \sigma + tI \in \C$, $1/2 \le \sigma\le 2, 3 < |t|$ + and any $0 < A < 1$ sufficiently small, and $1-A/\log |t| \le \sigma$, we have + $$ + |\zeta(s)| \ll \log t. + $$ +First replace $\zeta(s)$ by $\zeta_0(N,s)$ for $N = \lfloor |t| \rfloor$. + We estimate: + $$ + |\zeta_0(N,s)| \ll + \sum_{1\le n \le |t|} |n^{-s}| + + + \frac{- |t|^{1-\sigma}}{|1-s|} + \frac{-|t|^{-\sigma}}{2} + + |t| \cdot |t| ^ {-σ} / σ + $$ + $$ + \ll + e^A \sum_{1\le n < |t|} n^{-1} + +|t|^{1-\sigma} + $$ + , + where we used Lemma \ref{ZetaBnd_aux2} and Lemma \ref{ZetaBnd_aux1}. + The first term is $\ll \log |t|$. + For the second term, estimate + $$ + |t|^{1-\sigma} + \le |t|^{1-(1-A/\log |t|)} + = |t|^{A/\log |t|} \ll 1. + $$ +-/ +lemma ZetaUpperBnd : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (C : ℝ) (_ : 0 < C), ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Icc (1 - A / Real.log |t|) 2), ‖ζ (σ + t * I)‖ ≤ C * Real.log |t| := by + let A := (1 / 2 : ℝ) + let C := Real.exp A * (5 + 8 * 2) -- the 2 comes from ZetaBnd_aux1 + refine ⟨A, ⟨by norm_num, by norm_num⟩, C, (by positivity), ?_⟩ + intro σ t t_gt ⟨σ_ge, σ_le⟩ + obtain ⟨Npos, _, _, _, σPos, neOne⟩ := UpperBnd_aux ⟨by norm_num, by norm_num⟩ t_gt σ_ge + rw [← Zeta0EqZeta Npos (by simp [σPos]) neOne] + apply le_trans (by apply norm_add₄_le) ?_ + convert! ZetaUpperBnd' ⟨by norm_num, le_rfl⟩ t_gt ⟨σ_ge, σ_le⟩ using 1; simp + +lemma norm_complex_log_ofNat (n : ℕ) : ‖(n : ℂ).log‖ = (n : ℝ).log := by + have := Complex.ofReal_log (x := (n : ℝ)) (Nat.cast_nonneg n) + rw [(by simp : ((n : ℝ) : ℂ) = (n : ℂ))] at this + rw [← this, Complex.norm_of_nonneg] + exact Real.log_natCast_nonneg n + +lemma _root_.Real.log_natCast_monotone : Monotone (fun (n : ℕ) ↦ Real.log n) := by + intro n m hnm + cases n + · simp only [CharP.cast_eq_zero, Real.log_zero, Real.log_natCast_nonneg] + · apply Real.log_le_log <;> simp only [Nat.cast_add, Nat.cast_one] + · exact Nat.cast_add_one_pos _ + · exact_mod_cast hnm + +lemma _root_.Finset.Icc0_eq (N : ℕ) : Finset.Icc 0 N = {0} ∪ Finset.Icc 1 N := by + refine Finset.ext_iff.mpr ?_ + intro a + cases a + · simp only [Finset.mem_Icc, le_refl, zero_le, and_self, Finset.mem_union, Finset.mem_singleton, + nonpos_iff_eq_zero, one_ne_zero, and_true, or_false] + · simp only [Finset.mem_Icc, le_add_iff_nonneg_left, zero_le, true_and, Finset.mem_union, + Finset.mem_singleton, add_eq_zero, one_ne_zero, and_false, false_or] + +lemma harmonic_eq_sum_Icc0_aux (N : ℕ) : + ∑ i ∈ Finset.Icc 0 N, (i : ℝ)⁻¹ = ∑ i ∈ Finset.Icc 1 N, (i : ℝ)⁻¹ := by + rw [Finset.Icc0_eq, Finset.sum_union] + · simp only [Finset.sum_singleton, CharP.cast_eq_zero, inv_zero, zero_add] + · simp only [Finset.disjoint_singleton_left, Finset.mem_Icc, nonpos_iff_eq_zero, one_ne_zero, + zero_le, and_true, not_false_eq_true] + +lemma harmonic_eq_sum_Icc0 (N : ℕ) : ∑ i ∈ Finset.Icc 0 N, (i : ℝ)⁻¹ = (harmonic N : ℝ) := by + rw [harmonic_eq_sum_Icc0_aux, harmonic_eq_sum_Icc] + simp only [Rat.cast_sum, Rat.cast_inv, Rat.cast_natCast] + +lemma DerivUpperBnd_aux1 {A C σ t : ℝ} (hA : A ∈ Ioc 0 (1 / 2)) + (σ_ge : 1 - A / Real.log |t| ≤ σ) (t_gt : 3 < |t|) (hC : 2 ≤ C) : let N := ⌊|t|⌋₊; + ‖∑ n ∈ Finset.range (N + 1), -1 / (n : ℂ) ^ (σ + t * I) * (Real.log n)‖ + ≤ Real.exp A * C * (Real.log |t|) ^ 2 := by + intro N + obtain ⟨Npos, N_le_t, _, _, σPos, _⟩ := UpperBnd_aux hA t_gt σ_ge + have logt_gt := logt_gt_one t_gt.le + have logN_pos : 0 ≤ Real.log N := Real.log_nonneg (by norm_cast) + have fact0 {n : ℕ} (hn : n ≤ N) : n ≤ |t| := by linarith [(by exact_mod_cast hn : (n : ℝ) ≤ N)] + have fact1 {n : ℕ} (hn : n ≤ N) : + ‖(n : ℂ) ^ (-(σ + t * I))‖ ≤ (n : ℝ)⁻¹ * A.exp := ZetaBnd_aux2 hA.1 σPos (fact0 hn) σ_ge + have fact2 {n : ℕ} (hn : n ≤ N) : Real.log n ≤ Real.log |t| := by + cases n + · simp only [CharP.cast_eq_zero, Real.log_zero]; linarith + · exact Real.log_le_log (by exact_mod_cast Nat.add_one_pos _) (fact0 hn) + have fact3 (n : ℕ) (hn : n ≤ N) : + ‖-1 / (n : ℂ) ^ (σ + t * I) * (Real.log n)‖ ≤ (n : ℝ)⁻¹ * Real.exp A * (Real.log |t|) := by + convert! mul_le_mul (fact1 hn) (fact2 hn) (Real.log_natCast_nonneg n) (by positivity) + simp only [norm_mul, norm_div, norm_neg, norm_one, one_div, natCast_log, ← norm_inv, cpow_neg] + congr; exact norm_complex_log_ofNat n + have := norm_sum_le_of_le (Finset.range (N + 1)) + (by simp only [Finset.mem_range, Nat.lt_succ_iff]; exact fact3) + rw [← Finset.sum_mul, ← Finset.sum_mul, mul_comm _ A.exp, mul_assoc] at this + rw [mul_assoc] + apply le_trans this <| (mul_le_mul_iff_right₀ A.exp_pos).mpr ?_ + rw [pow_two, ← mul_assoc, Finset.range_eq_Ico, ← Finset.Icc_eq_Ico, harmonic_eq_sum_Icc0] + apply le_trans (mul_le_mul (h₁ := harmonic_le_one_add_log (n := N)) (le_refl (Real.log |t|)) + (by linarith) (by linarith)) + apply (mul_le_mul_iff_left₀ (by linarith)).mpr + rw [(by ring : C * Real.log |t| = Real.log |t| + (C - 1) * Real.log |t|), + ← one_mul <| Real.log (N: ℝ)] + refine add_le_add logt_gt.le <| mul_le_mul (by linarith) ?_ (by positivity) (by linarith) + exact Real.log_le_log (by positivity) N_le_t + +lemma DerivUpperBnd_aux2 {A σ t : ℝ} (t_gt : 3 < |t|) (hσ : σ ∈ Icc (1 - A / |t|.log) 2) : + let N := ⌊|t|⌋₊; + let s := ↑σ + ↑t * I; + 0 < N → ↑N ≤ |t| → s ≠ 1 → + 1 / 2 < σ → ‖-↑N ^ (1 - s) / (1 - s) ^ 2‖ ≤ A.exp * 2 * (1 / 3) := by + intro N s Npos N_le_t neOne σ_gt + dsimp only [s] + simp_rw [norm_div, norm_neg, norm_pow, norm_natCast_cpow_of_pos Npos _, + sub_re, one_re, add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, + mul_one, sub_self, add_zero] + have h := UpperBnd_aux6 t_gt ⟨σ_gt, hσ.2⟩ neOne Npos N_le_t |>.1 + rw [(by ring_nf : N ^ (1 - σ) / ‖1 - (↑σ + ↑t * I)‖ ^ 2 = + N ^ (1 - σ) / ‖1 - (↑σ + ↑t * I)‖ * 1 / ‖1 - (↑σ + ↑t * I)‖)] + apply mul_le_mul ?_ ?_ (inv_nonneg.mpr <| norm_nonneg _) ?_ + · rw [mul_one]; exact le_trans h (by gcongr; exact UpperBnd_aux2 t_gt hσ.1) + · rw [inv_eq_one_div, div_le_iff₀ <| norm_pos_iff.mpr <| sub_ne_zero_of_ne neOne.symm, + mul_comm, ← mul_div_assoc, mul_one, le_div_iff₀ (by norm_num), one_mul] + apply le_trans t_gt.le ?_ + rw [← abs_neg]; convert! abs_im_le_norm (1 - (σ + t * I)); simp + · exact mul_nonneg (Real.exp_nonneg _) (by norm_num) + +theorem DerivUpperBnd_aux3 {A σ t : ℝ} (t_gt : 3 < |t|) (hσ : σ ∈ Icc (1 - A / |t|.log) 2) : + let N := ⌊|t|⌋₊; + let s := ↑σ + ↑t * I; + 0 < N → ↑N ≤ |t| → s ≠ 1 → 1 / 2 < σ → + ‖↑(N : ℝ).log * ↑N ^ (1 - s) / (1 - s)‖ ≤ A.exp * 2 * |t|.log := by + intro N s Npos N_le_t neOne σ_gt + rw [norm_div, norm_mul, mul_div_assoc, mul_comm] + apply mul_le_mul ?_ ?_ (by positivity) (by positivity) + · have h := UpperBnd_aux6 t_gt ⟨σ_gt, hσ.2⟩ neOne Npos N_le_t |>.1 + convert le_trans h ?_ using 1 + · simp [s, norm_natCast_cpow_of_pos Npos _, N] + · gcongr; exact UpperBnd_aux2 t_gt hσ.1 + · rw [natCast_log, norm_complex_log_ofNat] + exact Real.log_le_log (by positivity) N_le_t + +theorem DerivUpperBnd_aux4 {A σ t : ℝ} (t_gt : 3 < |t|) (hσ : σ ∈ Icc (1 - A / |t|.log) 2) : + let N := ⌊|t|⌋₊; + let s := ↑σ + ↑t * I; + 0 < N → ↑N ≤ |t| → s ≠ 1 → 1 / 2 < σ → + ‖↑(N : ℝ).log * (N : ℂ) ^ (-s) / 2‖ ≤ A.exp * |t|.log := by + intro N s Npos N_le_t neOne σ_gt + rw [norm_div, norm_mul, mul_div_assoc, mul_comm, RCLike.norm_ofNat] + apply mul_le_mul ?_ ?_ (by positivity) (by positivity) + · have h := UpperBnd_aux6 t_gt ⟨σ_gt, hσ.2⟩ neOne Npos N_le_t |>.2.1 + convert le_trans h (UpperBnd_aux2 t_gt hσ.1) using 1 + simp [s, norm_natCast_cpow_of_pos Npos _, N] + · rw [natCast_log, norm_complex_log_ofNat] + exact Real.log_le_log (by positivity) N_le_t + +theorem DerivUpperBnd_aux5 {A σ t : ℝ} (t_gt : 3 < |t|) (hσ : σ ∈ Icc (1 - A / |t|.log) 2) : + let N := ⌊|t|⌋₊; + let s := ↑σ + ↑t * I; + 0 < N → 1 / 2 < σ → + ‖1 * ∫ (x : ℝ) in Ioi (N : ℝ), (↑⌊x⌋ + 1 / 2 - ↑x) * (x : ℂ) ^ (-s - 1)‖ ≤ + 1 / 3 * (2 * |t| * ↑N ^ (-σ) / σ) := by + intro N s Npos σ_gt + have neZero : s ≠ 0 := by + contrapose! σ_gt + simp only [Complex.ext_iff, add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, + sub_self, add_zero, zero_re, add_im, mul_im, zero_add, zero_im, s] at σ_gt + linarith + have : 1 = 1 / s * s := by field_simp + nth_rewrite 1 [this] + rw [mul_assoc, norm_mul] + apply mul_le_mul ?_ ?_ (by positivity) (by positivity) + · simp only [s, norm_div, norm_one] + apply one_div_le_one_div (norm_pos_iff.mpr neZero) (by norm_num) |>.mpr + apply le_trans t_gt.le ?_ + convert! abs_im_le_norm (σ + t * I); simp + · have hσ : σ ∈ Ioc 0 2 := ⟨(by linarith), hσ.2⟩ + simp only [s] + have := ZetaBnd_aux1 N (by omega) hσ (by linarith) + simp only [div_cpow_eq_cpow_neg] at this + convert! this using 1; congr; funext x; ring_nf + +theorem DerivUpperBnd_aux6 {A σ t : ℝ} (t_gt : 3 < |t|) (hσ : σ ∈ Icc (1 - A / |t|.log) 2) : + let N := ⌊|t|⌋₊; + 0 < N → ↑N ≤ |t| → ↑σ + ↑t * I ≠ 1 → 1 / 2 < σ → + 2 * |t| * ↑N ^ (-σ) / σ ≤ 2 * (8 * A.exp) := by + intro N Npos N_le_t neOne σ_gt + rw [mul_div_assoc, mul_assoc] + apply mul_le_mul_iff_right₀ (by norm_num) |>.mpr + have h := UpperBnd_aux6 t_gt ⟨σ_gt, hσ.2⟩ neOne Npos N_le_t |>.2.2 + apply le_trans (mul_le_mul_iff_right₀ (a := |t|) (by positivity) |>.mpr h) ?_ + rw [← mul_assoc, mul_comm _ 8, mul_assoc] + gcongr + convert! UpperBnd_aux2 t_gt hσ.1 using 1 + rw [mul_comm, ← Real.rpow_add_one (by positivity)]; ring_nf + +lemma DerivUpperBnd_aux7_1 {x σ t : ℝ} (hx : 1 ≤ x) : + let s := ↑σ + ↑t * I; + ‖(↑⌊x⌋ + 1 / 2 - ↑x) * (x : ℂ) ^ (-s - 1) * -↑x.log‖ = |(↑⌊x⌋ + 1 / 2 - x)| * x ^ (-σ - 1) * + x.log := by + have xpos : 0 < x := lt_of_lt_of_le (by norm_num) hx + have : ‖(x.log : ℂ)‖ = x.log := Complex.norm_of_nonneg <| Real.log_nonneg hx + simp [← norm_real, this, Complex.norm_cpow_eq_rpow_re_of_pos xpos, ← Real.norm_eq_abs, ← + ofReal_ofNat, + ← ofReal_inv, ← ofReal_add, ← ofReal_sub, ← ofReal_intCast, one_div] + +lemma DerivUpperBnd_aux7_2 {x σ : ℝ} (hx : 1 ≤ x) : + |(↑⌊x⌋ + 1 / 2 - x)| * x ^ (-σ - 1) * x.log ≤ x ^ (-σ - 1) * x.log := by + rw [← one_mul (x ^ (-σ - 1) * Real.log x), mul_assoc] + apply mul_le_mul_of_nonneg_right _ (by bound) + exact le_trans (ZetaSum_aux1_3 x) (by norm_num) + +lemma DerivUpperBnd_aux7_3 {x σ : ℝ} (xpos : 0 < x) (σnz : σ ≠ 0) : + HasDerivAt (fun t ↦ -(1 / σ ^ 2 * t ^ (-σ) + 1 / σ * t ^ (-σ) * Real.log t)) + (x ^ (-σ - 1) * Real.log x) x := by + have h1 := Real.hasDerivAt_rpow_const (p := -σ) (Or.inl xpos.ne.symm) + have h2 := h1.const_mul (1 / σ^2) + have cancel : 1 / σ^2 * σ = 1 / σ := by field_simp + rw [neg_mul, mul_neg, ← mul_assoc, cancel] at h2 + have h3 := Real.hasDerivAt_log xpos.ne.symm + have h4 := HasDerivAt.mul (h1.const_mul (1 / σ)) h3 + have cancel := Real.rpow_add xpos (-σ) (-1) + have : -σ + -1 = -σ - 1 := by rfl + rw [← Real.rpow_neg_one x, mul_assoc (1 / σ) (x ^ (-σ)), ← cancel, this] at h4 + convert! h2.add h4 |>.neg using 1 + field_simp; ring + +lemma DerivUpperBnd_aux7_3' {a σ : ℝ} (apos : 0 < a) (σnz : σ ≠ 0) : + ∀ x ∈ Ici a, HasDerivAt (fun t ↦ -(1 / σ ^ 2 * t ^ (-σ) + 1 / σ * t ^ (-σ) * Real.log t)) + (x ^ (-σ - 1) * Real.log x) x := by + intro x hx + simp at hx + exact DerivUpperBnd_aux7_3 (by linarith) σnz + +lemma DerivUpperBnd_aux7_nonneg {a σ : ℝ} (ha : 1 ≤ a) : + ∀ x ∈ Ioi a, 0 ≤ x ^ (-σ - 1) * Real.log x := by + intro x hx + simp at hx + bound + +lemma DerivUpperBnd_aux7_tendsto {σ : ℝ} (σpos : 0 < σ) : + Tendsto (fun t ↦ -(1 / σ ^ 2 * t ^ (-σ) + 1 / σ * t ^ (-σ) * Real.log t)) atTop (nhds 0) := by + have h1 := tendsto_rpow_neg_atTop σpos + have h2 := h1.const_mul (1 / σ^2) + have h3 : Tendsto (fun t : ℝ ↦ t ^ (-σ) * Real.log t) atTop (nhds 0) := by + have := MooreBound.Real.tendsto_pow_log_div_pow_atTop σ 1 σpos + simp only [Real.rpow_one] at this + apply Tendsto.congr' _ this + filter_upwards [eventually_ge_atTop 0] with x hx + rw [mul_comm] + apply div_rpow_eq_rpow_neg _ _ _ hx + have h4 := h3.const_mul (1 / σ) + have h5 := (h2.add h4).neg + convert h5 using 1 + · ext; ring + simp + + +open MeasureTheory in +lemma DerivUpperBnd_aux7_4 {a σ : ℝ} (σpos : 0 < σ) (ha : 1 ≤ a) : + IntegrableOn (fun x ↦ x ^ (-σ - 1) * Real.log x) (Ioi a) volume := by + apply integrableOn_Ioi_deriv_of_nonneg' (l := 0) + · exact DerivUpperBnd_aux7_3' (by linarith) (by linarith) + · exact DerivUpperBnd_aux7_nonneg ha + · exact DerivUpperBnd_aux7_tendsto σpos + +open MeasureTheory in +lemma DerivUpperBnd_aux7_5 {a σ : ℝ} (σpos : 0 < σ) (ha : 1 ≤ a) : + IntegrableOn (fun x ↦ |(↑⌊x⌋ + (1 : ℝ) / 2 - x)| * x ^ (-σ - 1) * Real.log x) + (Ioi a) volume := by + simp_rw [mul_assoc] + apply Integrable.bdd_mul (c := 1 / 2) <| DerivUpperBnd_aux7_4 σpos ha + · exact Measurable.aestronglyMeasurable <| Measurable.abs measurable_floor_add_half_sub + apply ae_of_all + intro x + simp only [Real.norm_eq_abs, _root_.abs_abs] + exact ZetaSum_aux1_3 x + +open MeasureTheory in +lemma DerivUpperBnd_aux7_integral_eq {a σ : ℝ} (ha : 1 ≤ a) (σpos : 0 < σ) : + ∫ (x : ℝ) in Ioi a, x ^ (-σ - 1) * Real.log x = + 1 / σ^2 * a ^ (-σ) + 1 / σ * a ^ (-σ) * Real.log a := by + convert integral_Ioi_of_hasDerivAt_of_nonneg' + (DerivUpperBnd_aux7_3' (by linarith) (by linarith)) + (DerivUpperBnd_aux7_nonneg ha) (DerivUpperBnd_aux7_tendsto σpos) using 1 + ring + +open MeasureTheory in +/- +For any $s = \sigma + tI \in \C$, $1/2 \le \sigma\le 2, 3 < |t|$, and any $0 < A < 1$ + sufficiently small, and $1-A/\log |t| \le \sigma$, we have + $$ + \left\|s \cdot \int_{N}^{\infty} + \left(\left\lfloor x \right\rfloor + \frac{1}{2} - x\right) \cdot x^{-s-1} \cdot (-\log x) + \right\| + \le 2 \cdot |t| \cdot N^{-\sigma} / \sigma \cdot \log |t|. + $$ +Estimate $|s|= |\sigma + tI|$ by $|s|\le 2 +|t| \le 2|t|$ (since $|t|>3$). + Estimating $|\left\lfloor x \right\rfloor+1/2-x|$ by $1$, + and using $|x^{-s-1}| = x^{-\sigma-1}$, we have + $$ + \left\| s \cdot \int_{N}^{\infty} + \left(\left\lfloor x \right\rfloor + \frac{1}{2} - x\right) \cdot x^{-s-1} \cdot (-\log x) + \right\| + \le 2 \cdot |t| + \int_{N}^{\infty} x^{-\sigma} \cdot (\log x). + $$ + For the last integral, integrate by parts, getting: + $$ + \int_{N}^{\infty} x^{-\sigma-1} \cdot (\log x) = + \frac{1}{\sigma}N^{-\sigma} \cdot \log N + \frac1{\sigma^2} \cdot N^{-\sigma}. + $$ + Now use $\log N \le \log |t|$ to get the result. +-/ +theorem DerivUpperBnd_aux7 {A σ t : ℝ} (t_gt : 3 < |t|) (hσ : σ ∈ Icc (1 - A / |t|.log) 2) : + let N := ⌊|t|⌋₊; + let s := ↑σ + ↑t * I; + 0 < N → ↑N ≤ |t| → s ≠ 1 → 1 / 2 < σ → + ‖s * ∫ (x : ℝ) in Ioi (N : ℝ), (↑⌊x⌋ + 1 / 2 - ↑x) * (x : ℂ) ^ (-s - 1) * -↑x.log‖ ≤ + 6 * |t| * ↑N ^ (-σ) / σ * |t|.log := by + intro N s Npos N_le_t neOne σ_gt + have σpos : 0 < σ := lt_trans (by norm_num) σ_gt + rw [norm_mul, (by ring : 6 * |t| * ↑N ^ (-σ) / σ * Real.log |t| = (2 * |t|) * (3 * ↑N ^ (-σ) / σ + * Real.log |t|))] + apply mul_le_mul _ _ (by positivity) (by positivity) + · apply le_trans (by apply norm_add_le) + simp [abs_of_pos σpos] + linarith [hσ.2] + apply le_trans (by apply norm_integral_le_integral_norm) + calc ∫ (x : ℝ) in Ioi (N : ℝ), ‖(↑⌊x⌋ + 1 / 2 - ↑x) * (x : ℂ) ^ (-s - 1) * -↑x.log‖ + _ = ∫ (x : ℝ) in Ioi (N : ℝ), |(↑⌊x⌋ + 1 / 2 - x)| * x ^ (-σ - 1) * x.log := by + apply setIntegral_congr_fun (by measurability) + intro x hx + simp only [mem_Ioi] at hx + exact DerivUpperBnd_aux7_1 (lt_of_le_of_lt (mod_cast Npos) hx).le + _ ≤ ∫ (x : ℝ) in Ioi (N : ℝ), x ^ (-σ - 1) * x.log := by + apply setIntegral_mono_on _ _ (by measurability) + · intro x hx + exact DerivUpperBnd_aux7_2 (lt_of_le_of_lt (mod_cast Npos) hx).le + · apply DerivUpperBnd_aux7_5 σpos (mod_cast Npos) + apply DerivUpperBnd_aux7_4 σpos (mod_cast Npos) + _ = 1 / σ^2 * N ^ (-σ) + 1 / σ * N ^ (-σ) * Real.log N := + DerivUpperBnd_aux7_integral_eq (mod_cast Npos) σpos + _ ≤ 3 * ↑N ^ (-σ) / σ * |t|.log := by + have h2 : 1 / σ * ↑N ^ (-σ) * Real.log ↑N ≤ ↑N ^ (-σ) / σ * Real.log |t| := calc + _ = ↑N ^ (-σ) / σ * Real.log N := by ring + _ ≤ _ := by + apply mul_le_mul_of_nonneg_left _ (by positivity) + exact Real.log_le_log (mod_cast Npos) N_le_t + have : 2 ≤ 2 * Real.log |t| := by + nth_rewrite 1 [← mul_one 2] + apply mul_le_mul_of_nonneg_left _ (by norm_num) + exact logt_gt_one t_gt.le |>.le + have h1 : 1 / σ^2 * ↑N ^ (-σ) ≤ 2 * ↑N ^ (-σ) / σ * Real.log |t| := calc + 1 / σ^2 * ↑N ^ (-σ) = (↑N ^ (-σ) / σ) * (1 / σ) := by ring + _ ≤ ↑N ^ (-σ) / σ * (2 * Real.log |t|):= by + apply mul_le_mul_of_nonneg_left _ (by positivity) + apply le_trans _ this + exact (one_div_le σpos (by norm_num)).mpr σ_gt.le + _ = _ := by ring + convert! add_le_add h1 h2 using 1 + ring + + +lemma ZetaDerivUpperBnd' {A σ t : ℝ} (hA : A ∈ Ioc 0 (1 / 2)) (t_gt : 3 < |t|) + (hσ : σ ∈ Icc (1 - A / Real.log |t|) 2) : + let C := Real.exp A * 59; + let N := ⌊|t|⌋₊; + let s := σ + t * I; + ‖∑ n ∈ Finset.range (N + 1), -1 / (n : ℂ) ^ s * (Real.log n)‖ + + ‖-(N : ℂ) ^ (1 - s) / (1 - s) ^ 2‖ + + ‖(Real.log N) * (N : ℂ) ^ (1 - s) / (1 - s)‖ + + ‖(Real.log N) * (N : ℂ) ^ (-s) / 2‖ + + ‖(1 * ∫ (x : ℝ) in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1))‖ + + ‖s * ∫ (x : ℝ) in Ioi (N : ℝ), + (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1) * -(Real.log x)‖ + ≤ C * Real.log |t| ^ 2 := by + intros C N s + obtain ⟨Npos, N_le_t, logt_gt, σ_gt, _, neOne⟩ := UpperBnd_aux hA t_gt hσ.1 + replace σ_gt : 1 / 2 < σ := by linarith [hA.2] + calc _ ≤ Real.exp A * 2 * (Real.log |t|) ^ 2 + + ‖-(N : ℂ) ^ (1 - s) / (1 - s) ^ 2‖ + + ‖(Real.log N) * (N : ℂ) ^ (1 - s) / (1 - s)‖ + + ‖(Real.log N) * (N : ℂ) ^ (-s) / 2‖ + + ‖(1 * ∫ (x : ℝ) in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1))‖ + + ‖s * ∫ (x : ℝ) in Ioi (N : ℝ), + (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1) * -(Real.log x)‖ := by + gcongr; exact DerivUpperBnd_aux1 hA hσ.1 t_gt (by simp : (2 : ℝ) ≤ 2) + _ ≤ Real.exp A * 2 * (Real.log |t|) ^ 2 + + Real.exp A * 2 * (1 / 3) + + ‖(Real.log N) * (N : ℂ) ^ (1 - s) / (1 - s)‖ + + ‖(Real.log N) * (N : ℂ) ^ (-s) / 2‖ + + ‖(1 * ∫ (x : ℝ) in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1))‖ + + ‖s * ∫ (x : ℝ) in Ioi (N : ℝ), + (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1) * -(Real.log x)‖ := by + gcongr; exact DerivUpperBnd_aux2 t_gt hσ Npos N_le_t neOne σ_gt + _ ≤ Real.exp A * 2 * (Real.log |t|) ^ 2 + + Real.exp A * 2 * (1 / 3) + + Real.exp A * 2 * (Real.log |t|) + + ‖(Real.log N) * (N : ℂ) ^ (-s) / 2‖ + + ‖(1 * ∫ (x : ℝ) in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1))‖ + + ‖s * ∫ (x : ℝ) in Ioi (N : ℝ), + (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1) * -(Real.log x)‖ := by + gcongr; exact DerivUpperBnd_aux3 t_gt hσ Npos N_le_t neOne σ_gt + _ ≤ Real.exp A * 2 * (Real.log |t|) ^ 2 + + Real.exp A * 2 * (1 / 3) + + Real.exp A * 2 * (Real.log |t|) + + Real.exp A * (Real.log |t|) + + ‖(1 * ∫ (x : ℝ) in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1))‖ + + ‖s * ∫ (x : ℝ) in Ioi (N : ℝ), + (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1) * -(Real.log x)‖ := by + gcongr; exact DerivUpperBnd_aux4 t_gt hσ Npos N_le_t neOne σ_gt + _ ≤ Real.exp A * 2 * (Real.log |t|) ^ 2 + + Real.exp A * 2 * (1 / 3) + + Real.exp A * 2 * (Real.log |t|) + + Real.exp A * (Real.log |t|) + + 1 / 3 * (2 * |t| * N ^ (-σ) / σ) + + ‖s * ∫ (x : ℝ) in Ioi (N : ℝ), + (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1) * -(Real.log x)‖ := by + gcongr; exact DerivUpperBnd_aux5 t_gt hσ Npos σ_gt + _ ≤ Real.exp A * 2 * (Real.log |t|) ^ 2 + + Real.exp A * 2 * (1 / 3) + + Real.exp A * 2 * (Real.log |t|) + + Real.exp A * (Real.log |t|) + + 1 / 3 * (2 * (8 * Real.exp A)) + + ‖s * ∫ (x : ℝ) in Ioi (N : ℝ), + (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-s - 1) * -(Real.log x)‖ := by + gcongr; exact DerivUpperBnd_aux6 t_gt hσ Npos N_le_t neOne σ_gt + _ ≤ Real.exp A * 2 * (Real.log |t|) ^ 2 + + Real.exp A * 2 * (1 / 3) + + Real.exp A * 2 * (Real.log |t|) + + Real.exp A * (Real.log |t|) + + 1 / 3 * (2 * (8 * Real.exp A)) + + (6 * |t| * N ^ (-σ) / σ) * (Real.log |t|) := by + gcongr; exact DerivUpperBnd_aux7 t_gt hσ Npos N_le_t neOne σ_gt + _ ≤ Real.exp A * 2 * (Real.log |t|) ^ 2 + + Real.exp A * 2 * (1 / 3) + + Real.exp A * 2 * (Real.log |t|) + + Real.exp A * (Real.log |t|) + + 1 / 3 * (2 * (8 * Real.exp A)) + + (6 * (8 * Real.exp A)) * (Real.log |t|) := by + gcongr; convert mul_le_mul_of_nonneg_left (DerivUpperBnd_aux6 t_gt hσ Npos N_le_t neOne + σ_gt) (by norm_num : (0 : ℝ) ≤ 3) using 1 <;> ring + _ ≤ _ := by + simp only [C] + ring_nf + rw [(by ring : A.exp * |t|.log ^ 2 * 59 = A.exp * |t|.log ^ 2 * 6 + A.exp * |t|.log ^ 2 * 51 + + A.exp * |t|.log ^ 2 * 2)] + nth_rewrite 1 [← mul_one A.exp] + gcongr + swap + · nth_rewrite 1 [← mul_one |t|.log, (by ring : |t|.log ^ 2 = |t|.log * |t|.log)] + gcongr + nlinarith + +/- +For any $s = \sigma + tI \in \C$, $1/2 \le \sigma\le 2, 3 < |t|$, + there is an $A>0$ so that for $1-A/\log t \le \sigma$, we have + $$ + |\zeta'(s)| \ll \log^2 t. + $$ +First replace $\zeta(s)$ by $\zeta_0(N,s)$ for $N = \lfloor |t| \rfloor$. + Differentiating term by term, we get: + $$ + \zeta'(s) = -\sum_{1\le n < N} n^{-s} \log n + + \frac{N^{1 - s}}{(1 - s)^2} + \frac{N^{1 - s} \log N} {1 - s} + + \frac{N^{-s}\log N}{2} + + \int_N^\infty \frac{\lfloor x\rfloor + 1/2 - x}{x^{s+1}} \, dx + -s \int_N^\infty \log x \frac{\lfloor x\rfloor + 1/2 - x}{x^{s+1}} \, dx + . + $$ + Estimate as before, with an extra factor of $\log |t|$. +-/ +lemma ZetaDerivUpperBnd : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (C : ℝ) (_ : 0 < C), ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Icc (1 - A / Real.log |t|) 2), + ‖ζ' (σ + t * I)‖ ≤ C * Real.log |t| ^ 2 := by + obtain ⟨A, hA, _, _, _⟩ := ZetaUpperBnd + let C := Real.exp A * 59 + refine ⟨A, hA, C, by positivity, ?_⟩ + intro σ t t_gt ⟨σ_ge, σ_le⟩ + obtain ⟨Npos, N_le_t, _, _, σPos, neOne⟩ := UpperBnd_aux hA t_gt σ_ge + rw [← DerivZeta0EqDerivZeta Npos (by simp [σPos]) neOne] + set N : ℕ := ⌊|t|⌋₊ + rw [(HasDerivAtZeta0 Npos (s := σ + t * I) (by simp [σPos]) neOne).deriv] + dsimp only [ζ₀'] + rw [← add_assoc] + set aa := ∑ n ∈ Finset.range (N + 1), -1 / (n : ℂ) ^ (σ + t * I) * (Real.log n) + set bb := -(N : ℂ) ^ (1 - (σ + t * I)) / (1 - (σ + t * I)) ^ 2 + set cc := (Real.log N) * (N : ℂ) ^ (1 - (σ + t * I)) / (1 - (σ + t * I)) + set dd := (Real.log N) * (N : ℂ) ^ (-(σ + t * I)) / 2 + set ee := 1 * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-(σ + t * I) - 1) + set ff := (σ + t * I) * ∫ x in Ioi (N : ℝ), (⌊x⌋ + 1 / 2 - x) * (x : ℂ) ^ (-(σ + t * I) - 1) * + -(Real.log x) + rw [(by ring : aa + (bb + cc) + dd + ee + ff = aa + bb + cc + dd + ee + ff)] + apply le_trans (by apply norm_add₆_le) ?_ + convert ZetaDerivUpperBnd' hA t_gt ⟨σ_ge, σ_le⟩ + +lemma Tendsto_nhdsWithin_punctured_map_add {f : ℝ → ℝ} (a x : ℝ) + (f_mono : StrictMono f) (f_iso : Isometry f) : + Tendsto (fun y ↦ f y + a) (𝓝[>] x) (𝓝[>] (f x + a)) := by + refine tendsto_iff_forall_eventually_mem.mpr ?_ + intro v hv + simp only [mem_nhdsWithin] at hv + obtain ⟨u, hu, hu2, hu3⟩ := hv + let t := {x | f x + a ∈ u} + have : t ∩ Ioi x ∈ 𝓝[>] x := by + simp only [mem_nhdsWithin] + use t + simp only [subset_inter_iff, inter_subset_left, inter_subset_right, and_self, + and_true, t, mem_ofPred_eq] + refine ⟨?_, by simp [hu2]⟩ + simp only [Metric.isOpen_iff, gt_iff_lt, mem_ofPred_eq] at hu ⊢ + intro x hx + obtain ⟨ε, εpos, hε⟩ := hu (f x + a) hx + simp only [Metric.ball, ofPred_subset_ofPred] at hε ⊢ + exact ⟨ε, εpos, fun _ hy ↦ hε (by simp [isometry_iff_dist_eq.mp f_iso, hy])⟩ + filter_upwards [this] + intro b hb + simp only [mem_inter_iff, mem_ofPred_eq, mem_Ioi, t] at hb + refine hu3 ?_ + simp only [mem_inter_iff, mem_Ioi, add_lt_add_iff_right] + exact ⟨hb.1, f_mono hb.2⟩ + +lemma Tendsto_nhdsWithin_punctured_add (a x : ℝ) : + Tendsto (fun y ↦ y + a) (𝓝[>] x) (𝓝[>] (x + a)) := + Tendsto_nhdsWithin_punctured_map_add a x strictMono_id isometry_id + +lemma riemannZeta_isBigO_near_one_horizontal : + (fun x : ℝ ↦ ζ (1 + x)) =O[𝓝[>] 0] (fun x ↦ (1 : ℂ) / x) := by + have : (fun w : ℂ ↦ ζ (1 + w)) =O[𝓝[≠] 0] (1 / ·) := by + have H : Tendsto (fun w ↦ w * ζ (1 + w)) (𝓝[≠] 0) (𝓝 1) := by + convert Tendsto.comp (f := fun w ↦ 1 + w) riemannZeta_residue_one ?_ using 1 + · ext w + simp only [Function.comp_apply, add_sub_cancel_left] + · refine tendsto_iff_comap.mpr <| map_le_iff_le_comap.mp <| Eq.le ?_ + convert Homeomorph.map_punctured_nhds_eq (Homeomorph.addLeft (1 : ℂ)) 0 using 2 <;> simp + exact ((Asymptotics.isBigO_mul_iff_isBigO_div eventually_mem_nhdsWithin).mp <| + Tendsto.isBigO_one ℂ H).trans <| Asymptotics.isBigO_refl .. + exact (isBigO_comp_ofReal_nhds_ne this).mono <| nhdsGT_le_nhdsNE 0 + + +/- +As $\sigma\to1^+$, + $$ + |\zeta(\sigma)| \ll 1/(\sigma-1). + $$ +Zeta has a simple pole at $s=1$. Equivalently, $\zeta(s)(s-1)$ remains bounded near $1$. + Lots of ways to prove this. + Probably the easiest one: use the expression for $\zeta_0 (N,s)$ with $N=1$ (the term + $N^{1-s}/(1-s)$ being the only unbounded one). +-/ +lemma ZetaNear1BndFilter : + (fun σ : ℝ ↦ ζ σ) =O[𝓝[>](1 : ℝ)] (fun σ ↦ (1 : ℂ) / (σ - 1)) := by + have := Tendsto_nhdsWithin_punctured_add (a := -1) (x := 1) + simp only [add_neg_cancel, ← sub_eq_add_neg] at this + have := riemannZeta_isBigO_near_one_horizontal.comp_tendsto this + convert this using 1 <;> {ext; simp} + +/- +There exists a $c>0$ such that for all $1 < \sigma ≤ 2$, + $$ + |\zeta(\sigma)| ≤ c/(\sigma-1). + $$ +Split into two cases, use Lemma \ref{ZetaNear1BndFilter} for $\sigma$ sufficiently small + and continuity on a compact interval otherwise. +-/ +lemma ZetaNear1BndExact : + ∃ (c : ℝ) (_ : 0 < c), ∀ (σ : ℝ) (_ : σ ∈ Ioc 1 2), ‖ζ σ‖ ≤ c / (σ - 1) := by + have := ZetaNear1BndFilter + rw [Asymptotics.isBigO_iff] at this + obtain ⟨c, U, hU, V, hV, h⟩ := this + obtain ⟨T, hT, T_open, h1T⟩ := mem_nhds_iff.mp hU + obtain ⟨ε, εpos, hε⟩ := Metric.isOpen_iff.mp T_open 1 h1T + simp only [Metric.ball] at hε + replace hε : Ico 1 (1 + ε) ⊆ U := by + refine subset_trans (subset_trans ?_ hε) hT + intro x hx + simp only [mem_Ico] at hx + simp only [dist, abs_lt] + exact ⟨by linarith, by linarith⟩ + let W := Icc (1 + ε) 2 + have W_compact : IsCompact {ofReal z | z ∈ W} := + IsCompact.image isCompact_Icc continuous_ofReal + have cont : ContinuousOn ζ {ofReal z | z ∈ W} := by + apply HasDerivAt.continuousOn (f' := ζ') + intro σ hσ + exact (differentiableAt_riemannZeta (by contrapose! hσ; simp [W, hσ, εpos])).hasDerivAt + obtain ⟨C, hC⟩ := IsCompact.exists_bound_of_continuousOn W_compact cont + let C' := max (C + 1) 1 + replace hC : ∀ (σ : ℝ), σ ∈ W → ‖ζ σ‖ < C' := by + intro σ hσ + simp only [lt_max_iff, C'] + have := hC σ + simp only [mem_ofPred_eq, ofReal_inj, exists_eq_right] at this + exact Or.inl <| lt_of_le_of_lt (this hσ) (by norm_num) + have Cpos : 0 < C' := by simp [C'] + use max (2 * C') c, (by simp [Cpos]) + intro σ ⟨σ_ge, σ_le⟩ + by_cases hσ : σ ∈ U ∩ V + · simp only [← h, mem_ofPred_eq] at hσ + apply le_trans hσ ?_ + norm_cast + have : 0 ≤ 1 / (σ - 1) := by apply one_div_nonneg.mpr; linarith + simp only [Real.norm_eq_abs, abs_eq_self.mpr this, mul_div, mul_one] + exact div_le_div₀ (by simp [Cpos.le]) (by simp) (by linarith) (by rfl) + · replace hσ : σ ∈ W := by + simp only [mem_inter_iff, hV σ_ge, and_true] at hσ + simp only [mem_Icc, σ_le, and_true, W] + contrapose! hσ; exact hε ⟨σ_ge.le, hσ⟩ + apply le_trans (hC σ hσ).le ((le_div_iff₀ (by linarith)).mpr ?_) + rw [le_max_iff, mul_comm 2]; exact Or.inl <| mul_le_mul_of_nonneg_left (by linarith) Cpos.le + +/-- For positive `x` and nonzero `y` we have that +$|\zeta(x)^3 \cdot \zeta(x+iy)^4 \cdot \zeta(x+2iy)| \ge 1$. -/ +lemma norm_zeta_product_ge_one {x : ℝ} (hx : 0 < x) (y : ℝ) : + ‖ζ (1 + x) ^ 3 * ζ (1 + x + I * y) ^ 4 * ζ (1 + x + 2 * I * y)‖ ≥ 1 := by + have h₀ : 1 < ( 1 + x : ℂ).re := by simp[hx] + have h₁ : 1 < (1 + x + I * y).re := by simp [hx] + have h₂ : 1 < (1 + x + 2 * I * y).re := by simp [hx] + simpa only [one_pow, norm_mul, norm_pow, DirichletCharacter.LSeries_modOne_eq, + LSeries_one_eq_riemannZeta, h₀, h₁, h₂] using + DirichletCharacter.norm_LSeries_product_ge_one (1 : DirichletCharacter ℂ 1) hx y + + +theorem ZetaLowerBound1_aux1 {σ t : ℝ} (this : 1 ≤ ‖ζ σ‖ ^ (3 : ℝ) * ‖ζ (σ + I * t)‖ ^ (4 : ℝ) * + ‖ζ (σ + 2 * I * t)‖) : + ‖ζ σ‖ ^ ((3 : ℝ) / 4) * ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4) * ‖ζ (σ + t * I)‖ ≥ 1 := by + use (one_le_pow_iff_of_nonneg (by bound) four_ne_zero).1 (by_contra (this.not_gt ∘ ?_)) + simp_rw [mul_pow, ← Real.rpow_natCast, ← Real.rpow_mul (norm_nonneg _)] + norm_num [mul_right_comm, mul_comm (t : ℂ), mul_pow] + +lemma ZetaLowerBound1 {σ t : ℝ} (σ_gt : 1 < σ) : + ‖ζ σ‖ ^ ((3 : ℝ) / 4) * ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4) * ‖ζ (σ + t * I)‖ ≥ 1 := by + -- Start with the fundamental identity + have := norm_zeta_product_ge_one (x := σ - 1) (by linarith) t + simp_rw [ge_iff_le, norm_mul, norm_pow, ofReal_sub, ofReal_one, add_sub_cancel, ← + Real.rpow_natCast] + at this + apply ZetaLowerBound1_aux1 this + +lemma ZetaLowerBound2 {σ t : ℝ} (σ_gt : 1 < σ) : + 1 / (‖ζ σ‖ ^ ((3 : ℝ) / 4) * ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4)) ≤ ‖ζ (σ + t * I)‖ := by + have := ZetaLowerBound1 (t := t) σ_gt + exact (div_le_iff₀' (pos_of_mul_pos_left (one_pos.trans_le this) (norm_nonneg _) ) ).mpr this + +theorem ZetaLowerBound3_aux1 (A : ℝ) (ha : A ∈ Ioc 0 (1 / 2)) (t : ℝ) + (ht_2 : 3 < |2 * t|) : 0 < A / Real.log |2 * t| := by + exact div_pos ha.1 <| Real.log_pos (by linarith) + +theorem ZetaLowerBound3_aux2 {C : ℝ} + {σ t : ℝ} + (ζ_2t_bound : ‖ζ (σ + (2 * t) * I)‖ ≤ C * Real.log |2 * t|) : + ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4) ≤ (C * Real.log |2 * t|) ^ ((1 : ℝ) / 4) := by + bound + +theorem ZetaLowerBound3_aux3 (C : ℝ) (c_near : ℝ) {σ : ℝ} (t : ℝ) (σ_gt : 1 < σ) : + c_near ^ ((3 : ℝ) / 4) * ((-1 + σ) ^ ((3 : ℝ) / 4))⁻¹ * C ^ ((1 : ℝ) / 4) * Real.log |t * 2| ^ + ((1 : ℝ) / 4) = + c_near ^ ((3 : ℝ) / 4) * C ^ ((1 : ℝ) / 4) * Real.log |t * 2| ^ ((1 : ℝ) / 4) * (-1 + σ) ^ + (-(3 : ℝ) / 4) := by + exact (symm) (.trans (by rw [neg_div, Real.rpow_neg (by linarith)]) (by ring)) + +theorem ZetaLowerBound3_aux4 (C : ℝ) (hC : 0 < C) + (c_near : ℝ) (hc_near : 0 < c_near) {σ : ℝ} (t : ℝ) (ht : 3 < |t|) + (σ_gt : 1 < σ) + : + 0 < c_near ^ ((3 : ℝ) / 4) * (σ - 1) ^ (-(3 : ℝ) / 4) * C ^ ((1 : ℝ) / 4) * Real.log |2 * t| ^ + ((1 : ℝ) / 4) := by + match sub_pos.mpr σ_gt with | S => match Real.log_pos (by simp; linarith : abs (2 *t) > 1) with + | S => positivity + +theorem ZetaLowerBound3_aux5 + {σ : ℝ} (t : ℝ) + (this : ‖ζ σ‖ ^ ((3 : ℝ) / 4) * ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4) * ‖ζ (σ + t * I)‖ ≥ 1) : + 0 < ‖ζ σ‖ ^ ((3 : ℝ) / 4) * ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4) := + pos_of_mul_pos_left (this.trans_lt' zero_lt_one) (norm_nonneg _) + +/- +There exists a $c>0$ such that for all $1 < \sigma <= 2$ and $3 < |t|$, + $$ + c \frac{(\sigma-1)^{3/4}}{(\log |t|)^{1/4}} \le |\zeta(\sigma + tI)|. + $$ +Combine Lemma \ref{ZetaLowerBound2} with upper bounds for + $|\zeta(\sigma)|$ (from Lemma \ref{ZetaNear1BndExact}) and + $|\zeta(\sigma+2it)|$ (from Lemma \ref{ZetaUpperBnd}). +-/ +lemma ZetaLowerBound3 : + ∃ c > 0, ∀ {σ : ℝ} (_ : σ ∈ Ioc 1 2) (t : ℝ) (_ : 3 < |t|), + c * (σ - 1) ^ ((3 : ℝ) / 4) / (Real.log |t|) ^ ((1 : ℝ) / 4) ≤ ‖ζ (σ + t * I)‖ := by + obtain ⟨A, ha, C, hC, h_upper⟩ := ZetaUpperBnd + obtain ⟨c_near, hc_near, h_near⟩ := ZetaNear1BndExact + use 1 / (c_near ^ ((3 : ℝ) / 4) * (2 * C) ^ ((1 : ℝ) / 4)), by positivity + intro σ hσ t ht + obtain ⟨σ_gt, σ_le⟩ := hσ + -- Use ZetaLowerBound2 + have lower := ZetaLowerBound2 (t := t) σ_gt + apply le_trans _ lower + -- Now we need to bound the denominator from above + -- This will give us a lower bound on the whole expression + -- Upper bound on ‖ζ σ‖ from ZetaNear1BndExact + have ζ_σ_bound : ‖ζ σ‖ ≤ c_near / (σ - 1) := by + exact h_near σ ⟨σ_gt, σ_le⟩ + have ht_2 : 3 < |2 * t| := by simp only [abs_mul, Nat.abs_ofNat]; linarith + -- Upper bound on ‖ζ (σ + 2*t * I)‖ from ZetaUpperBnd + have σ_in_range : σ ∈ Icc (1 - A / Real.log |2 * t|) 2 := by + constructor + · -- σ ≥ 1 - A / Real.log |2*t| + have : 0 < A / Real.log |2 * t| := by + exact ZetaLowerBound3_aux1 A ha t ht_2 + nlinarith + · exact σ_le + have ζ_2t_bound := h_upper σ (2 * t) ht_2 σ_in_range + -- Combine the bounds + have denom_bound : ‖ζ σ‖ ^ ((3 : ℝ) / 4) * ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4) ≤ + (c_near / (σ - 1)) ^ ((3 : ℝ) / 4) * (C * Real.log |2 * t|) ^ ((1 : ℝ) / 4) := by + apply mul_le_mul + · apply Real.rpow_le_rpow (norm_nonneg _) ζ_σ_bound (by norm_num) + · apply ZetaLowerBound3_aux2 + convert ζ_2t_bound + norm_cast + · apply Real.rpow_nonneg (norm_nonneg _) + · apply Real.rpow_nonneg (div_nonneg (by linarith) (by linarith)) + -- Simplify the bound + have : (c_near / (σ - 1)) ^ ((3 : ℝ) / 4) * (C * Real.log |2 * t|) ^ ((1 : ℝ) / 4) = + c_near ^ ((3 : ℝ) / 4) * (σ - 1) ^ (-(3 : ℝ) / 4) * C ^ ((1 : ℝ) / 4) * (Real.log |2 * + t|) ^ ((1 : ℝ) / 4) := by + rw [Real.div_rpow (by linarith) (by linarith), Real.mul_rpow (by linarith) (Real.log_nonneg + (by linarith))] + ring_nf + exact ZetaLowerBound3_aux3 _ _ _ σ_gt + rw [this] at denom_bound + -- Take reciprocal (flipping inequality) + have pos_left : 0 < c_near ^ ((3 : ℝ) / 4) * (σ - 1) ^ (-(3 : ℝ) / 4) * C ^ ((1 : ℝ) / 4) * + (Real.log |2 * t|) ^ ((1 : ℝ) / 4) := by + apply ZetaLowerBound3_aux4 C hC c_near hc_near t ht σ_gt + have pos_right : 0 < ‖ζ σ‖ ^ ((3 : ℝ) / 4) * ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4) := by + -- This follows from ZetaLowerBound1 - if either factor were zero, we'd get 0 ≥ 1 + apply ZetaLowerBound3_aux5 _ <| ZetaLowerBound1 (t := t) σ_gt + use (div_le_div_of_nonneg_left zero_le_one pos_right denom_bound).trans' ?_ + simp_rw [abs_mul, abs_two, neg_div, Real.rpow_neg (sub_pos.2 σ_gt).le] at * + have hlog : 0 < Real.log |t| := Real.log_pos <| ht.trans' <| by norm_num + have : 0 < Real.log |t| ^ (1 / 4 : ℝ) := Real.rpow_pos_of_pos hlog _ + have hlog2 : 0 < Real.log (2 * |t|) := Real.log_pos <| ht_2.trans' <| by norm_num + have : 0 < Real.log (2 * |t|) ^ (1 / 4 : ℝ) := Real.rpow_pos_of_pos hlog2 (1 / 4) + field_simp + rw [Real.mul_rpow two_pos.le hC.le] + move_mul [C ^ (1 / 4)] + rw [mul_le_mul_iff_left₀] + swap + · positivity + rw [← Real.mul_rpow two_pos.le hlog.le] + apply Real.rpow_le_rpow hlog2.le ?_ (by norm_num) + rw [← Real.log_rpow (ht.trans' (by norm_num))] + apply Real.log_le_log (ht_2.trans' (by norm_num)) + rw [Real.rpow_two, sq] + gcongr + exact ht.trans' (by norm_num) |>.le + +/- +For all $\sigma>1$, + $$ + 1/|\zeta(\sigma+it)| \le |\zeta(\sigma)|^{3/4}|\zeta(\sigma+2it)|^{1/4} + $$ +The identity + $$ + 1 \le |\zeta(\sigma)|^3 |\zeta(\sigma+it)|^4 |\zeta(\sigma+2it)| + $$ + for $\sigma>1$ + is already proved by Michael Stoll in the EulerProducts PNT file. +-/ +lemma ZetaInvBound1 {σ t : ℝ} (σ_gt : 1 < σ) : + 1 / ‖ζ (σ + t * I)‖ ≤ ‖ζ σ‖ ^ ((3 : ℝ) / 4) * ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4) := by + apply (div_le_iff₀ ?_).mpr + · apply (Real.rpow_le_rpow_iff (z := 4) (by norm_num) ?_ (by norm_num)).mp + · simp only [Real.one_rpow] + rw [Real.mul_rpow, Real.mul_rpow, ← Real.rpow_mul, ← Real.rpow_mul] + · simp only [isUnit_iff_ne_zero, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, + IsUnit.div_mul_cancel, Real.rpow_one] + conv => rw [mul_assoc]; rhs; rhs; rw [mul_comm] + rw [← mul_assoc] + have := norm_zeta_product_ge_one (x := σ - 1) (by linarith) t + simp_rw [ge_iff_le, norm_mul, norm_pow, ofReal_sub, ofReal_one, add_sub_cancel, ← + Real.rpow_natCast] at this + convert this using 3 <;> ring_nf + any_goals ring_nf + any_goals apply norm_nonneg + any_goals apply Real.rpow_nonneg <| norm_nonneg _ + apply mul_nonneg <;> apply Real.rpow_nonneg <| norm_nonneg _ + · refine mul_nonneg (mul_nonneg ?_ ?_) ?_ <;> simp [Real.rpow_nonneg] + · have s_ne_one : σ + t * I ≠ 1 := by + contrapose! σ_gt; apply le_of_eq; apply And.left; simpa [Complex.ext_iff] using σ_gt + simpa using riemannZeta_ne_zero_of_one_le_re (by simp [σ_gt.le]) + +lemma Ioi_union_Iio_mem_cocompact {a : ℝ} (ha : 0 ≤ a) : Ioi (a : ℝ) ∪ Iio (-a : ℝ) ∈ cocompact ℝ + := by + simp only [Filter.mem_cocompact] + use Icc (-a) a + constructor + · exact isCompact_Icc + · rw [@compl_subset_iff_union, ← union_assoc, Icc_union_Ioi_eq_Ici, union_comm, Iio_union_Ici] + linarith + +lemma lt_abs_mem_cocompact {a : ℝ} (ha : 0 ≤ a) : {t | a < |t|} ∈ cocompact ℝ := by + convert Ioi_union_Iio_mem_cocompact ha using 1; ext t + simp only [mem_ofPred_eq, mem_union, mem_Ioi, mem_Iio, lt_abs, lt_neg] + +/- +For $\sigma>1$ (and $\sigma \le 2$), + $$ + 1/|\zeta(\sigma+it)| \ll (\sigma-1)^{-3/4}(\log |t|)^{1/4}, + $$ + as $|t|\to\infty$. +Combine Lemma \ref{ZetaInvBound1} with the bounds in Lemmata \ref{ZetaNear1BndExact} and + \ref{ZetaUpperBnd}. +-/ +lemma ZetaInvBound2 : + ∃ C > 0, ∀ {σ : ℝ} (_ : σ ∈ Ioc 1 2) (t : ℝ) (_ : 3 < |t|), + 1 / ‖ζ (σ + t * I)‖ ≤ C * (σ - 1) ^ (-(3 : ℝ) / 4) * (Real.log |t|) ^ ((1 : ℝ) / 4) := by + obtain ⟨A, ha, C, hC, h⟩ := ZetaUpperBnd + obtain ⟨c, hc, h_inv⟩ := ZetaNear1BndExact + refine ⟨(2 * C) ^ ((1 : ℝ)/ 4) * c ^ ((3 : ℝ)/ 4), by positivity, ?_⟩ + intro σ hσ t t_gt + obtain ⟨σ_gt, σ_le⟩ := hσ + have ht' : 3 < |2 * t| := by simp only [abs_mul, Nat.abs_ofNat]; linarith + have hnezero: ((σ - 1) / c) ^ (-3 / 4 : ℝ) ≠ 0 := by + have : (σ - 1) / c ≠ 0 := ne_of_gt <| div_pos (by linarith) hc + contrapose! this + rwa [Real.rpow_eq_zero (div_nonneg (by linarith) hc.le) (by norm_num)] at this + calc + _ ≤ ‖‖ζ σ‖ ^ (3 / 4 : ℝ) * ‖ζ (↑σ + 2 * ↑t * I)‖ ^ (1 / 4 : ℝ)‖ := ?_ + _ ≤ ‖((σ - 1) / c) ^ (-3 / 4 : ℝ) * ‖ζ (↑σ + 2 * ↑t * I)‖ ^ (1 / 4 : ℝ)‖ := ?_ + _ ≤ ‖((σ - 1) / c) ^ (-3 / 4 : ℝ) * C ^ (1 / 4 : ℝ) * (Real.log |2 * t|) ^ (1 / 4 : ℝ)‖ := ?_ + _ ≤ ‖((σ - 1) / c) ^ (-3 / 4 : ℝ) * C ^ (1 / 4 : ℝ) * (Real.log (|t| ^ 2)) ^ (1 / 4 : ℝ)‖ := ?_ + _ = ‖((σ - 1)) ^ (-3 / 4 : ℝ) * c ^ (3 / 4 : ℝ) * (C ^ (1 / 4 : ℝ) * (Real.log (|t| ^ 2)) ^ (1 + / 4 : ℝ))‖ := ?_ + _ = ‖((σ - 1)) ^ (-3 / 4 : ℝ) * c ^ (3 / 4 : ℝ) * ((2 * C) ^ (1 / 4 : ℝ) * Real.log |t| ^ (1 / + 4 : ℝ))‖ := ?_ + _ = _ := ?_ + · simp only [norm_mul] + convert ZetaInvBound1 σ_gt using 2 + <;> exact abs_eq_self.mpr <| Real.rpow_nonneg (norm_nonneg _) _ + · have bnd1: ‖ζ σ‖ ^ (3 / 4 : ℝ) ≤ ((σ - 1) / c) ^ (-(3 : ℝ) / 4) := by + have : ((σ - 1) / c) ^ (-(3 : ℝ) / 4) = (((σ - 1) / c) ^ (-1 : ℝ)) ^ (3 / 4 : ℝ) := by + rw [← Real.rpow_mul ?_] + · ring_nf + · exact div_nonneg (by linarith) hc.le + rw [this] + apply Real.rpow_le_rpow (by simp [norm_nonneg]) ?_ (by norm_num) + convert! h_inv σ ⟨σ_gt, σ_le⟩ using 1; simp [Real.rpow_neg_one, inv_div] + simp only [norm_mul] + apply (mul_le_mul_iff_left₀ ?_).mpr + · convert! bnd1 using 1 + · exact abs_eq_self.mpr <| Real.rpow_nonneg (norm_nonneg _) _ + · exact abs_eq_self.mpr <| Real.rpow_nonneg (div_nonneg (by linarith) hc.le) _ + · apply lt_iff_le_and_ne.mpr ⟨(by simp), ?_⟩ + have : ζ (↑σ + 2 * ↑t * I) ≠ 0 := by + apply riemannZeta_ne_zero_of_one_le_re (by simp [σ_gt.le]) + symm; exact fun h2 ↦ this (by simpa using h2) + · replace h := h σ (2 * t) (by simpa using ht') ⟨?_, σ_le⟩ + · have : 0 ≤ Real.log |2 * t| := Real.log_nonneg (by linarith) + conv => rhs; rw [mul_assoc, ← Real.mul_rpow hC.le this] + rw [norm_mul, norm_mul] + conv => rhs; rhs; rw [Real.norm_rpow_of_nonneg <| mul_nonneg hC.le this] + conv => lhs; rhs; rw [Real.norm_rpow_of_nonneg <| norm_nonneg _] + apply (mul_le_mul_iff_right₀ ?_).mpr + · apply Real.rpow_le_rpow (norm_nonneg _) ?_ (by norm_num) + convert h using 1 + · simp + · rw [Real.norm_eq_abs, abs_eq_self.mpr <| mul_nonneg hC.le this] + · simpa only [Real.norm_eq_abs, abs_pos] + · linarith [(div_nonneg ha.1.le (Real.log_nonneg (by linarith)) : 0 ≤ A / Real.log |2 * t|)] + · simp only [Real.log_abs, norm_mul] + apply (mul_le_mul_iff_right₀ ?_).mpr + · rw [← Real.log_abs, Real.norm_rpow_of_nonneg <| Real.log_nonneg (by linarith)] + have : 1 ≤ |(|t| ^ 2)| := by + simp only [_root_.sq_abs, _root_.abs_pow, one_le_sq_iff_one_le_abs] + linarith + conv => rhs; rw [← Real.log_abs, Real.norm_rpow_of_nonneg <| Real.log_nonneg this] + apply Real.rpow_le_rpow (abs_nonneg _) ?_ (by norm_num) + · rw [Real.norm_eq_abs, abs_eq_self.mpr <| Real.log_nonneg (by linarith)] + rw [abs_eq_self.mpr <| Real.log_nonneg this, abs_mul, Real.log_abs, Nat.abs_ofNat] + apply Real.log_le_log (mul_pos (by norm_num) (by linarith)) (by nlinarith) + · apply mul_pos (abs_pos.mpr hnezero) (abs_pos.mpr ?_) + have : C ≠ 0 := ne_of_gt hC + contrapose! this; rwa [Real.rpow_eq_zero (by linarith) (by norm_num)] at this + · have : (-3 : ℝ) / 4 = -((3 : ℝ)/ 4) := by norm_num + simp only [norm_mul, mul_eq_mul_right_iff, this, ← mul_assoc]; left; left + conv => lhs; rw [Real.div_rpow (by linarith) hc.le, Real.rpow_neg hc.le, div_inv_eq_mul, + norm_mul] + · simp only [Real.log_pow, Nat.cast_ofNat, norm_mul, Real.norm_eq_abs] + congr! 1 + rw [Real.mul_rpow (by norm_num) hC.le, Real.mul_rpow (by norm_num) <| + Real.log_nonneg (by linarith), abs_mul, abs_mul, ← mul_assoc, mul_comm _ |2 ^ (1 / 4)|] + · simp only [norm_mul, Real.norm_eq_abs] + have : (2 * C) ^ ((1 : ℝ)/ 4) * c ^ ((3 : ℝ)/ 4) = + |(2 * C) ^ ((1 : ℝ)/ 4) * c ^ ((3 : ℝ)/ 4)| := by + rw [abs_eq_self.mpr (by apply mul_nonneg <;> (apply Real.rpow_nonneg; linarith))] + rw [this, abs_mul, abs_eq_self.mpr (by apply Real.rpow_nonneg; linarith), abs_eq_self.mpr (by + positivity), + abs_eq_self.mpr (by positivity), abs_eq_self.mpr (by apply Real.rpow_nonneg (Real.log_nonneg + (by linarith)))] + ring_nf + +lemma deriv_fun_re {t : ℝ} {f : ℂ → ℂ} (diff : ∀ (σ : ℝ), DifferentiableAt ℂ f (↑σ + ↑t * I)) : + (deriv fun {σ₂ : ℝ} ↦ f (σ₂ + t * I)) = fun (σ : ℝ) ↦ deriv f (σ + t * I) := by + ext σ + have := deriv_comp (h := fun (σ : ℝ) ↦ σ + t * I) (h₂ := f) σ (diff σ) ?_ + · simp only [deriv_add_const', MooreBound.deriv_ofReal, mul_one] at this + exact this + · apply DifferentiableAt.add_const _ <| differentiableAt_ofReal σ + +/- +For any $t\ne0$ (so we don't pass through the pole), and $\sigma_1 < \sigma_2$, + $$ + \int_{\sigma_1}^{\sigma_2}\zeta'(\sigma + it) dt = + \zeta(\sigma_2+it) - \zeta(\sigma_1+it). + $$ +This is the fundamental theorem of calculus. +-/ +lemma Zeta_eq_int_derivZeta {σ₁ σ₂ t : ℝ} (t_ne_zero : t ≠ 0) : + (∫ σ in σ₁..σ₂, ζ' (σ + t * I)) = ζ (σ₂ + t * I) - ζ (σ₁ + t * I) := by + have diff : ∀ (σ : ℝ), DifferentiableAt ℂ ζ (σ + t * I) := by + intro σ + refine differentiableAt_riemannZeta ?_ + contrapose! t_ne_zero; apply And.right; simpa [Complex.ext_iff] using t_ne_zero + apply intervalIntegral.integral_deriv_eq_sub' + · exact deriv_fun_re diff + · intro s _ + apply DifferentiableAt.comp + · exact (diff s).restrictScalars ℝ + · exact DifferentiableAt.add_const (c := t * I) <| differentiableAt_ofReal _ + · apply ContinuousOn.comp (g := ζ') ?_ ?_ (mapsTo_image _ _) + · apply HasDerivAt.continuousOn (f' := deriv <| ζ') + intro x hx + apply hasDerivAt_deriv_iff.mpr + replace hx : x ≠ 1 := by + contrapose! hx + simp only [hx, mem_image, Complex.ext_iff, add_re, ofReal_re, mul_re, I_re, mul_zero, + ofReal_im, + I_im, mul_one, sub_self, add_zero, one_re, add_im, mul_im, zero_add, one_im, not_exists, + not_and] + exact fun _ _ _ ↦ t_ne_zero + exact differentiableAt_deriv_riemannZeta hx + · exact continuous_ofReal.continuousOn.add continuousOn_const + +/- +For any $A>0$ sufficiently small, there is a constant $C>0$ so that + whenever $1- A / \log t \le \sigma_1 < \sigma_2\le 2$ and $3 < |t|$, we have that: + $$ + |\zeta (\sigma_2 + it) - \zeta (\sigma_1 + it)| + \le C (\log |t|)^2 (\sigma_2 - \sigma_1). + $$ +Use Lemma \ref{Zeta_eq_int_derivZeta} and + estimate trivially using Lemma \ref{ZetaDerivUpperBnd}. +-/ +lemma Zeta_diff_Bnd : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (C : ℝ) (_ : 0 < C), ∀ (σ₁ σ₂ : ℝ) (t : ℝ) (_ : 3 < |t|) + (_ : 1 - A / Real.log |t| ≤ σ₁) (_ : σ₂ ≤ 2) (_ : σ₁ < σ₂), + ‖ζ (σ₂ + t * I) - ζ (σ₁ + t * I)‖ ≤ C * Real.log |t| ^ 2 * (σ₂ - σ₁) := by + obtain ⟨A, hA, C, Cpos, hC⟩ := ZetaDerivUpperBnd + refine ⟨A, hA, C, Cpos, ?_⟩ + intro σ₁ σ₂ t t_gt σ₁_ge σ₂_le σ₁_lt_σ₂ + have t_ne_zero : t ≠ 0 := by contrapose! t_gt; simp only [t_gt, abs_zero, Nat.ofNat_nonneg] + rw [← Zeta_eq_int_derivZeta t_ne_zero] + convert intervalIntegral.norm_integral_le_of_norm_le_const ?_ using 1 + · congr; rw [_root_.abs_of_nonneg (by linarith)] + · intro σ hσ; rw [uIoc_of_le σ₁_lt_σ₂.le, mem_Ioc] at hσ + exact hC σ t t_gt ⟨le_trans σ₁_ge hσ.1.le, le_trans hσ.2 σ₂_le⟩ + +lemma ZetaInvBnd_aux' {t : ℝ} (logt_gt_one : 1 < Real.log |t|) : Real.log |t| < Real.log |t| ^ (9 + : ℝ) := by + nth_rewrite 1 [← Real.rpow_one <| Real.log |t|] + exact mod_cast Real.rpow_lt_rpow_left_iff (y := 1) (z := 9) logt_gt_one |>.mpr (by norm_num) + +lemma ZetaInvBnd_aux {t : ℝ} (logt_gt_one : 1 < Real.log |t|) : Real.log |t| ≤ Real.log |t| ^ (9 : + ℝ) := + ZetaInvBnd_aux' logt_gt_one |>.le + +lemma ZetaInvBnd_aux2 {A C₁ C₂ : ℝ} (Apos : 0 < A) (C₁pos : 0 < C₁) (C₂pos : 0 < C₂) + (hA : A ≤ 1 / 2 * (C₁ / (C₂ * 2)) ^ (4 : ℝ)) : + 0 < (C₁ * A ^ (3 / 4 : ℝ) - C₂ * 2 * A)⁻¹ := by + simp only [inv_pos, sub_pos] + apply div_lt_iff₀ (by positivity) |>.mp + rw [div_eq_mul_inv, ← Real.rpow_neg (by positivity), mul_assoc] + apply lt_div_iff₀' (by positivity) |>.mp + nth_rewrite 1 [← Real.rpow_one A] + rw [← Real.rpow_add (by positivity)] + norm_num + apply Real.rpow_lt_rpow_iff (z := 4) (by positivity) (by positivity) (by positivity) |>.mp + rw [← Real.rpow_mul (by positivity)] + norm_num + apply lt_of_le_of_lt hA + rw [div_mul_comm, mul_one, Real.rpow_ofNat] + apply half_lt_self + positivity + + +/- +For any $A>0$ sufficiently small, there is a constant $C>0$ so that + whenever $1- A / \log^9 |t| \le \sigma < 1+A/\log^9 |t|$ and $3 < |t|$, we have that: + $$ + 1/|\zeta(\sigma+it)| \le C \log^7 |t|. + $$ +Let $\sigma$ be given in the prescribed range, and set $\sigma' := 1+ A / \log^9 |t|$. + Then + $$ + |\zeta(\sigma+it)| \ge + |\zeta(\sigma'+it)| - |\zeta(\sigma+it) - \zeta(\sigma'+it)| + \ge + C (\sigma'-1)^{3/4}\log |t|^{-1/4} - C \log^2 |t| (\sigma'-\sigma) + $$ + $$ + \ge + C A^{3/4} \log |t|^{-7} - C \log^2 |t| (2 A / \log^9 |t|), + $$ + where we used Lemma \ref{ZetaInvBound2} and Lemma \ref{Zeta_diff_Bnd}. + Now by making $A$ sufficiently small (in particular, something like $A = 1/16$ should work), we + can guarantee that + $$ + |\zeta(\sigma+it)| \ge \frac C 2 (\log |t|)^{-7}, + $$ + as desired. +-/ +lemma ZetaInvBnd : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (C : ℝ) (_ : 0 < C), ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Ico (1 - A / (Real.log |t|) ^ (9 : ℝ)) (1 + A / (Real.log |t|) ^ (9 : ℝ))), + 1 / ‖ζ (σ + t * I)‖ ≤ C * (Real.log |t|) ^ (7 : ℝ) := by + obtain ⟨C', C'pos, hC₁⟩ := ZetaInvBound2 + obtain ⟨A', hA', C₂, C₂pos, hC₂⟩ := Zeta_diff_Bnd + set C₁ := 1 / C' + let A := min A' <| (1 / 2 : ℝ) * (C₁ / (C₂ * 2)) ^ (4 : ℝ) + have Apos : 0 < A := by have := hA'.1; positivity + have Ale : A ≤ 1 / 2 := by dsimp only [A]; apply min_le_iff.mpr; left; exact hA'.2 + set C := (C₁ * A ^ (3 / 4 : ℝ) - C₂ * 2 * A)⁻¹ + have Cpos : 0 < C := by + refine ZetaInvBnd_aux2 (by positivity) (by positivity) (by positivity) ?_ + apply min_le_right + refine ⟨A, ⟨Apos, by linarith [hA'.2]⟩ , C, Cpos, ?_⟩ + intro σ t t_gt hσ + have logt_gt_one := logt_gt_one t_gt.le + have σ_ge : 1 - A / Real.log |t| ≤ σ := by + apply le_trans ?_ hσ.1 + suffices A / Real.log |t| ^ (9 : ℝ) ≤ A / Real.log |t| by linarith + exact div_le_div₀ Apos.le (by rfl) (by positivity) <| ZetaInvBnd_aux logt_gt_one + obtain ⟨_, _, neOne⟩ := UpperBnd_aux ⟨Apos, Ale⟩ t_gt σ_ge + set σ' := 1 + A / Real.log |t| ^ (9 : ℝ) + have σ'_gt : 1 < σ' := by simp only [σ', lt_add_iff_pos_right]; positivity + have σ'_le : σ' ≤ 2 := by + simp only [σ'] + suffices A / Real.log |t| ^ (9 : ℝ) < 1 by linarith + apply div_lt_one (by positivity) |>.mpr + exact lt_trans₄ (by linarith) logt_gt_one <| ZetaInvBnd_aux' logt_gt_one + set s := σ + t * I + set s' := σ' + t * I + by_cases h0 : ‖ζ s‖ ≠ 0 + swap + · simp only [ne_eq, not_not] at h0; simp only [h0, div_zero]; positivity + apply div_le_iff₀ (by positivity) |>.mpr <| div_le_iff₀' (by positivity) |>.mp ?_ + have pos_aux : 0 < (σ' - 1) := by linarith + calc + _ ≥ ‖ζ s'‖ - ‖ζ s - ζ s'‖ := ?_ + _ ≥ C₁ * (σ' - 1) ^ ((3 : ℝ)/ 4) * Real.log |t| ^ ((-1 : ℝ)/ 4) - C₂ * Real.log |t| ^ 2 * (σ' + - σ) := ?_ + _ ≥ C₁ * (A / Real.log |t| ^ (9 : ℝ)) ^ ((3 : ℝ)/ 4) * Real.log |t| ^ ((-1 : ℝ)/ 4) - C₂ * + Real.log |t| ^ (2 : ℝ) * 2 * A / Real.log |t| ^ (9 : ℝ) := ?_ + _ ≥ C₁ * A ^ ((3 : ℝ)/ 4) * Real.log |t| ^ (-7 : ℝ) - C₂ * 2 * A * Real.log |t| ^ (-7 : ℝ) := ?_ + _ = (C₁ * A ^ ((3 : ℝ)/ 4) - C₂ * 2 * A) * Real.log |t| ^ (-7 : ℝ) := by ring + _ ≥ _ := ?_ + · apply ge_iff_le.mpr + convert norm_sub_norm_le (a := ζ s') (b := ζ s' - ζ s) using 1 + · rw [(by simp : ζ s' - ζ s = -(ζ s - ζ s'))]; simp only [norm_neg] + · simp + · apply sub_le_sub + · have := one_div_le ?_ (by positivity) |>.mp <| hC₁ ⟨σ'_gt, σ'_le⟩ t t_gt + · convert this using 1 + rw [one_div, mul_inv_rev, mul_comm, mul_inv_rev, mul_comm _ C'⁻¹] + simp only [one_div C', C₁] + congr <;> (rw [← Real.rpow_neg (by linarith), neg_div]); rw [neg_neg] + · apply norm_pos_iff.mpr <| riemannZeta_ne_zero_of_one_lt_re (by simp [σ'_gt]) + · rw [(by simp : ζ s - ζ s' = -(ζ s' - ζ s)), norm_neg] + refine hC₂ σ σ' t t_gt ?_ σ'_le <| by rw [Set.mem_Ico] at hσ; exact hσ.2 + apply le_trans ?_ hσ.1 + rw [tsub_le_iff_right, ← add_sub_right_comm, le_sub_iff_add_le, add_le_add_iff_left] + exact div_le_div₀ hA'.1.le (by simp [A]) (by positivity) <| ZetaInvBnd_aux logt_gt_one + · apply sub_le_sub (by simp only [add_sub_cancel_left, σ']; exact_mod_cast le_rfl) ?_ + rw [mul_div_assoc, mul_assoc _ 2 _] + apply mul_le_mul (by exact_mod_cast le_rfl) ?_ (by linarith [hσ.2]) (by positivity) + suffices h : σ' + (1 - A / Real.log |t| ^ (9 : ℝ)) ≤ (1 + A / Real.log |t| ^ (9 : ℝ)) + σ by + simp only [tsub_le_iff_right] + convert! le_sub_right_of_add_le h using 1; ring_nf + exact add_le_add (by linarith) (by linarith [hσ.1]) + · simp_rw [tsub_le_iff_right, div_eq_mul_inv _ (Real.log |t| ^ (9 : ℝ))] + rw [← Real.rpow_neg (by positivity), Real.mul_rpow (by positivity) (by positivity)] + rw [← Real.rpow_mul (by positivity)] + ring_nf + conv => rhs; lhs; rw [mul_assoc, ← Real.rpow_add (by positivity)] + rw [(by ring : C₂ * Real.log |t| ^ (2 : ℝ) * A * Real.log |t| ^ (-9 : ℝ) * 2 = C₂ * (Real.log + |t| ^ (2 : ℝ) * Real.log |t| ^ (-9 : ℝ) ) * A * 2)] + rw [← Real.rpow_add (by positivity)]; norm_num; group; exact le_rfl + · apply div_le_iff₀ (by positivity) |>.mpr + conv => rw [mul_assoc]; rhs; rhs; rw [mul_comm C, ← mul_assoc, ← Real.rpow_add (by positivity)] + have := inv_inv C ▸ mul_inv_cancel₀ (a := C⁻¹) (by positivity) |>.symm.le + simpa [C] using this + + + +-- **Another AlphaProof collaboration (thanks to Thomas Hubert!)** + +/- +Annoyingly, it is not immediate from this that $\zeta$ doesn't vanish there! That's because +$1/0 = 0$ in Lean. So we give a second proof of the same fact (refactor this later), with a lower + bound on $\zeta$ instead of upper bound on $1 / \zeta$. +-/ +/- +For any $A>0$ sufficiently small, there is a constant $C>0$ so that + whenever $1- A / \log^9 |t| \le \sigma < 1$ and $3 < |t|$, we have that: + $$ + |\zeta(\sigma+it)| \ge C \log^7 |t|. + $$ +Follow same argument. +-/ +lemma ZetaLowerBnd : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (c : ℝ) (_ : 0 < c), + ∀ (σ : ℝ) + (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Ico (1 - A / (Real.log |t|) ^ (9 : ℝ)) 1), + c / (Real.log |t|) ^ (7 : ℝ) ≤ ‖ζ (σ + t * I)‖ := by + obtain ⟨C₁, C₁pos, hC₁⟩ := ZetaLowerBound3 + obtain ⟨A', hA', C₂, C₂pos, hC₂⟩ := Zeta_diff_Bnd + -- Pick the right constants. + -- Don't really like this because I can only do that after first finishing the proof. + -- Is there a way to delay picking those + let A := min A' ((C₁ / (4 * C₂)) ^ 4) + have hA : A ∈ Ioc 0 (1 / 2) := + ⟨lt_min hA'.1 (by positivity), (min_le_left A' _).trans hA'.2⟩ + let C := C₁ * A ^ ((3:ℝ) /4) - 2 * C₂ * A + have hc_pos : 0 < C := by + have:= A.rpow_le_rpow hA.1.le (min_le_right _ _) (inv_pos.mpr four_pos).le + erw [Real.pow_rpow_inv_natCast (div_pos C₁pos (mul_pos four_pos C₂pos)).le four_ne_zero, + le_div_iff₀ (mul_pos four_pos C₂pos)] at this + norm_num [mul_assoc, C, mul_left_comm, C₂pos, hA.1, + (mul_le_mul_of_nonneg_right this (A.rpow_nonneg hA.1.le _)).trans_lt', ←A.rpow_add] + refine ⟨A, hA, C, hc_pos, fun σ t L ⟨σ_low_bound, σ_le_one⟩=>?_⟩ + -- From here I followed the proof found in the blueprint + let σ' := 1 + A / Real.log |t| ^ (9 : ℝ) + have triangular : ‖ζ (σ + t * I)‖ ≥ ‖ζ (σ' + t * I)‖ - ‖ζ (σ + t * I) - ζ (σ' + t * I)‖ := by + apply sub_le_iff_le_add.mpr.comp (sub_sub_self @_ (@_ : ℂ)▸norm_sub_le _ _).trans + (by rw [add_comm]) + have one_leLogT : 1 ≤ Real.log |t| := (logt_gt_one L.le).le + have one_half_le_log_pow : 1 / 2 ≤ Real.log |t| ^ 9 := + one_half_lt_one.le.trans <| one_le_pow₀ one_leLogT + have σ'_ge : 1 ≤ σ' := by + simp_all only [gt_iff_lt, mem_Ioc, Real.log_abs, one_div, and_imp, tsub_le_iff_right, + lt_inf_iff, div_pos_iff_of_pos_left, Nat.ofNat_pos, mul_pos_iff_of_pos_left, pow_pos, + and_self, inf_le_iff, true_or, sub_pos, mem_Ico, and_true, ofReal_add, ofReal_one, + ofReal_div, ge_iff_le, le_add_iff_nonneg_right, A, C, σ'] + apply div_nonneg + · apply le_min + · linarith + · have : (C₁ / (4 * C₂)) ^ 4 = ((C₁ / (4 * C₂)) ^ 2) ^ 2 := by ring + rw [this] + apply sq_nonneg + · positivity + have right_sub : -‖ζ (σ + t * I) - ζ (σ' + t * I)‖ ≥ - C₂ * Real.log |t| ^ 2 * (σ' - σ) := by + change - C₂ * Real.log |t| ^ 2 * (σ' - σ) ≤ -‖ζ (σ + t * I) - ζ (σ' + t * I)‖ + have := hC₂ σ σ' t L ?_ ?_ ?_ + · convert! neg_le_neg this using 1 + · ring + · congr! 1 + have : ζ (↑σ + ↑t * I) - ζ (↑σ' + ↑t * I) = + - (ζ (↑σ' + ↑t * I) - ζ (↑σ + ↑t * I)) := by ring + rw [this, norm_neg] + · have : 1 - A' / Real.log |t| ≤ (1 : ℝ) - A / (Real.log |t|) ^ (9 : ℝ) := by + gcongr + · exact hA'.1.le + · bound + · rw [← Real.rpow_one (Real.log |t|), ← Real.rpow_mul (by linarith), one_mul] + exact Real.rpow_le_rpow_of_exponent_le one_leLogT Nat.one_le_ofNat + linarith + · have : σ' ≤ 1 + A := by + simp_all only [gt_iff_lt, mem_Ioc, Real.log_abs, one_div, and_imp, tsub_le_iff_right, + lt_inf_iff, div_pos_iff_of_pos_left, Nat.ofNat_pos, mul_pos_iff_of_pos_left, pow_pos, + and_self, inf_le_iff, true_or, sub_pos, mem_Ico, and_true, ofReal_add, ofReal_one, + ofReal_div, ge_iff_le, le_add_iff_nonneg_right, add_le_add_iff_left, le_inf_iff, + σ', A, C] + have : 1 ≤ Real.log t ^ (9 : ℝ) := Real.one_le_rpow one_leLogT (Nat.ofNat_nonneg' 9) + refine ⟨?_, ?_⟩ + · rw [← min_div_div_right] + · rw [min_le_iff] + left + bound + · exact le_trans (zero_le_one) this + · rw [← min_div_div_right] + · rw [min_le_iff] + right + bound + · exact le_trans (zero_le_one) this + · bound [hA.2] + · linarith + have right' : -‖ζ (σ + t * I) - ζ (σ' + t * I)‖ ≥ - C₂ * 2 * A / Real.log |t| ^ 7 := by + have := (abs t).log_pos (by bound) + refine right_sub.trans' ((div_le_iff₀ (pow_pos this 7)).2 @?_|>.trans + (mul_le_mul_of_nonpos_left (sub_le_sub_left σ_low_bound (1+_) ) + (by ·linear_combination C₂*this*(.log |t|)))) + exact (mod_cast (by linear_combination (2 *_* A) *div_self ↑(pow_pos this 09).ne')) + have left_sub : ‖ζ (σ' + t * I)‖ ≥ C₁ * (σ' - 1) ^ ((3:ℝ) /4) / Real.log |t| ^ 4 := by + use (hC₁ ⟨lt_add_of_pos_right (1) (by bound[hA.1]), + add_le_of_le_sub_left ((div_le_iff₀ (by bound)).2 (hA.2.trans (?_)))⟩ t L).trans' ?_ + · norm_num only [one_mul, Real.rpow_ofNat, one_half_le_log_pow] + · simp_all only [gt_iff_lt, mem_Ioc, lt_inf_iff, div_pos_iff_of_pos_left, Nat.ofNat_pos, + mul_pos_iff_of_pos_left, pow_pos, and_self, inf_le_iff, true_or, sub_pos, mem_Ico, + ofReal_add, ofReal_one, ofReal_div, ge_iff_le, le_add_iff_nonneg_right, neg_mul, + neg_le_neg_iff, add_sub_cancel_left, σ', A, C] + gcongr + have : Real.log |t| ^ ((1 : ℝ) / 4) ≤ Real.log |t| ^ (4 : ℝ) := + Real.rpow_le_rpow_of_exponent_le one_leLogT (by norm_num) + exact_mod_cast this + have left' : ‖ζ (σ' + t * I)‖ ≥ C₁ * A ^ ((3:ℝ) /4) / Real.log |t| ^ 7 := by + contrapose! hC₁ + use σ', ⟨lt_add_of_pos_right 1<|by bound[hA'.1], + add_le_of_le_sub_left ((div_le_iff₀ (by bound)).2 (hA.2.trans ?_))⟩, t, L, hC₁.trans_le ?_ + · norm_num only [one_mul, Real.rpow_ofNat, one_half_le_log_pow] + · norm_num only [σ', add_sub_cancel_left, A.div_rpow hA.1.le, mul_div, pow_pos, L.trans', + ←Real.rpow_natCast, ←Real.rpow_mul, le_of_lt, Real.log_pos, refl, div_div, ←Real.rpow_sub] + rw [Real.div_rpow hA.1.le, ← Real.rpow_mul (by linarith), ← mul_div_assoc, div_div, ← + Real.rpow_add (by linarith)] + · norm_num + · apply Real.rpow_nonneg (by linarith) + have ineq : ‖ζ (σ + t * I)‖ ≥ (C₁ * A ^ ((3:ℝ) /4) - C₂ * 2 * A) / Real.log |t| ^ 7 := by + linear_combination left'+triangular+right' + rw [mul_comm C₂] at ineq + exact_mod_cast ineq + +-- **End collaboration 6/20/25** + +/- +Now we get a zero free region. +-/ +/-- A zero-free region of width a constant times `log |t|` to the power `-n`. -/ +def ZetaZeroFreeGenProp (n : ℝ) : Prop := ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)), + ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) (_ : σ ∈ Ico (1 - A / (Real.log |t|) ^ n) 1), + ζ (σ + t * I) ≠ 0 + +/- +There is an $A>0$ so that for $1-A/\log^9 |t| \le \sigma < 1$ and $3 < |t|$, + $$ + \zeta(\sigma+it) \ne 0. + $$ +Apply Lemma \ref{ZetaLowerBnd}. +-/ +lemma ZetaZeroFree9 : ZetaZeroFreeGenProp 9 := by + obtain ⟨A, hA, c, hc, h_lower⟩ := ZetaLowerBnd + -- Use the same A for our result + refine ⟨A, hA, ?_⟩ + -- Now prove that ζ has no zeros in this region + intro σ t ht hσ h_zero + have := h_lower σ t ht hσ + rw [h_zero, norm_zero] at this + have pos_bound : 0 < c / (Real.log |t|) ^ (7 : ℝ) := by + apply div_pos hc + apply Real.rpow_pos_of_pos + apply Real.log_pos + linarith + linarith + + +/- +There is an $A>0$ so that for $1-A/\log^9 |t| \le \sigma < 1+A/\log^9 |t|$ and $3 < |t|$, + $$ + |\frac {\zeta'}{\zeta} (\sigma+it)| \ll \log^9 |t|. + $$ +Combine the bound on $|\zeta'|$ from Lemma \ref{ZetaDerivUpperBnd} with the + bound on $1/|\zeta|$ from Lemma \ref{ZetaInvBnd}. +-/ +lemma LogDerivZetaBnd : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (C : ℝ) (_ : 0 < C), ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Ico (1 - A / Real.log |t| ^ (9 : ℝ)) (1 + A / Real.log |t| ^ (9 : ℝ))), + ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ ≤ C * Real.log |t| ^ (9 : ℝ) := by + obtain ⟨A, hA, C, hC, h⟩ := ZetaInvBnd + obtain ⟨A', hA', C', hC', h'⟩ := ZetaDerivUpperBnd + use min A A', ⟨lt_min hA.1 hA'.1, min_le_of_right_le hA'.2⟩, C * C', mul_pos hC hC' + intro σ t t_gt ⟨σ_ge, σ_lt⟩ + have logt_gt : (1 : ℝ) < Real.log |t| := logt_gt_one t_gt.le + have σ_ge' : 1 - A / Real.log |t| ^ (9 : ℝ) ≤ σ := by + apply le_trans (tsub_le_tsub_left ?_ 1) σ_ge + apply div_le_div_of_nonneg_right (min_le_left A A') + apply Real.rpow_nonneg + linarith + have σ_ge'' : 1 - A' / Real.log |t| ≤ σ := by + apply le_trans (tsub_le_tsub_left ?_ 1) σ_ge + apply div_le_div₀ hA'.1.le (min_le_right A A') (lt_trans (by norm_num) logt_gt) ?_ + rw [← Real.rpow_one (Real.log |t|), ← Real.rpow_mul (by linarith), one_mul] + exact Real.rpow_le_rpow_of_exponent_le logt_gt.le Nat.one_le_ofNat + replace h := h σ t t_gt ⟨σ_ge', by calc + σ < 1 + min A A' / Real.log |t| ^ (9 : ℝ) := σ_lt + _ ≤ 1 + A / Real.log |t| ^ (9 : ℝ) := by gcongr; simp⟩ + replace h' := h' σ t t_gt ⟨σ_ge'', by + calc + σ ≤ 1 + min A A' / Real.log |t| ^ (9 : ℝ) := by linarith [σ_lt] + _ ≤ 1 + (1/2) / Real.log |t| ^ (9 : ℝ) := by gcongr; simp [Set.mem_Ioc] at hA' hA ⊢ ; simp + [hA.2] + _ ≤ 1 + (1/2) / 1 := by + gcongr + calc + 1 ≤ Real.log |t| := by linarith + _ ≤ (Real.log |t|) ^ (9 : ℝ) := Real.self_le_rpow_of_one_le (by linarith) (by linarith) + _ ≤ 2 := by linarith + ⟩ + simp only [norm_div] + convert! mul_le_mul h h' (by simp) ?_ using 1 <;> (norm_cast; ring_nf); positivity + + + + +/-% ** Bad delimiters on purpose ** +Annoying: we have reciprocals of $log |t|$ in the bounds, and we've assumed that $|t|>3$; but we +want to make things uniform in $t$. Let's change to things like $log (|t|+3)$ instead of $log |t|$. +\begin{lemma}[LogLeLog]\label{LogLeLog}\lean{LogLeLog}\leanok +There is a constant $C>0$ so that for all $t>3$, +$$ +1/\log t \le C / \log (t + 3). +$$ +\end{lemma} +%-/ +/-% +\begin{proof} +Write +$$ +\log (t + 3) = \log t + \log (1 + 3/t) = \log t + O(1/t). +$$ +Then we can bound $1/\log t$ by $C / \log (t + 3)$ for some constant $C>0$. +\end{proof} +%-/ + +/- +The zeta function does not vanish on the 1-line. +This fact is already proved in Stoll's work. +-/ +lemma ZetaNoZerosOn1Line (t : ℝ) : ζ (1 + t * I) ≠ 0 := by + refine riemannZeta_ne_zero_of_one_le_re ?_ + simp + +-- **Begin collaboration with the Alpha Proof team! 5/29/25** + +lemma ZetaCont : ContinuousOn ζ (univ \ {1}) := by + apply continuousOn_of_forall_continuousAt (fun x hx ↦ ?_) + apply DifferentiableAt.continuousAt (𝕜 := ℂ) + convert differentiableAt_riemannZeta ?_ + simp only [Set.mem_sdiff, mem_univ, mem_singleton_iff, true_and] at hx + exact hx + +/- +Then, since $\zeta$ doesn't vanish on the 1-line, there is a $\sigma<1$ (depending on $T$), so that +the box $[\sigma,1] \times_{ℂ} [-T,T]$ is free of zeros of $\zeta$. +-/ + +/- +For any $T>0$, there is a constant $\sigma<1$ so that + $$ + \zeta(\sigma'+it) \ne 0 + $$ + for all $|t| \leq T$ and $\sigma' \ge \sigma$. +Assume not. Then there is a sequence $|t_n| \le T$ and $\sigma_n \to 1$ so that + $\zeta(\sigma_n + it_n) = 0$. + By compactness, there is a subsequence $t_{n_k} \to t_0$ along which + $\zeta(\sigma_{n_k} + it_{n_k}) = 0$. + If $t_0\ne0$, use the continuity of $\zeta$ to get that $\zeta(1 + it_0) = 0$; + this is a contradiction. + If $t_0=0$, $\zeta$ blows up near $1$, so can't be zero nearby. +-/ +lemma ZetaNoZerosInBox (T : ℝ) : + ∃ (σ : ℝ) (_ : σ < 1), ∀ (t : ℝ) (_ : |t| ≤ T) + (σ' : ℝ) (_ : σ' ≥ σ), ζ (σ' + t * I) ≠ 0 := by + by_contra! h + have hn (n : ℕ) := h (1 - 1 / (n + 1)) (sub_lt_self _ (by positivity)) + have : ∃ (tn : ℕ → ℝ) (σn : ℕ → ℝ), (∀ n, σn n ≤ 1) ∧ + (∀ n, (1 : ℝ) - 1 / (n + 1) ≤ σn n) ∧ (∀ n, |tn n| ≤ T) ∧ + (∀ n, ζ (σn n + tn n * I) = 0) := by + choose t ht σ' hσ' hζ using hn + refine ⟨t, σ', ?_, hσ', ht, hζ⟩ + intro n + by_contra! hσn + have := riemannZeta_ne_zero_of_one_lt_re (s := σ' n + t n * I) + simp only [add_re, ofReal_re, mul_re, I_re, mul_zero, ofReal_im, I_im, mul_one, sub_self, + add_zero, ne_eq] at this + exact this hσn (hζ n) + choose t σ' hσ'_le hσ'_ge ht hζ using this + have σTo1 : Filter.Tendsto σ' Filter.atTop (𝓝 1) := by + use sub_zero (1: ℝ)▸tendsto_order.2 ⟨fun A B=>? _,fun A B=>?_⟩ + · apply (((tendsto_inv_atTop_nhds_zero_nat.comp + (Filter.tendsto_add_atTop_nat (1))).congr (by norm_num)).const_sub 1).eventually_const_lt + B|>.mono (hσ'_ge ·|>.trans_lt') + · norm_num[(hσ'_le _).trans_lt, B.trans_le'] + have : ∃ (t₀ : ℝ) (subseq : ℕ → ℕ), + Filter.Tendsto (t ∘ subseq) Filter.atTop (𝓝 t₀) ∧ + Filter.Tendsto subseq Filter.atTop Filter.atTop := by + refine (isCompact_Icc.isSeqCompact fun and => abs_le.1 (ht and)).imp fun and ⟨x, A, B, _⟩ => ?_ + use A, by omega, B.tendsto_atTop + obtain ⟨t₀, subseq, tTendsto, subseqTendsto⟩ := this + have σTo1 : Filter.Tendsto (σ' ∘ subseq) Filter.atTop (𝓝 1) := + σTo1.comp subseqTendsto + have (n : ℕ) : ζ (σ' (subseq n) + I * (t (subseq n))) = 0 := by + convert hζ (subseq n) using 3 + ring + have ToOneT0 : Filter.Tendsto (fun n ↦ (σ' (subseq n) : ℂ) + Complex.I * (t (subseq n))) + Filter.atTop + (𝓝[≠]((1 : ℂ) + I * t₀)) := by + simp_rw [tendsto_nhdsWithin_iff, Function.comp_def] at tTendsto ⊢ + constructor + · exact (σTo1.ofReal.add (tTendsto.ofReal.const_mul _)).trans (by simp) + · filter_upwards with n + apply ne_of_apply_ne ζ + rw [this] + apply Ne.symm + apply riemannZeta_ne_zero_of_one_le_re + simp only [add_re, one_re, mul_re, I_re, ofReal_re, zero_mul, I_im, ofReal_im, mul_zero, + sub_self, add_zero, le_refl] + by_cases ht₀ : t₀ = 0 + · have ZetaBlowsUp : ∀ᶠ s in 𝓝[≠](1 : ℂ), ‖ζ s‖ ≥ 1 := by + simp_all only [ge_iff_le, one_div, tsub_le_iff_right, Function.comp_def, ofReal_zero, + mul_zero, add_zero, norm_eq_sqrt_real_inner, Complex.inner, mul_re, conj_re, conj_im, + mul_neg, sub_neg_eq_add, Real.one_le_sqrt, eventually_nhdsWithin_iff, mem_compl_iff, + mem_singleton_iff] + contrapose! h + simp_all only [ne_eq] + delta abs at* + exfalso + simp_rw [Metric.nhds_basis_ball.frequently_iff]at* + choose! I A B using h + choose a s using exists_seq_strictAnti_tendsto (0: ℝ) + apply ((isCompact_closedBall _ _).isSeqCompact + fun and=>(A _ (s.2.1 and)).le.trans (s.2.2.bddAbove_range.some_mem ⟨and, rfl⟩)).elim + simp only [Metric.mem_ball, dist_eq_norm_sub] at A + refine fun and ⟨a, H, S, M⟩=> ?_ + refine absurd (tendsto_nhds_unique M (tendsto_sub_nhds_zero_iff.1 + (( squeeze_zero_norm fun and=>le_of_lt (A _ (s.2.1 _) ) ) + (s.2.2.comp S.tendsto_atTop)))) fun and=>?_ + norm_num[*,Function.comp_def] at M + have:=@riemannZeta_residue_one + use one_ne_zero (tendsto_nhds_unique (this.comp (tendsto_nhdsWithin_iff.2 + ⟨ M,.of_forall (by norm_num[*])⟩)) ( squeeze_zero_norm ?_ + ((M.sub_const 1).norm.trans (by rw [sub_self,norm_zero])))) + use fun and =>.trans (norm_mul_le_of_le ↑(le_rfl) (Complex.norm_def _▸Real.sqrt_le_one.mpr + (B ↑_ (s.2.1 ↑_)).right.le)) (by rw [mul_one]) + have ZetaNonZ : ∀ᶠ s in 𝓝[≠](1 : ℂ), ζ s ≠ 0 := by + filter_upwards [ZetaBlowsUp] + intro s hs hfalse + rw [hfalse] at hs + simp only [norm_zero, ge_iff_le] at hs + linarith + rw [ht₀] at ToOneT0 + simp only [ofReal_zero, mul_zero, add_zero] at ToOneT0 + rcases (ToOneT0.eventually ZetaNonZ).exists with ⟨n, hn⟩ + exact hn (this n) + · have zetaIsZero : ζ (1 + Complex.I * t₀) = 0 := by + have cont := @ZetaCont + use isClosed_singleton.isSeqClosed + this + (.comp + (cont.continuousAt.comp (eventually_ne_nhds (by field_simp; simp [ht₀])).mono + fun and=>.intro ⟨⟩) + (ToOneT0.trans (inf_le_left))) + exact riemannZeta_ne_zero_of_one_le_re (s := 1 + I * t₀) (by simp) zetaIsZero + + +-- **End collaboration** + +lemma LogDerivZetaHoloOn {S : Set ℂ} (s_ne_one : 1 ∉ S) + (nonzero : ∀ s ∈ S, ζ s ≠ 0) : + HolomorphicOn (fun s ↦ ζ' s / ζ s) S := by + apply DifferentiableOn.div _ _ nonzero <;> intro s hs <;> apply + DifferentiableAt.differentiableWithinAt + · apply differentiableAt_deriv_riemannZeta + exact ne_of_mem_of_not_mem hs s_ne_one + · apply differentiableAt_riemannZeta + exact ne_of_mem_of_not_mem hs s_ne_one + +/- +We now prove that there's an absolute constant $\sigma_0$ so that $\zeta'/\zeta$ is holomorphic on +a rectangle $[\sigma_2,2] \times_{ℂ} [-3,3] \setminus \{1\}$. +-/ +/- +There is a $\sigma_2 < 1$ so that the function + $$ + \frac {\zeta'}{\zeta}(s) + $$ + is holomorphic on $\{ \sigma_2 \le \Re s \le 2, |\Im s| \le 3 \} \setminus \{1\}$. +The derivative of $\zeta$ is holomorphic away from $s=1$; the denominator $\zeta(s)$ is nonzero + in this range by Lemma \ref{ZetaNoZerosInBox}. +-/ +theorem LogDerivZetaHolcSmallT : + ∃ (σ₂ : ℝ) (_ : σ₂ < 1), HolomorphicOn (fun (s : ℂ) ↦ ζ' s / (ζ s)) + (( [[ σ₂, 2 ]] ×ℂ [[ -3, 3 ]]) \ {1}) := by + obtain ⟨σ₂, hσ₂_lt_one, hζ_ne_zero⟩ := ZetaNoZerosInBox 3 + refine ⟨σ₂, hσ₂_lt_one, ?_⟩ + let U := ([[σ₂, 2]] ×ℂ [[-3, 3]]) \ {1} + have s_in_U_im_le3 : ∀ s ∈ U, |s.im| ≤ 3 := by + intro s hs + rw [Set.mem_sdiff_singleton] at hs + rcases hs with ⟨hbox, _hne⟩ + rcases hbox with ⟨hre, him⟩ + simp only [Set.mem_preimage] at him + obtain ⟨him_lower, him_upper⟩ := him + apply abs_le.2 + simp only [neg_le_self_iff, Nat.ofNat_nonneg, inf_of_le_left] at him_lower + simp only [neg_le_self_iff, Nat.ofNat_nonneg, sup_of_le_right] at him_upper + exact ⟨him_lower, him_upper⟩ + have s_in_U_re_ges2 : ∀ s ∈ U, σ₂ ≤ s.re := by + intro s hs + rw [Set.mem_sdiff_singleton] at hs + rcases hs with ⟨hbox, _hne⟩ + rcases hbox with ⟨hre, _him⟩ + simp only [Set.mem_preimage] at hre + obtain ⟨hre_lower, hre_upper⟩ := hre + have : min σ₂ 2 = σ₂ := by + apply min_eq_left + linarith [hσ₂_lt_one] + rwa [← this] + apply LogDerivZetaHoloOn + · exact Set.notMem_sdiff_of_mem rfl + · intro s hs + rw[← re_add_im s] + apply hζ_ne_zero + · apply s_in_U_im_le3 _ hs + · apply s_in_U_re_ges2 _ hs + +lemma LogDerivZetaHolcSmallT' : ∃ (σ₂ : ℝ) + (_ : σ₂ ∈ Ioo 0 1), HolomorphicOn (fun (s : ℂ) ↦ ζ' s / (ζ s)) + (( [[ σ₂, 2 ]] ×ℂ [[ -3, 3 ]]) \ {1}) := by + obtain ⟨σ₂', σ₂'_lt_one, holo2'⟩ := LogDerivZetaHolcSmallT + let σ₂ : ℝ := max σ₂' (1 / 2) + have σ₂_pos : 0 < σ₂ := by bound + have σ₂_lt_one : σ₂ < 1 := by bound + refine ⟨σ₂, ⟨σ₂_pos, σ₂_lt_one⟩, holo2'.mono (fun s hs ↦ ?_)⟩ + simp only [neg_le_self_iff, Nat.ofNat_nonneg, uIcc_of_le, Set.mem_sdiff, mem_reProdIm, mem_Icc, + mem_singleton_iff] at hs ⊢ + refine ⟨?_, hs.2⟩ + refine ⟨?_, hs.1.2⟩ + rcases hs.1.1 with ⟨left, right⟩ + constructor + · apply le_trans _ left + apply min_le_min_right + apply le_max_left + · rw [max_eq_right (by linarith)] at right ⊢ + exact right + +/-- Holomorphy of the logarithmic derivative on expanding zero-free rectangles. -/ +def LogDerivZetaHolcLargeTGenProp (n : ℝ) : Prop := ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)), + ∀ (T : ℝ) (_ : 3 ≤ T), + HolomorphicOn (fun (s : ℂ) ↦ ζ' s / (ζ s)) + (( (Icc ((1 : ℝ) - A / Real.log T ^ n) 2) ×ℂ (Icc (-T) T) ) \ {1}) + +lemma LogDerivZetaHolcLargeTGen {n : ℝ} (ZetaZeroFree : ZetaZeroFreeGenProp n) (n_pos : 0 < n) : + LogDerivZetaHolcLargeTGenProp n := by + obtain ⟨A, A_inter, restOfZetaZeroFree⟩ := ZetaZeroFree + obtain ⟨σ₁, σ₁_lt_one, noZerosInBox⟩ := ZetaNoZerosInBox 3 + let A₀ := min A ((1 - σ₁) * Real.log 3 ^ n) + refine ⟨A₀, ?_, ?_⟩ + · constructor + · apply lt_min A_inter.1 + bound + · exact le_trans (min_le_left _ _) A_inter.2 + intro T hT + apply LogDerivZetaHoloOn + · exact Set.notMem_sdiff_of_mem rfl + intro s hs + rcases le_or_gt 1 s.re with one_le|lt_one + · exact riemannZeta_ne_zero_of_one_le_re one_le + rw [← re_add_im s] + have := Complex.mem_reProdIm.mp hs.1 + rcases lt_or_ge 3 |s.im| with gt3|le3 + · apply restOfZetaZeroFree _ _ gt3 + refine ⟨?_, lt_one⟩ + calc + _ ≤ 1 - A₀ / Real.log T ^ n := by + gcongr + · exact A_inter.1.le + · bound + · bound + · bound + · exact abs_le.mpr ⟨this.2.1, this.2.2⟩ + _ ≤ _:= by exact this.1.1 + · apply noZerosInBox _ le3 + calc + _ ≥ 1 - A₀ / Real.log T ^ n := by exact this.1.1 + _ ≥ 1 - A₀ / Real.log 3 ^ n := by + gcongr + apply le_min A_inter.1.le + bound + _ ≥ 1 - (((1 - σ₁) * Real.log 3 ^ n)) / Real.log 3 ^ n := by + gcongr + apply min_le_right + _ = _ := by field_simp; simp + +/- +There is an $A>0$ so that for all $T>3$, the function + $ + \frac {\zeta'}{\zeta}(s) + $ + is holomorphic on $\{1-A/\log^9 T \le \Re s \le 2, |\Im s|\le T \}\setminus\{1\}$. +The derivative of $\zeta$ is holomorphic away from $s=1$; the denominator $\zeta(s)$ is nonzero + in this range by Lemma \ref{ZetaZeroFree9}. +-/ +theorem LogDerivZetaHolcLargeT9 : LogDerivZetaHolcLargeTGenProp 9 := by + apply LogDerivZetaHolcLargeTGen ZetaZeroFree9 Nat.ofNat_pos' + +theorem summable_complex_then_summable_real_part (f : ℕ → ℂ) + (h : Summable f) : Summable (fun n ↦ (f n).re) := by + rcases h with ⟨s, hs⟩ + exact ⟨s.re, hasSum_re hs⟩ + +open ArithmeticFunction (vonMangoldt) +local notation "Λ" => vonMangoldt +--TODO generalize to any LSeries with nonnegative coefficients +open scoped ComplexOrder in +theorem dlog_riemannZeta_bdd_on_vertical_lines_generalized + (σ₀ σ₁ t : ℝ) (σ₀_gt_one : 1 < σ₀) (σ₀_lt_σ₁ : σ₀ ≤ σ₁) : + ‖(- ζ' (σ₁ + t * I) / ζ (σ₁ + t * I))‖ ≤ ‖ζ' σ₀ / ζ σ₀‖ := by + let s₁ := σ₁ + t * I + have s₁_re_eq_sigma : s₁.re = σ₁ := by + rw [add_re, ofReal_re, mul_I_re, ofReal_im] + ring + have s₀_re_eq_sigma : (↑σ₀ : ℂ).re = σ₀ := by + rw [ofReal_re] + let s₀ := σ₀ + have σ₁_gt_one : 1 < σ₁ := by exact lt_of_le_of_lt' σ₀_lt_σ₁ σ₀_gt_one + have s₀_gt_one : 1 < (↑σ₀ : ℂ).re := by exact σ₀_gt_one + have s₁_re_geq_one : 1 < s₁.re := by exact lt_of_lt_of_eq σ₁_gt_one (id (Eq.symm s₁_re_eq_sigma)) + rw [← (ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div s₁_re_geq_one)] + unfold LSeries + have summable_von_mangoldt_at_σ₀ : Summable (fun i ↦ LSeries.term (fun n ↦ ↑(Λ n)) σ₀ i) := by + exact ArithmeticFunction.LSeriesSummable_vonMangoldt σ₀_gt_one + have summable_re_von_mangoldt_at_σ₀ : + Summable (fun i ↦ (LSeries.term (fun n ↦ ↑(Λ n)) σ₀ i).re) := by + exact summable_complex_then_summable_real_part (LSeries.term (fun n ↦ ↑(Λ n)) σ₀) + summable_von_mangoldt_at_σ₀ + have summable_abs_value : Summable (fun i ↦ ‖LSeries.term (fun n ↦ ↑(Λ n)) s₁ i‖) := by + rw [summable_norm_iff] + exact ArithmeticFunction.LSeriesSummable_vonMangoldt s₁_re_geq_one + apply le_trans <| norm_tsum_le_tsum_norm summable_abs_value + rw [← norm_neg, ← neg_div, ← ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div + s₀_gt_one] + unfold LSeries + rw [← re_eq_norm.mpr, re_tsum summable_von_mangoldt_at_σ₀] + · apply Summable.tsum_mono summable_abs_value summable_re_von_mangoldt_at_σ₀ + intro n + beta_reduce + apply le_trans <| LSeries.norm_term_le_of_re_le_re (s := σ₀) _ _ _ + · rw [re_eq_norm.mpr] + apply LSeries.term_nonneg + exact_mod_cast ArithmeticFunction.vonMangoldt_nonneg + · rwa [s₁_re_eq_sigma, s₀_re_eq_sigma] + · apply tsum_nonneg + intro n + apply LSeries.term_nonneg + exact_mod_cast ArithmeticFunction.vonMangoldt_nonneg + +theorem triv_bound_zeta : ∃C ≥ 0, ∀(σ₀ t : ℝ), 1 < σ₀ → + ‖- ζ' (σ₀ + t * I) / ζ (σ₀ + t * I)‖ ≤ (σ₀ - 1)⁻¹ + C := by + let ⟨U, ⟨U_in_nhds, zeta_residue_on_U⟩⟩ := riemannZetaLogDerivResidue + let ⟨open_in_U, ⟨open_in_U_subs_U, open_in_U_is_open, one_in_open_U⟩⟩ := + mem_nhds_iff.mp U_in_nhds + let ⟨ε₀, ⟨ε_pos, metric_ball_around_1_is_in_U'⟩⟩ := + EMetric.isOpen_iff.mp open_in_U_is_open (1 : ℂ) one_in_open_U + let ε := if ε₀ = ⊤ then ENNReal.ofReal 1 else ε₀ + have O1 : ε ≠ ⊤ := by + unfold ε + by_cases h : ε₀ = ⊤ <;> simp [*] + have metric_ball_around_1_is_in_U : + Metric.eball (1 : ℂ) ε ⊆ U := by + unfold ε + by_cases h : ε₀ = ⊤ + · simp only [↓reduceIte, ENNReal.ofReal_one, h] + have T : Metric.eball (1 : ℂ) 1 ⊆ Metric.eball 1 ε₀ := by + simp [*] + exact subset_trans (subset_trans T metric_ball_around_1_is_in_U') open_in_U_subs_U + · simp only [h, ↓reduceIte] + exact subset_trans metric_ball_around_1_is_in_U' open_in_U_subs_U + have O2 : ε ≠ 0 := by + unfold ε + by_cases h : ε₀ = ⊤ + · simp [*] + · simp only [↓reduceIte, ne_eq, h] + exact pos_iff_ne_zero.mp ε_pos + let metric_ball_around_1 := Metric.eball (1 : ℂ) ε + let ε_div_two := ε / 2 + let boundary := ENNReal.toReal (1 + ε_div_two) + let ⟨bound, ⟨bound_pos, bound_prop⟩⟩ := + BddAbove.exists_ge zeta_residue_on_U 0 + have boundary_geq_one : 1 < boundary := by + unfold boundary + have Z : (1 : ENNReal).toReal = 1 := by rfl + rw [←Z] + have U : ε_div_two ≠ ⊤ := by + refine ENNReal.div_ne_top O1 ?_ + simp + simp only [ENNReal.toReal_one, ne_eq, ENNReal.one_ne_top, not_false_eq_true, + ENNReal.toReal_add _ U, lt_add_iff_pos_right, gt_iff_lt] + refine ENNReal.toReal_pos ?_ ?_ + · unfold ε_div_two + simp [*] + · exact U + let const : ℝ := bound + let final_const : ℝ := (boundary - 1)⁻¹ + const + have final_const_pos : final_const ≥ 0 := by bound + have const_le_final_const : const ≤ final_const := by bound + /- final const is actually the constant that we will use -/ + refine ⟨final_const, final_const_pos, fun σ₀ t σ₀_gt ↦ ?_⟩ + have U4 : ENNReal.ofReal 1 ≠ ⊤ := by exact ENNReal.ofReal_ne_top + have Z0 : ε_div_two.toReal < ε.toReal := by + exact ENNReal.toReal_strict_mono O1 <| ENNReal.half_lt_self O2 O1 + -- Pick a neighborhood, if in neighborhood then we are good + -- If outside of the neighborhood then use that ζ' / ζ is monotonic + -- and take the bound to be the edge but this will require some more work + by_cases! h : σ₀ ≤ boundary + · have σ₀_in_ball : (↑σ₀ : ℂ) ∈ metric_ball_around_1 := by + unfold metric_ball_around_1 + unfold Metric.eball + simp only [mem_ofPred_eq] + rw [edist_dist, dist_eq_norm] + norm_cast + have U : 0 ≤ σ₀ - 1 := by linarith + simp only [Real.norm_of_nonneg U, gt_iff_lt] + simp only [ENNReal.ofReal_lt_iff_lt_toReal U O1] + calc + _ ≤ boundary - 1 := by linarith + _ = ENNReal.toReal (1 + ε_div_two) - 1 := rfl + _ = ENNReal.toReal (1 + ε_div_two) - ENNReal.toReal (ENNReal.ofReal 1) := by simp + _ ≤ ENNReal.toReal (1 + ε_div_two - ENNReal.ofReal 1) := ENNReal.le_toReal_sub U4 + _ = ENNReal.toReal (ε_div_two) := by + simp + _ < ε.toReal := Z0 + have σ₀_in_U : (↑σ₀ : ℂ) ∈ (U \ {1}) := by + refine Set.mem_sdiff_singleton.mpr ?_ + constructor + · exact metric_ball_around_1_is_in_U σ₀_in_ball + · by_contra a + have U : σ₀ = 1 := by exact ofReal_eq_one.mp a + rw [U] at σ₀_gt + linarith + have bdd := Set.forall_mem_image.mp bound_prop (σ₀_in_U) + simp only [Function.comp_apply, Pi.sub_apply, Pi.neg_apply, Pi.div_apply] at bdd + calc + _ ≤ ‖ζ' σ₀ / ζ σ₀‖ := by + exact dlog_riemannZeta_bdd_on_vertical_lines_generalized σ₀ σ₀ t (σ₀_gt) (by simp) + _ = ‖- ζ' σ₀ / ζ σ₀‖ := by simp only [Complex.norm_div, norm_neg] + _ = ‖(- ζ' σ₀ / ζ σ₀ - (σ₀ - 1)⁻¹) + (σ₀ - 1)⁻¹‖ := by + simp only [Complex.norm_div, norm_neg, ofReal_inv, ofReal_sub, ofReal_one, sub_add_cancel] + _ ≤ ‖(- ζ' σ₀ / ζ σ₀ - (σ₀ - 1)⁻¹)‖ + ‖(σ₀ - 1)⁻¹‖ := by + have Z := norm_add_le (- ζ' σ₀ / ζ σ₀ - (σ₀ - 1)⁻¹) ((σ₀ - 1)⁻¹) + norm_cast at Z + _ ≤ const + ‖(σ₀ - 1)⁻¹‖ := by + have U := add_le_add_left bdd ‖(σ₀ - 1)⁻¹‖ + ring_nf at U + ring_nf + norm_cast at U + norm_cast + _ ≤ const + (σ₀ - 1)⁻¹ := by + simp [norm_inv] + have pos : 0 ≤ σ₀ - 1 := by + linarith + simp [abs_of_nonneg pos] + _ = (σ₀ - 1)⁻¹ + const := by + rw [add_comm] + _ ≤ (σ₀ - 1)⁻¹ + final_const := by + simp [const_le_final_const] + · have boundary_in_ball : (↑boundary : ℂ) ∈ metric_ball_around_1 := by + unfold metric_ball_around_1 + unfold Metric.eball + simp only [mem_ofPred_eq] + rw [edist_dist, dist_eq_norm] + norm_cast + have U : 0 ≤ boundary - 1 := by linarith + simp only [Real.norm_of_nonneg U, gt_iff_lt] + simp only [ENNReal.ofReal_lt_iff_lt_toReal U O1] + calc + _ = ENNReal.toReal (1 + ε_div_two) - 1 := rfl + _ = ENNReal.toReal (1 + ε_div_two) - ENNReal.toReal (ENNReal.ofReal 1) := by simp + _ ≤ ENNReal.toReal (1 + ε_div_two - ENNReal.ofReal 1) := ENNReal.le_toReal_sub U4 + _ = ENNReal.toReal (ε_div_two) := by + simp + _ < ε.toReal := Z0 + have boundary_in_U : (↑boundary : ℂ) ∈ U \ {1} := by + refine Set.mem_sdiff_singleton.mpr ?_ + constructor + · exact metric_ball_around_1_is_in_U boundary_in_ball + · by_contra a + norm_cast at a + norm_cast at boundary_geq_one + simp [←a] at boundary_geq_one + have bdd := Set.forall_mem_image.mp bound_prop (boundary_in_U) + calc + _ ≤ ‖ζ' boundary / ζ boundary‖ := by + exact dlog_riemannZeta_bdd_on_vertical_lines_generalized boundary σ₀ t + (boundary_geq_one) (by linarith) + _ = ‖- ζ' boundary / ζ boundary‖ := by simp only [Complex.norm_div, norm_neg] + _ = ‖(- ζ' boundary / ζ boundary - (boundary - 1)⁻¹) + (boundary - 1)⁻¹‖ := by + simp only [Complex.norm_div, norm_neg, ofReal_inv, ofReal_sub, ofReal_one, sub_add_cancel] + _ ≤ ‖(- ζ' boundary / ζ boundary - (boundary - 1)⁻¹)‖ + ‖(boundary - 1)⁻¹‖ := by + have Z := norm_add_le (- ζ' boundary / ζ boundary - (boundary - 1)⁻¹) ((boundary - 1)⁻¹) + norm_cast at Z + _ ≤ const + ‖(boundary - 1)⁻¹‖ := by + have U9 := add_le_add_left bdd ‖(boundary - 1)⁻¹‖ + ring_nf at U9 + ring_nf + norm_cast at U9 + norm_cast + simpa [*] using! U9 + _ ≤ const + (boundary - 1)⁻¹ := by + simp [norm_inv] + have pos : 0 ≤ boundary - 1 := by + linarith + simp [abs_of_nonneg pos] + _ = (boundary - 1)⁻¹ + const := by + rw [add_comm] + _ = final_const := by rfl + _ ≤ _ := by bound + +/-- Existence of constants giving a uniform logarithmic-derivative bound near `re = 1`. -/ +def LogDerivZetaBndUnifGenProp (n₁ n₂ : ℝ) : Prop := ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) + (C : ℝ) (_ : 0 < C), ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Ici (1 - A / Real.log |t| ^ n₁)), ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ ≤ + C * Real.log |t| ^ n₂ + +/- +There exist $A, C > 0$ such that + $$|\frac{\zeta'}{\zeta}(\sigma + it)|\leq C \log |t|^9$$ + whenever $|t|>3$ and $\sigma > 1 - A/\log |t|^9$. +For $\sigma$ close to $1$ use Lemma \ref{LogDerivZetaBnd}, otherwise estimate trivially. +-/ +lemma LogDerivZetaBndUnif99 : LogDerivZetaBndUnifGenProp 9 9 := by + let ⟨A, pf_A, C, C_pos, ζbd_in⟩ := LogDerivZetaBnd + let ⟨C_triv, ⟨pf_C_triv, ζbd_out⟩⟩ := triv_bound_zeta + have T0 : A > 0 := pf_A.1 + have ha : 1 ≤ A⁻¹ := by + simp only [one_div, mem_Ioc, true_and, T0] at pf_A + have U := (inv_le_inv₀ (by positivity) (by positivity)).mpr pf_A + simp only [inv_inv] at U + linarith + refine ⟨A, pf_A, ((1 + C + C_triv) * A⁻¹), (by positivity), fun σ t hyp_t hyp_σ ↦ ?_⟩ + have logt_gt' : (1 : ℝ) < Real.log |t| ^ (9 : ℝ) := by + calc + 1 < Real.log |t| := logt_gt_one hyp_t.le + _ ≤ (Real.log |t|) ^ (9 : ℝ) := ZetaInvBnd_aux (logt_gt_one hyp_t.le) + have logt_gt'' : (1 : ℝ) < 1 + A / Real.log |t| ^ (9 : ℝ) := by + simp only [lt_add_iff_pos_right, div_pos_iff_of_pos_left, T0] + positivity + have T1 : ∀⦃σ : ℝ⦄, 1 + A / Real.log |t| ^ (9 : ℝ) ≤ σ → 1 < σ := by + intros + linarith + have T2 : ∀⦃σ : ℝ⦄, 1 + A / Real.log |t| ^ (9 : ℝ) ≤ σ → A / Real.log |t| ^ (9 : ℝ) ≤ σ - 1 := by + intro σ' hyp_σ' + calc + A / Real.log |t| ^ (9 : ℝ) = (1 + A / Real.log |t| ^ (9 : ℝ)) - 1 := by ring_nf + _ ≤ σ' - 1 := by gcongr + by_cases h : σ ∈ Ico (1 - A / Real.log |t| ^ (9 : ℝ)) (1 + A / Real.log |t| ^ (9 : ℝ)) + · calc + ‖ζ' (↑σ + ↑t * I) / ζ (↑σ + ↑t * I)‖ ≤ C * Real.log |t| ^ 9 := ζbd_in σ t hyp_t h + _ ≤ ((1 + C + C_triv) * A⁻¹) * Real.log |t| ^ (9 : ℝ) := by + gcongr + · calc + C ≤ 1 + C := by simp only [le_add_iff_nonneg_left, zero_le_one] + _ ≤ (1 + C + C_triv) * 1 := by + simp only [mul_one, le_add_iff_nonneg_right] + positivity + _ ≤ (1 + C + C_triv) * A⁻¹ := by gcongr + · simp only [mem_Ico, tsub_le_iff_right, not_and, not_lt, mem_Ici] at h hyp_σ + replace h := h hyp_σ + calc + ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ = ‖-ζ' (σ + t * I) / ζ (σ + t * I)‖ := by + simp only [Complex.norm_div, norm_neg] + _ ≤ (σ - 1)⁻¹ + C_triv := ζbd_out σ t (by exact T1 h) + _ ≤ (A / Real.log |t| ^ (9 : ℝ))⁻¹ + C_triv := by + gcongr + · exact T2 h + _ ≤ (A / Real.log |t| ^ (9 : ℝ))⁻¹ + C_triv * A⁻¹ := by + gcongr + exact le_mul_of_one_le_right pf_C_triv ha + _ ≤ (1 + C_triv) * A⁻¹ * Real.log |t| ^ (9 : ℝ) := by + simp only [inv_div] + ring_nf + gcongr + · simp only [inv_pos, le_mul_iff_one_le_left, T0] + linarith + _ ≤ (1 + C + C_triv) * A⁻¹ * Real.log |t| ^ (9 : ℝ) := by + gcongr + linarith + +end IwaniecLinearSievePNT diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaConj.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaConj.lean new file mode 100644 index 000000000..6a0785282 --- /dev/null +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaConj.lean @@ -0,0 +1,79 @@ +/- +Copyright (c) 2026 PrimeNumberTheoremAnd contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: PrimeNumberTheoremAnd contributors +-/ + +module + +public import Mathlib.NumberTheory.LSeries.RiemannZeta +import Mathlib.Analysis.Calculus.Deriv.Star +import Mathlib.NumberTheory.Harmonic.ZetaAsymp + +/-! +Adapted from PrimeNumberTheoremAnd revision +`127b50e33f6033e2147921167a117af96d9ba4ea`, via Jason Davies's +Iwaniec linear sieve snapshot `c8d01549d2ae640b36ec198c1f0f6495f1b036cf` +(both Apache-2.0). Blueprint-only machinery is omitted. + +Supporting lemmas for Iwaniec's sieve and its prime-number-theorem input. +-/ + +@[expose] public section + +namespace IwaniecLinearSievePNT + + +open scoped Complex ComplexConjugate + + +/- +Now in Mathlib: +-/ +/- +Let $f : \mathbb{C} \to \mathbb{C}$ be a function at $p \in \mathbb{C}$ with derivative $a$. + Then the derivative of the function $g(z) = \overline{f(\overline{z})}$ at $\overline{p}$ is + $\overline{a}$. +We proceed by case analysis on whether $f$ is differentiable at $p$. If $f$ is differentiable + at $p$, then we can apply the previous theorem. If $f$ is not differentiable at $p$, then + neither is $g$, and both derivatives have the default value of zero. +-/ +theorem deriv_conj_conj' (f : ℂ → ℂ) (p : ℂ) : + deriv (fun z ↦ conj (f (conj z))) (conj p) = conj (deriv f p) := by + trans deriv (conj ∘ f ∘ conj) (conj p) + · rfl + simp + +/- +Conjugation symmetry of the derivative of the Riemann zeta function. Let $s \in \mathbb{C}$. + Then $$\zeta'(\overline{s}) = \overline{\zeta'(s)}.$$ +We apply the derivative conjugation symmetry to the Riemann zeta function and use the + conjugation symmetry of the Riemann zeta function itself. +-/ +theorem deriv_riemannZeta_conj (s : ℂ) : + deriv riemannZeta (conj s) = conj (deriv riemannZeta s) := by + simp [← deriv_conj_conj'] + +theorem logDerivZeta_conj (s : ℂ) : + (deriv riemannZeta / riemannZeta) (conj s) = conj ((deriv riemannZeta / riemannZeta) s) := by + simp [deriv_riemannZeta_conj, riemannZeta_conj] + +theorem logDerivZeta_conj' (s : ℂ) : + (logDeriv riemannZeta) (conj s) = conj (logDeriv riemannZeta s) := logDerivZeta_conj s + +/- +% TODO: Submit this to Mathlib. +-/ +/- +The conjugation symmetry of the interval integral. Let $f : \mathbb{R} \to \mathbb{C}$ be a + measurable function, and let $a, b \in \mathbb{R}$. Then + $$\int_{a}^{b} \overline{f(x)} \, dx = \overline{\int_{a}^{b} f(x) \, dx}.$$ +We unfold the interval integral into an integral over a uIoc and use the conjugation property + of integrals. +-/ +theorem intervalIntegral_conj {f : ℝ → ℂ} {a b : ℝ} : + ∫ (x : ℝ) in a..b, conj (f x) = conj (∫ (x : ℝ) in a..b, f x) := by + rw [intervalIntegral.intervalIntegral_eq_integral_uIoc, integral_conj, ← RCLike.conj_smul, + ← intervalIntegral.intervalIntegral_eq_integral_uIoc] + +end IwaniecLinearSievePNT diff --git a/LeanPool/projects/iwaniec-linear-sieve.yaml b/LeanPool/projects/iwaniec-linear-sieve.yaml new file mode 100644 index 000000000..eb3df3b45 --- /dev/null +++ b/LeanPool/projects/iwaniec-linear-sieve.yaml @@ -0,0 +1,56 @@ +slug: iwaniec-linear-sieve +title: Iwaniec's linear sieve and Jacobsthal's bound +summary: >- + Proves an absolute O((r log r)^2) bound for any run of consecutive integers + covered by r distinct primes, using the Rosser-Iwaniec linear sieve at the + sifting limit. Preserves the combinatorial sieve, delay-equation majorants, + prime-sum estimates and the proved strong prime-number-theorem dependency. + This imports the dependency closure of the Jacobsthal corollary, rather than + claiming the upstream formalizations of both papers in full. +branch: analytic number theory +entry_module: LeanPool.IwaniecLinearSieve +authors: +- Jason Davies +- PrimeNumberTheoremAnd contributors +source: + title: On the problem of Jacobsthal + authors: + - Henryk Iwaniec + doi: 10.1515/dema-1978-0121 + url: https://github.com/jasondavies/iwaniec-linear-sieve/tree/c8d01549d2ae640b36ec198c1f0f6495f1b036cf + github_repo: jasondavies/iwaniec-linear-sieve + commit: c8d01549d2ae640b36ec198c1f0f6495f1b036cf + announcement_url: https://leanprover.zulipchat.com/#narrow/channel/583339/near/633293145 + announcement_date: '2026-10-20' + dependency_repository: https://github.com/AlexKontorovich/PrimeNumberTheoremAnd + dependency_commit: 127b50e33f6033e2147921167a117af96d9ba4ea +license: Apache-2.0 +status: verified +provenance: AI +main_declarations: +- IwaniecLinearSieve.iwaniecBound +main_results: +- declaration: IwaniecLinearSieve.iwaniecBound + informal: >- + There is an absolute real constant C such that, for every finite set S of + at least two primes and every interval of m consecutive integers each + divisible by a prime in S, m is at most C times (|S| log |S|)^2. +- declaration: IwaniecLinearSieve.shiftedSieve + informal: >- + Rosser's lower-bound sieve for the first r primes transfers to any set of + r primes, bounding the number of integers avoiding all those primes. +- declaration: IwaniecLinearSieve.linearSieveEstimate + informal: >- + At a fixed constant times z squared, Rosser's lower-bound sieve has main + term bounded below by a positive constant times R(z)/log z and support + bounded above by a constant times z squared divided by log squared z, + for all sufficiently large z. +tags: +- analytic-number-theory +- sieve-theory +- jacobsthal-function +- prime-number-theorem +msc: +- 11N35 +- 11N36 +- 11N25 From d6bc653782d90c0d92c0815263339a692238c818 Mon Sep 17 00:00:00 2001 From: Vasily Ilin Date: Wed, 21 Oct 2026 10:38:26 +0000 Subject: [PATCH 2/5] Account for the vendored PNT contributions in provenance --- LeanPool/projects/iwaniec-linear-sieve.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LeanPool/projects/iwaniec-linear-sieve.yaml b/LeanPool/projects/iwaniec-linear-sieve.yaml index eb3df3b45..24d946a2e 100644 --- a/LeanPool/projects/iwaniec-linear-sieve.yaml +++ b/LeanPool/projects/iwaniec-linear-sieve.yaml @@ -26,7 +26,7 @@ source: dependency_commit: 127b50e33f6033e2147921167a117af96d9ba4ea license: Apache-2.0 status: verified -provenance: AI +provenance: mix main_declarations: - IwaniecLinearSieve.iwaniecBound main_results: From 2d7d6005157a0660dc7c0a043a074ad11a3ba581 Mon Sep 17 00:00:00 2001 From: Vasily Ilin Date: Wed, 21 Oct 2026 10:49:02 +0000 Subject: [PATCH 3/5] Trim unused residue scaffolding from the PNT dependency --- .../ResidueCalcOnRectangles.lean | 560 +----------------- .../PrimeNumberTheoremAnd/StrongPNT.lean | 1 + 2 files changed, 2 insertions(+), 559 deletions(-) diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean index a20b13f57..9832a34ee 100644 --- a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean @@ -7,11 +7,10 @@ Authors: PrimeNumberTheoremAnd contributors module public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.Rectangle -public import Mathlib.Analysis.Meromorphic.Order +public import Mathlib.Analysis.Calculus.FDeriv.Defs public import Mathlib.Analysis.SpecialFunctions.Trigonometric.Arctan public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic import Mathlib.Analysis.Complex.RemovableSingularity -import Mathlib.Analysis.Meromorphic.NormalForm import Mathlib.Analysis.SpecialFunctions.Integrals.Basic /-! @@ -741,561 +740,4 @@ theorem ResidueTheoremOnRectangleWithSimplePole' {f : ℂ → ℂ} {z w p A : obtain ⟨h, ⟨hHolo, hEq⟩⟩ := existsDifferentiableOn_of_bddAbove pInRectInterior gHolo this exact ResidueTheoremOnRectangleWithSimplePole zRe_le_wRe zIm_le_wIm pInRectInterior hHolo hEq -/-! ## Residue calculus: residues, simple poles, and the rectangle residue theorem - -The simple-pole `residue`, `sumResiduesIn`, the `HasSimplePolesOn` scaffold, and the rectangle -residue theorem `RectangleIntegral'_eq_sumResiduesIn`. Extracted from `CH2.lean` as general, -reusable contour-integration lemmas (see issue #1537). -/ - -/-- Every pole of `f` in `s` is at most simple: the meromorphic order is `≥ -1` everywhere on `s` -(no poles of order `≤ -2`). - -**Temporary scaffold.** The placeholder `residue` below (and Mathlib's current residue-theorem API) -is only correct for simple poles, so this hypothesis is added to Lemma 5.1 / Proposition 5.2 and -their sub-lemmas to make them provable with the present API. It holds in the intended applications -(e.g. `ζ'/ζ`, whose poles are all simple) and is to be removed once Mathlib gains general -higher-order residue support. -/ -def HasSimplePolesOn (f : ℂ → ℂ) (s : Set ℂ) : Prop := - ∀ z ∈ s, (-1 : ℤ) ≤ meromorphicOrderAt f z - -lemma HasSimplePolesOn.mono {f : ℂ → ℂ} {s t : Set ℂ} - (h : HasSimplePolesOn f t) (hst : s ⊆ t) : HasSimplePolesOn f s := by - intro z hz - exact h z (hst hz) - -/-- **Placeholder definition — valid only for simple poles.** The residue of `f` at `z₀`, defined -as the simple-pole limit `lim_{z → z₀} (z - z₀) · f z` (matching the convention of -`Phi_circ.residue` / `Phi_star.residue`). At a point of analyticity this is `0` and at a simple -pole it is the usual residue, but at a higher-order or essential singularity the limit diverges -and this returns a junk value. - -A general complex residue (and the residue theorem) is planned for Mathlib but not yet available, -so results stated in terms of this `residue` are likely **not provable in full generality** with -the current API. This is a deliberate stopgap, to be replaced with the robust notion once the -Mathlib residue-theorem API lands. -/ -noncomputable def residue (f : ℂ → ℂ) (z₀ : ℂ) : ℂ := - Filter.limUnder (nhdsWithin z₀ {z₀}ᶜ) (fun z ↦ (z - z₀) * f z) - -/-- The sum of residues of `f` over a region `S`, as a `tsum` over `S`. Points of analyticity -contribute `0`, so this is effectively the sum over the poles of `f` in `S`; when finitely many -poles lie in `S` the `tsum` equals the finite sum of their residues, regardless of `|S|`. (With -infinitely many poles, summability must be assumed for the value to be meaningful.) -/ -noncomputable def sumResiduesIn (f : ℂ → ℂ) (S : Set ℂ) : ℂ := - ∑' z : S, residue f z - -lemma residue_eq_of_tendsto {f : ℂ → ℂ} {p c : ℂ} - (h : Filter.Tendsto (fun z ↦ (z - p) * f z) (nhdsWithin p {p}ᶜ) (nhds c)) : - residue f p = c := by - unfold residue - exact h.limUnder_eq - -lemma residue_analyticAt_eq_zero {f : ℂ → ℂ} {p : ℂ} (hf : AnalyticAt ℂ f p) : - residue f p = 0 := by - apply residue_eq_of_tendsto - have hsub : Filter.Tendsto (fun z : ℂ ↦ z - p) (nhdsWithin p {p}ᶜ) (nhds 0) := - tendsto_sub_nhds_zero_iff.mpr (tendsto_id.mono_left nhdsWithin_le_nhds) - have hf' : Filter.Tendsto f (nhdsWithin p {p}ᶜ) (nhds (f p)) := - hf.continuousAt.continuousWithinAt.tendsto - simpa using hsub.mul hf' - -lemma simplePole_sub_residue_isBigO_one {f : ℂ → ℂ} {p : ℂ} - (hf : MeromorphicAt f p) (hord : meromorphicOrderAt f p = (-1 : ℤ)) : - (f - (fun z ↦ residue f p / (z - p))) =O[nhdsWithin p {p}ᶜ] (1 : ℂ → ℂ) := by - obtain ⟨g, hg_analytic, hg_ne, hg_eq⟩ := (meromorphicOrderAt_eq_int_iff hf).1 hord - have hres : residue f p = g p := - residue_eq_of_tendsto (hg_analytic.continuousAt.continuousWithinAt.tendsto.congr' - (show (fun z ↦ (z - p) * f z) =ᶠ[nhdsWithin p {p}ᶜ] g from by - filter_upwards [hg_eq, self_mem_nhdsWithin] with z hz hz_ne - simp [hz, sub_ne_zero.mpr hz_ne]).symm) - have hdslope : (fun z ↦ (z - p)⁻¹ * (g z - g p)) =O[nhdsWithin p {p}ᶜ] (1 : ℂ → ℂ) := by - have hcont : ContinuousAt (dslope g p) p := - continuousAt_dslope_same.2 hg_analytic.differentiableAt - have hbig : dslope g p =O[nhds p] (1 : ℂ → ℂ) := - hcont.norm.isBoundedUnder_le.isBigO_one ℂ - have hbig_ne : dslope g p =O[nhdsWithin p {p}ᶜ] (1 : ℂ → ℂ) := - IsBigO.mono hbig inf_le_left - simpa [slope] using! hbig_ne.congr' (dslope_eventuallyEq_slope_nhdsNE (f := g) (a := p)) .rfl - refine hdslope.congr' ?_ .rfl - filter_upwards [hg_eq, self_mem_nhdsWithin] with z hz hz_ne - simp [hz, hres, div_eq_mul_inv, sub_eq_add_neg]; ring - --- If two functions `f g : ℂ → ℂ` agree on a `codiscreteWithin R` full set, and `φ : ℝ → ℂ` is --- an analytic non-constant path mapping `[a,b]` into `R`, then `∫ f(φ x) dx = ∫ g(φ x) dx`. --- (a.e. agreement along the preimage suffices for interval integrals) -private lemma intervalIntegral_congr_ae_of_codiscreteWithin_along_path - {f g : ℂ → ℂ} {R : Set ℂ} - (heq : {s : ℂ | f s = g s} ∈ Filter.codiscreteWithin R) - {a b : ℝ} {p : ℝ → ℂ} - (hp_an : AnalyticOnNhd ℝ p (Set.uIcc a b)) - (hp_nonconst : ∀ x ∈ Set.uIcc a b, ¬Filter.EventuallyConst p (nhds x)) - (hp_maps : Set.MapsTo p (Set.uIcc a b) R) : - ∫ x in a..b, f (p x) = ∫ x in a..b, g (p x) := by - refine intervalIntegral.integral_congr_ae_restrict (μ := volume) ?_ - apply ae_restrict_le_codiscreteWithin measurableSet_uIoc - change {x : ℝ | f (p x) = g (p x)} ∈ Filter.codiscreteWithin (Set.uIoc a b) - simpa [Set.preimage] using Filter.codiscreteWithin_mono Set.uIoc_subset_uIcc - (hp_an.preimage_mem_codiscreteWithin hp_nonconst - (Filter.codiscreteWithin_mono - (by intro s hs; rcases hs with ⟨x, hx, rfl⟩; exact hp_maps hx) heq)) - --- Under `HasSimplePolesOn f U`, every point with strictly negative meromorphic order has order --- exactly -1: the simple-pole hypothesis gives `(-1 : ℤ) ≤ order`, negativity gives `order < 0`, --- so the only integer fitting both is -1. -private lemma meromorphicOrderAt_eq_neg_one_of_simplePole - {f : ℂ → ℂ} {U : Set ℂ} {p : ℂ} - (hpU : p ∈ U) - (hf_simple : HasSimplePolesOn f U) - (hpneg : meromorphicOrderAt f p < 0) : - meromorphicOrderAt f p = (-1 : ℤ) := by - lift meromorphicOrderAt f p to ℤ using hpneg.ne_top with n hn - have hsimple : (-1 : ℤ) ≤ n := WithTop.coe_le_coe.mp (hn ▸ hf_simple p hpU) - have hneg : n < 0 := by exact_mod_cast hpneg - have hn1 : n = -1 := by omega - simp [hn1] - --- At a simple pole `p` of `f` inside `U`, the residue of the meromorphic normal form --- `toMeromorphicNFOn f U` equals the residue of `f`. The two functions agree on a punctured --- neighborhood of `p` (by definition of the normal form), so their `(z - p) * ·` limits coincide. -private lemma residue_toMeromorphicNFOn_eq_residue - {f : ℂ → ℂ} {U : Set ℂ} {p : ℂ} - (hpU : p ∈ U) - (hf_mero : MeromorphicOn f U) - (hf_simple : HasSimplePolesOn f U) - (hpneg : meromorphicOrderAt f p < 0) : - residue (toMeromorphicNFOn f U) p = residue f p := by - have hmero : MeromorphicAt f p := hf_mero p hpU - have h_exists : ∃ c, Filter.Tendsto (fun z : ℂ ↦ (z - p) * f z) (nhdsWithin p ({p}ᶜ)) (nhds c) - := by - have hmul_mero : MeromorphicAt (fun z : ℂ ↦ (z - p) * f z) p := - (by fun_prop : MeromorphicAt (fun z : ℂ ↦ z - p) p).mul hmero - have hmul_nonneg : 0 ≤ meromorphicOrderAt (fun z : ℂ ↦ (z - p) * f z) p := by - change 0 ≤ meromorphicOrderAt ((fun z ↦ z - p) * f) p - rw [meromorphicOrderAt_mul (by fun_prop : MeromorphicAt (fun z : ℂ ↦ z - p) p) hmero, - meromorphicOrderAt_id_sub_const, - meromorphicOrderAt_eq_neg_one_of_simplePole hpU hf_simple hpneg] - norm_num - exact tendsto_nhds_of_meromorphicOrderAt_nonneg hmul_mero hmul_nonneg - have h_tendsto : Filter.Tendsto (fun z : ℂ ↦ (z - p) * f z) (nhdsWithin p ({p}ᶜ)) (nhds (residue - f p)) := by - simpa [residue] using tendsto_nhds_limUnder h_exists - have h_eq : - (fun z ↦ (z - p) * toMeromorphicNFOn f U z) =ᶠ[nhdsWithin p ({p}ᶜ)] - (fun z ↦ (z - p) * f z) := by - filter_upwards [hf_mero.toMeromorphicNFOn_eq_self_on_nhdsNE hpU] with z hz - simp [hz] - exact residue_eq_of_tendsto - (h_tendsto.congr' h_eq.symm) - --- Non-constancy of horizontal paths `x ↦ x + h * I`. -private lemma horizontalPath_not_eventuallyConst (h : ℝ) (x : ℝ) : - ¬Filter.EventuallyConst (fun r : ℝ ↦ (r : ℂ) + (h : ℂ) * Complex.I) (nhds x) := by - intro hc - obtain ⟨c, hc⟩ := Filter.eventuallyConst_iff_exists_eventuallyEq.1 hc - have hpath : HasDerivAt (fun r : ℝ ↦ (r : ℂ) + (h : ℂ) * Complex.I) 1 x := by - simpa using (Complex.ofRealCLM.hasDerivAt (x := x)).add_const ((h : ℂ) * Complex.I) - have hconst : HasDerivAt (fun r : ℝ ↦ (r : ℂ) + (h : ℂ) * Complex.I) 0 x := - (hasDerivAt_const x c).congr_of_eventuallyEq hc - exact one_ne_zero (hpath.unique hconst) - --- Non-constancy of vertical paths `y ↦ r + y * I`. -lemma verticalPath_not_eventuallyConst (r : ℝ) (x : ℝ) : - ¬Filter.EventuallyConst (fun y : ℝ ↦ (r : ℂ) + (y : ℂ) * Complex.I) (nhds x) := by - intro hc - obtain ⟨c, hc⟩ := Filter.eventuallyConst_iff_exists_eventuallyEq.1 hc - have hpath : HasDerivAt (fun y : ℝ ↦ (r : ℂ) + (y : ℂ) * Complex.I) Complex.I x := by - simpa using ((Complex.ofRealCLM.hasDerivAt (x := x)).mul_const Complex.I).const_add (r : ℂ) - have hconst : HasDerivAt (fun y : ℝ ↦ (r : ℂ) + (y : ℂ) * Complex.I) 0 x := - (hasDerivAt_const x c).congr_of_eventuallyEq hc - exact Complex.I_ne_zero (hpath.unique hconst) - --- Helper for horizontal integral congruence on codiscrete set -private lemma HIntegral_congr_codiscreteWithin {f g : ℂ → ℂ} {R : Set ℂ} {a b c : ℝ} - (h_eq : {s : ℂ | f s = g s} ∈ Filter.codiscreteWithin R) - (hmaps : ∀ x ∈ Set.uIcc a b, (↑x + ↑c * Complex.I) ∈ R) : - HIntegral f a b c = HIntegral g a b c := by - unfold HIntegral - exact intervalIntegral_congr_ae_of_codiscreteWithin_along_path h_eq - (by intro x _; exact (Complex.ofRealCLM.analyticAt x).add analyticAt_const) - (fun x _ ↦ horizontalPath_not_eventuallyConst c x) hmaps - --- Helper for vertical integral congruence on codiscrete set -private lemma VIntegral_congr_codiscreteWithin {f g : ℂ → ℂ} {R : Set ℂ} {c a b : ℝ} - (h_eq : {s : ℂ | f s = g s} ∈ Filter.codiscreteWithin R) - (hmaps : ∀ y ∈ Set.uIcc a b, (↑c + ↑y * Complex.I) ∈ R) : - VIntegral f c a b = VIntegral g c a b := by - unfold VIntegral; simp only [smul_eq_mul]; congr 1 - exact intervalIntegral_congr_ae_of_codiscreteWithin_along_path h_eq - (by intro y _; exact analyticAt_const.add ((Complex.ofRealCLM.analyticAt y).mul - analyticAt_const)) - (fun x _ ↦ verticalPath_not_eventuallyConst c x) hmaps - --- At the boundary, `f` and its normal-form representative differ only at a discrete set --- of poles, so their boundary integrals coincide. -private lemma rectangleIntegral'_toMeromorphicNFOn_eq {f : ℂ → ℂ} {z w : ℂ} - (f_mero : MeromorphicOn f (Rectangle z w)) : - RectangleIntegral' f z w = RectangleIntegral' (toMeromorphicNFOn f (Rectangle z w)) z w := by - classical - let R : Set ℂ := Rectangle z w - let fNF : ℂ → ℂ := toMeromorphicNFOn f R - have h_eq : {s : ℂ | f s = fNF s} ∈ Filter.codiscreteWithin R := by - simpa [Filter.EventuallyEq, Filter.Eventually, fNF] using - (toMeromorphicNFOn_eqOn_codiscrete (f := f) (U := R) f_mero) - have hbot := HIntegral_congr_codiscreteWithin h_eq - (by simpa [R] using! mapsTo_rectangle_left_im z w) - have htop := HIntegral_congr_codiscreteWithin h_eq - (by simpa [R] using! mapsTo_rectangle_right_im z w) - have hright := VIntegral_congr_codiscreteWithin h_eq - (by simpa [R] using! mapsTo_rectangle_right_re z w) - have hleft := VIntegral_congr_codiscreteWithin h_eq - (by simpa [R] using! mapsTo_rectangle_left_re z w) - unfold RectangleIntegral'; congr 1; unfold RectangleIntegral - rw [hbot, htop, hright, hleft] - -private lemma principalPart_meromorphicOn {R : Set ℂ} {polesFin : Finset ℂ} {c : ℂ → ℂ} : - MeromorphicOn (fun s ↦ ∑ p ∈ polesFin, c p / (s - p)) R := by - intro x _ - refine MeromorphicAt.fun_sum (G := fun p s ↦ c p / (s - p)) ?_ - intro p _ - exact (analyticAt_const.meromorphicAt.div - ((analyticAt_id.sub analyticAt_const).meromorphicAt)) - -private lemma sub_principalPart_analyticAt_of_not_mem_poles - {f : ℂ → ℂ} {polesFin : Finset ℂ} {x : ℂ} - (h_nf : MeromorphicNFAt f x) - (hxnp : x ∉ polesFin) - (hxneg : 0 ≤ meromorphicOrderAt f x) : - AnalyticAt ℂ (f - fun s ↦ ∑ p ∈ polesFin, residue f p / (s - p)) x := by - have h_f_analytic : AnalyticAt ℂ f x := - h_nf.meromorphicOrderAt_nonneg_iff_analyticAt.1 hxneg - have h_principal_analytic : AnalyticAt ℂ (fun s ↦ ∑ p ∈ polesFin, residue f p / (s - p)) x := by - refine Finset.analyticAt_fun_sum polesFin ?_ - intro p hp - have hxp : x ≠ p := by - intro heq - subst heq - exact hxnp hp - have : AnalyticAt ℂ (fun z : ℂ ↦ residue f p / (z - p)) x := by - fun_prop (disch := exact sub_ne_zero.mpr hxp) - simpa using this - exact h_f_analytic.sub h_principal_analytic - -private lemma meromorphicOrderAt_sub_principalPart_nonneg - {f : ℂ → ℂ} {polesFin : Finset ℂ} {p : ℂ} - (hpFin : p ∈ polesFin) - (h_mero : MeromorphicAt f p) - (h_ord : meromorphicOrderAt f p = -1) : - 0 ≤ meromorphicOrderAt (f - fun s ↦ ∑ q ∈ polesFin, residue f q / (s - q)) p := by - have hcore : (f - fun z ↦ residue f p / (z - p)) =O[nhdsWithin p ({p}ᶜ)] (1 : ℂ → ℂ) := by - exact simplePole_sub_residue_isBigO_one h_mero h_ord - let rest : ℂ → ℂ := fun z ↦ ∑ q ∈ polesFin.erase p, residue f q / (z - q) - have hrest_cont : ContinuousAt rest p := by - dsimp [rest] - refine tendsto_finsetSum _ (fun q hq ↦ ?_) - have hpq : p - q ≠ 0 := sub_ne_zero.mpr (Finset.mem_erase.mp hq).1.symm - have h_cont : ContinuousAt (fun z : ℂ ↦ residue f q / (z - q)) p := by - fun_prop (disch := exact hpq) - exact h_cont - have hrest : rest =O[nhdsWithin p ({p}ᶜ)] (1 : ℂ → ℂ) := by - have hbig : rest =O[nhds p] (1 : ℂ → ℂ) := - hrest_cont.norm.isBoundedUnder_le.isBigO_one ℂ - exact IsBigO.mono hbig inf_le_left - have hraw_big : (f - fun s ↦ ∑ q ∈ polesFin, residue f q / (s - q)) =O[nhdsWithin p ({p}ᶜ)] (1 : - ℂ → ℂ) := by - have htmp : (fun z : ℂ ↦ (f z - residue f p / (z - p)) - rest z) =O[nhdsWithin p ({p}ᶜ)] (1 : - ℂ → ℂ) := - hcore.sub hrest - have hdecomp : (f - fun s ↦ ∑ q ∈ polesFin, residue f q / (s - q)) = - (fun z : ℂ ↦ (f z - residue f p / (z - p)) - rest z) := by - funext z - dsimp [rest] - rw [← Finset.add_sum_erase (s := polesFin) (f := fun q ↦ residue f q / (z - q)) hpFin] - simp [sub_eq_add_neg, add_assoc, add_comm] - simpa [hdecomp, rest] using htmp - by_contra hneg - have hnorm : Filter.Tendsto (fun z : ℂ ↦ ‖(f - fun s ↦ ∑ q ∈ polesFin, residue f q / (s - q)) - z‖) (nhdsWithin p ({p}ᶜ)) Filter.atTop := by - rw [tendsto_norm_atTop_iff_cobounded] - exact tendsto_cobounded_of_meromorphicOrderAt_neg (not_le.mp hneg) - exact (Filter.not_isBoundedUnder_of_tendsto_atTop hnorm) hraw_big.isBoundedUnder_le - -private lemma holoPart_holomorphicOn {f : ℂ → ℂ} {z w : ℂ} - (f_mero : MeromorphicOn f (Rectangle z w)) - (f_simple_poles : HasSimplePolesOn f (Rectangle z w)) - (f_poles_finite : (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}).Finite) : - HolomorphicOn (toMeromorphicNFOn (toMeromorphicNFOn f (Rectangle z w) - - fun s ↦ ∑ p ∈ f_poles_finite.toFinset, residue (toMeromorphicNFOn f (Rectangle z w)) p / (s - - p)) (Rectangle z w)) (Rectangle z w) := by - classical - let R := Rectangle z w - let poles := R ∩ {u | meromorphicOrderAt f u < 0} - let polesFin := f_poles_finite.toFinset - let fNF := toMeromorphicNFOn f R - let principalPart := fun s ↦ ∑ p ∈ polesFin, residue fNF p / (s - p) - let holoPart := toMeromorphicNFOn (fNF - principalPart) R - have h_fNF_mero : MeromorphicOn fNF R := by - simpa [fNF] using - (meromorphicNFOn_toMeromorphicNFOn (f := f) (U := R)).meromorphicOn - have h_principalPart_mero : MeromorphicOn principalPart R := principalPart_meromorphicOn - have h_raw_mero : MeromorphicOn (fNF - principalPart) R := h_fNF_mero.sub h_principalPart_mero - intro x hx - have h_raw_nonneg : 0 ≤ meromorphicOrderAt (fNF - principalPart) x := by - by_cases hxp : x ∈ poles - · have hpFin : x ∈ polesFin := by simpa [polesFin, poles] using hxp - have hord : meromorphicOrderAt f x = (-1 : ℤ) := - meromorphicOrderAt_eq_neg_one_of_simplePole hxp.1 f_simple_poles hxp.2 - have hordNF : meromorphicOrderAt fNF x = (-1 : ℤ) := by - rw [show meromorphicOrderAt fNF x = meromorphicOrderAt f x by - simpa [fNF] using - (meromorphicOrderAt_toMeromorphicNFOn (f := f) (U := R) f_mero hxp.1)] - exact hord - exact meromorphicOrderAt_sub_principalPart_nonneg hpFin (h_fNF_mero x hxp.1) hordNF - · have hxnp : x ∉ polesFin := by - intro h - exact hxp (by simpa [polesFin, poles] using h) - have h_fNF_nonneg : 0 ≤ meromorphicOrderAt fNF x := by - rw [show meromorphicOrderAt fNF x = meromorphicOrderAt f x by - simpa [fNF] using - (meromorphicOrderAt_toMeromorphicNFOn (f := f) (U := R) f_mero hx)] - exact le_of_not_gt fun hxneg => hxp ⟨hx, hxneg⟩ - have h_fNF_nf : MeromorphicNFAt fNF x := by - simpa [fNF] using - (meromorphicNFOn_toMeromorphicNFOn (f := f) (U := R) hx) - exact (sub_principalPart_analyticAt_of_not_mem_poles h_fNF_nf hxnp - h_fNF_nonneg).meromorphicOrderAt_nonneg - have h_nf : MeromorphicNFAt holoPart x := by - simpa [holoPart] using - (meromorphicNFOn_toMeromorphicNFOn (f := fNF - principalPart) (U := R) hx) - have h_ord : - meromorphicOrderAt holoPart x = meromorphicOrderAt (fNF - principalPart) x := by - simpa [holoPart] using - (meromorphicOrderAt_toMeromorphicNFOn (f := fNF - principalPart) (U := R) h_raw_mero hx) - exact (h_nf.meromorphicOrderAt_nonneg_iff_analyticAt.1 (h_ord.symm ▸ - h_raw_nonneg)).differentiableAt.differentiableWithinAt - --- Since no poles lie on the boundary of the rectangle, the principal part is continuous --- on the boundary and therefore integrable. -private lemma principalPart_borderIntegrable {f : ℂ → ℂ} {z w : ℂ} - (f_no_poles_boundary : Disjoint (RectangleBorder z w) {z | meromorphicOrderAt f z < 0}) - (f_poles_finite : (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}).Finite) : - RectangleBorderIntegrable (fun s ↦ ∑ p ∈ f_poles_finite.toFinset, residue (toMeromorphicNFOn f - (Rectangle z w)) p / (s - p)) z w := by - classical - let R := Rectangle z w - let poles := R ∩ {u | meromorphicOrderAt f u < 0} - let polesFin := f_poles_finite.toFinset - let fNF := toMeromorphicNFOn f R - let principalPart := fun s ↦ ∑ p ∈ polesFin, residue fNF p / (s - p) - refine ContinuousOn.rectangleBorder_integrable ?_ - refine continuousOn_finsetSum _ ?_ - intro p hp s hs - have hsp : s ≠ p := fun hsp => Set.disjoint_right.mp f_no_poles_boundary - ((by simpa [polesFin, poles] using hp : p ∈ poles).2) (hsp ▸ hs) - have : ContinuousAt (fun z : ℂ ↦ residue fNF p / (z - p)) s := by - fun_prop (disch := exact sub_ne_zero.mpr hsp) - exact this.continuousWithinAt - -private lemma rectangle_mem_nhds_of_interior {z w p : ℂ} - (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : z.im ≤ w.im) - (hpR : p ∈ Rectangle z w) (hpnot : p ∉ RectangleBorder z w) : - Rectangle z w ∈ nhds p := by - rw [mem_Rect zRe_le_wRe zIm_le_wIm] at hpR - have hp_re_left : z.re < p.re := - lt_of_le_of_ne hpR.1 fun hEq => hpnot - (by simp [RectangleBorder, hEq, hpR.2.2.1, hpR.2.2.2, zIm_le_wIm, mem_reProdIm]) - have hp_re_right : p.re < w.re := - lt_of_le_of_ne hpR.2.1 fun hEq => hpnot - (by simp [RectangleBorder, hEq, hpR.2.2.1, hpR.2.2.2, zIm_le_wIm, mem_reProdIm]) - have hp_im_left : z.im < p.im := - lt_of_le_of_ne hpR.2.2.1 fun hEq => hpnot - (by simp [RectangleBorder, hEq, hpR.1, hpR.2.1, zRe_le_wRe, mem_reProdIm]) - have hp_im_right : p.im < w.im := - lt_of_le_of_ne hpR.2.2.2 fun hEq => hpnot - (by simp [RectangleBorder, hEq, hpR.1, hpR.2.1, zRe_le_wRe, mem_reProdIm]) - rw [rectangle_mem_nhds_iff, mem_reProdIm, Set.uIoo_of_le zRe_le_wRe, Set.uIoo_of_le zIm_le_wIm] - exact ⟨⟨hp_re_left, hp_re_right⟩, ⟨hp_im_left, hp_im_right⟩⟩ - -private lemma sum_div_rectangleBorderIntegrable {z w : ℂ} {S : Finset ℂ} - (hS_disjoint : Disjoint (RectangleBorder z w) S) (c : ℂ → ℂ) : - RectangleBorderIntegrable (fun s ↦ ∑ p ∈ S, c p / (s - p)) z w := by - refine ContinuousOn.rectangleBorder_integrable ?_ - refine continuousOn_finsetSum _ ?_ - intro p hp s hs - have hsp : s ≠ p := fun hsp => Set.disjoint_right.mp hS_disjoint hp (hsp ▸ hs) - have : ContinuousAt (fun z : ℂ ↦ c p / (z - p)) s := by - fun_prop (disch := exact sub_ne_zero.mpr hsp) - exact this.continuousWithinAt - --- The integral of a sum of simple pole terms `c p / (s - p)` along the boundary of the rectangle --- equals the sum of the coefficients `c p` for all points `p` in the interior. -private lemma rectangleIntegral'_sum_div_sub {z w : ℂ} (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : - z.im ≤ w.im) - {S : Finset ℂ} (hS_subset : (S : Set ℂ) ⊆ Rectangle z w) - (hS_disjoint : Disjoint (RectangleBorder z w) S) - (c : ℂ → ℂ) : - RectangleIntegral' (fun s ↦ ∑ p ∈ S, c p / (s - p)) z w = ∑ p ∈ S, c p := by - classical - have h_partial_border : ∀ (S' : Finset ℂ), S' ⊆ S → RectangleBorderIntegrable (fun s ↦ ∑ p ∈ S', - c p / (s - p)) z w := by - intro S' hS' - exact sum_div_rectangleBorderIntegrable (Disjoint.mono_right hS' hS_disjoint) c - have h_term_integral : ∀ {p : ℂ}, p ∈ S → RectangleIntegral' (fun s ↦ c p / (s - p)) z w = c p := - fun {p} hp => ResidueTheoremInRectangle zRe_le_wRe zIm_le_wIm - (rectangle_mem_nhds_of_interior zRe_le_wRe zIm_le_wIm - (hS_subset hp) (Set.disjoint_right.mp hS_disjoint hp)) - have h_partial_integral : - ∀ (S' : Finset ℂ), S' ⊆ S → - RectangleIntegral' (fun s ↦ ∑ p ∈ S', c p / (s - p)) z w = - ∑ p ∈ S', c p := by - intro S' hS' - revert hS' - refine Finset.induction_on S' ?_ ?_ - · intro _ - simp [RectangleIntegral', RectangleIntegral, HIntegral, VIntegral] - · intro a S' ha ih hS' - obtain ⟨haFin, hSsub⟩ := Finset.insert_subset_iff.mp hS' - have hterm_border : - RectangleBorderIntegrable (fun s ↦ c a / (s - a)) z w := - by simpa using h_partial_border ({a} : Finset ℂ) (Finset.singleton_subset_iff.mpr haFin) - have hfun : - (fun s ↦ ∑ p ∈ insert a S', c p / (s - p)) = - (fun s ↦ c a / (s - a)) + - (fun s ↦ ∑ p ∈ S', c p / (s - p)) := by - funext s; simp [Finset.sum_insert, ha] - have h_add_primed : - RectangleIntegral' ((fun s ↦ c a / (s - a)) + (fun s ↦ ∑ p ∈ S', c p / (s - p))) z w = - RectangleIntegral' (fun s ↦ c a / (s - a)) z w + - RectangleIntegral' (fun s ↦ ∑ p ∈ S', c p / (s - p)) z w := by - unfold RectangleIntegral' - rw [RectangleBorderIntegrable.add hterm_border (h_partial_border S' hSsub), smul_add] - rw [hfun, h_add_primed, h_term_integral haFin, ih hSsub, Finset.sum_insert ha] - exact h_partial_integral S (by intro p hp; exact hp) - --- Splits the integral of `fNF` into the integral of its holomorphic part and its principal part. -private lemma toMeromorphicNFOn_add_integral {f : ℂ → ℂ} {z w : ℂ} - (f_mero : MeromorphicOn f (Rectangle z w)) - (f_no_poles_boundary : Disjoint (RectangleBorder z w) {z | meromorphicOrderAt f z < 0}) - (f_poles_finite : (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}).Finite) - (f_simple_poles : HasSimplePolesOn f (Rectangle z w)) : - RectangleIntegral' (toMeromorphicNFOn f (Rectangle z w)) z w = - RectangleIntegral' (toMeromorphicNFOn (toMeromorphicNFOn f (Rectangle z w) - - fun s ↦ ∑ p ∈ f_poles_finite.toFinset, residue (toMeromorphicNFOn f (Rectangle z w)) p / - (s - p)) (Rectangle z w)) z w + - RectangleIntegral' (fun s ↦ ∑ p ∈ f_poles_finite.toFinset, residue (toMeromorphicNFOn f - (Rectangle z w)) p / (s - p)) z w := by - let R : Set ℂ := Rectangle z w - let poles : Set ℂ := R ∩ {u | meromorphicOrderAt f u < 0} - let polesFin : Finset ℂ := f_poles_finite.toFinset - let fNF : ℂ → ℂ := toMeromorphicNFOn f R - let principalPart : ℂ → ℂ := fun s ↦ ∑ p ∈ polesFin, residue fNF p / (s - p) - let holoPart : ℂ → ℂ := toMeromorphicNFOn (fNF - principalPart) R - have h_holoPart_border : RectangleBorderIntegrable holoPart z w := - (holoPart_holomorphicOn f_mero f_simple_poles f_poles_finite).rectangleBorderIntegrable - have h_fNF_eq : - Set.EqOn fNF (holoPart + principalPart) (RectangleBorder z w) := by - intro s hs - have hsR : s ∈ R := rectangleBorder_subset_rectangle z w hs - have hsnp : s ∉ poles := fun hsp => Set.disjoint_right.mp f_no_poles_boundary hsp.2 hs - have hraw_analytic : AnalyticAt ℂ (fNF - principalPart) s := by - have h_fNF_nonneg : 0 ≤ meromorphicOrderAt fNF s := by - rw [show meromorphicOrderAt fNF s = meromorphicOrderAt f s by - simpa [fNF] using - (meromorphicOrderAt_toMeromorphicNFOn (f := f) (U := R) f_mero hsR)] - exact le_of_not_gt fun hsneg => hsnp ⟨hsR, hsneg⟩ - exact sub_principalPart_analyticAt_of_not_mem_poles - (by simpa [fNF] using meromorphicNFOn_toMeromorphicNFOn (f := f) (U := R) hsR) - (fun h => hsnp (by simpa [polesFin, poles] using h)) - h_fNF_nonneg - have hs_eq : holoPart s = (fNF - principalPart) s := by - rw [show holoPart = toMeromorphicNFOn (fNF - principalPart) R by rfl] - have h_fNF_mero : MeromorphicOn fNF R := by - simpa [fNF] using (meromorphicNFOn_toMeromorphicNFOn (f := f) (U := R)).meromorphicOn - have hf_sub_mero : MeromorphicOn (fNF - principalPart) R := - h_fNF_mero.sub principalPart_meromorphicOn - rw [toMeromorphicNFOn_eq_toMeromorphicNFAt (f := fNF - principalPart) (U := R) hf_sub_mero - hsR] - exact congr_fun (toMeromorphicNFAt_eq_self.2 hraw_analytic.meromorphicNFAt) s - calc - fNF s = (fNF - principalPart) s + principalPart s := by simp - _ = holoPart s + principalPart s := by rw [← hs_eq] - rw [RectangleIntegral'_congr h_fNF_eq, RectangleIntegral', - RectangleBorderIntegrable.add h_holoPart_border - (principalPart_borderIntegrable f_no_poles_boundary f_poles_finite), smul_add] - -/-- The Residue Theorem on a rectangle for functions with simple poles. -/ -lemma RectangleIntegral'_eq_sumResiduesIn {f : ℂ → ℂ} {z w : ℂ} - (zRe_le_wRe : z.re ≤ w.re) (zIm_le_wIm : z.im ≤ w.im) - (f_mero : MeromorphicOn f (Rectangle z w)) - (f_no_poles_boundary : Disjoint (RectangleBorder z w) {z | meromorphicOrderAt f z < 0}) - (f_poles_finite : (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}).Finite) - (f_simple_poles : HasSimplePolesOn f (Rectangle z w)) : - RectangleIntegral' f z w = sumResiduesIn f (Rectangle z w ∩ {z | meromorphicOrderAt f z < 0}) - := by - let R : Set ℂ := Rectangle z w - let poles : Set ℂ := R ∩ {u | meromorphicOrderAt f u < 0} - let polesFin : Finset ℂ := f_poles_finite.toFinset - let fNF : ℂ → ℂ := toMeromorphicNFOn f R - let principalPart : ℂ → ℂ := fun s ↦ ∑ p ∈ polesFin, residue fNF p / (s - p) - let holoPart : ℂ → ℂ := toMeromorphicNFOn (fNF - principalPart) R - have h_residue_congr : sumResiduesIn f poles = sumResiduesIn fNF poles := by - rw [sumResiduesIn, sumResiduesIn] - apply tsum_congr - intro p - exact (residue_toMeromorphicNFOn_eq_residue p.2.1 f_mero f_simple_poles p.2.2).symm - have h_principalPart_integral : RectangleIntegral' principalPart z w = sumResiduesIn fNF poles - := by - have h_sum : RectangleIntegral' principalPart z w = ∑ p ∈ polesFin, residue fNF p := by - apply rectangleIntegral'_sum_div_sub zRe_le_wRe zIm_le_wIm - · intro p hp - dsimp [polesFin, poles, R] at hp - simp only [Finset.mem_coe, Set.Finite.mem_toFinset] at hp - exact hp.1 - · exact Disjoint.mono_right (by rw [f_poles_finite.coe_toFinset]; exact - Set.inter_subset_right) f_no_poles_boundary - rw [h_sum] - have h_eq_poles : poles = ↑polesFin := by - dsimp [poles, polesFin, R] - exact f_poles_finite.coe_toFinset.symm - rw [sumResiduesIn, h_eq_poles, - tsum_fintype (f := fun p : (polesFin : Set ℂ) => residue fNF p), - ← Finset.sum_coe_sort polesFin]; rfl - calc - RectangleIntegral' f z w = RectangleIntegral' fNF z w := - rectangleIntegral'_toMeromorphicNFOn_eq f_mero - _ = RectangleIntegral' holoPart z w + RectangleIntegral' principalPart z w := - toMeromorphicNFOn_add_integral f_mero f_no_poles_boundary f_poles_finite f_simple_poles - _ = 0 + sumResiduesIn fNF poles := by - rw [h_principalPart_integral] - rw [RectangleIntegral', - (holoPart_holomorphicOn f_mero f_simple_poles f_poles_finite).vanishesOnRectangle - subset_rfl] - simp - _ = sumResiduesIn fNF poles := by simp - _ = sumResiduesIn f poles := h_residue_congr.symm - -lemma residue_eq_zero_of_not_pole_of_meromorphicAt {F : ℂ → ℂ} {s : ℂ} - (hs_mero : MeromorphicAt F s) (hs_not_pole : 0 ≤ meromorphicOrderAt F s) : - residue F s = 0 := by - apply residue_eq_of_tendsto - obtain ⟨c, hc⟩ := tendsto_nhds_of_meromorphicOrderAt_nonneg hs_mero hs_not_pole - have hsub : Filter.Tendsto (fun z : ℂ ↦ z - s) (nhdsWithin s {s}ᶜ) (nhds 0) := - tendsto_sub_nhds_zero_iff.mpr (tendsto_id.mono_left nhdsWithin_le_nhds) - simpa using hsub.mul hc - -lemma sumResiduesIn_inter_eq_of_set_eq {F : ℂ → ℂ} {Rn S2 P : Set ℂ} - (h_set_eq : Rn ∩ P = S2 ∩ P) - (h_residue_zero : ∀ s ∈ S2, s ∉ P → residue F s = 0) : - sumResiduesIn F (Rn ∩ P) = sumResiduesIn F S2 := by - rw [sumResiduesIn, sumResiduesIn, tsum_subtype, tsum_subtype] - apply tsum_congr - intro s - by_cases hs_S2 : s ∈ S2 - · by_cases hs_pole : s ∈ P - · have hs_rect_pole : s ∈ Rn ∩ P := h_set_eq.symm ▸ ⟨hs_S2, hs_pole⟩ - simp [hs_S2, hs_rect_pole] - · have hs_not_rect_pole : s ∉ Rn ∩ P := fun hs => hs_pole hs.2 - have hres0 : residue F s = 0 := h_residue_zero s hs_S2 hs_pole - simp [hs_S2, hs_not_rect_pole, hres0] - · have hs_not_rect_pole : s ∉ Rn ∩ P := fun hs => hs_S2 (h_set_eq ▸ hs).1 - simp [hs_S2, hs_not_rect_pole] - end IwaniecLinearSievePNT diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/StrongPNT.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/StrongPNT.lean index eb46f659a..a81b9a347 100644 --- a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/StrongPNT.lean +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/StrongPNT.lean @@ -6,6 +6,7 @@ Authors: PrimeNumberTheoremAnd contributors module +public import Mathlib.Analysis.Analytic.Order public import Mathlib.Analysis.CStarAlgebra.Classes public import LeanPool.IwaniecLinearSieve.Vendor.PrimeNumberTheoremAnd.MediumPNT import Mathlib.Algebra.Order.Star.Real From b02090ffa725d5a099f47f1da5a2ea5ac0d5431f Mon Sep 17 00:00:00 2001 From: Vasily Ilin Date: Wed, 21 Oct 2026 11:18:13 +0000 Subject: [PATCH 4/5] Replace nonlinear count estimates with explicit monotonicity --- .../LinearSieve/TheoremFiveCount.lean | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveCount.lean b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveCount.lean index 050dde37d..1ad0535ed 100644 --- a/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveCount.lean +++ b/LeanPool/IwaniecLinearSieve/LinearSieve/TheoremFiveCount.lean @@ -434,11 +434,16 @@ theorem exists_card_small : ∃ y₀ : ℝ, ∀ y ≥ y₀, ∀ (lower : Bool) ( have hxl : 4 * (xi y * lam y ^ 2) ≤ log y := by have hsplit : lam y ^ (11 / 5 : ℝ) = lam y ^ 2 * lam y ^ (1 / 5 : ℝ) := by rw [← rpow_natCast, ← rpow_add hm0]; norm_num - rw [xi_eq_lam, hsplit] have hμ0 : 0 < lam y ^ (1 / 5 : ℝ) := rpow_pos_of_pos hm0 _ - rw [div_mul_eq_mul_div, mul_div_assoc', div_le_iff₀ (by positivity)] - have : 4 ≤ lam y ^ (1 / 5 : ℝ) := by linarith - nlinarith [mul_pos hL0 (pow_pos hm0 2)] + have hμ4 : 4 ≤ lam y ^ (1 / 5 : ℝ) := + (show (4 : ℝ) ≤ 100 by norm_num).trans (hc1.trans hμ) + rw [xi_eq_lam, hsplit] + calc + 4 * (log y / (lam y ^ 2 * lam y ^ (1 / 5 : ℝ)) * lam y ^ 2) = + (4 / lam y ^ (1 / 5 : ℝ)) * log y := by + field_simp [hm0.ne', hμ0.ne'] + _ ≤ 1 * log y := mul_le_mul_of_nonneg_right ((div_le_one hμ0).2 hμ4) hL0.le + _ = log y := one_mul _ have hcrude := crude_exponent_le hL0 rfl hℓ1 (by linarith) (a := log (lam y)) (by linarith) hxl h24 h16 h10 have hB := exp_le_delta_errMaj hcG0 hG hy1 (by linarith) (by linarith) h8 (by linarith) h10 @@ -450,7 +455,9 @@ theorem exists_card_small : ∃ y₀ : ℝ, ∀ y ≥ y₀, ∀ (lower : Bool) ( calc (1 + (#(rosserSet lower y (y ^ (1 / (xi y - 1)))) : ℝ)) * (8 * log y ^ 4) ≤ 8 * log y ^ 4 * (1 + exp (log y + 2 * xi y - log y / lam y) + 2 * exp (log y - xi y * log (xi y) + xi y * log (lam y) + 5 * xi y)) := by - nlinarith [pow_pos hL0 4] + simpa only [add_comm, add_left_comm, add_assoc, mul_comm] using + mul_le_mul_of_nonneg_left (add_le_add_left hcard 1) + (by positivity : 0 ≤ 8 * log y ^ 4) _ ≤ y * exp (-(xi y * log (xi y)) + 3 / 2 * xi y * log (lam y)) := hcrude.trans hy'.le _ ≤ y * (delta s y * errMaj lower s) := by gcongr _ = delta s y * errMaj lower s * y := by ring From 5335fa1de5f83b86bafccdf250dcd7343c4f7eaa Mon Sep 17 00:00:00 2001 From: Vasily Ilin Date: Wed, 21 Oct 2026 12:35:21 +0000 Subject: [PATCH 5/5] refactor(IwaniecLinearSieve): share zeta estimates and simplify contour proofs --- .../PrimeNumberTheoremAnd/MediumPNT.lean | 8 +- .../ResidueCalcOnRectangles.lean | 25 +- .../PrimeNumberTheoremAnd/ZetaBounds.lean | 306 +++--------------- 3 files changed, 53 insertions(+), 286 deletions(-) diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MediumPNT.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MediumPNT.lean index 330fe578d..72c402315 100644 --- a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MediumPNT.lean +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/MediumPNT.lean @@ -1806,13 +1806,7 @@ theorem I1Bound rw [trivialize] at final_bound_pointwise exact final_bound_pointwise have σ₀_gt : 1 < pts_re := pts_re_ge_1 - have σ₀_le_2 : pts_re ≤ 2 := by - unfold pts_re - -- LOL! - exact - Preorder.le_trans (1 + (Real.log X)⁻¹) (pts (SmoothingF (SmoothingF M))).re 2 - (triv_pts_lo_bound (SmoothingF (SmoothingF M))) - (triv_pts_up_bound (SmoothingF (SmoothingF M))) + have σ₀_le_2 : pts_re ≤ 2 := pts_re_le_one.le have f_integrable := SmoothedChebyshevPull1_aux_integrable eps_pos eps_less_one X_large σ₀_gt σ₀_le_2 suppSmoothingF SmoothingFnonneg mass_one ContDiffSmoothingF have S : X^pts_re = rexp 1 * X := by diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean index 9832a34ee..812fa9f8b 100644 --- a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ResidueCalcOnRectangles.lean @@ -278,30 +278,7 @@ lemma RectangleIntegralHSplit {a x₀ x₁ y₀ y₁ : ℝ} Complex.I_im, mul_one, mul_zero, add_zero, zero_add, sub_self] have h₁ := integral_add_adjacent_intervals f_int_x₀_a_bot f_int_a_x₁_bot have h₂ := integral_add_adjacent_intervals f_int_x₀_a_top f_int_a_x₁_top - have h₁' : - (∫ (x : ℝ) in x₀..a, f (↑x + ↑y₀ * I)) + - ∫ (x : ℝ) in a..x₁, f (↑y₀ * I + ↑x) = - ∫ (x : ℝ) in x₀..x₁, f (↑x + ↑y₀ * I) := by - simpa [add_comm] using h₁ - have h₂' : - (∫ (x : ℝ) in x₀..a, f (↑x + ↑y₁ * I)) + - ∫ (x : ℝ) in a..x₁, f (↑y₁ * I + ↑x) = - ∫ (x : ℝ) in x₀..x₁, f (↑x + ↑y₁ * I) := by - simpa [add_comm] using h₂ - rw [← h₁', ← h₂'] - have hcomm₁ : - ∫ (x : ℝ) in a..x₁, f (↑y₀ * I + ↑x) = - ∫ (x : ℝ) in a..x₁, f (↑x + ↑y₀ * I) := by - apply intervalIntegral.integral_congr - intro x _ - exact congrArg f (by ring) - have hcomm₂ : - ∫ (x : ℝ) in a..x₁, f (↑y₁ * I + ↑x) = - ∫ (x : ℝ) in a..x₁, f (↑x + ↑y₁ * I) := by - apply intervalIntegral.integral_congr - intro x _ - exact congrArg f (by ring) - rw [hcomm₁, hcomm₂] + rw [← h₁, ← h₂] abel lemma RectangleIntegralHSplit' {a x₀ x₁ y₀ y₁ : ℝ} diff --git a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaBounds.lean b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaBounds.lean index f7a543218..dc3b51be8 100644 --- a/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaBounds.lean +++ b/LeanPool/IwaniecLinearSieve/Vendor/PrimeNumberTheoremAnd/ZetaBounds.lean @@ -2368,26 +2368,10 @@ The identity -/ lemma ZetaInvBound1 {σ t : ℝ} (σ_gt : 1 < σ) : 1 / ‖ζ (σ + t * I)‖ ≤ ‖ζ σ‖ ^ ((3 : ℝ) / 4) * ‖ζ (σ + 2 * t * I)‖ ^ ((1 : ℝ) / 4) := by - apply (div_le_iff₀ ?_).mpr - · apply (Real.rpow_le_rpow_iff (z := 4) (by norm_num) ?_ (by norm_num)).mp - · simp only [Real.one_rpow] - rw [Real.mul_rpow, Real.mul_rpow, ← Real.rpow_mul, ← Real.rpow_mul] - · simp only [isUnit_iff_ne_zero, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, - IsUnit.div_mul_cancel, Real.rpow_one] - conv => rw [mul_assoc]; rhs; rhs; rw [mul_comm] - rw [← mul_assoc] - have := norm_zeta_product_ge_one (x := σ - 1) (by linarith) t - simp_rw [ge_iff_le, norm_mul, norm_pow, ofReal_sub, ofReal_one, add_sub_cancel, ← - Real.rpow_natCast] at this - convert this using 3 <;> ring_nf - any_goals ring_nf - any_goals apply norm_nonneg - any_goals apply Real.rpow_nonneg <| norm_nonneg _ - apply mul_nonneg <;> apply Real.rpow_nonneg <| norm_nonneg _ - · refine mul_nonneg (mul_nonneg ?_ ?_) ?_ <;> simp [Real.rpow_nonneg] - · have s_ne_one : σ + t * I ≠ 1 := by - contrapose! σ_gt; apply le_of_eq; apply And.left; simpa [Complex.ext_iff] using σ_gt - simpa using riemannZeta_ne_zero_of_one_le_re (by simp [σ_gt.le]) + have lower := ZetaLowerBound1 (t := t) σ_gt + have positive : 0 < ‖ζ (σ + t * I)‖ := + pos_of_mul_pos_right (zero_lt_one.trans_le lower) (by positivity) + exact (div_le_iff₀ positive).mpr lower lemma Ioi_union_Iio_mem_cocompact {a : ℝ} (ha : 0 ≤ a) : Ioi (a : ℝ) ∪ Iio (-a : ℝ) ∈ cocompact ℝ := by @@ -2414,90 +2398,17 @@ Combine Lemma \ref{ZetaInvBound1} with the bounds in Lemmata \ref{ZetaNear1BndEx lemma ZetaInvBound2 : ∃ C > 0, ∀ {σ : ℝ} (_ : σ ∈ Ioc 1 2) (t : ℝ) (_ : 3 < |t|), 1 / ‖ζ (σ + t * I)‖ ≤ C * (σ - 1) ^ (-(3 : ℝ) / 4) * (Real.log |t|) ^ ((1 : ℝ) / 4) := by - obtain ⟨A, ha, C, hC, h⟩ := ZetaUpperBnd - obtain ⟨c, hc, h_inv⟩ := ZetaNear1BndExact - refine ⟨(2 * C) ^ ((1 : ℝ)/ 4) * c ^ ((3 : ℝ)/ 4), by positivity, ?_⟩ - intro σ hσ t t_gt - obtain ⟨σ_gt, σ_le⟩ := hσ - have ht' : 3 < |2 * t| := by simp only [abs_mul, Nat.abs_ofNat]; linarith - have hnezero: ((σ - 1) / c) ^ (-3 / 4 : ℝ) ≠ 0 := by - have : (σ - 1) / c ≠ 0 := ne_of_gt <| div_pos (by linarith) hc - contrapose! this - rwa [Real.rpow_eq_zero (div_nonneg (by linarith) hc.le) (by norm_num)] at this + obtain ⟨c, hc, lower⟩ := ZetaLowerBound3 + refine ⟨c⁻¹, inv_pos.mpr hc, ?_⟩ + intro σ hσ t ht + have positive_sigma : 0 < σ - 1 := sub_pos.mpr hσ.1 + have positive_log : 0 < Real.log |t| := Real.log_pos (by linarith) calc - _ ≤ ‖‖ζ σ‖ ^ (3 / 4 : ℝ) * ‖ζ (↑σ + 2 * ↑t * I)‖ ^ (1 / 4 : ℝ)‖ := ?_ - _ ≤ ‖((σ - 1) / c) ^ (-3 / 4 : ℝ) * ‖ζ (↑σ + 2 * ↑t * I)‖ ^ (1 / 4 : ℝ)‖ := ?_ - _ ≤ ‖((σ - 1) / c) ^ (-3 / 4 : ℝ) * C ^ (1 / 4 : ℝ) * (Real.log |2 * t|) ^ (1 / 4 : ℝ)‖ := ?_ - _ ≤ ‖((σ - 1) / c) ^ (-3 / 4 : ℝ) * C ^ (1 / 4 : ℝ) * (Real.log (|t| ^ 2)) ^ (1 / 4 : ℝ)‖ := ?_ - _ = ‖((σ - 1)) ^ (-3 / 4 : ℝ) * c ^ (3 / 4 : ℝ) * (C ^ (1 / 4 : ℝ) * (Real.log (|t| ^ 2)) ^ (1 - / 4 : ℝ))‖ := ?_ - _ = ‖((σ - 1)) ^ (-3 / 4 : ℝ) * c ^ (3 / 4 : ℝ) * ((2 * C) ^ (1 / 4 : ℝ) * Real.log |t| ^ (1 / - 4 : ℝ))‖ := ?_ - _ = _ := ?_ - · simp only [norm_mul] - convert ZetaInvBound1 σ_gt using 2 - <;> exact abs_eq_self.mpr <| Real.rpow_nonneg (norm_nonneg _) _ - · have bnd1: ‖ζ σ‖ ^ (3 / 4 : ℝ) ≤ ((σ - 1) / c) ^ (-(3 : ℝ) / 4) := by - have : ((σ - 1) / c) ^ (-(3 : ℝ) / 4) = (((σ - 1) / c) ^ (-1 : ℝ)) ^ (3 / 4 : ℝ) := by - rw [← Real.rpow_mul ?_] - · ring_nf - · exact div_nonneg (by linarith) hc.le - rw [this] - apply Real.rpow_le_rpow (by simp [norm_nonneg]) ?_ (by norm_num) - convert! h_inv σ ⟨σ_gt, σ_le⟩ using 1; simp [Real.rpow_neg_one, inv_div] - simp only [norm_mul] - apply (mul_le_mul_iff_left₀ ?_).mpr - · convert! bnd1 using 1 - · exact abs_eq_self.mpr <| Real.rpow_nonneg (norm_nonneg _) _ - · exact abs_eq_self.mpr <| Real.rpow_nonneg (div_nonneg (by linarith) hc.le) _ - · apply lt_iff_le_and_ne.mpr ⟨(by simp), ?_⟩ - have : ζ (↑σ + 2 * ↑t * I) ≠ 0 := by - apply riemannZeta_ne_zero_of_one_le_re (by simp [σ_gt.le]) - symm; exact fun h2 ↦ this (by simpa using h2) - · replace h := h σ (2 * t) (by simpa using ht') ⟨?_, σ_le⟩ - · have : 0 ≤ Real.log |2 * t| := Real.log_nonneg (by linarith) - conv => rhs; rw [mul_assoc, ← Real.mul_rpow hC.le this] - rw [norm_mul, norm_mul] - conv => rhs; rhs; rw [Real.norm_rpow_of_nonneg <| mul_nonneg hC.le this] - conv => lhs; rhs; rw [Real.norm_rpow_of_nonneg <| norm_nonneg _] - apply (mul_le_mul_iff_right₀ ?_).mpr - · apply Real.rpow_le_rpow (norm_nonneg _) ?_ (by norm_num) - convert h using 1 - · simp - · rw [Real.norm_eq_abs, abs_eq_self.mpr <| mul_nonneg hC.le this] - · simpa only [Real.norm_eq_abs, abs_pos] - · linarith [(div_nonneg ha.1.le (Real.log_nonneg (by linarith)) : 0 ≤ A / Real.log |2 * t|)] - · simp only [Real.log_abs, norm_mul] - apply (mul_le_mul_iff_right₀ ?_).mpr - · rw [← Real.log_abs, Real.norm_rpow_of_nonneg <| Real.log_nonneg (by linarith)] - have : 1 ≤ |(|t| ^ 2)| := by - simp only [_root_.sq_abs, _root_.abs_pow, one_le_sq_iff_one_le_abs] - linarith - conv => rhs; rw [← Real.log_abs, Real.norm_rpow_of_nonneg <| Real.log_nonneg this] - apply Real.rpow_le_rpow (abs_nonneg _) ?_ (by norm_num) - · rw [Real.norm_eq_abs, abs_eq_self.mpr <| Real.log_nonneg (by linarith)] - rw [abs_eq_self.mpr <| Real.log_nonneg this, abs_mul, Real.log_abs, Nat.abs_ofNat] - apply Real.log_le_log (mul_pos (by norm_num) (by linarith)) (by nlinarith) - · apply mul_pos (abs_pos.mpr hnezero) (abs_pos.mpr ?_) - have : C ≠ 0 := ne_of_gt hC - contrapose! this; rwa [Real.rpow_eq_zero (by linarith) (by norm_num)] at this - · have : (-3 : ℝ) / 4 = -((3 : ℝ)/ 4) := by norm_num - simp only [norm_mul, mul_eq_mul_right_iff, this, ← mul_assoc]; left; left - conv => lhs; rw [Real.div_rpow (by linarith) hc.le, Real.rpow_neg hc.le, div_inv_eq_mul, - norm_mul] - · simp only [Real.log_pow, Nat.cast_ofNat, norm_mul, Real.norm_eq_abs] - congr! 1 - rw [Real.mul_rpow (by norm_num) hC.le, Real.mul_rpow (by norm_num) <| - Real.log_nonneg (by linarith), abs_mul, abs_mul, ← mul_assoc, mul_comm _ |2 ^ (1 / 4)|] - · simp only [norm_mul, Real.norm_eq_abs] - have : (2 * C) ^ ((1 : ℝ)/ 4) * c ^ ((3 : ℝ)/ 4) = - |(2 * C) ^ ((1 : ℝ)/ 4) * c ^ ((3 : ℝ)/ 4)| := by - rw [abs_eq_self.mpr (by apply mul_nonneg <;> (apply Real.rpow_nonneg; linarith))] - rw [this, abs_mul, abs_eq_self.mpr (by apply Real.rpow_nonneg; linarith), abs_eq_self.mpr (by - positivity), - abs_eq_self.mpr (by positivity), abs_eq_self.mpr (by apply Real.rpow_nonneg (Real.log_nonneg - (by linarith)))] - ring_nf + _ ≤ (c * (σ - 1) ^ ((3 : ℝ) / 4) / Real.log |t| ^ ((1 : ℝ) / 4))⁻¹ := by + simpa only [one_div] using one_div_le_one_div_of_le (by positivity) (lower hσ t ht) + _ = _ := by + rw [inv_div, div_eq_mul_inv, mul_inv_rev, neg_div, Real.rpow_neg positive_sigma.le] + ring lemma deriv_fun_re {t : ℝ} {f : ℂ → ℂ} (diff : ∀ (σ : ℝ), DifferentiableAt ℂ f (↑σ + ↑t * I)) : (deriv fun {σ₂ : ℝ} ↦ f (σ₂ + t * I)) = fun (σ : ℝ) ↦ deriv f (σ + t * I) := by @@ -2597,7 +2508,7 @@ lemma ZetaInvBnd_aux2 {A C₁ C₂ : ℝ} (Apos : 0 < A) (C₁pos : 0 < C₁) (C For any $A>0$ sufficiently small, there is a constant $C>0$ so that whenever $1- A / \log^9 |t| \le \sigma < 1+A/\log^9 |t|$ and $3 < |t|$, we have that: $$ - 1/|\zeta(\sigma+it)| \le C \log^7 |t|. + C / \log^7 |t| \le |\zeta(\sigma+it)|. $$ Let $\sigma$ be given in the prescribed range, and set $\sigma' := 1+ A / \log^9 |t|$. Then @@ -2611,36 +2522,30 @@ Let $\sigma$ be given in the prescribed range, and set $\sigma' := 1+ A / \log^9 \ge C A^{3/4} \log |t|^{-7} - C \log^2 |t| (2 A / \log^9 |t|), $$ - where we used Lemma \ref{ZetaInvBound2} and Lemma \ref{Zeta_diff_Bnd}. - Now by making $A$ sufficiently small (in particular, something like $A = 1/16$ should work), we - can guarantee that + where we used Lemma \ref{ZetaLowerBound3} and Lemma \ref{Zeta_diff_Bnd}. + Choosing $A$ sufficiently small makes the coefficient positive and gives $$ |\zeta(\sigma+it)| \ge \frac C 2 (\log |t|)^{-7}, $$ as desired. -/ -lemma ZetaInvBnd : +lemma ZetaLowerBndStrip : ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (C : ℝ) (_ : 0 < C), ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) (_ : σ ∈ Ico (1 - A / (Real.log |t|) ^ (9 : ℝ)) (1 + A / (Real.log |t|) ^ (9 : ℝ))), - 1 / ‖ζ (σ + t * I)‖ ≤ C * (Real.log |t|) ^ (7 : ℝ) := by - obtain ⟨C', C'pos, hC₁⟩ := ZetaInvBound2 + C / (Real.log |t|) ^ (7 : ℝ) ≤ ‖ζ (σ + t * I)‖ := by + obtain ⟨C₁, C₁pos, hC₁⟩ := ZetaLowerBound3 obtain ⟨A', hA', C₂, C₂pos, hC₂⟩ := Zeta_diff_Bnd - set C₁ := 1 / C' let A := min A' <| (1 / 2 : ℝ) * (C₁ / (C₂ * 2)) ^ (4 : ℝ) have Apos : 0 < A := by have := hA'.1; positivity - have Ale : A ≤ 1 / 2 := by dsimp only [A]; apply min_le_iff.mpr; left; exact hA'.2 - set C := (C₁ * A ^ (3 / 4 : ℝ) - C₂ * 2 * A)⁻¹ + have Ale : A ≤ 1 / 2 := (min_le_left _ _).trans hA'.2 + set C := C₁ * A ^ (3 / 4 : ℝ) - C₂ * 2 * A have Cpos : 0 < C := by - refine ZetaInvBnd_aux2 (by positivity) (by positivity) (by positivity) ?_ + apply inv_pos.mp + refine ZetaInvBnd_aux2 Apos C₁pos C₂pos ?_ apply min_le_right - refine ⟨A, ⟨Apos, by linarith [hA'.2]⟩ , C, Cpos, ?_⟩ + refine ⟨A, ⟨Apos, Ale⟩, C, Cpos, ?_⟩ intro σ t t_gt hσ have logt_gt_one := logt_gt_one t_gt.le - have σ_ge : 1 - A / Real.log |t| ≤ σ := by - apply le_trans ?_ hσ.1 - suffices A / Real.log |t| ^ (9 : ℝ) ≤ A / Real.log |t| by linarith - exact div_le_div₀ Apos.le (by rfl) (by positivity) <| ZetaInvBnd_aux logt_gt_one - obtain ⟨_, _, neOne⟩ := UpperBnd_aux ⟨Apos, Ale⟩ t_gt σ_ge set σ' := 1 + A / Real.log |t| ^ (9 : ℝ) have σ'_gt : 1 < σ' := by simp only [σ', lt_add_iff_pos_right]; positivity have σ'_le : σ' ≤ 2 := by @@ -2650,11 +2555,7 @@ lemma ZetaInvBnd : exact lt_trans₄ (by linarith) logt_gt_one <| ZetaInvBnd_aux' logt_gt_one set s := σ + t * I set s' := σ' + t * I - by_cases h0 : ‖ζ s‖ ≠ 0 - swap - · simp only [ne_eq, not_not] at h0; simp only [h0, div_zero]; positivity - apply div_le_iff₀ (by positivity) |>.mpr <| div_le_iff₀' (by positivity) |>.mp ?_ - have pos_aux : 0 < (σ' - 1) := by linarith + change ‖ζ s‖ ≥ C / Real.log |t| ^ (7 : ℝ) calc _ ≥ ‖ζ s'‖ - ‖ζ s - ζ s'‖ := ?_ _ ≥ C₁ * (σ' - 1) ^ ((3 : ℝ)/ 4) * Real.log |t| ^ ((-1 : ℝ)/ 4) - C₂ * Real.log |t| ^ 2 * (σ' @@ -2669,12 +2570,9 @@ lemma ZetaInvBnd : · rw [(by simp : ζ s' - ζ s = -(ζ s - ζ s'))]; simp only [norm_neg] · simp · apply sub_le_sub - · have := one_div_le ?_ (by positivity) |>.mp <| hC₁ ⟨σ'_gt, σ'_le⟩ t t_gt - · convert this using 1 - rw [one_div, mul_inv_rev, mul_comm, mul_inv_rev, mul_comm _ C'⁻¹] - simp only [one_div C', C₁] - congr <;> (rw [← Real.rpow_neg (by linarith), neg_div]); rw [neg_neg] - · apply norm_pos_iff.mpr <| riemannZeta_ne_zero_of_one_lt_re (by simp [σ'_gt]) + · have lower := hC₁ ⟨σ'_gt, σ'_le⟩ t t_gt + rw [neg_div, Real.rpow_neg (by positivity), ← div_eq_mul_inv] + exact lower · rw [(by simp : ζ s - ζ s' = -(ζ s' - ζ s)), norm_neg] refine hC₂ σ σ' t t_gt ?_ σ'_le <| by rw [Set.mem_Ico] at hσ; exact hσ.2 apply le_trans ?_ hσ.1 @@ -2695,139 +2593,37 @@ lemma ZetaInvBnd : rw [(by ring : C₂ * Real.log |t| ^ (2 : ℝ) * A * Real.log |t| ^ (-9 : ℝ) * 2 = C₂ * (Real.log |t| ^ (2 : ℝ) * Real.log |t| ^ (-9 : ℝ) ) * A * 2)] rw [← Real.rpow_add (by positivity)]; norm_num; group; exact le_rfl - · apply div_le_iff₀ (by positivity) |>.mpr - conv => rw [mul_assoc]; rhs; rhs; rw [mul_comm C, ← mul_assoc, ← Real.rpow_add (by positivity)] - have := inv_inv C ▸ mul_inv_cancel₀ (a := C⁻¹) (by positivity) |>.symm.le - simpa [C] using this - + · change C / Real.log |t| ^ (7 : ℝ) ≤ C * Real.log |t| ^ (-7 : ℝ) + rw [Real.rpow_neg (by positivity), div_eq_mul_inv] +lemma ZetaInvBnd : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (C : ℝ) (_ : 0 < C), ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Ico (1 - A / (Real.log |t|) ^ (9 : ℝ)) (1 + A / (Real.log |t|) ^ (9 : ℝ))), + 1 / ‖ζ (σ + t * I)‖ ≤ C * (Real.log |t|) ^ (7 : ℝ) := by + obtain ⟨A, hA, c, hc, lower⟩ := ZetaLowerBndStrip + refine ⟨A, hA, c⁻¹, inv_pos.mpr hc, ?_⟩ + intro σ t ht hσ + have positive_log : 0 < Real.log |t| := Real.log_pos (by linarith) + calc + _ ≤ (c / Real.log |t| ^ (7 : ℝ))⁻¹ := by + simpa only [one_div] using one_div_le_one_div_of_le (by positivity) (lower σ t ht hσ) + _ = _ := by rw [inv_div, div_eq_mul_inv, mul_comm] --- **Another AlphaProof collaboration (thanks to Thomas Hubert!)** -/- -Annoyingly, it is not immediate from this that $\zeta$ doesn't vanish there! That's because -$1/0 = 0$ in Lean. So we give a second proof of the same fact (refactor this later), with a lower - bound on $\zeta$ instead of upper bound on $1 / \zeta$. --/ -/- -For any $A>0$ sufficiently small, there is a constant $C>0$ so that - whenever $1- A / \log^9 |t| \le \sigma < 1$ and $3 < |t|$, we have that: - $$ - |\zeta(\sigma+it)| \ge C \log^7 |t|. - $$ -Follow same argument. --/ +/- Restrict the shared lower estimate to the left half of the zero-free strip. -/ lemma ZetaLowerBnd : ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (c : ℝ) (_ : 0 < c), ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) (_ : σ ∈ Ico (1 - A / (Real.log |t|) ^ (9 : ℝ)) 1), c / (Real.log |t|) ^ (7 : ℝ) ≤ ‖ζ (σ + t * I)‖ := by - obtain ⟨C₁, C₁pos, hC₁⟩ := ZetaLowerBound3 - obtain ⟨A', hA', C₂, C₂pos, hC₂⟩ := Zeta_diff_Bnd - -- Pick the right constants. - -- Don't really like this because I can only do that after first finishing the proof. - -- Is there a way to delay picking those - let A := min A' ((C₁ / (4 * C₂)) ^ 4) - have hA : A ∈ Ioc 0 (1 / 2) := - ⟨lt_min hA'.1 (by positivity), (min_le_left A' _).trans hA'.2⟩ - let C := C₁ * A ^ ((3:ℝ) /4) - 2 * C₂ * A - have hc_pos : 0 < C := by - have:= A.rpow_le_rpow hA.1.le (min_le_right _ _) (inv_pos.mpr four_pos).le - erw [Real.pow_rpow_inv_natCast (div_pos C₁pos (mul_pos four_pos C₂pos)).le four_ne_zero, - le_div_iff₀ (mul_pos four_pos C₂pos)] at this - norm_num [mul_assoc, C, mul_left_comm, C₂pos, hA.1, - (mul_le_mul_of_nonneg_right this (A.rpow_nonneg hA.1.le _)).trans_lt', ←A.rpow_add] - refine ⟨A, hA, C, hc_pos, fun σ t L ⟨σ_low_bound, σ_le_one⟩=>?_⟩ - -- From here I followed the proof found in the blueprint - let σ' := 1 + A / Real.log |t| ^ (9 : ℝ) - have triangular : ‖ζ (σ + t * I)‖ ≥ ‖ζ (σ' + t * I)‖ - ‖ζ (σ + t * I) - ζ (σ' + t * I)‖ := by - apply sub_le_iff_le_add.mpr.comp (sub_sub_self @_ (@_ : ℂ)▸norm_sub_le _ _).trans - (by rw [add_comm]) - have one_leLogT : 1 ≤ Real.log |t| := (logt_gt_one L.le).le - have one_half_le_log_pow : 1 / 2 ≤ Real.log |t| ^ 9 := - one_half_lt_one.le.trans <| one_le_pow₀ one_leLogT - have σ'_ge : 1 ≤ σ' := by - simp_all only [gt_iff_lt, mem_Ioc, Real.log_abs, one_div, and_imp, tsub_le_iff_right, - lt_inf_iff, div_pos_iff_of_pos_left, Nat.ofNat_pos, mul_pos_iff_of_pos_left, pow_pos, - and_self, inf_le_iff, true_or, sub_pos, mem_Ico, and_true, ofReal_add, ofReal_one, - ofReal_div, ge_iff_le, le_add_iff_nonneg_right, A, C, σ'] - apply div_nonneg - · apply le_min - · linarith - · have : (C₁ / (4 * C₂)) ^ 4 = ((C₁ / (4 * C₂)) ^ 2) ^ 2 := by ring - rw [this] - apply sq_nonneg - · positivity - have right_sub : -‖ζ (σ + t * I) - ζ (σ' + t * I)‖ ≥ - C₂ * Real.log |t| ^ 2 * (σ' - σ) := by - change - C₂ * Real.log |t| ^ 2 * (σ' - σ) ≤ -‖ζ (σ + t * I) - ζ (σ' + t * I)‖ - have := hC₂ σ σ' t L ?_ ?_ ?_ - · convert! neg_le_neg this using 1 - · ring - · congr! 1 - have : ζ (↑σ + ↑t * I) - ζ (↑σ' + ↑t * I) = - - (ζ (↑σ' + ↑t * I) - ζ (↑σ + ↑t * I)) := by ring - rw [this, norm_neg] - · have : 1 - A' / Real.log |t| ≤ (1 : ℝ) - A / (Real.log |t|) ^ (9 : ℝ) := by - gcongr - · exact hA'.1.le - · bound - · rw [← Real.rpow_one (Real.log |t|), ← Real.rpow_mul (by linarith), one_mul] - exact Real.rpow_le_rpow_of_exponent_le one_leLogT Nat.one_le_ofNat - linarith - · have : σ' ≤ 1 + A := by - simp_all only [gt_iff_lt, mem_Ioc, Real.log_abs, one_div, and_imp, tsub_le_iff_right, - lt_inf_iff, div_pos_iff_of_pos_left, Nat.ofNat_pos, mul_pos_iff_of_pos_left, pow_pos, - and_self, inf_le_iff, true_or, sub_pos, mem_Ico, and_true, ofReal_add, ofReal_one, - ofReal_div, ge_iff_le, le_add_iff_nonneg_right, add_le_add_iff_left, le_inf_iff, - σ', A, C] - have : 1 ≤ Real.log t ^ (9 : ℝ) := Real.one_le_rpow one_leLogT (Nat.ofNat_nonneg' 9) - refine ⟨?_, ?_⟩ - · rw [← min_div_div_right] - · rw [min_le_iff] - left - bound - · exact le_trans (zero_le_one) this - · rw [← min_div_div_right] - · rw [min_le_iff] - right - bound - · exact le_trans (zero_le_one) this - · bound [hA.2] - · linarith - have right' : -‖ζ (σ + t * I) - ζ (σ' + t * I)‖ ≥ - C₂ * 2 * A / Real.log |t| ^ 7 := by - have := (abs t).log_pos (by bound) - refine right_sub.trans' ((div_le_iff₀ (pow_pos this 7)).2 @?_|>.trans - (mul_le_mul_of_nonpos_left (sub_le_sub_left σ_low_bound (1+_) ) - (by ·linear_combination C₂*this*(.log |t|)))) - exact (mod_cast (by linear_combination (2 *_* A) *div_self ↑(pow_pos this 09).ne')) - have left_sub : ‖ζ (σ' + t * I)‖ ≥ C₁ * (σ' - 1) ^ ((3:ℝ) /4) / Real.log |t| ^ 4 := by - use (hC₁ ⟨lt_add_of_pos_right (1) (by bound[hA.1]), - add_le_of_le_sub_left ((div_le_iff₀ (by bound)).2 (hA.2.trans (?_)))⟩ t L).trans' ?_ - · norm_num only [one_mul, Real.rpow_ofNat, one_half_le_log_pow] - · simp_all only [gt_iff_lt, mem_Ioc, lt_inf_iff, div_pos_iff_of_pos_left, Nat.ofNat_pos, - mul_pos_iff_of_pos_left, pow_pos, and_self, inf_le_iff, true_or, sub_pos, mem_Ico, - ofReal_add, ofReal_one, ofReal_div, ge_iff_le, le_add_iff_nonneg_right, neg_mul, - neg_le_neg_iff, add_sub_cancel_left, σ', A, C] - gcongr - have : Real.log |t| ^ ((1 : ℝ) / 4) ≤ Real.log |t| ^ (4 : ℝ) := - Real.rpow_le_rpow_of_exponent_le one_leLogT (by norm_num) - exact_mod_cast this - have left' : ‖ζ (σ' + t * I)‖ ≥ C₁ * A ^ ((3:ℝ) /4) / Real.log |t| ^ 7 := by - contrapose! hC₁ - use σ', ⟨lt_add_of_pos_right 1<|by bound[hA'.1], - add_le_of_le_sub_left ((div_le_iff₀ (by bound)).2 (hA.2.trans ?_))⟩, t, L, hC₁.trans_le ?_ - · norm_num only [one_mul, Real.rpow_ofNat, one_half_le_log_pow] - · norm_num only [σ', add_sub_cancel_left, A.div_rpow hA.1.le, mul_div, pow_pos, L.trans', - ←Real.rpow_natCast, ←Real.rpow_mul, le_of_lt, Real.log_pos, refl, div_div, ←Real.rpow_sub] - rw [Real.div_rpow hA.1.le, ← Real.rpow_mul (by linarith), ← mul_div_assoc, div_div, ← - Real.rpow_add (by linarith)] - · norm_num - · apply Real.rpow_nonneg (by linarith) - have ineq : ‖ζ (σ + t * I)‖ ≥ (C₁ * A ^ ((3:ℝ) /4) - C₂ * 2 * A) / Real.log |t| ^ 7 := by - linear_combination left'+triangular+right' - rw [mul_comm C₂] at ineq - exact_mod_cast ineq + obtain ⟨A, hA, c, hc, lower⟩ := ZetaLowerBndStrip + refine ⟨A, hA, c, hc, ?_⟩ + intro σ t ht hσ + apply lower σ t ht + refine ⟨hσ.1, hσ.2.trans ?_⟩ + have positive_log : 0 < Real.log |t| := Real.log_pos (by linarith) + exact lt_add_of_pos_right _ (div_pos hA.1 (Real.rpow_pos_of_pos positive_log _)) -- **End collaboration 6/20/25**