diff --git a/PrimeNumberTheoremAnd/Catalan.lean b/PrimeNumberTheoremAnd/Catalan.lean new file mode 100644 index 0000000..0c4ccd6 --- /dev/null +++ b/PrimeNumberTheoremAnd/Catalan.lean @@ -0,0 +1 @@ +import PrimeNumberTheoremAnd.Catalan.Consequences diff --git a/PrimeNumberTheoremAnd/Catalan/Consequences.lean b/PrimeNumberTheoremAnd/Catalan/Consequences.lean new file mode 100644 index 0000000..470ade9 --- /dev/null +++ b/PrimeNumberTheoremAnd/Catalan/Consequences.lean @@ -0,0 +1,68 @@ +import Mathlib.Analysis.Asymptotics.SpecificAsymptotics +import Mathlib.Analysis.SpecialFunctions.Log.Basic +import PrimeNumberTheoremAnd.Catalan.Wiener + +namespace CatalanPNT + +open ZetaFivePNT + +open ArithmeticFunction hiding log +open Nat hiding log +open _root_.Finset +open BigOperators _root_.Filter _root_.Real _root_.Asymptotics +open scoped Chebyshev + +theorem WeakPNT' : Tendsto (fun N ↦ (∑ n ∈ Iic N, Λ n) / N) atTop (nhds 1) := by + have : (fun N ↦ (∑ n ∈ Iic N, Λ n) / N) = + (fun N ↦ (∑ n ∈ range N, Λ n)/N + Λ N / N) := by + ext N + have : N ∈ Iic N := mem_Iic.mpr (le_refl _) + rw [← Finset.sum_erase_add _ _ this, ← Nat.Iio_eq_range, Iic_erase] + exact add_div _ _ _ + rw [this, ← add_zero 1] + apply Tendsto.add WeakPNT + convert squeeze_zero (f := fun N ↦ Λ N / N) (g := fun N ↦ log N / N) (t₀ := atTop) ?_ ?_ ?_ + · intro N + exact div_nonneg vonMangoldt_nonneg (cast_nonneg N) + · intro N + exact div_le_div_of_nonneg_right vonMangoldt_le_log (cast_nonneg N) + simpa only [Function.comp_def, pow_one, one_mul, add_zero] using + (Real.tendsto_pow_log_div_mul_add_atTop 1 0 1 one_ne_zero).comp + tendsto_natCast_atTop_atTop + +theorem WeakPNT'' : ψ ~[atTop] (fun x ↦ x) := by + rw [(by rfl : ψ = (fun x ↦ ψ x))] + simp_rw [Chebyshev.psi_eq_sum_Icc] + apply IsEquivalent.trans (v := fun x ↦ (⌊x⌋₊:ℝ)) + · rw [isEquivalent_iff_tendsto_one] + · convert Tendsto.comp WeakPNT' (tendsto_nat_floor_atTop (α := ℝ)) using 1 + ext x + rfl + rw [eventually_iff] + simp only [ne_eq, cast_eq_zero, floor_eq_zero, not_lt, mem_atTop_sets, + Set.mem_ofPred_eq] + use 1 + simp only [imp_self, implies_true] + exact Asymptotics.isEquivalent_nat_floor + +theorem isLittleO_sqrt_mul_log : (fun x : ℝ ↦ x.sqrt * x.log) =o[atTop] _root_.id := by + have : (fun x : ℝ ↦ x.sqrt * x.log) =o[atTop] fun x ↦ x := by + refine (isLittleO_mul_iff_isLittleO_div ?_).mpr ?_ + · filter_upwards [eventually_gt_atTop 0] with x hx; exact (sqrt_ne_zero hx.le).mpr hx.ne' + · convert isLittleO_log_rpow_atTop (by norm_num : (0 : ℝ) < 1 / 2) using 2 with x + rw [div_sqrt, sqrt_eq_rpow] + exact this + +theorem chebyshev_asymptotic : θ ~[atTop] id := by + rw [← sub_sub_self ψ θ] + refine WeakPNT''.sub_isLittleO + (IsBigO.trans_isLittleO (g := fun x ↦ 2 * x.sqrt * x.log) ?_ ?_) + · rw [isBigO_iff']; refine ⟨1, one_pos, ?_⟩ + simp only [one_mul, eventually_atTop] + exact ⟨2, fun x hx ↦ by + rw [Pi.sub_apply, norm_eq_abs, norm_eq_abs, abs_of_nonneg (by bound : 0 ≤ 2 * √x * log x)] + exact (abs_of_nonneg (sub_nonneg.mpr (Chebyshev.theta_le_psi x))).symm ▸ + Chebyshev.abs_psi_sub_theta_le_sqrt_mul_log (by linarith : 1 ≤ x)⟩ + · convert isLittleO_sqrt_mul_log.const_mul_left 2 using 1 <;> first | rfl | (funext x; ring) + +end CatalanPNT diff --git a/PrimeNumberTheoremAnd/Catalan/OrdinaryZetaContinuation.lean b/PrimeNumberTheoremAnd/Catalan/OrdinaryZetaContinuation.lean new file mode 100644 index 0000000..723a0e3 --- /dev/null +++ b/PrimeNumberTheoremAnd/Catalan/OrdinaryZetaContinuation.lean @@ -0,0 +1,92 @@ +import PrimeNumberTheoremAnd.Catalan.OrdinaryZetaZeroFree +import Mathlib.Analysis.Complex.RemovableSingularity + +namespace CatalanPNT + +noncomputable section + +open Complex Filter Set +open scoped Topology + +namespace CatalanOrdinaryZeta + +noncomputable def regularizedZeta : ℂ → ℂ := + Function.update (fun s ↦ (s - 1) * riemannZeta s) 1 1 + +@[simp] theorem regularizedZeta_one : regularizedZeta 1 = 1 := by + simp only [regularizedZeta, Function.update_self] + +theorem regularizedZeta_of_ne_one {s : ℂ} (hs : s ≠ 1) : + regularizedZeta s = (s - 1) * riemannZeta s := by + exact Function.update_of_ne hs .. + +theorem regularizedZeta_ne_zero_at_one : regularizedZeta 1 ≠ 0 := by + rw [regularizedZeta_one] + exact one_ne_zero + +theorem differentiable_regularizedZeta : Differentiable ℂ regularizedZeta := by + rw [← differentiableOn_univ, + ← differentiableOn_compl_singleton_and_continuousAt_iff (c := 1) Filter.univ_mem] + constructor + · refine DifferentiableOn.congr (f := fun s ↦ (s - 1) * riemannZeta s) ?_ ?_ + · intro s hs + exact ((differentiableAt_id.sub_const 1).mul + (differentiableAt_riemannZeta (Set.mem_sdiff_singleton.mp hs).2)).differentiableWithinAt + · intro s hs + exact regularizedZeta_of_ne_one (Set.mem_sdiff_singleton.mp hs).2 + · simpa only [regularizedZeta, continuousAt_update_same] using riemannZeta_residue_one + +theorem deriv_regularizedZeta_of_ne_one {s : ℂ} (hs : s ≠ 1) : + deriv regularizedZeta s = + (s - 1) * deriv riemannZeta s + riemannZeta s := by + have hderiv : deriv regularizedZeta s = + deriv (fun w ↦ (w - 1) * riemannZeta w) s := by + refine eventuallyEq_iff_exists_mem.mpr ?_ |>.deriv_eq + exact ⟨_, isOpen_ne.mem_nhds hs, + fun _ hw ↦ regularizedZeta_of_ne_one (Set.mem_ofPred.mp hw)⟩ + rw [hderiv, deriv_fun_mul (by fun_prop) (differentiableAt_riemannZeta hs), + deriv_sub_const, deriv_id'', one_mul, add_comm] + +theorem regularizedZeta_ne_zero_of_one_le_re {s : ℂ} (hs : 1 ≤ s.re) : + regularizedZeta s ≠ 0 := by + rcases eq_or_ne s 1 with rfl | hs₁ + · exact regularizedZeta_ne_zero_at_one + · rw [regularizedZeta_of_ne_one hs₁] + exact mul_ne_zero (sub_ne_zero.mpr hs₁) + (riemannZeta_ne_zero_of_one_le_re_of_ne_one hs hs₁) + +noncomputable def vonMangoldtAux (s : ℂ) : ℂ := + -deriv regularizedZeta s / regularizedZeta s + +theorem continuousOn_vonMangoldtAux : + ContinuousOn vonMangoldtAux {s | 1 ≤ s.re} := by + change ContinuousOn (fun s ↦ -deriv regularizedZeta s / regularizedZeta s) + {s | 1 ≤ s.re} + simp_rw [neg_div] + have h := differentiable_regularizedZeta + exact ((h.contDiff.continuous_deriv le_rfl).continuousOn.div + h.continuous.continuousOn fun s hs ↦ regularizedZeta_ne_zero_of_one_le_re hs).neg + +theorem eqOn_vonMangoldtAux : + Set.EqOn vonMangoldtAux + (fun s ↦ LSeries (fun n ↦ (ArithmeticFunction.vonMangoldt n : ℂ)) s - 1 / (s - 1)) + {s | 1 < s.re} := by + intro s hs + change vonMangoldtAux s = + LSeries (fun n ↦ (ArithmeticFunction.vonMangoldt n : ℂ)) s - 1 / (s - 1) + have hs' : 1 < s.re := hs + have hs₁ : s ≠ 1 := by + rintro rfl + norm_num at hs' + have hz : riemannZeta s ≠ 0 := riemannZeta_ne_zero_of_one_lt_re hs' + unfold vonMangoldtAux + rw [deriv_regularizedZeta_of_ne_one hs₁, regularizedZeta_of_ne_one hs₁, + ArithmeticFunction.LSeries_vonMangoldt_eq_deriv_riemannZeta_div hs'] + field_simp [sub_ne_zero.mpr hs₁, hz] + ring + +end CatalanOrdinaryZeta + +end + +end CatalanPNT diff --git a/PrimeNumberTheoremAnd/Catalan/OrdinaryZetaZeroFree.lean b/PrimeNumberTheoremAnd/Catalan/OrdinaryZetaZeroFree.lean new file mode 100644 index 0000000..e0f363f --- /dev/null +++ b/PrimeNumberTheoremAnd/Catalan/OrdinaryZetaZeroFree.lean @@ -0,0 +1,175 @@ +import Mathlib.Analysis.SpecialFunctions.Complex.LogBounds +import Mathlib.Analysis.Complex.Asymptotics +import Mathlib.Analysis.Asymptotics.Lemmas +import Mathlib.NumberTheory.EulerProduct.DirichletLSeries + +namespace CatalanPNT + +open Complex Asymptotics Filter +open scoped Topology + +namespace CatalanOrdinaryZeta + +private lemma re_log_comb_nonneg' {a : ℝ} (ha₀ : 0 ≤ a) (ha₁ : a < 1) + {z : ℂ} (hz : ‖z‖ = 1) : + 0 ≤ 3 * (-log (1 - a)).re + 4 * (-log (1 - a * z)).re + + (-log (1 - a * z ^ 2)).re := by + have hac₀ : ‖(a : ℂ)‖ < 1 := by + simp only [Complex.norm_of_nonneg ha₀, ha₁] + have hac₁ : ‖a * z‖ < 1 := by rwa [norm_mul, hz, mul_one] + have hac₂ : ‖a * z ^ 2‖ < 1 := by rwa [norm_mul, norm_pow, hz, one_pow, mul_one] + rw [← ((hasSum_re <| hasSum_taylorSeries_neg_log hac₀).mul_left 3).add + ((hasSum_re <| hasSum_taylorSeries_neg_log hac₁).mul_left 4) |>.add + (hasSum_re <| hasSum_taylorSeries_neg_log hac₂) |>.tsum_eq] + refine tsum_nonneg fun n ↦ ?_ + simp only [← ofReal_pow, div_natCast_re, ofReal_re, mul_pow, mul_re, ofReal_im, + zero_mul, sub_zero] + rcases n.eq_zero_or_pos with rfl | hn + · simp + · simp only [← mul_div_assoc, ← add_div] + refine div_nonneg ?_ n.cast_nonneg + rw [← pow_mul, pow_mul', sq, mul_re, ← sq, ← sq, ← sq_norm_sub_sq_re, norm_pow, hz] + convert! (show 0 ≤ 2 * a ^ n * ((z ^ n).re + 1) ^ 2 by positivity) using 1 + ring + +private lemma re_log_comb_nonneg {n : ℕ} (hn : 2 ≤ n) {x : ℝ} (hx : 1 < x) + (y : ℝ) : + 0 ≤ 3 * (-log (1 - (n : ℂ) ^ (-x : ℂ))).re + + 4 * (-log (1 - (n : ℂ) ^ (-(x + I * y)))).re + + (-log (1 - (n : ℂ) ^ (-(x + 2 * I * y)))).re := by + let a : ℝ := (n : ℝ) ^ (-x) + let z : ℂ := (n : ℂ) ^ (-(I * y)) + have hn₀ : (n : ℂ) ≠ 0 := by exact_mod_cast (show n ≠ 0 by omega) + have ha₀ : 0 ≤ a := by dsimp [a]; positivity + have ha₁ : a < 1 := by + dsimp [a] + rw [Real.rpow_neg (Nat.cast_nonneg n), inv_lt_one_iff₀] + exact .inr <| Real.one_lt_rpow (mod_cast one_lt_two.trans_le hn) <| zero_lt_one.trans hx + have hz : ‖z‖ = 1 := by + dsimp [z] + rw [← ofReal_natCast, norm_cpow_eq_rpow_re_of_pos (mod_cast by omega)] + simp only [neg_re, mul_re, I_re, ofReal_re, zero_mul, I_im, ofReal_im, + mul_zero, sub_self, neg_zero, Real.rpow_zero] + have h₀ : (n : ℂ) ^ (-x : ℂ) = (a : ℂ) := by + dsimp [a] + simp only [ofReal_cpow n.cast_nonneg (-x), ofReal_natCast, ofReal_neg] + have h₁ : (n : ℂ) ^ (-(x + I * y)) = (a : ℂ) * z := by + dsimp [z] + rw [neg_add, cpow_add _ _ hn₀, h₀] + have h₂ : (n : ℂ) ^ (-(x + 2 * I * y)) = (a : ℂ) * z ^ 2 := by + dsimp [z] + rw [neg_add, cpow_add _ _ hn₀, h₀, + show -(2 * I * y) = (2 : ℕ) * -(I * y) by ring, cpow_nat_mul] + simpa only [h₀, h₁, h₂] using re_log_comb_nonneg' ha₀ ha₁ hz + +private lemma summable_prime_log {s : ℂ} (hs : 1 < s.re) : + Summable (fun p : Nat.Primes ↦ -log (1 - (p : ℂ) ^ (-s))) := by + simpa only [riemannZetaSummandHom, MonoidWithZeroHom.coe_mk, ZeroHom.coe_mk] using! + (summable_riemannZetaSummand hs).of_norm.clog_one_sub.neg.subtype Nat.Prime + +private lemma one_lt_re_one_add {x : ℝ} (hx : 0 < x) (y : ℝ) : + 1 < (1 + x : ℂ).re ∧ 1 < (1 + x + I * y).re ∧ + 1 < (1 + x + 2 * I * y).re := by + simp only [add_re, one_re, ofReal_re, lt_add_iff_pos_right, hx, mul_re, I_re, + zero_mul, I_im, ofReal_im, mul_zero, sub_self, add_zero, re_ofNat, im_ofNat, + mul_one, mul_im, and_self] + +theorem norm_riemannZeta_product_ge_one {x : ℝ} (hx : 0 < x) (y : ℝ) : + 1 ≤ ‖riemannZeta (1 + x) ^ 3 * riemannZeta (1 + x + I * y) ^ 4 * + riemannZeta (1 + x + 2 * I * y)‖ := by + have ⟨h₀, h₁, h₂⟩ := one_lt_re_one_add hx y + have H₀ := summable_prime_log h₀ + have H₁ := summable_prime_log h₁ + have H₂ := summable_prime_log h₂ + have hsum₀ := (hasSum_re H₀.hasSum).summable.mul_left 3 + have hsum₁ := (hasSum_re H₁.hasSum).summable.mul_left 4 + have hsum₂ := (hasSum_re H₂.hasSum).summable + rw [← riemannZeta_eulerProduct_exp_log h₀, ← riemannZeta_eulerProduct_exp_log h₁, + ← riemannZeta_eulerProduct_exp_log h₂] + simp only [← exp_nat_mul, Nat.cast_ofNat, ← exp_add, norm_exp, add_re, mul_re, + re_ofNat, im_ofNat, zero_mul, sub_zero, Real.one_le_exp_iff] + rw [re_tsum H₀, re_tsum H₁, re_tsum H₂, ← tsum_mul_left, ← tsum_mul_left, + ← hsum₀.tsum_add hsum₁, ← (hsum₀.add hsum₁).tsum_add hsum₂] + simpa only [neg_add_rev, neg_re, ge_iff_le, add_re, one_re, ofReal_re, + ofReal_add, ofReal_one] using + tsum_nonneg (fun p : Nat.Primes ↦ re_log_comb_nonneg p.prop.two_le + (show 1 < 1 + x by linarith) y) + +private lemma riemannZeta_isBigO_near_one_horizontal : + (fun x : ℝ ↦ riemannZeta (1 + x)) =O[𝓝[>] 0] fun x ↦ (1 : ℂ) / x := by + have : (fun w : ℂ ↦ riemannZeta (1 + w)) =O[𝓝[≠] 0] (1 / ·) := by + have H : Tendsto (fun w : ℂ ↦ w * riemannZeta (1 + w)) (𝓝[≠] 0) (𝓝 1) := by + convert! riemannZeta_residue_one.comp (f := fun w ↦ 1 + w) ?_ using 1 + · simp only [Function.comp_def, add_sub_cancel_left] + · simpa only [tendsto_iff_comap, Homeomorph.coe_addLeft, add_zero, + map_le_iff_le_comap] using + ((Homeomorph.addLeft (1 : ℂ)).map_punctured_nhds_eq 0).le + exact (isBigO_mul_iff_isBigO_div eventually_mem_nhdsWithin).mp <| H.isBigO_one ℂ + exact (isBigO_comp_ofReal_nhds_ne this).mono <| nhdsGT_le_nhdsNE 0 + +private lemma one_add_I_mul_ne_one {y : ℝ} (hy : y ≠ 0) : 1 + I * y ≠ 1 := by + simpa only [ne_eq, add_eq_left, mul_eq_zero, I_ne_zero, ofReal_eq_zero, false_or] using hy + +private lemma riemannZeta_isBigO_horizontal {y : ℝ} (hy : y ≠ 0) : + (fun x : ℝ ↦ riemannZeta (1 + x + I * y)) =O[𝓝[>] 0] + fun _ ↦ (1 : ℂ) := by + refine IsBigO.mono ?_ nhdsWithin_le_nhds + simp_rw [add_comm (1 : ℂ), add_assoc] + have := (differentiableAt_riemannZeta (one_add_I_mul_ne_one hy)).continuousAt + rw [← zero_add (1 + _)] at this + exact this.comp (f := fun x : ℝ ↦ x + (1 + I * y)) (x := 0) (by fun_prop) + |>.tendsto.isBigO_one ℂ + +private lemma riemannZeta_isBigO_horizontal_of_eq_zero {y : ℝ} (hy : y ≠ 0) + (h : riemannZeta (1 + I * y) = 0) : + (fun x : ℝ ↦ riemannZeta (1 + x + I * y)) =O[𝓝[>] 0] + fun x : ℝ ↦ (x : ℂ) := by + simp_rw [add_comm (1 : ℂ), add_assoc] + have := (differentiableAt_riemannZeta (one_add_I_mul_ne_one hy)).hasDerivAt + rw [← zero_add (1 + _)] at this + simpa only [zero_add, h, sub_zero] using + (Complex.isBigO_comp_ofReal_nhds + (this.comp_add_const 0 _).differentiableAt.isBigO_sub) |>.mono nhdsWithin_le_nhds + +private lemma riemannZeta_ne_zero_one_add_I_mul {t : ℝ} (ht : t ≠ 0) : + riemannZeta (1 + I * t) ≠ 0 := by + intro Hz + have ht₂ : 2 * t ≠ 0 := mul_ne_zero two_ne_zero ht + have help (x : ℝ) : ((1 / x) ^ 3 * x ^ 4 * 1 : ℂ) = x := by + rcases eq_or_ne x 0 with rfl | h + · rw [ofReal_zero, zero_pow (by omega), mul_zero, mul_one] + · rw [one_div, inv_pow, pow_succ _ 3, ← mul_assoc, + inv_mul_cancel₀ <| pow_ne_zero 3 (ofReal_ne_zero.mpr h), one_mul, mul_one] + have H₀ : (fun _ : ℝ ↦ (1 : ℝ)) =O[𝓝[>] 0] + fun x ↦ riemannZeta (1 + x) ^ 3 * riemannZeta (1 + x + I * t) ^ 4 * + riemannZeta (1 + x + 2 * I * t) := + IsBigO.of_bound' <| eventually_nhdsWithin_of_forall + fun _ hx ↦ (norm_one (α := ℝ)).symm ▸ (norm_riemannZeta_product_ge_one hx t) + have H := riemannZeta_isBigO_near_one_horizontal.pow 3 |>.mul <| + (riemannZeta_isBigO_horizontal_of_eq_zero ht Hz).pow 4 |>.mul <| + riemannZeta_isBigO_horizontal ht₂ + simp only [ofReal_mul, ofReal_ofNat, mul_left_comm I, ← mul_assoc, help] at H + replace H := (H₀.trans H).norm_right + simp only [norm_real] at H + exact isLittleO_irrefl (.of_forall (fun _ ↦ one_ne_zero)) <| + H.of_norm_right.trans_isLittleO <| isLittleO_id_one.mono nhdsWithin_le_nhds + +theorem riemannZeta_ne_zero_of_re_eq_one_of_ne_one {s : ℂ} (hs : s.re = 1) + (hs₁ : s ≠ 1) : riemannZeta s ≠ 0 := by + have hs' : s = 1 + I * s.im := by + conv_lhs => rw [← re_add_im s, hs, ofReal_one, mul_comm] + have him : s.im ≠ 0 := by + intro h + apply hs₁ + rw [hs', h, ofReal_zero, mul_zero, add_zero] + exact hs'.symm ▸ riemannZeta_ne_zero_one_add_I_mul him + +theorem riemannZeta_ne_zero_of_one_le_re_of_ne_one {s : ℂ} (hs : 1 ≤ s.re) + (hs₁ : s ≠ 1) : riemannZeta s ≠ 0 := by + rcases hs.eq_or_lt with h | h + · exact riemannZeta_ne_zero_of_re_eq_one_of_ne_one h.symm hs₁ + · exact _root_.riemannZeta_ne_zero_of_one_lt_re h + +end CatalanOrdinaryZeta + +end CatalanPNT diff --git a/PrimeNumberTheoremAnd/Catalan/Wiener.lean b/PrimeNumberTheoremAnd/Catalan/Wiener.lean new file mode 100644 index 0000000..0a6b505 --- /dev/null +++ b/PrimeNumberTheoremAnd/Catalan/Wiener.lean @@ -0,0 +1,582 @@ +import PrimeNumberTheoremAnd.Catalan.WienerBounds + +namespace CatalanPNT + +open ZetaFivePNT + +open _root_.Real BigOperators ArithmeticFunction MeasureTheory _root_.Filter Set FourierTransform LSeries + _root_.Asymptotics SchwartzMap +open Complex hiding log +open scoped Topology +open scoped ContDiff +open scoped ComplexConjugate + +variable {n : ℕ} {A a b c d u x y t σ' : ℝ} {ψ Ψ : ℝ → ℂ} {F G : ℂ → ℂ} {f : ℕ → ℂ} {𝕜 : Type} + [RCLike 𝕜] + +attribute [local gcongr] norm_lt_norm_of_nonneg + +theorem limiting_cor_schwartz (ψ : 𝓢(ℝ, ℂ)) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := + limiting_cor_W21 ψ hf hcheby hG hG' + +theorem fourier_surjection_on_schwartz (f : 𝓢(ℝ, ℂ)) : ∃ g : 𝓢(ℝ, ℂ), 𝓕 g = f := by + refine ⟨𝓕⁻ f, ?_⟩ + exact FourierTransform.fourier_fourierInv_eq f + +noncomputable def toSchwartz (f : ℝ → ℂ) (h1 : ContDiff ℝ ∞ f) + (h2 : HasCompactSupport f) : 𝓢(ℝ, ℂ) := + h2.toSchwartzMap h1 + +@[simp] theorem toSchwartz_apply (f : ℝ → ℂ) {h1 h2 x} : SchwartzMap.mk f h1 h2 x = f x := rfl + +theorem comp_exp_support0 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : + ∀ᶠ x in 𝓝 0, Ψ x = 0 := + notMem_tsupport_iff_eventuallyEq.mp (fun h => lt_irrefl 0 <| mem_Ioi.mp (hplus h)) + +theorem comp_exp_support1 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : + ∀ᶠ x in atBot, Ψ (exp x) = 0 := + Real.tendsto_exp_atBot <| comp_exp_support0 hplus + +theorem comp_exp_support2 {Ψ : ℝ → ℂ} (hsupp : HasCompactSupport Ψ) : + ∀ᶠ (x : ℝ) in atTop, (Ψ ∘ rexp) x = 0 := by + simp only [hasCompactSupport_iff_eventuallyEq, coclosedCompact_eq_cocompact, + cocompact_eq_atBot_atTop] at hsupp + exact Real.tendsto_exp_atTop hsupp.2 + +theorem comp_exp_support {Ψ : ℝ → ℂ} (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : HasCompactSupport (Ψ ∘ rexp) := by + simp only [hasCompactSupport_iff_eventuallyEq, coclosedCompact_eq_cocompact, + cocompact_eq_atBot_atTop] + exact ⟨comp_exp_support1 hplus, comp_exp_support2 hsupp⟩ + +theorem wiener_ikehara_smooth_aux (l0 : Continuous Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Ioi 0) (x : ℝ) (hx : 0 < x) : + ∫ (u : ℝ) in Ioi (-Real.log x), ↑(rexp u) * Ψ (rexp u) = ∫ (y : ℝ) in Ioi (1 / x), Ψ y := by + have l1 : ContinuousOn rexp (Ici (-Real.log x)) := by fun_prop + have l2 : Tendsto rexp atTop atTop := Real.tendsto_exp_atTop + have l3 t (_ : t ∈ Ioi (-log x)) : HasDerivWithinAt rexp (rexp t) (Ioi t) t := + (Real.hasDerivAt_exp t).hasDerivWithinAt + have l4 : ContinuousOn Ψ (rexp '' Ioi (-Real.log x)) := by fun_prop + have l5 : IntegrableOn Ψ (rexp '' Ici (-Real.log x)) volume := + (l0.integrable_of_hasCompactSupport hsupp).integrableOn + have l6 : IntegrableOn (fun x ↦ rexp x • (Ψ ∘ rexp) x) (Ici (-Real.log x)) volume := by + refine (Continuous.integrable_of_hasCompactSupport (by fun_prop) ?_).integrableOn + change HasCompactSupport (rexp • (Ψ ∘ rexp)) + exact (comp_exp_support hsupp hplus).smul_left + have := MeasureTheory.integral_deriv_smul_comp_Ioi l1 l2 l3 l4 l5 l6 + simpa [Real.exp_neg, Real.exp_log hx] using this + +theorem wiener_ikehara_smooth_sub (h1 : Integrable Ψ) + (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : + Tendsto (fun x ↦ (↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y) - ↑A * ∫ (y : ℝ) in Ioi 0, Ψ y) + atTop (𝓝 0) := by + obtain ⟨ε, hε, hh⟩ := Metric.eventually_nhds_iff.mp <| comp_exp_support0 hplus + apply tendsto_nhds_of_eventually_eq ; filter_upwards [eventually_gt_atTop ε⁻¹] with x hxε + have l1 : Integrable (indicator (Ioi x⁻¹) (fun x : ℝ => Ψ x)) := h1.indicator measurableSet_Ioi + have l2 : Integrable (indicator (Ioi 0) (fun x : ℝ => Ψ x)) := h1.indicator measurableSet_Ioi + simp_rw [← MeasureTheory.integral_indicator measurableSet_Ioi, ← mul_sub, ← integral_sub l1 l2] + simp only [mul_eq_zero, ofReal_eq_zero] + right + apply MeasureTheory.integral_eq_zero_of_ae + apply Eventually.of_forall + intro t + simp only [Pi.zero_apply] + have hε' : 0 < ε⁻¹ := by positivity + have hx : 0 < x := by linarith + have hx' : 0 < x⁻¹ := by positivity + have hεx : x⁻¹ < ε := (inv_lt_comm₀ hε hx).mp hxε + have l3 : Ioi 0 = Ioc 0 x⁻¹ ∪ Ioi x⁻¹ := by + ext t ; simp only [mem_Ioi, mem_union, mem_Ioc] ; constructor <;> intro h + · simp [h, le_or_gt] + · cases h with + | inl h => exact h.1 + | inr h => exact hx'.trans h + have l4 : Disjoint (Ioc 0 x⁻¹) (Ioi x⁻¹) := by simp + have l5 := Set.indicator_union_of_disjoint l4 Ψ + rw [l3, l5] + simp only + rw [add_comm, sub_add_cancel_left] + by_cases ht : t ∈ Ioc 0 x⁻¹ + · simp only [ht, indicator_of_mem, neg_eq_zero] + apply hh ; simp only [mem_Ioc, dist_zero_right, norm_eq_abs] at ht ⊢ + apply hεx.trans_le' + rw [abs_le] ; constructor <;> linarith + simp [ht] + +theorem wiener_ikehara_smooth (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x - A * ∫ y in Set.Ioi 0, Ψ y) + atTop (𝓝 0) := by + let h (x : ℝ) : ℂ := rexp (2 * π * x) * Ψ (exp (2 * π * x)) + have h1 : ContDiff ℝ ∞ h := by + have : ContDiff ℝ ∞ (fun x : ℝ => (rexp (2 * π * x))) := (contDiff_const.mul contDiff_id).exp + exact (contDiff_ofReal.comp this).mul (hsmooth.comp this) + have h2 : HasCompactSupport h := by + have hπ : 2 * π ≠ 0 := by simp [pi_ne_zero] + have hh : HasCompactSupport (fun x : ℝ => Ψ (rexp (2 * π * x))) := by + simpa only [Function.comp_def, smul_eq_mul] using + (comp_exp_support hsupp hplus).comp_smul hπ + change HasCompactSupport + ((fun x : ℝ => (rexp (2 * π * x) : ℂ)) * fun x : ℝ => Ψ (rexp (2 * π * x))) + exact hh.mul_left + obtain ⟨g, hg⟩ := fourier_surjection_on_schwartz (toSchwartz h h1 h2) + have l1 {y} (hy : 0 < y) : y * Ψ y = 𝓕 g (1 / (2 * π) * Real.log y) := by + rw [hg] + change (y : ℂ) * Ψ y = h (1 / (2 * π) * Real.log y) + have harg : 2 * π * (1 / (2 * π) * Real.log y) = Real.log y := by + rw [← mul_assoc, mul_one_div_cancel (mul_ne_zero (by norm_num) pi_ne_zero), one_mul] + dsimp only [h] + rw [harg, Real.exp_log hy] + have key := limiting_cor_schwartz g hf hcheby hG hG' + have l2 : ∀ᶠ x in atTop, ∑' (n : ℕ), f n / ↑n * 𝓕 g (1 / (2 * π) * Real.log (↑n / x)) = + ∑' (n : ℕ), f n * Ψ (↑n / x) / x := by + filter_upwards [eventually_gt_atTop 0] with x hx + congr ; ext n + by_cases hn : n = 0 + · simp [hn, (comp_exp_support0 hplus).self_of_nhds] + rw [← l1 (by positivity)] + have : (n : ℂ) ≠ 0 := by simpa using hn + have : (x : ℂ) ≠ 0 := by simpa using hx.ne.symm + simp only [ofReal_div, ofReal_natCast] + field_simp + have l3 : ∀ᶠ x in atTop, ↑A * ∫ (u : ℝ) in Ici (-Real.log x), 𝓕 g (u / (2 * π)) = + ↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y := by + filter_upwards [eventually_gt_atTop 0] with x hx + congr 1 + rw [hg] + change (∫ u in Ici (-Real.log x), h (u / (2 * π))) = ∫ y in Ioi x⁻¹, Ψ y + dsimp only [h] + have hscale : (2 : ℝ) * π ≠ 0 := mul_ne_zero (by norm_num) pi_ne_zero + have harg (u : ℝ) : 2 * π * (u / (2 * π)) = u := mul_div_cancel₀ u hscale + simp_rw [harg] + rw [MeasureTheory.integral_Ici_eq_integral_Ioi] + simpa only [one_div] using wiener_ikehara_smooth_aux hsmooth.continuous hsupp hplus x hx + have l4 : Tendsto (fun x => (↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y) - ↑A * ∫ (y : ℝ) in Ioi 0, Ψ y) + atTop (𝓝 0) := by + exact wiener_ikehara_smooth_sub (hsmooth.continuous.integrable_of_hasCompactSupport hsupp) hplus + simpa [tsum_div_const] using (key.congr' <| EventuallyEq.sub l2 l3) |>.add l4 + +theorem wiener_ikehara_smooth' (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x) atTop (nhds (A * ∫ y in Set.Ioi 0, Ψ y)) := + tendsto_sub_nhds_zero_iff.mp <| wiener_ikehara_smooth hf hcheby hG hG' hsmooth hsupp hplus + +local instance coeRealFunctionComplex {E : Type*} : Coe (E → ℝ) (E → ℂ) := + ⟨fun f n => f n⟩ + +@[norm_cast] +theorem set_integral_ofReal {f : ℝ → ℝ} {s : Set ℝ} : ∫ x in s, (f x : ℂ) = ∫ x in s, f x := + integral_ofReal + +theorem wiener_ikehara_smooth_real {f : ℕ → ℝ} {Ψ : ℝ → ℝ} + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x) atTop (nhds (A * ∫ y in Set.Ioi 0, Ψ y)) := by + let Ψ' := ofReal ∘ Ψ + have l1 : ContDiff ℝ ∞ Ψ' := contDiff_ofReal.comp hsmooth + have l2 : HasCompactSupport Ψ' := hsupp.comp_left rfl + have l3 : closure (Function.support Ψ') ⊆ Ioi 0 := by rwa [Function.support_comp_eq] ; simp + have key := (continuous_re.tendsto _).comp + (@wiener_ikehara_smooth' A Ψ G f hf hcheby hG hG' l1 l2 l3) + simp at key ; norm_cast at key + +theorem interval_approx_inf (ha : 0 < a) (hab : a < b) : + ∀ᶠ ε in 𝓝[>] 0, ∃ ψ : ℝ → ℝ, ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ + closure (Function.support ψ) ⊆ Set.Ioi 0 ∧ + ψ ≤ indicator (Ico a b) 1 ∧ b - a - ε ≤ ∫ y in Ioi 0, ψ y := by + have l1 : Iio ((b - a) / 3) ∈ 𝓝[>] 0 := nhdsWithin_le_nhds <| Iio_mem_nhds <| by + rw [← sub_pos] at hab + positivity + filter_upwards [self_mem_nhdsWithin, l1] with ε (hε : 0 < ε) (hε' : ε < (b - a) / 3) + have l2 : a < a + ε / 2 := by simp [hε] + have l3 : b - ε / 2 < b := by simp [hε] + obtain ⟨ψ, h1, h2, h3, h4, h5⟩ := smooth_urysohn_support_Ioo l2 l3 + refine ⟨ψ, h1, h2, ?_, ?_, ?_⟩ + · simp [h5, hab.ne, Icc_subset_Ioi_iff hab.le, ha] + · exact h4.trans <| indicator_le_indicator_of_subset Ioo_subset_Ico_self (by simp) + · have l4 : 0 ≤ b - a - ε := by linarith + have l5 : Icc (a + ε / 2) (b - ε / 2) ⊆ Ioi 0 := by + intro t ht + simp only [mem_Icc, mem_Ioi] at ht ⊢ + exact ha.trans <| l2.trans_le <| ht.1 + have l6 : Icc (a + ε / 2) (b - ε / 2) ∩ Ioi 0 = Icc (a + ε / 2) (b - ε / 2) := + inter_eq_left.mpr l5 + have l7 : ∫ y in Ioi 0, indicator (Icc (a + ε / 2) (b - ε / 2)) 1 y = b - a - ε := by + simp only [measurableSet_Icc, integral_indicator_one, measureReal_restrict_apply, l6, + volume_real_Icc] + convert max_eq_left l4 using 1 ; ring_nf + have l8 : IntegrableOn ψ (Ioi 0) volume := + (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + rw [← l7] ; apply setIntegral_mono ?_ l8 h3 + rw [IntegrableOn, integrable_indicator_iff measurableSet_Icc] + apply IntegrableOn.mono ?_ subset_rfl Measure.restrict_le_self + apply integrableOn_const <;> + simp + +theorem interval_approx_sup (ha : 0 < a) (hab : a < b) : + ∀ᶠ ε in 𝓝[>] 0, ∃ ψ : ℝ → ℝ, ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ + closure (Function.support ψ) ⊆ Set.Ioi 0 ∧ + indicator (Ico a b) 1 ≤ ψ ∧ ∫ y in Ioi 0, ψ y ≤ b - a + ε := by + have l1 : Iio (a / 2) ∈ 𝓝[>] 0 := nhdsWithin_le_nhds <| Iio_mem_nhds (by linarith) + filter_upwards [self_mem_nhdsWithin, l1] with ε (hε : 0 < ε) (hε' : ε < a / 2) + have l2 : a - ε / 2 < a := by linarith + have l3 : b < b + ε / 2 := by linarith + obtain ⟨ψ, h1, h2, h3, h4, h5⟩ := smooth_urysohn_support_Ioo l2 l3 + refine ⟨ψ, h1, h2, ?_, ?_, ?_⟩ + · have l4 : a - ε / 2 < b + ε / 2 := by linarith + have l5 : ε / 2 < a := by linarith + simp [h5, l4.ne, Icc_subset_Ioi_iff l4.le, l5] + · apply le_trans ?_ h3 + apply indicator_le_indicator_of_subset Ico_subset_Icc_self (by simp) + · have l4 : 0 ≤ b - a + ε := by linarith + have l5 : Ioo (a - ε / 2) (b + ε / 2) ⊆ Ioi 0 := by intro t ht ; simp at ht ⊢ ; linarith + have l6 : Ioo (a - ε / 2) (b + ε / 2) ∩ Ioi 0 = Ioo (a - ε / 2) (b + ε / 2) := + inter_eq_left.mpr l5 + have l7 : ∫ y in Ioi 0, indicator (Ioo (a - ε / 2) (b + ε / 2)) 1 y = b - a + ε := by + simp only [measurableSet_Ioo, integral_indicator_one, measureReal_restrict_apply, l6, + volume_real_Ioo] + convert max_eq_left l4 using 1 ; ring_nf + have l8 : IntegrableOn ψ (Ioi 0) volume := + (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + rw [← l7] + refine setIntegral_mono l8 ?_ h4 + rw [IntegrableOn, integrable_indicator_iff measurableSet_Ioo] + apply IntegrableOn.mono ?_ subset_rfl Measure.restrict_le_self + apply integrableOn_const <;> + simp + +theorem WI_summable {f : ℕ → ℝ} {g : ℝ → ℝ} (hg : HasCompactSupport g) (hx : 0 < x) : + Summable (fun n => f n * g (n / x)) := by + obtain ⟨M, hM⟩ := hg.bddAbove.mono subset_closure + apply summable_of_hasFiniteSupport + unfold Function.HasFiniteSupport + simp only [Function.support_mul] ; apply Finite.inter_of_right ; rw [finite_iff_bddAbove] + exact ⟨Nat.ceil (M * x), fun i hi => by simpa using Nat.ceil_mono ((div_le_iff₀ hx).mp (hM hi))⟩ + +theorem WI_sum_le {f : ℕ → ℝ} {g₁ g₂ : ℝ → ℝ} (hf : 0 ≤ f) (hg : g₁ ≤ g₂) (hx : 0 < x) + (hg₁ : HasCompactSupport g₁) (hg₂ : HasCompactSupport g₂) : + (∑' n, f n * g₁ (n / x)) / x ≤ (∑' n, f n * g₂ (n / x)) / x := by + apply div_le_div_of_nonneg_right ?_ hx.le + exact Summable.tsum_le_tsum (fun n => mul_le_mul_of_nonneg_left (hg _) (hf _)) + (WI_summable hg₁ hx) (WI_summable hg₂ hx) + +theorem WI_sum_Iab_le {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hb : 0 < b) (hxb : 2 / b < x) : + (∑' n, f n * indicator (Ico a b) 1 (n / x)) / x ≤ C * 2 * b := by + have hb' : 0 < 2 / b := by positivity + have hx : 0 < x := by linarith + have hxb' : 2 < x * b := (div_lt_iff₀ hb).mp hxb + have l1 (i : ℕ) (hi : i ∉ Finset.range ⌈b * x⌉₊) : f i * indicator (Ico a b) 1 (i / x) = 0 := by + simp_all [le_div_iff₀ hx] + have l2 (i : ℕ) (_ : i ∈ Finset.range ⌈b * x⌉₊) : + f i * indicator (Ico a b) 1 (i / x) ≤ |f i| := by + rw [abs_eq_self.mpr (hpos _)] + convert_to _ ≤ f i * 1 + · ring + apply mul_le_mul_of_nonneg_left ?_ (hpos _) + by_cases hi : (i / x) ∈ (Ico a b) <;> simp [hi] + rw [tsum_eq_sum l1, div_le_iff₀ hx, mul_assoc, mul_assoc] + apply Finset.sum_le_sum l2 |>.trans + have := hcheby ⌈b * x⌉₊ ; simp only [norm_real, norm_eq_abs] at this ; apply this.trans + have : 0 ≤ C := by have := hcheby 1 ; simp only [cumsum, Finset.range_one, norm_real, + Finset.sum_singleton, Nat.cast_one, mul_one] at this ; exact (abs_nonneg _).trans this + refine mul_le_mul_of_nonneg_left ?_ this + apply (Nat.ceil_lt_add_one (by positivity)).le.trans + linarith + +theorem WI_sum_Iab_le' {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hb : 0 < b) : + ∀ᶠ x : ℝ in atTop, (∑' n, f n * indicator (Ico a b) 1 (n / x)) / x ≤ C * 2 * b := by + filter_upwards [eventually_gt_atTop (2 / b)] with x hx using WI_sum_Iab_le hpos hcheby hb hx + +theorem le_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[>] b, a ≤ c) : a ≤ b := by + exact ge_of_tendsto + (show Tendsto (fun c : ℝ => c) (𝓝[>] b) (𝓝 b) from nhdsWithin_le_nhds) h + +theorem ge_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[<] b, c ≤ a) : b ≤ a := by + exact le_of_tendsto + (show Tendsto (fun c : ℝ => c) (𝓝[<] b) (𝓝 b) from nhdsWithin_le_nhds) h + +theorem WI_tendsto_aux (a b : ℝ) {A : ℝ} (hA : 0 < A) : + Tendsto (fun c => c / A - (b - a)) (𝓝[>] (A * (b - a))) (𝓝[>] 0) := by + rw [Metric.tendsto_nhdsWithin_nhdsWithin] + intro ε hε + refine ⟨A * ε, by positivity, ?_⟩ + intro x hx1 hx2 + constructor + · simpa [lt_div_iff₀' hA] + · simp only [Real.dist_eq, dist_zero_right, Real.norm_eq_abs] at hx2 ⊢ + have : |x / A - (b - a)| = |x - A * (b - a)| / A := by + rw [← abs_eq_self.mpr hA.le, ← abs_div, abs_eq_self.mpr hA.le] ; congr ; field_simp + rwa [this, div_lt_iff₀' hA] + +theorem WI_tendsto_aux' (a b : ℝ) {A : ℝ} (hA : 0 < A) : + Tendsto (fun c => (b - a) - c / A) (𝓝[<] (A * (b - a))) (𝓝[>] 0) := by + rw [Metric.tendsto_nhdsWithin_nhdsWithin] + intro ε hε + refine ⟨A * ε, by positivity, ?_⟩ + intro x hx1 hx2 + constructor + · simpa [div_lt_iff₀' hA] + · simp only [Real.dist_eq, dist_zero_right, norm_eq_abs] at hx2 ⊢ + have : |(b - a) - x / A| = |A * (b - a) - x| / A := by + rw [← abs_eq_self.mpr hA.le, ← abs_div, abs_eq_self.mpr hA.le] ; congr ; field_simp + rwa [this, div_lt_iff₀' hA, ← neg_sub, abs_neg] + +theorem residue_nonneg {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm (fun n ↦ ↑(f n)) σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : EqOn G (fun s ↦ LSeries (fun n ↦ ↑(f n)) s - ↑A / (s - 1)) {s | 1 < s.re}) : + 0 ≤ A := by + let S (g : ℝ → ℝ) (x : ℝ) := (∑' n, f n * g (n / x)) / x + have hSnonneg {g : ℝ → ℝ} (hg : 0 ≤ g) : ∀ᶠ x : ℝ in atTop, 0 ≤ S g x := by + filter_upwards [eventually_ge_atTop 0] with x hx + exact div_nonneg (tsum_nonneg (fun i => mul_nonneg (hpos _) (hg _))) hx + obtain ⟨ε, ψ, h1, h2, h3, h4, -⟩ := (interval_approx_sup zero_lt_one one_lt_two).exists + have key := @wiener_ikehara_smooth_real A G f ψ hf hcheby hG hG' h1 h2 h3 + have l2 : 0 ≤ ψ := by apply le_trans _ h4 ; apply indicator_nonneg ; simp + have l1 : ∀ᶠ x in atTop, 0 ≤ S ψ x := hSnonneg l2 + have l3 : 0 ≤ A * ∫ (y : ℝ) in Ioi 0, ψ y := ge_of_tendsto key l1 + have l4 : 0 < ∫ (y : ℝ) in Ioi 0, ψ y := by + have r1 : 0 ≤ᵐ[Measure.restrict volume (Ioi 0)] ψ := Eventually.of_forall l2 + have r2 : IntegrableOn (fun y ↦ ψ y) (Ioi 0) volume := + (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + have r3 : Ico 1 2 ⊆ Function.support ψ := by + intro x hx ; have := h4 x ; simp [hx] at this ⊢ ; linarith + have r4 : Ico 1 2 ⊆ Function.support ψ ∩ Ioi 0 := by + simp only [subset_inter_iff, r3, + true_and] ; apply Ico_subset_Icc_self.trans ; rw [Icc_subset_Ioi_iff] <;> linarith + have r5 : 1 ≤ volume ((Function.support fun y ↦ ψ y) ∩ Ioi 0) := by + convert volume.mono r4 ; norm_num + simpa [setIntegral_pos_iff_support_of_nonneg_ae r1 r2] using zero_lt_one.trans_le r5 + have := div_nonneg l3 l4.le ; field_simp at this ; exact this + +theorem WienerIkeharaInterval {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * (indicator (Ico a b) 1 (n / x))) / x) + atTop (nhds (A * (b - a))) := by + + by_cases hab : a = b + · simp [hab] + replace hb : a < b := lt_of_le_of_ne hb hab ; clear hab + + let S (g : ℝ → ℝ) (x : ℝ) := (∑' n, f n * g (n / x)) / x + have hSnonneg {g : ℝ → ℝ} (hg : 0 ≤ g) : ∀ᶠ x : ℝ in atTop, 0 ≤ S g x := by + filter_upwards [eventually_ge_atTop 0] with x hx + refine div_nonneg ?_ hx + refine tsum_nonneg (fun i => mul_nonneg (hpos _) (hg _)) + have hA : 0 ≤ A := residue_nonneg hpos hf hcheby hG hG' + + let Iab : ℝ → ℝ := indicator (Ico a b) 1 + change Tendsto (S Iab) atTop (𝓝 (A * (b - a))) + have hIab : HasCompactSupport Iab := by + simpa [Iab, HasCompactSupport, tsupport, hb.ne] using isCompact_Icc + have Iab_nonneg : ∀ᶠ x : ℝ in atTop, 0 ≤ S Iab x := hSnonneg (indicator_nonneg (by simp)) + have Iab2 : IsBoundedUnder (· ≤ ·) atTop (S Iab) := by + obtain ⟨C, hC⟩ := hcheby ; exact ⟨C * 2 * b, WI_sum_Iab_le' hpos hC (by linarith)⟩ + have Iab3 : IsBoundedUnder (· ≥ ·) atTop (S Iab) := ⟨0, Iab_nonneg⟩ + have Iab0 : IsCoboundedUnder (· ≥ ·) atTop (S Iab) := Iab2.isCoboundedUnder_ge + have Iab1 : IsCoboundedUnder (· ≤ ·) atTop (S Iab) := Iab3.isCoboundedUnder_le + + have sup_le : limsup (S Iab) atTop ≤ A * (b - a) := by + have l_sup : ∀ᶠ ε in 𝓝[>] 0, limsup (S Iab) atTop ≤ A * (b - a + ε) := by + filter_upwards [interval_approx_sup ha hb] with ε happrox + rcases happrox with ⟨ψ, h1, h2, h3, h4, h6⟩ + have l1 : Tendsto (S ψ) atTop _ := wiener_ikehara_smooth_real hf hcheby hG hG' h1 h2 h3 + have l6 : S Iab ≤ᶠ[atTop] S ψ := by + filter_upwards [eventually_gt_atTop 0] with x hx using WI_sum_le hpos h4 hx hIab h2 + have l5 : IsBoundedUnder (· ≤ ·) atTop (S ψ) := l1.isBoundedUnder_le + have l3 : limsup (S Iab) atTop ≤ limsup (S ψ) atTop := limsup_le_limsup l6 Iab1 l5 + apply l3.trans ; rw [l1.limsup_eq] ; gcongr + obtain rfl | h := eq_or_ne A 0 + · simpa using l_sup + apply le_of_eventually_nhdsWithin + have key : 0 < A := lt_of_le_of_ne hA h.symm + filter_upwards [WI_tendsto_aux a b key l_sup] with x hx + simpa [mul_div_cancel₀ _ h] using hx + + have le_inf : A * (b - a) ≤ liminf (S Iab) atTop := by + have l_inf : ∀ᶠ ε in 𝓝[>] 0, A * (b - a - ε) ≤ liminf (S Iab) atTop := by + filter_upwards [interval_approx_inf ha hb] with ε happrox + rcases happrox with ⟨ψ, h1, h2, h3, h5, h6⟩ + have l1 : Tendsto (S ψ) atTop _ := wiener_ikehara_smooth_real hf hcheby hG hG' h1 h2 h3 + have l2 : S ψ ≤ᶠ[atTop] S Iab := by + filter_upwards [eventually_gt_atTop 0] with x hx using WI_sum_le hpos h5 hx h2 hIab + have l4 : IsBoundedUnder (· ≥ ·) atTop (S ψ) := l1.isBoundedUnder_ge + have l3 : liminf (S ψ) atTop ≤ liminf (S Iab) atTop := liminf_le_liminf l2 l4 Iab0 + apply le_trans ?_ l3 ; rw [l1.liminf_eq] ; gcongr + obtain rfl | h := eq_or_ne A 0 + · simpa using l_inf + apply ge_of_eventually_nhdsWithin + have key : 0 < A := lt_of_le_of_ne hA h.symm + filter_upwards [WI_tendsto_aux' a b key l_inf] with x hx + simpa [mul_div_cancel₀ _ h] using hx + + have : liminf (S Iab) atTop ≤ limsup (S Iab) atTop := liminf_le_limsup Iab2 Iab3 + refine tendsto_of_liminf_eq_limsup ?_ ?_ Iab2 Iab3 <;> linarith + +theorem le_floor_mul_iff (hb : 0 ≤ b) (hx : 0 < x) : n ≤ ⌊b * x⌋₊ ↔ n / x ≤ b := by + rw [div_le_iff₀ hx, Nat.le_floor_iff] ; positivity + +theorem lt_ceil_mul_iff (hx : 0 < x) : n < ⌈b * x⌉₊ ↔ n / x < b := by + rw [div_lt_iff₀ hx, Nat.lt_ceil] + +theorem ceil_mul_le_iff (hx : 0 < x) : ⌈a * x⌉₊ ≤ n ↔ a ≤ n / x := by + rw [le_div_iff₀ hx, Nat.ceil_le] + +theorem mem_Icc_iff_div (hb : 0 ≤ b) (hx : 0 < x) : + n ∈ Finset.Icc ⌈a * x⌉₊ ⌊b * x⌋₊ ↔ n / x ∈ Icc a b := by + rw [Finset.mem_Icc, mem_Icc, ceil_mul_le_iff hx, le_floor_mul_iff hb hx] + +theorem mem_Ico_iff_div (hx : 0 < x) : n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊ ↔ n / x ∈ Ico a b := by + rw [Finset.mem_Ico, mem_Ico, ceil_mul_le_iff hx, lt_ceil_mul_iff hx] + +theorem tsum_indicator {f : ℕ → ℝ} (hx : 0 < x) : + ∑' n, f n * (indicator (Ico a b) 1 (n / x)) = ∑ n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n := by + have l1 : ∀ n ∉ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n * indicator (Ico a b) 1 (↑n / x) = 0 := by + simp [mem_Ico_iff_div hx] ; tauto + rw [tsum_eq_sum l1] ; apply Finset.sum_congr rfl ; simp only + [mem_Ico_iff_div hx] ; intro n hn ; simp [hn] + +theorem WienerIkeharaInterval_discrete {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun x : ℝ ↦ (∑ n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n) / x) + atTop (nhds (A * (b - a))) := by + apply (WienerIkeharaInterval hpos hf hcheby hG hG' ha hb).congr' + filter_upwards [eventually_gt_atTop 0] with x hx + rw [tsum_indicator hx] + +theorem WienerIkeharaInterval_discrete' {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun N : ℕ ↦ (∑ n ∈ Finset.Ico ⌈a * N⌉₊ ⌈b * N⌉₊, f n) / N) + atTop (nhds (A * (b - a))) := + WienerIkeharaInterval_discrete hpos hf hcheby hG hG' ha hb |>.comp tendsto_natCast_atTop_atTop + +theorem tendsto_mul_ceil_div : + Tendsto (fun (p : ℝ × ℕ) => ⌈p.1 * p.2⌉₊ / (p.2 : ℝ)) (𝓝[>] 0 ×ˢ atTop) (𝓝 0) := by + rw [Metric.tendsto_nhds] ; intro δ hδ + have l1 : ∀ᶠ ε : ℝ in 𝓝[>] 0, ε ∈ Ioo 0 (δ / 2) := + inter_mem_nhdsWithin _ (Iio_mem_nhds (by positivity)) + have l2 : ∀ᶠ N : ℕ in atTop, 1 ≤ δ / 2 * N := by + apply Tendsto.eventually_ge_atTop + exact tendsto_natCast_atTop_atTop.const_mul_atTop (by positivity) + filter_upwards [l1.prod_mk l2] with p hp + rcases p with ⟨ε, N⟩ + rcases hp with ⟨⟨hε, h1⟩, h2⟩ + dsimp only at * + have l3 : 0 < (N : ℝ) := by + simp only [Nat.cast_pos, Nat.pos_iff_ne_zero] ; rintro rfl ; simp [zero_lt_one.not_ge] at h2 + have l5 : 0 ≤ ε * ↑N := by positivity + have l6 : ε * N ≤ δ / 2 * N := mul_le_mul h1.le le_rfl (by positivity) (by positivity) + simp only [dist_zero_right, norm_div, RCLike.norm_natCast, div_lt_iff₀ l3, gt_iff_lt] + convert (Nat.ceil_lt_add_one l5).trans_le (add_le_add l6 h2) using 1 ; ring + +noncomputable def S (f : ℕ → 𝕜) (ε : ℝ) (N : ℕ) : 𝕜 := (∑ n ∈ Finset.Ico ⌈ε * N⌉₊ N, f n) / N + +theorem S_sub_S {f : ℕ → 𝕜} {ε : ℝ} {N : ℕ} (hε : ε ≤ 1) : + S f 0 N - S f ε N = cumsum f ⌈ε * N⌉₊ / N := by + have r1 : Finset.range N = Finset.range ⌈ε * N⌉₊ ∪ Finset.Ico ⌈ε * N⌉₊ N := by + simp_rw [Finset.range_eq_Ico] + symm + apply Finset.Ico_union_Ico_eq_Ico (Nat.zero_le _) + simp only [Nat.ceil_le] + exact mul_le_of_le_one_left N.cast_nonneg hε + have r2 : Disjoint (Finset.range ⌈ε * N⌉₊) (Finset.Ico ⌈ε * N⌉₊ N) := by + rw [Finset.range_eq_Ico] ; apply Finset.Ico_disjoint_Ico_consecutive + simp [S, r1, Finset.sum_union r2, cumsum, add_div] + +theorem tendsto_S_S_zero {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + TendstoUniformlyOnFilter (S f) (S f 0) (𝓝[>] 0) atTop := by + rw [Metric.tendstoUniformlyOnFilter_iff] ; intro δ hδ + obtain ⟨C, hC⟩ := hcheby + have l1 : ∀ᶠ (p : ℝ × ℕ) in 𝓝[>] 0 ×ˢ atTop, C * ⌈p.1 * p.2⌉₊ / p.2 < δ := by + have r1 := tendsto_mul_ceil_div.const_mul C + simp only [mul_div_assoc', mul_zero] at r1 ; exact r1 (Iio_mem_nhds hδ) + have : Ioc 0 1 ∈ 𝓝[>] (0 : ℝ) := inter_mem_nhdsWithin _ (Iic_mem_nhds zero_lt_one) + filter_upwards [l1, Eventually.prod_inl this _] with p h1 h2 + rcases p with ⟨ε, N⟩ + have l2 : ‖cumsum f ⌈ε * ↑N⌉₊ / ↑N‖ ≤ C * ⌈ε * N⌉₊ / N := by + have r1 := hC ⌈ε * N⌉₊ + have r2 : 0 ≤ cumsum f ⌈ε * N⌉₊ := by apply cumsum_nonneg hpos + simp only [norm_real, norm_of_nonneg (hpos _), norm_div, + norm_of_nonneg r2, Real.norm_natCast] at r1 ⊢ + apply div_le_div_of_nonneg_right r1 (by positivity) + simpa [dist_eq_norm, ← S_sub_S h2.2] using l2.trans_lt h1 + +theorem WienerIkeharaTheorem' {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun N => cumsum f N / N) atTop (𝓝 A) := by + convert_to Tendsto (S f 0) atTop (𝓝 A) ; · ext N ; simp [S, cumsum] + apply (tendsto_S_S_zero hpos hcheby).tendsto_of_eventually_tendsto + · have L0 : Ioc 0 1 ∈ 𝓝[>] (0 : ℝ) := inter_mem_nhdsWithin _ (Iic_mem_nhds zero_lt_one) + apply eventually_of_mem L0 + · intro ε hε + convert WienerIkeharaInterval_discrete' hpos hf hcheby hG hG' hε.1 hε.2 using 1 + funext N + simp only [S, one_mul, Nat.ceil_natCast] + · have : Tendsto (fun ε : ℝ => ε) (𝓝[>] 0) (𝓝 0) := nhdsWithin_le_nhds + simpa using (this.const_sub 1).const_mul A + +theorem vonMangoldt_cheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(Λ k : ℂ)‖) n ≤ C * n) := by + use Real.log 4 + 4 + intro N + by_cases! h : N = 0 + · simp [h, cumsum] + simp only [cumsum, norm_real, norm_eq_abs] + rw [Nat.range_eq_Icc_zero_sub_one _ h, (by simp : N - 1 = ⌊(N : ℝ) - 1⌋₊)] + simp_rw [abs_of_nonneg vonMangoldt_nonneg] + rw [← Chebyshev.psi_eq_sum_Icc] + grw [Chebyshev.psi_le_const_mul_self <| sub_nonneg_of_le <| Nat.one_le_cast_iff_ne_zero.mpr h] + gcongr + linarith + +theorem WeakPNT : Tendsto (fun N ↦ cumsum Λ N / N) atTop (𝓝 1) := by + let F : ℂ → ℂ := CatalanOrdinaryZeta.vonMangoldtAux + have l1 (n : ℕ) : 0 ≤ Λ n := vonMangoldt_nonneg + have l2 s (hs : 1 < s.re) : F s = LSeries Λ s - 1 / (s - 1) := by + exact CatalanOrdinaryZeta.eqOn_vonMangoldtAux hs + have l3 : ContinuousOn F {s | 1 ≤ s.re} := + CatalanOrdinaryZeta.continuousOn_vonMangoldtAux + have l4 : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(Λ k : ℂ)‖) n ≤ C * n) := vonMangoldt_cheby + have l5 (σ' : ℝ) (hσ' : 1 < σ') : Summable (nterm Λ σ') := by + simpa only [← nterm_eq_norm_term] + using (@ArithmeticFunction.LSeriesSummable_vonMangoldt σ' hσ').norm + apply WienerIkeharaTheorem' l1 l5 l4 l3 l2 + +end CatalanPNT diff --git a/PrimeNumberTheoremAnd/Catalan/WienerBounds.lean b/PrimeNumberTheoremAnd/Catalan/WienerBounds.lean new file mode 100644 index 0000000..06122cf --- /dev/null +++ b/PrimeNumberTheoremAnd/Catalan/WienerBounds.lean @@ -0,0 +1,582 @@ +import PrimeNumberTheoremAnd.Catalan.WienerLimits + +namespace CatalanPNT + +open ZetaFivePNT + +open _root_.Real BigOperators ArithmeticFunction MeasureTheory _root_.Filter Set FourierTransform LSeries + _root_.Asymptotics SchwartzMap +open Complex hiding log +open scoped Topology +open scoped ContDiff +open scoped ComplexConjugate + +variable {n : ℕ} {A a b c d u x y t σ' : ℝ} {ψ Ψ : ℝ → ℂ} {F G : ℂ → ℂ} {f : ℕ → ℂ} {𝕜 : Type} + [RCLike 𝕜] + +attribute [local gcongr] norm_lt_norm_of_nonneg + +theorem smooth_urysohn (a b c d : ℝ) (h1 : a < b) (h3 : c < d) : ∃ Ψ : ℝ → ℝ, + (ContDiff ℝ ∞ Ψ) ∧ (HasCompactSupport Ψ) ∧ + Set.indicator (Set.Icc b c) 1 ≤ Ψ ∧ Ψ ≤ Set.indicator (Set.Ioo a d) 1 := by + obtain ⟨ψ, l1, l2, l3, l4, -⟩ := smooth_urysohn_support_Ioo h1 h3 + refine ⟨ψ, l1, l2, l3, l4⟩ + +noncomputable def compactTruncation : trunc := by + choose ψ h1 h2 h3 h4 using smooth_urysohn (-2) (-1) (1) (2) (by linarith) (by linarith) + exact ⟨⟨ψ, h1.of_le (by norm_cast), h2⟩, h3, h4⟩ + +theorem one_div_sub_one (n : ℕ) : 1 / (↑(n - 1) : ℝ) ≤ 2 / n := by + cases n with + | zero => simp + | succ n => + cases n with + | zero => simp + | succ n => norm_cast ; rw [div_le_div_iff₀] <;> simp [mul_add] <;> linarith + +noncomputable def pp (a x : ℝ) : ℝ := a ^ 2 * (x + 1) ^ 2 + (1 - a) * (1 + a) + +noncomputable def pp' (a x : ℝ) : ℝ := a ^ 2 * (2 * (x + 1)) + +theorem pp_pos {a : ℝ} (ha : a ∈ Ioo (-1) 1) (x : ℝ) : 0 < pp a x := by + simp only [pp] + have : 0 < 1 - a := by linarith [ha.2] + have : 0 < 1 + a := by linarith [ha.1] + positivity + +theorem pp_deriv (a x : ℝ) : HasDerivAt (pp a) (pp' a x) x := by + unfold pp pp' + simpa using hasDerivAt_id x |>.add_const 1 |>.pow 2 |>.const_mul _ + +theorem pp_deriv_eq (a : ℝ) : deriv (pp a) = pp' a := by + ext x ; exact pp_deriv a x |>.deriv + +theorem pp'_deriv (a x : ℝ) : HasDerivAt (pp' a) (a ^ 2 * 2) x := by + change HasDerivAt (fun y : ℝ => a ^ 2 * (2 * (y + 1))) (a ^ 2 * 2) x + convert hasDerivAt_id x |>.add_const 1 |>.const_mul 2 |>.const_mul (a ^ 2) + using 1 <;> first | rfl | ring + +theorem pp'_deriv_eq (a : ℝ) : deriv (pp' a) = fun _ => a ^ 2 * 2 := by + ext x ; exact pp'_deriv a x |>.deriv + +noncomputable def hh (a t : ℝ) : ℝ := (t * (1 + (a * log t) ^ 2))⁻¹ + +noncomputable def hh' (a t : ℝ) : ℝ := - pp a (log t) * hh a t ^ 2 + +theorem hh_nonneg (a : ℝ) {t : ℝ} (ht : 0 ≤ t) : 0 ≤ hh a t := by dsimp only [hh] ; positivity + +theorem hh_le (a t : ℝ) (ht : 0 ≤ t) : |hh a t| ≤ t⁻¹ := by + by_cases h0 : t = 0 + · simp [hh, h0] + replace ht : 0 < t := lt_of_le_of_ne ht (by tauto) + unfold hh + rw [abs_inv, inv_le_inv₀ (by positivity) ht, abs_mul, abs_eq_self.mpr ht.le] + convert_to t * 1 ≤ _ + · simp + apply mul_le_mul le_rfl ?_ zero_le_one ht.le + rw [abs_eq_self.mpr (by positivity)] + simp only [le_add_iff_nonneg_right] + positivity + +theorem hh_deriv (a : ℝ) {t : ℝ} (ht : t ≠ 0) : HasDerivAt (hh a) (hh' a t) t := by + have e1 : t * (1 + (a * log t) ^ 2) ≠ 0 := mul_ne_zero ht (_root_.ne_of_lt (by positivity)).symm + have l5 : HasDerivAt (fun t : ℝ => log t) t⁻¹ t := Real.hasDerivAt_log ht + have l4 : HasDerivAt (fun t : ℝ => a * log t) (a * t⁻¹) t := l5.const_mul _ + have l3 : HasDerivAt (fun t : ℝ => (a * log t) ^ 2) (2 * a ^ 2 * t⁻¹ * log t) t := by + convert l4.pow 2 using 1 ; ring + have l2 : HasDerivAt (fun t : ℝ => 1 + (a * log t) ^ 2) (2 * a ^ 2 * t⁻¹ * log t) t := + l3.const_add _ + have l1 : HasDerivAt (fun t : ℝ => t * (1 + (a * log t) ^ 2)) + (1 + 2 * a ^ 2 * log t + a ^ 2 * log t ^ 2) t := by + convert (hasDerivAt_id' t).mul l2 using 1; field_simp; ring + apply (l1.inv e1).congr_deriv + dsimp only [hh', pp, hh] + simp only [div_eq_mul_inv, inv_pow] + ring + +theorem hh_continuous (a : ℝ) : ContinuousOn (hh a) (Ioi 0) := + fun t (ht : 0 < t) => (hh_deriv a ht.ne.symm).continuousAt.continuousWithinAt + +theorem hh'_nonpos {a x : ℝ} (ha : a ∈ Ioo (-1) 1) : hh' a x ≤ 0 := by + have := pp_pos ha (log x) + simp only [hh', neg_mul, Left.neg_nonpos_iff, ge_iff_le] + positivity + +theorem hh_antitone {a : ℝ} (ha : a ∈ Ioo (-1) 1) : AntitoneOn (hh a) (Ioi 0) := by + have l1 x (hx : x ∈ interior (Ioi 0)) : + HasDerivWithinAt (hh a) (hh' a x) (interior (Ioi 0)) x := by + have : x ≠ 0 := by contrapose! hx ; simp [hx] + exact (hh_deriv a this).hasDerivWithinAt + apply antitoneOn_of_hasDerivWithinAt_nonpos (convex_Ioi _) (hh_continuous _) l1 + (fun x _ => hh'_nonpos ha) + +noncomputable def gg (x i : ℝ) : ℝ := 1 / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ + +theorem gg_of_hh {x : ℝ} (hx : x ≠ 0) (i : ℝ) : gg x i = x⁻¹ * hh (1 / (2 * π)) (i / x) := by + simp only [gg, hh] + field_simp + +theorem gg_l1 {x : ℝ} (hx : 0 < x) (n : ℕ) : |gg x n| ≤ 1 / n := by + simp only [gg_of_hh hx.ne.symm, one_div, mul_inv_rev, abs_mul] + apply mul_le_mul le_rfl (hh_le _ _ (by positivity)) (by positivity) (by positivity) |>.trans + (le_of_eq ?_) + simp [abs_inv, abs_eq_self.mpr hx.le] ; field_simp + +theorem gg_le_one (i : ℕ) : gg x i ≤ 1 := by + by_cases hi : i = 0 <;> simp only [gg, hi, CharP.cast_eq_zero, div_zero, one_div, mul_inv_rev, + zero_div, Real.log_zero, mul_zero, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, zero_pow, + add_zero, inv_one, mul_one, zero_le_one] + have l1 : 1 ≤ (i : ℝ) := by simp ; omega + have l2 : 1 ≤ 1 + (π⁻¹ * 2⁻¹ * Real.log (↑i / x)) ^ 2 := by + simp only [le_add_iff_nonneg_right] ; positivity + rw [← mul_inv] ; apply inv_le_one_of_one_le₀ ; simpa using mul_le_mul l1 l2 zero_le_one (by simp) + +theorem one_div_two_pi_mem_Ioo : 1 / (2 * π) ∈ Ioo (-1) 1 := by + constructor + · trans 0 + · linarith + · positivity + · rw [div_lt_iff₀ (by positivity)] + convert_to 1 * 1 < 2 * π + · simp + · simp + apply mul_lt_mul one_lt_two ?_ zero_lt_one zero_le_two + trans 2 + · exact one_le_two + · exact two_le_pi + +theorem cancel_aux {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : + ∑ i ∈ Finset.range n, f i * g i ≤ g (n - 1) * (C * n) + (C * (↑(n - 1 - 1) + 1) * g 0 + - C * (↑(n - 1 - 1) + 1) * g (n - 1) - + ((n - 1 - 1) • (C * g 0) - ∑ x ∈ Finset.range (n - 1 - 1), C * g (x + 1))) := by + have l1 (n : ℕ) : + (g n - g (n + 1)) * ∑ i ∈ Finset.range (n + 1), f i ≤ (g n - g (n + 1)) * (C * (n + 1)) := by + apply mul_le_mul le_rfl (by simpa only [cumsum, Nat.cast_add, Nat.cast_one] using hf' (n + 1)) + (Finset.sum_nonneg (fun i _ => hf i)) ?_ + simp only [sub_nonneg] ; apply hg' ; simp + have l2 (x : ℕ) : C * (↑(x + 1) + 1) - C * (↑x + 1) = C := by simp ; ring + have l3 (n : ℕ) : 0 ≤ cumsum f n := Finset.sum_nonneg (fun i _ => hf i) + convert_to ∑ i ∈ Finset.range n, (g i) • (f i) ≤ _ + · simp [mul_comm] + rw [Finset.sum_range_by_parts, sub_eq_add_neg, ← Finset.sum_neg_distrib] + simp_rw [← neg_smul, neg_sub, smul_eq_mul] + apply _root_.add_le_add + · exact mul_le_mul le_rfl (hf' n) (l3 n) (hg _) + · apply Finset.sum_le_sum (fun n _ => l1 n) |>.trans + convert_to ∑ i ∈ Finset.range (n - 1), (C * (↑i + 1)) • (g i - g (i + 1)) ≤ _ + · congr ; ext i ; simp ; ring + rw [Finset.sum_range_by_parts] + simp_rw [Finset.sum_range_sub', l2, smul_sub, smul_eq_mul, Finset.sum_sub_distrib, + Finset.sum_const, Finset.card_range] + apply le_of_eq ; ring_nf + +theorem sum_range_succ (a : ℕ → ℝ) (n : ℕ) : + ∑ i ∈ Finset.range n, a (i + 1) = (∑ i ∈ Finset.range (n + 1), a i) - a 0 := by + have := Finset.sum_range_sub a n + rw [Finset.sum_sub_distrib, sub_eq_iff_eq_add] at this + rw [Finset.sum_range_succ, this] ; ring + +theorem cancel_aux' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : + ∑ i ∈ Finset.range n, f i * g i ≤ + C * n * g (n - 1) + + C * cumsum g (n - 1 - 1 + 1) + - C * (↑(n - 1 - 1) + 1) * g (n - 1) + := by + have := cancel_aux hf hg hf' hg' n + simp only [nsmul_eq_mul, ← Finset.mul_sum, sum_range_succ] at this + convert this using 1 ; unfold cumsum ; ring + +theorem cancel_main {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) (hn : 2 ≤ n) : + cumsum (f * g) n ≤ C * cumsum g n := by + change (∑ i ∈ Finset.range n, f i * g i) ≤ C * cumsum g n + refine (cancel_aux' hf hg hf' hg' n).trans_eq ?_ + have hindex : n - 1 - 1 + 1 = n - 1 := by omega + have hcast : (n : ℝ) = ↑(n - 1) + 1 := by + exact_mod_cast (show n = (n - 1) + 1 by omega) + have hcast' : (↑(n - 1 - 1) : ℝ) + 1 = ↑(n - 1) := by + exact_mod_cast hindex + have hsum : cumsum g n = cumsum g (n - 1) + g (n - 1) := by + conv_lhs => rw [show n = (n - 1) + 1 by omega] + exact cumsum_succ (n - 1) + rw [hindex, hcast', hcast, hsum] + ring + +theorem cancel_main' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hf0 : f 0 = 0) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : + cumsum (f * g) n ≤ C * cumsum g n := by + cases n with + | zero => simp [cumsum] + | succ n => + cases n with + | zero => + have hC : 0 ≤ C := by simpa [cumsum, hf0] using hf' 1 + simpa [cumsum, hf0] using mul_nonneg hC (hg 0) + | succ n => exact cancel_main hf hg hf' hg' (n + 2) (by omega) + +theorem sum_le_integral {x₀ : ℝ} {f : ℝ → ℝ} {n : ℕ} (hf : AntitoneOn f (Ioc x₀ (x₀ + n))) + (hfi : IntegrableOn f (Icc x₀ (x₀ + n))) : + (∑ i ∈ Finset.range n, f (x₀ + ↑(i + 1))) ≤ ∫ x in x₀..x₀ + n, f x := by + cases n with simp only [Nat.cast_add, Nat.cast_one, CharP.cast_eq_zero, add_zero, + lt_self_iff_false, not_false_eq_true, + Ioc_eq_empty, Finset.range_zero, Nat.cast_add, Nat.cast_one, Finset.sum_empty, + intervalIntegral.integral_same, le_refl] at hf ⊢ + | succ n => + have : Finset.range (n + 1) = {0} ∪ Finset.Ico 1 (n + 1) := by + ext i ; by_cases hi : i = 0 <;> simp [hi] ; omega + simp only [this, Finset.singleton_union, Finset.mem_Ico, nonpos_iff_eq_zero, one_ne_zero, + lt_add_iff_pos_left, add_pos_iff, zero_lt_one, or_true, and_true, not_false_eq_true, + Finset.sum_insert, CharP.cast_eq_zero, zero_add, ge_iff_le] + have l4 : IntervalIntegrable f volume x₀ (x₀ + 1) := by + apply IntegrableOn.intervalIntegrable + simp only [le_add_iff_nonneg_right, zero_le_one, uIcc_of_le] + apply hfi.mono_set + apply Icc_subset_Icc le_rfl + simp + have l5 x (hx : x ∈ Ioc x₀ (x₀ + 1)) : (fun x ↦ f (x₀ + 1)) x ≤ f x := by + rcases hx with ⟨hx1, hx2⟩ + refine hf ⟨hx1, by linarith⟩ ⟨by linarith, by linarith⟩ hx2 + have l6 : ∫ x in x₀..x₀ + 1, f (x₀ + 1) = f (x₀ + 1) := by simp + have l1 : f (x₀ + 1) ≤ ∫ x in x₀..x₀ + 1, f x := by + rw [← l6] + apply intervalIntegral.integral_mono_on_of_le_Ioo (by linarith) (by simp) l4 + intro x hx + exact l5 x ⟨hx.1, hx.2.le⟩ + have l2 : AntitoneOn (fun x ↦ f (x₀ + x)) (Icc 1 ↑(n + 1)) := by + intro u hu v hv huv + have hu1 := hu.1 + have hv2 := hv.2 + push_cast at hv2 + refine hf ⟨?_, ?_⟩ ⟨?_, ?_⟩ ?_ <;> linarith + have l3 := @AntitoneOn.sum_le_integral_Ico 1 (n + 1) (fun x => f (x₀ + x)) (by simp) + (by simpa using l2) + simp only [Nat.cast_add, Nat.cast_one, intervalIntegral.integral_comp_add_left] at l3 + convert _root_.add_le_add l1 l3 + have := @intervalIntegral.integral_comp_mul_add ℝ _ _ 1 (n + 1) 1 f one_ne_zero x₀ + rw [intervalIntegral.integral_add_adjacent_intervals] + · exact l4 + · apply IntegrableOn.intervalIntegrable + simp only [add_le_add_iff_left, le_add_iff_nonneg_left, Nat.cast_nonneg, uIcc_of_le] + apply hfi.mono_set + apply Icc_subset_Icc + · linarith + · simp + +theorem hh_integrable_aux (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : + (IntegrableOn (fun t ↦ a * hh b (t / c)) (Ici 0)) ∧ + (∫ (t : ℝ) in Ioi 0, a * hh b (t / c) = a * c / b * π) := by + rw [integrableOn_Ici_iff_integrableOn_Ioi] + simp only [hh] + let g (x : ℝ) := (a * c / b) * Real.arctan (b * log (x / c)) + let g₀ (x : ℝ) := if x = 0 then ((a * c / b) * (- (π / 2))) else g x + let g' (x : ℝ) := a * (x / c * (1 + (b * Real.log (x / c)) ^ 2))⁻¹ + have l3 (x) (hx : 0 < x) : HasDerivAt Real.log x⁻¹ x := by apply Real.hasDerivAt_log (by linarith) + have l4 (x) : HasDerivAt (fun t => t / c) (1 / c) x := (hasDerivAt_id x).div_const c + have l2 (x) (hx : 0 < x) : HasDerivAt (fun t => log (t / c)) x⁻¹ x := by + have hcomp := (l3 (x / c) (by positivity)).comp x (l4 x) + convert hcomp using 1 + · rfl + · field_simp [hc.ne', hx.ne'] + have l5 (x) (hx : 0 < x) := (l2 x hx).const_mul b + have l1 (x) (hx : 0 < x) := (l5 x hx).arctan + have l6 (x) (hx : 0 < x) : HasDerivAt g (g' x) x := by + convert (l1 x hx).const_mul (a * c / b) using 1 + simp only [g'] + field_simp + have key (x) (hx : 0 < x) : HasDerivAt g₀ (g' x) x := by + apply (l6 x hx).congr_of_eventuallyEq + apply eventually_of_mem <| Ioi_mem_nhds hx + intro y (hy : 0 < y) + simp [g₀, hy.ne.symm] + have k1 : Tendsto g₀ atTop (𝓝 ((a * c / b) * (π / 2))) := by + have : g =ᶠ[atTop] g₀ := by + apply eventually_of_mem (Ioi_mem_atTop 0) + intro y (hy : 0 < y) + simp [g₀, hy.ne.symm] + apply Tendsto.congr' this + apply Tendsto.const_mul + apply (tendsto_arctan_atTop.mono_right nhdsWithin_le_nhds).comp + apply Tendsto.const_mul_atTop hb + apply tendsto_log_atTop.comp + apply Tendsto.atTop_div_const hc + apply tendsto_id + have k2 : Tendsto g₀ (𝓝[>] 0) (𝓝 (g₀ 0)) := by + have : g =ᶠ[𝓝[>] 0] g₀ := by + apply eventually_of_mem self_mem_nhdsWithin + intro x (hx : 0 < x) ; simp [g₀, hx.ne.symm] + simp only [g₀] + apply Tendsto.congr' this + apply Tendsto.const_mul + apply (tendsto_arctan_atBot.mono_right nhdsWithin_le_nhds).comp + apply Tendsto.const_mul_atBot hb + apply tendsto_log_nhdsGT_zero.comp + rw [Metric.tendsto_nhdsWithin_nhdsWithin] + intro ε hε + refine ⟨c * ε, by positivity, fun x hx1 hx2 => ⟨?_, ?_⟩⟩ + · simp only [mem_Ioi] at hx1 ⊢ ; positivity + · simp only [dist_zero_right, norm_eq_abs, norm_div, abs_eq_self.mpr hc.le] at hx2 ⊢ + rwa [div_lt_iff₀ hc, mul_comm] + have k3 : ContinuousWithinAt g₀ (Ici 0) 0 := by + rw [Metric.continuousWithinAt_iff] + rw [Metric.tendsto_nhdsWithin_nhds] at k2 + intro ε hε + obtain ⟨δ, hδ, hδx⟩ := k2 ε hε + refine ⟨δ, hδ, ?_⟩ + intro x hx hdist + change 0 ≤ x at hx + rcases lt_or_eq_of_le hx with hx | hx + · exact hδx hx hdist + · subst x + simpa only [dist_self] using hε + have k4 : ∀ x ∈ Ioi 0, 0 ≤ g' x := by + intro x (hx : 0 < x) ; simp only [mul_inv_rev, inv_div, g'] ; positivity + constructor + · convert_to IntegrableOn g' _ + exact integrableOn_Ioi_deriv_of_nonneg k3 key k4 k1 + · have := integral_Ioi_of_hasDerivAt_of_nonneg k3 key k4 k1 + simp only [mul_inv_rev, inv_div, mul_neg, ↓reduceIte, sub_neg_eq_add, g', g₀] at this ⊢ + convert this using 1 ; field_simp ; ring + +theorem hh_integrable (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : + IntegrableOn (fun t ↦ a * hh b (t / c)) (Ici 0) := + hh_integrable_aux ha hb hc |>.1 + +theorem hh_integral (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : + ∫ (t : ℝ) in Ioi 0, a * hh b (t / c) = a * c / b * π := + hh_integrable_aux ha hb hc |>.2 + +theorem hh_integral' : ∫ t in Ioi 0, hh (1 / (2 * π)) t = 2 * π ^ 2 := by + have := hh_integral (a := 1) (b := 1 / (2 * π)) (c := 1) + (by positivity) (by positivity) (by positivity) + convert this using 1 <;> simp ; ring + +theorem bound_sum_log {C : ℝ} (hf0 : f 0 = 0) + (hf : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + {x : ℝ} (hx : 1 ≤ x) : + ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ + C * (1 + ∫ t in Ioi 0, hh (1 / (2 * π)) t) := by + let ggg (i : ℕ) : ℝ := if i = 0 then 1 else gg x i + have l0 : x ≠ 0 := by linarith + have l1 i : 0 ≤ ggg i := by by_cases hi : i = 0 <;> simp only [gg, one_div, mul_inv_rev, hi, + ↓reduceIte, zero_le_one, ggg] ; positivity + have l2 : Antitone ggg := by + intro i j hij ; by_cases hi : i = 0 <;> by_cases hj : j = 0 <;> simp only [hj, ↓reduceIte, hi, + le_refl, ggg] + · exact gg_le_one _ + · omega + · simp only [gg_of_hh l0] + gcongr + apply hh_antitone one_div_two_pi_mem_Ioo + · simp only [mem_Ioi] ; positivity + · simp only [mem_Ioi] ; positivity + · gcongr + have l3 : 0 ≤ C := by simpa [cumsum, hf0] using hf 1 + have l4 : 0 ≤ ∫ (t : ℝ) in Ioi 0, hh (π⁻¹ * 2⁻¹) t := + setIntegral_nonneg measurableSet_Ioi (fun x hx => hh_nonneg _ (LT.lt.le hx)) + have l5 {n : ℕ} : AntitoneOn (fun t ↦ x⁻¹ * hh (1 / (2 * π)) (t / x)) (Ioc 0 n) := by + intro u hu v hv huv + have hu1 := hu.1 + have hv1 := hv.1 + simp only + apply mul_le_mul le_rfl ?_ (hh_nonneg _ (by positivity)) (by positivity) + apply hh_antitone one_div_two_pi_mem_Ioo (by simp only [mem_Ioi] ; positivity) + (by simp only [mem_Ioi] ; positivity) + apply (div_le_div_iff_of_pos_right (by positivity)).mpr huv + have l6 {n : ℕ} : IntegrableOn (fun t ↦ x⁻¹ * hh (π⁻¹ * 2⁻¹) (t / x)) (Icc 0 n) volume := by + apply IntegrableOn.mono_set + (hh_integrable (by positivity) (by positivity) (by positivity)) Icc_subset_Ici_self + apply Real.tsum_le_of_sum_range_le (fun n => by positivity) ; intro n + convert_to ∑ i ∈ Finset.range n, ‖f i‖ * ggg i ≤ _ + · congr ; ext i + by_cases hi : i = 0 + · simp [hi, hf0] + · simp only [gg, hi, ↓reduceIte, ggg] + field_simp + apply cancel_main' (fun _ => norm_nonneg _) (by simp [hf0]) l1 hf l2 n |>.trans + gcongr ; simp only [cumsum, gg_of_hh l0, one_div, mul_inv_rev, ggg] + by_cases hn : n = 0 + · simp only [hn, Finset.range_zero, Finset.sum_empty] ; positivity + replace hn : 0 < n := by omega + have : Finset.range n = {0} ∪ Finset.Ico 1 n := by + ext i ; simp ; by_cases hi : i = 0 <;> simp [hi, hn] ; omega + simp only [this, Finset.singleton_union, Finset.mem_Ico, nonpos_iff_eq_zero, one_ne_zero, + false_and, not_false_eq_true, Finset.sum_insert, ↓reduceIte, add_le_add_iff_left, ge_iff_le] + convert_to ∑ x_1 ∈ Finset.Ico 1 n, x⁻¹ * hh (π⁻¹ * 2⁻¹) (↑x_1 / x) ≤ _ + · apply Finset.sum_congr rfl (fun i hi => ?_) + simp at hi + have : i ≠ 0 := by omega + simp [this] + simp_rw [Finset.sum_Ico_eq_sum_range, add_comm 1] + have := @sum_le_integral 0 (fun t => x⁻¹ * hh (π⁻¹ * 2⁻¹) (t / x)) (n - 1) + (by simpa using l5) (by simpa using l6) + simp only [zero_add] at this + apply this.trans + rw [@intervalIntegral.integral_comp_div ℝ _ _ 0 ↑(n - 1) x (fun t => x⁻¹ * hh (π⁻¹ * 2⁻¹) (t)) l0] + simp only [zero_div, intervalIntegral.integral_const_mul, smul_eq_mul, ← mul_assoc, + mul_inv_cancel₀ l0, one_mul] + have : (0 : ℝ) ≤ ↑(n - 1) / x := by positivity + rw [intervalIntegral.intervalIntegral_eq_integral_uIoc] + simp only [this, ↓reduceIte, uIoc_of_le, smul_eq_mul, one_mul, ge_iff_le] + apply integral_mono_measure + · apply Measure.restrict_mono Ioc_subset_Ioi_self le_rfl + · apply eventually_of_mem (self_mem_ae_restrict measurableSet_Ioi) + intro x (hx : 0 < x) + apply hh_nonneg _ hx.le + · have h := (@hh_integrable 1 (1 / (2 * π)) 1 (by positivity) (by positivity) (by positivity)) + have h' := h.mono_set Ioi_subset_Ici_self + unfold IntegrableOn at h' + apply h'.congr + exact Eventually.of_forall (fun t => by simp) + +theorem bound_sum_log0 {C : ℝ} + (hf : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + {x : ℝ} (hx : 1 ≤ x) : + ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ + C * (1 + ∫ t in Ioi 0, hh (1 / (2 * π)) t) := by + let f0 i := if i = 0 then 0 else f i + have l1 : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f0 k : ℂ)‖) n ≤ C * n) := by + intro n ; refine Finset.sum_le_sum (fun i _ => ?_) |>.trans (hf n) + by_cases hi : i = 0 <;> simp [hi, f0] + have l2 i : ‖f i‖ / i = ‖f0 i‖ / i := by by_cases hi : i = 0 <;> simp [hi, f0] + simp_rw [l2] ; apply bound_sum_log rfl l1 hx + +theorem bound_sum_log' {C : ℝ} + (hf : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + {x : ℝ} (hx : 1 ≤ x) : + ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ C * (1 + 2 * π ^ 2) := by + simpa only [hh_integral'] using bound_sum_log0 hf hx + +variable (f x) in +theorem summable_fourier_aux (ψ : W21) (i : ℕ) : + ‖f i / i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (i / x))‖ ≤ + W21.norm ψ * (‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹) := by + convert mul_le_mul_of_nonneg_left (decay_bounds_key ψ (1 / (2 * π) * log (i / x))) + (norm_nonneg (f i / i)) using 1 + · simp + · change _ = _ * (W21.norm ψ * _) + simp only [W21.norm, mul_inv_rev, one_div, Complex.norm_div, RCLike.norm_natCast] + ring + +theorem summable_fourier (x : ℝ) (hx : 0 < x) (ψ : W21) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + Summable fun i ↦ ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑i / x))‖ := by + have l5 : Summable fun i ↦ ‖f i‖ / ↑i * ((1 + (1 / (2 * ↑π) * ↑(Real.log (↑i / x))) ^ 2)⁻¹) := by + simpa using limiting_fourier_lim1_aux hcheby hx 1 (zero_le_one' ℝ) + have l6 := summable_fourier_aux x f ψ + exact Summable.of_nonneg_of_le (fun _ => norm_nonneg _) l6 + (by simpa using l5.const_smul (W21.norm ψ)) + +theorem bound_I1 (x : ℝ) (hx : 0 < x) (ψ : W21) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ + W21.norm ψ • ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ := by + have l5 : Summable fun i ↦ ‖f i‖ / ↑i * ((1 + (1 / (2 * ↑π) * ↑(Real.log (↑i / x))) ^ 2)⁻¹) := by + simpa using limiting_fourier_lim1_aux hcheby hx 1 (zero_le_one' ℝ) + have l6 := summable_fourier_aux x f ψ + have l1 : Summable fun i ↦ ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑i / x))‖ := by + exact summable_fourier x hx ψ hcheby + apply (norm_tsum_le_tsum_norm l1).trans + change (∑' i, ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) + (1 / (2 * π) * Real.log (↑i / x))‖) ≤ W21.norm ψ * _ + rw [← tsum_mul_left] + exact Summable.tsum_mono l1 (l5.mul_left (W21.norm ψ)) l6 + +theorem bound_I1' {C : ℝ} (x : ℝ) (hx : 1 ≤ x) (ψ : W21) + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ + W21.norm ψ * C * (1 + 2 * π ^ 2) := by + apply bound_I1 x (by linarith) ψ ⟨_, hcheby⟩ |>.trans + rw [smul_eq_mul, mul_assoc] + apply mul_le_mul le_rfl (bound_sum_log' hcheby hx) ?_ W21.norm_nonneg + apply tsum_nonneg (fun i => by positivity) + +theorem bound_I2 (x : ℝ) (ψ : W21) : + ‖∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))‖ ≤ W21.norm ψ * (2 * π ^ 2) := by + have key a : ‖𝓕 (ψ : ℝ → ℂ) (a / (2 * π))‖ ≤ W21.norm ψ * (1 + (a / (2 * π)) ^ 2)⁻¹ := + decay_bounds_key ψ _ + have twopi : 0 ≤ 2 * π := by simp [pi_nonneg] + have l3 : Integrable (fun a ↦ (1 + (a / (2 * π)) ^ 2)⁻¹) := + integrable_inv_one_add_sq.comp_div (by norm_num [pi_ne_zero]) + have l2 : IntegrableOn (fun i ↦ W21.norm ψ * (1 + (i / (2 * π)) ^ 2)⁻¹) (Ici (-Real.log x)) := by + exact (l3.const_mul _).integrableOn + have l1 : IntegrableOn (fun i ↦ ‖𝓕 (ψ : ℝ → ℂ) (i / (2 * π))‖) (Ici (-Real.log x)) := by + refine ((l3.const_mul (W21.norm ψ)).mono' ?_ ?_).integrableOn + · apply Continuous.aestronglyMeasurable ; fun_prop + · simp only [norm_norm, key] ; simp + have l5 : 0 ≤ᵐ[volume] fun a ↦ (1 + (a / (2 * π)) ^ 2)⁻¹ := by + apply Eventually.of_forall ; intro x ; positivity + refine (norm_integral_le_integral_norm _).trans <| (setIntegral_mono l1 l2 key).trans ?_ + rw [integral_const_mul] ; gcongr + · apply W21.norm_nonneg + refine (setIntegral_le_integral l3 l5).trans ?_ + rw [Measure.integral_comp_div (fun x => (1 + x ^ 2)⁻¹) (2 * π)] + simp [abs_eq_self.mpr twopi] ; ring_nf ; rfl + +theorem bound_main {C : ℝ} (A : ℂ) (x : ℝ) (hx : 1 ≤ x) (ψ : W21) + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))‖ ≤ + W21.norm ψ * (C * (1 + 2 * π ^ 2) + ‖A‖ * (2 * π ^ 2)) := by + have l1 := bound_I1' x hx ψ hcheby + have l2 := mul_le_mul (le_refl ‖A‖) (bound_I2 x ψ) (by positivity) (by positivity) + apply norm_sub_le _ _ |>.trans ; rw [norm_mul] + convert _root_.add_le_add l1 l2 using 1 ; ring + +theorem limiting_cor_W21 (ψ : W21) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := by + + let S1 x (ψ : ℝ → ℂ) := ∑' (n : ℕ), f n / ↑n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑n / x)) + let S2 x (ψ : ℝ → ℂ) := ↑A * ∫ (u : ℝ) in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) + let S x ψ := S1 x ψ - S2 x ψ ; change Tendsto (fun x ↦ S x ψ) atTop (𝓝 0) + + obtain g := compactTruncation + let Ψ R := g.scale R * ψ + have key R : Tendsto (fun x ↦ S x (Ψ R)) atTop (𝓝 0) := limiting_cor (Ψ R) hf hcheby hG hG' + + obtain ⟨C, hcheby⟩ := hcheby + have hC : 0 ≤ C := by + have : ‖f 0‖ ≤ C := by simpa [cumsum] using hcheby 1 + have : 0 ≤ ‖f 0‖ := by positivity + linarith + have key2 : Tendsto (fun R ↦ W21.norm (ψ - Ψ R)) atTop (𝓝 0) := W21_approximation ψ g + simp_rw [Metric.tendsto_nhds] at key key2 ⊢ ; intro ε hε + let M := C * (1 + 2 * π ^ 2) + ‖(A : ℂ)‖ * (2 * π ^ 2) + obtain ⟨R, hRψ⟩ := (key2 ((ε / 2) / (1 + M)) (by positivity)).exists + simp only [dist_zero_right, Real.norm_eq_abs, abs_eq_self.mpr W21.norm_nonneg] at hRψ key + + filter_upwards [eventually_ge_atTop 1, key R (ε / 2) (by positivity)] with x hx key + + have key3 : ‖S x (ψ - Ψ R)‖ < ε / 2 := by + have hbound := @bound_main f C A x hx (ψ - Ψ R) hcheby + change ‖S x (⇑ψ - ⇑(Ψ R))‖ ≤ W21.norm (⇑ψ - ⇑(Ψ R)) * M at hbound + apply hbound.trans_lt + calc + W21.norm (⇑ψ - ⇑(Ψ R)) * M ≤ W21.norm (⇑ψ - ⇑(Ψ R)) * (1 + M) := + mul_le_mul_of_nonneg_left (by linarith) W21.norm_nonneg + _ < ε / 2 := (lt_div_iff₀ (show 0 < 1 + M by positivity)).mp hRψ + + have S1_sub_1 x : 𝓕 (⇑ψ - ⇑(Ψ R)) x = 𝓕 (ψ : ℝ → ℂ) x - 𝓕 ⇑(Ψ R) x := + F_sub ψ.hf (Ψ R : W21).hf x + have S1_sub : S1 x (ψ - Ψ R) = S1 x ψ - S1 x (Ψ R) := by + simp only [one_div, mul_inv_rev, S1_sub_1, mul_sub, S1] ; apply Summable.tsum_sub + · have := summable_fourier x (by positivity) ψ ⟨_, hcheby⟩ + rw [summable_norm_iff] at this + simpa using this + · have hsum := summable_fourier x (by positivity) (Ψ R : W21) ⟨_, hcheby⟩ + rw [summable_norm_iff] at hsum + simpa only [W21.ofCS2, one_div, mul_inv_rev] using hsum + have S2_sub : S2 x (ψ - Ψ R) = S2 x ψ - S2 x (Ψ R) := by + simp only [S1_sub_1, S2] ; rw [integral_sub] + · ring + · exact CatalanPNT.W21.integrable_fourier ψ (by positivity) |>.restrict + · exact CatalanPNT.W21.integrable_fourier (Ψ R : W21) (by positivity) |>.restrict + have S_sub : S x (ψ - Ψ R) = S x ψ - S x (Ψ R) := by simp [S, S1_sub, S2_sub] ; ring + simpa [S_sub, Ψ] using norm_add_le _ _ |>.trans_lt (_root_.add_lt_add key3 key) + +end CatalanPNT diff --git a/PrimeNumberTheoremAnd/Catalan/WienerFourier.lean b/PrimeNumberTheoremAnd/Catalan/WienerFourier.lean new file mode 100644 index 0000000..491332b --- /dev/null +++ b/PrimeNumberTheoremAnd/Catalan/WienerFourier.lean @@ -0,0 +1,332 @@ +import Mathlib.Analysis.Fourier.RiemannLebesgueLemma +import Mathlib.Analysis.Normed.Group.Tannery +import Mathlib.Analysis.SumIntegralComparisons +import Mathlib.NumberTheory.Chebyshev +import PrimeNumberTheoremAnd.Catalan.OrdinaryZetaContinuation +import Mathlib.NumberTheory.MulChar.Lemmas +import PrimeNumberTheoremAnd.ZetaFive.Fourier +import PrimeNumberTheoremAnd.ZetaFive.SmoothExistence +import Mathlib.Analysis.Convolution +import Mathlib.MeasureTheory.Group.Circle + +namespace CatalanPNT + +open ZetaFivePNT + +open Real BigOperators ArithmeticFunction MeasureTheory Filter Set FourierTransform LSeries + Asymptotics SchwartzMap +open Complex hiding log +open scoped Topology +open scoped ContDiff +open scoped ComplexConjugate + +variable {n : ℕ} {A a b c d u x y t σ' : ℝ} {ψ Ψ : ℝ → ℂ} {F G : ℂ → ℂ} {f : ℕ → ℂ} {𝕜 : Type} + [RCLike 𝕜] + +noncomputable +def nterm (f : ℕ → ℂ) (σ' : ℝ) (n : ℕ) : ℝ := if n = 0 then 0 else ‖f n‖ / n ^ σ' + +theorem nterm_eq_norm_term {f : ℕ → ℂ} : nterm f σ' n = ‖term f σ' n‖ := by + by_cases h : n = 0 <;> simp [nterm, term, h] + +theorem norm_term_eq_nterm_re (s : ℂ) : + ‖term f s n‖ = nterm f (s.re) n := by + simpa only [nterm] using LSeries.norm_term_eq f s n + +theorem hf_coe1 (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hσ : 1 < σ') : + ∑' i, (‖term f σ' i‖₊ : ENNReal) ≠ ⊤ := by + simp_rw [ENNReal.tsum_coe_ne_top_iff_summable_coe, ← norm_toNNReal] + norm_cast + apply Summable.toNNReal + convert hf σ' hσ with i + simp [nterm_eq_norm_term] + +attribute [fun_prop] Real.continuous_fourierChar + +theorem first_fourier_aux1 (hψ : AEMeasurable ψ) {x : ℝ} (n : ℕ) : AEMeasurable fun (u : ℝ) ↦ + (‖fourierChar (-(u * ((1 : ℝ) / ((2 : ℝ) * π) * (n / x).log))) • ψ u‖ₑ : ENNReal) := by + fun_prop + +theorem first_fourier_aux2a : + (2 : ℂ) * π * -(y * (1 / (2 * π) * Real.log ((n) / x))) = -(y * ((n) / x).log) := by + calc + _ = -(y * (((2 : ℂ) * π) / (2 * π) * Real.log ((n) / x))) := by ring + _ = _ := by rw [div_self (by norm_num), one_mul] + +theorem first_fourier_aux2 (hx : 0 < x) (n : ℕ) : + term f σ' n * 𝐞 (-(y * (1 / (2 * π) * Real.log (n / x)))) • ψ y = + term f (σ' + y * I) n • (ψ y * x ^ (y * I)) := by + by_cases hn : n = 0 + · simp [term, hn] + simp only [term, hn, ↓reduceIte] + calc + _ = (f n * (cexp ((2 * π * -(y * (1 / (2 * π) * Real.log (n / x)))) * I) / + ↑((n : ℝ) ^ σ'))) • ψ y := by + rw [Circle.smul_def, fourierChar_apply, ofReal_cpow (by norm_num)] + simp only [one_div, mul_inv_rev, mul_neg, ofReal_neg, ofReal_mul, ofReal_ofNat, ofReal_inv, + neg_mul, smul_eq_mul, ofReal_natCast] + ring + _ = (f n * (x ^ (y * I) / n ^ (σ' + y * I))) • ψ y := by + congr 2 + have l1 : 0 < (n : ℝ) := by simpa using Nat.pos_iff_ne_zero.mpr hn + have l2 : (x : ℂ) ≠ 0 := by simp [hx.ne.symm] + have l3 : (n : ℂ) ≠ 0 := by simp [hn] + rw [Real.rpow_def_of_pos l1, Complex.cpow_def_of_ne_zero l2, Complex.cpow_def_of_ne_zero l3] + push_cast + simp_rw [← Complex.exp_sub] + congr 1 + rw [first_fourier_aux2a, Real.log_div l1.ne.symm hx.ne.symm] + push_cast + rw [Complex.ofReal_log hx.le] + ring + _ = _ := by simp ; group + +theorem first_fourier (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hsupp : Integrable ψ) (hx : 0 < x) (hσ : 1 < σ') : + ∑' n : ℕ, term f σ' n * (𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))) = + ∫ t : ℝ, LSeries f (σ' + t * I) * ψ t * x ^ (t * I) := by + calc + _ = ∑' n, term f σ' n * ∫ (v : ℝ), 𝐞 (-(v * ((1 : ℝ) / + ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by + simp only [Real.fourier_eq] + simp only [one_div, mul_inv_rev, RCLike.inner_apply', conj_trivial] + _ = ∑' n, ∫ (v : ℝ), term f σ' n * 𝐞 (-(v * ((1 : ℝ) / + ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by + simp [integral_const_mul] + _ = ∫ (v : ℝ), ∑' n, term f σ' n * 𝐞 (-(v * ((1 : ℝ) / + ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by + refine (integral_tsum ?_ ?_).symm + · refine fun _ ↦ AEMeasurable.aestronglyMeasurable ?_ + have := hsupp.aemeasurable + fun_prop + · simp only [enorm_mul] + simp_rw [lintegral_const_mul'' _ (first_fourier_aux1 hsupp.aemeasurable _)] + calc + _ = (∑' (i : ℕ), ‖term f σ' i‖ₑ) * ∫⁻ (a : ℝ), ‖ψ a‖ₑ ∂volume := by + simp [ENNReal.tsum_mul_right, enorm_eq_nnnorm] + _ ≠ ⊤ := ENNReal.mul_ne_top (hf_coe1 hf hσ) + (ne_top_of_lt hsupp.2) + _ = _ := by + congr 1; ext y + simp_rw [mul_assoc (LSeries _ _), ← smul_eq_mul (a := (LSeries _ _)), LSeries] + rw [← Summable.tsum_smul_const] + · simp_rw [first_fourier_aux2 hx] + · apply Summable.of_norm + convert hf σ' hσ with n + rw [norm_term_eq_nterm_re] + simp + +@[continuity] +theorem continuous_multiplicative_ofAdd : Continuous (⇑Multiplicative.ofAdd : ℝ → ℝ) := ⟨fun _ ↦ id⟩ + +attribute [fun_prop] measurable_coe_nnreal_ennreal + +theorem second_fourier_integrable_aux1a (hσ : 1 < σ') : + IntegrableOn (fun (x : ℝ) ↦ cexp (-((x : ℂ) * ((σ' : ℂ) - 1)))) (Ici (-Real.log x)) := by + norm_cast + suffices IntegrableOn (fun (x : ℝ) ↦ (rexp (-(x * (σ' - 1))))) (Ici (-x.log)) _ from this.ofReal + simp_rw [fun (a x : ℝ) ↦ (by ring : -(x * a) = -a * x)] + rw [integrableOn_Ici_iff_integrableOn_Ioi] + apply exp_neg_integrableOn_Ioi + linarith + +theorem second_fourier_integrable_aux1 (hcont : Measurable ψ) (hsupp : Integrable ψ) (hσ : 1 < σ') : + let ν : Measure (ℝ × ℝ) := (volume.restrict (Ici (-Real.log x))).prod volume + Integrable (Function.uncurry fun (u : ℝ) (a : ℝ) ↦ ((rexp (-u * (σ' - 1))) : ℂ) • + (𝐞 (Multiplicative.ofAdd (-(a * (u / (2 * π))))) : ℂ) • ψ a) ν := by + intro ν + constructor + · apply Measurable.aestronglyMeasurable + change Measurable (fun p : ℝ × ℝ => + (rexp (-p.1 * (σ' - 1)) : ℂ) * + ((fourierChar (-(p.2 * (p.1 / (2 * π)))) : ℂ) * ψ p.2)) + fun_prop + · let f1 : ℝ → ENNReal := fun a1 ↦ ‖cexp (-(↑a1 * (↑σ' - 1)))‖ₑ + let f2 : ℝ → ENNReal := fun a2 ↦ ‖ψ a2‖ₑ + suffices ∫⁻ (a : ℝ × ℝ), f1 a.1 * f2 a.2 ∂ν < ⊤ by + simpa [hasFiniteIntegral_iff_enorm, enorm_eq_nnnorm, Function.uncurry] + refine (lintegral_prod_mul ?_ ?_).trans_lt ?_ <;> try fun_prop + exact ENNReal.mul_lt_top (second_fourier_integrable_aux1a hσ).2 hsupp.2 + +theorem second_fourier_integrable_aux2 (hσ : 1 < σ') : + IntegrableOn (fun (u : ℝ) ↦ cexp ((1 - ↑σ' - ↑t * I) * ↑u)) (Ioi (-Real.log x)) := by + refine (integrable_norm_iff (Measurable.aestronglyMeasurable <| by fun_prop)).mp ?_ + suffices IntegrableOn (fun a ↦ rexp (-(σ' - 1) * a)) (Ioi (-x.log)) _ by simpa [Complex.norm_exp] + apply exp_neg_integrableOn_Ioi + linarith + +theorem second_fourier_aux (hx : 0 < x) : + -(cexp (-((1 - ↑σ' - ↑t * I) * ↑(Real.log x))) / (1 - ↑σ' - ↑t * I)) = + ↑(x ^ (σ' - 1)) * (↑σ' + ↑t * I - 1)⁻¹ * ↑x ^ (↑t * I) := by + calc + _ = cexp (↑(Real.log x) * ((↑σ' - 1) + ↑t * I)) * (↑σ' + ↑t * I - 1)⁻¹ := by + rw [← div_neg]; ring_nf + _ = (x ^ ((↑σ' - 1) + ↑t * I)) * (↑σ' + ↑t * I - 1)⁻¹ := by + rw [Complex.cpow_def_of_ne_zero (ofReal_ne_zero.mpr (ne_of_gt hx)), Complex.ofReal_log hx.le] + _ = (x ^ ((σ' : ℂ) - 1)) * (x ^ (↑t * I)) * (↑σ' + ↑t * I - 1)⁻¹ := by + rw [Complex.cpow_add _ _ (ofReal_ne_zero.mpr (ne_of_gt hx))] + _ = _ := by rw [ofReal_cpow hx.le]; push_cast; ring + +theorem second_fourier (hcont : Measurable ψ) (hsupp : Integrable ψ) + {x σ' : ℝ} (hx : 0 < x) (hσ : 1 < σ') : + ∫ u in Ici (-log x), Real.exp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = + (x^(σ' - 1) : ℝ) * ∫ t, (1 / (σ' + t * I - 1)) * ψ t * x^(t * I) ∂ volume := by + conv in ↑(rexp _) * _ => { rw [Real.fourier_real_eq, ← smul_eq_mul, ← integral_smul] } + rw [MeasureTheory.integral_integral_swap] + swap + · exact second_fourier_integrable_aux1 hcont hsupp hσ + rw [← integral_const_mul] + congr 1; ext t + simp_rw [Circle.smul_def, smul_eq_mul, Real.fourierChar_apply, + ← mul_assoc, integral_mul_const] + rw [mul_right_comm _ (ψ t) _] + congr 1 + push_cast + simp_rw [← Complex.exp_add] + have (u : ℝ) : + -↑u * (↑σ' - 1) + 2 * ↑π * -(↑t * (↑u / (2 * ↑π))) * I = (1 - σ' - t * I) * u := calc + _ = -↑u * (↑σ' - 1) + (2 * ↑π) / (2 * ↑π) * -(↑t * ↑u) * I := by ring + _ = -↑u * (↑σ' - 1) + 1 * -(↑t * ↑u) * I := by rw [div_self (by norm_num)] + _ = _ := by ring + simp_rw [this] + let c : ℂ := (1 - ↑σ' - ↑t * I) + have : c ≠ 0 := by simp [Complex.ext_iff, c, sub_ne_zero.mpr hσ.ne] + let f' (u : ℝ) := cexp (c * u) + let f := fun (u : ℝ) ↦ (f' u) / c + have hderiv : ∀ u ∈ Ici (-Real.log x), HasDerivAt f (f' u) u := by + intro u _ + rw [show f' u = cexp (c * u) * (c * 1) / c by simp only [f']; field_simp] + exact (hasDerivAt_id' u).ofReal_comp.const_mul c |>.cexp.div_const c + have hf : Tendsto f atTop (𝓝 0) := by + apply tendsto_zero_iff_norm_tendsto_zero.mpr + suffices Tendsto (fun (x : ℝ) ↦ ‖cexp (c * ↑x)‖ / ‖c‖) atTop (𝓝 (0 / ‖c‖)) by + simpa [f, f'] using this + apply Filter.Tendsto.div_const + suffices Tendsto (· * (1 - σ')) atTop atBot by simpa [Complex.norm_exp, mul_comm (1 - σ'), c] + exact Tendsto.atTop_mul_const_of_neg (by linarith) fun ⦃s⦄ h ↦ h + rw [integral_Ici_eq_integral_Ioi, + integral_Ioi_of_hasDerivAt_of_tendsto' hderiv (second_fourier_integrable_aux2 hσ) hf] + simpa [f, f'] using second_fourier_aux hx + +theorem one_add_sq_pos (u : ℝ) : 0 < 1 + u ^ 2 := zero_lt_one.trans_le (by simpa using sq_nonneg u) + +theorem decay_bounds_key (f : W21) (u : ℝ) : ‖𝓕 (f : ℝ → ℂ) u‖ ≤ ‖f‖ * (1 + u ^ 2)⁻¹ := by + have l1 : 0 < 1 + u ^ 2 := one_add_sq_pos _ + have l2 : 1 + u ^ 2 = ‖(1 : ℂ) + u ^ 2‖ := by + norm_cast ; simp only [Real.norm_eq_abs, abs_eq_self.2 l1.le] + have l3 : ‖1 / ((4 : ℂ) * ↑π ^ 2)‖ ≤ (4 * π ^ 2)⁻¹ := by simp + have key := fourierIntegral_self_add_deriv_deriv f u + simp only [Function.iterate_succ _ 1, Function.iterate_one, Function.comp_apply] at key + rw [F_sub f.hf (f.hf''.const_mul (1 / (4 * ↑π ^ 2)))] at key + rw [← div_eq_mul_inv, le_div_iff₀ l1, mul_comm, l2, ← norm_mul, key, sub_eq_add_neg] + apply norm_add_le _ _ |>.trans + change _ ≤ W21.norm _ + rw [norm_neg, F_mul, norm_mul, W21.norm] + gcongr <;> apply VectorFourier.norm_fourierIntegral_le_integral_norm + +theorem decay_bounds_aux {f : ℝ → ℂ} (hf : AEStronglyMeasurable f volume) + (h : ∀ t, ‖f t‖ ≤ A * (1 + t ^ 2)⁻¹) : + ∫ t, ‖f t‖ ≤ π * A := by + have l1 : Integrable (fun x ↦ A * (1 + x ^ 2)⁻¹) := integrable_inv_one_add_sq.const_mul A + simp_rw [← integral_univ_inv_one_add_sq, mul_comm, ← integral_const_mul] + exact integral_mono (l1.mono' hf (Eventually.of_forall h)).norm l1 h + +theorem decay_bounds_W21 (f : W21) (hA : ∀ t, ‖f t‖ ≤ A / (1 + t ^ 2)) + (hA' : ∀ t, ‖deriv (deriv f) t‖ ≤ A / (1 + t ^ 2)) (u) : + ‖𝓕 (f : ℝ → ℂ) u‖ ≤ (π + 1 / (4 * π)) * A / (1 + u ^ 2) := by + have l0 : 1 * (4 * π)⁻¹ * A = (4 * π ^ 2)⁻¹ * (π * A) := by field_simp + have l1 : ∫ (v : ℝ), ‖f v‖ ≤ π * A := by + apply decay_bounds_aux f.continuous.aestronglyMeasurable + simp_rw [← div_eq_mul_inv] ; exact hA + have l2 : ∫ (v : ℝ), ‖deriv (deriv f) v‖ ≤ π * A := by + apply decay_bounds_aux f.deriv.deriv.continuous.aestronglyMeasurable + simp_rw [← div_eq_mul_inv] ; exact hA' + apply decay_bounds_key f u |>.trans + change W21.norm _ * _ ≤ _ + simp_rw [W21.norm, div_eq_mul_inv, add_mul, l0] ; gcongr + +theorem decay_bounds (ψ : CS 2 ℂ) (hA : ∀ t, ‖ψ t‖ ≤ A / (1 + t ^ 2)) + (hA' : ∀ t, ‖deriv^[2] ψ t‖ ≤ A / (1 + t ^ 2)) : + ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ (π + 1 / (4 * π)) * A / (1 + u ^ 2) := by + exact decay_bounds_W21 ψ hA hA' u + +theorem decay_bounds_cor_aux (ψ : CS 2 ℂ) : ∃ C : ℝ, ∀ u, ‖ψ u‖ ≤ C / (1 + u ^ 2) := by + have l1 : HasCompactSupport (fun u : ℝ => ((1 + u ^ 2) : ℝ) * ψ u) := by exact ψ.h2.mul_left + have := ψ.h1.continuous + obtain ⟨C, hC⟩ := l1.exists_bound_of_continuous (by fun_prop) + refine ⟨C, fun u => ?_⟩ + specialize hC u + simp only [norm_mul, Complex.norm_real, norm_of_nonneg (one_add_sq_pos u).le] at hC + rwa [le_div_iff₀' (one_add_sq_pos _)] + +theorem decay_bounds_cor (ψ : W21) : + ∃ C : ℝ, ∀ u, ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ C / (1 + u ^ 2) := by + simpa only [div_eq_mul_inv] using ⟨_, decay_bounds_key ψ⟩ + +@[continuity, fun_prop] theorem continuous_FourierIntegral (ψ : W21) : Continuous (𝓕 (ψ : ℝ → ℂ)) := + VectorFourier.fourierIntegral_continuous continuous_fourierChar + (by simp only [innerₗ_apply_apply, RCLike.inner_apply', conj_trivial, continuous_mul]) + ψ.hf + +theorem W21.integrable_fourier (ψ : W21) (hc : c ≠ 0) : + Integrable fun u ↦ 𝓕 (ψ : ℝ → ℂ) (u / c) := by + have l1 (C) : Integrable (fun u ↦ C / (1 + (u / c) ^ 2)) volume := by + simpa only [div_eq_mul_inv] using (integrable_inv_one_add_sq.comp_div hc).const_mul C + have l2 : AEStronglyMeasurable (fun u ↦ 𝓕 (ψ : ℝ → ℂ) (u / c)) volume := by + apply Continuous.aestronglyMeasurable ; fun_prop + obtain ⟨C, h⟩ := decay_bounds_cor ψ + apply @Integrable.mono' ℝ ℂ _ volume _ _ (fun u => C / (1 + (u / c) ^ 2)) (l1 C) l2 ?_ + apply Eventually.of_forall (fun x => h _) + +theorem continuous_LSeries_aux (hf : Summable (nterm f σ')) : + Continuous fun x : ℝ => LSeries f (σ' + x * I) := by + have l1 i : Continuous fun x : ℝ ↦ term f (σ' + x * I) i := by + by_cases h : i = 0 + · simpa [h] using continuous_const + · simpa [h] using continuous_const.div₀ (continuous_const.cpow (by fun_prop) (by simp [h])) + (fun x => by simp [h]) + have l2 n (x : ℝ) : ‖term f (σ' + x * I) n‖ = nterm f σ' n := by + simpa using norm_term_eq_nterm_re (f := f) (n := n) (σ' + x * I) + exact continuous_tsum l1 hf (fun n x => le_of_eq (l2 n x)) + +theorem limiting_fourier_aux (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 1 ≤ x) (σ' : ℝ) + (hσ' : 1 < σ') : + ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * (x ^ (1 - σ') : ℝ) * ∫ u in Ici (- log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) + (u / (2 * π)) = ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I) := by + have hint : Integrable ψ := ψ.h1.continuous.integrable_of_hasCompactSupport ψ.h2 + have l3 : 0 < x := zero_lt_one.trans_le hx + have l1 (σ') (hσ' : 1 < σ') := first_fourier hf hint l3 hσ' + have l2 (σ') (hσ' : 1 < σ') := second_fourier ψ.h1.continuous.measurable hint l3 hσ' + have l8 : Continuous fun t : ℝ ↦ (x : ℂ) ^ (t * I) := + continuous_const.cpow (continuous_ofReal.mul continuous_const) (by simp [l3]) + have l6 : Continuous fun t : ℝ ↦ LSeries f (↑σ' + ↑t * I) * ψ t * ↑x ^ (↑t * I) := by + apply ((continuous_LSeries_aux (hf _ hσ')).mul ψ.h1.continuous).mul l8 + have l4 : Integrable fun t : ℝ ↦ LSeries f (↑σ' + ↑t * I) * ψ t * ↑x ^ (↑t * I) := by + exact l6.integrable_of_hasCompactSupport ψ.h2.mul_left.mul_right + have e2 (u : ℝ) : σ' + u * I - 1 ≠ 0 := by + intro h ; have := congr_arg Complex.re h ; simp at this ; linarith + have l7 : Continuous fun a ↦ A * ↑(x ^ (1 - σ')) * (↑(x ^ (σ' - 1)) * + (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by + simp only [one_div, ← mul_assoc] + refine ((continuous_const.mul <| Continuous.inv₀ ?_ e2).mul ψ.h1.continuous).mul l8 + fun_prop + have l5 : Integrable fun a ↦ A * ↑(x ^ (1 - σ')) * (↑(x ^ (σ' - 1)) * + (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by + apply l7.integrable_of_hasCompactSupport + exact ψ.h2.mul_left.mul_right.mul_left.mul_left + simp_rw [l1 σ' hσ', l2 σ' hσ', ← integral_const_mul, ← integral_sub l4 l5] + apply integral_congr_ae + apply Eventually.of_forall + intro u + have e1 : 1 < ((σ' : ℂ) + (u : ℂ) * I).re := by simp [hσ'] + simp_rw [hG' e1, sub_mul, ← mul_assoc] + simp only [one_div, sub_right_inj, mul_eq_mul_right_iff, cpow_eq_zero_iff, ofReal_eq_zero, ne_eq, + mul_eq_zero, I_ne_zero, or_false] + left ; left + field_simp [e2] + norm_cast + simp [mul_assoc, ← rpow_add l3] + +end CatalanPNT diff --git a/PrimeNumberTheoremAnd/Catalan/WienerLimits.lean b/PrimeNumberTheoremAnd/Catalan/WienerLimits.lean new file mode 100644 index 0000000..fa60fec --- /dev/null +++ b/PrimeNumberTheoremAnd/Catalan/WienerLimits.lean @@ -0,0 +1,620 @@ +import PrimeNumberTheoremAnd.Catalan.WienerFourier + +namespace CatalanPNT + +open ZetaFivePNT + +open Real BigOperators ArithmeticFunction MeasureTheory Filter Set FourierTransform LSeries + Asymptotics SchwartzMap +open Complex hiding log +open scoped Topology +open scoped ContDiff +open scoped ComplexConjugate + +variable {n : ℕ} {A a b c d u x y t σ' : ℝ} {ψ Ψ : ℝ → ℂ} {F G : ℂ → ℂ} {f : ℕ → ℂ} {𝕜 : Type} + [RCLike 𝕜] + +section nabla + +variable {α E : Type*} [OfNat α 1] [Add α] [Sub α] {u : α → ℂ} + +def cumsum [AddCommMonoid E] (u : ℕ → E) (n : ℕ) : E := ∑ i ∈ Finset.range n, u i + +def nabla [Sub E] (u : α → E) (n : α) : E := u (n + 1) - u n + +def nnabla [Sub E] (u : α → E) (n : α) : E := u n - u (n + 1) + +def shift (u : α → E) (n : α) : E := u (n + 1) + +@[simp] theorem cumsum_zero [AddCommMonoid E] {u : ℕ → E} : cumsum u 0 = 0 := by simp [cumsum] + +theorem cumsum_succ [AddCommMonoid E] {u : ℕ → E} (n : ℕ) : + cumsum u (n + 1) = cumsum u n + u n := by + simp [cumsum, Finset.sum_range_succ] + +@[simp] theorem nabla_cumsum [AddCommGroup E] {u : ℕ → E} : nabla (cumsum u) = u := by + ext n ; simp [nabla, cumsum, Finset.range_add_one] + +theorem neg_cumsum [AddCommGroup E] {u : ℕ → E} : -(cumsum u) = cumsum (-u) := + funext (fun n => by simp [cumsum]) + +theorem cumsum_nonneg {u : ℕ → ℝ} (hu : 0 ≤ u) : 0 ≤ cumsum u := + fun _ => Finset.sum_nonneg (fun i _ => hu i) + +omit [Sub α] in +theorem neg_nabla [Ring E] {u : α → E} : -(nabla u) = nnabla u := by ext n ; simp [nabla, nnabla] + +omit [Sub α] in +@[simp] theorem nabla_mul [Ring E] {u : α → E} {c : E} : + nabla (fun n => c * u n) = c • nabla u := by + ext n ; simp [nabla, mul_sub] + +omit [Sub α] in +@[simp] theorem nnabla_mul [Ring E] {u : α → E} {c : E} : + nnabla (fun n => c * u n) = c • nnabla u := by + ext n ; simp [nnabla, mul_sub] + +theorem nnabla_cast (u : ℝ → E) [Sub E] : nnabla u ∘ ((↑) : ℕ → ℝ) = nnabla (u ∘ (↑)) := by + ext n ; simp [nnabla] + +end nabla + +theorem Finset.sum_shift_front {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : + cumsum u (n + 1) = u 0 + cumsum (shift u) n := by + simp_rw [add_comm n, cumsum, _root_.Finset.sum_range_add, + _root_.Finset.sum_range_one, add_comm 1] ; rfl + +theorem Finset.sum_shift_front' {E : Type*} [Ring E] {u : ℕ → E} : + shift (cumsum u) = (fun _ => u 0) + cumsum (shift u) := by + ext n ; apply Finset.sum_shift_front + +theorem Finset.sum_shift_back {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : + cumsum u (n + 1) = cumsum u n + u n := by + simp [cumsum, Finset.range_add_one, add_comm] + +theorem Finset.sum_shift_back' {E : Type*} [Ring E] {u : ℕ → E} : + shift (cumsum u) = cumsum u + u := by + ext n ; apply Finset.sum_shift_back + +theorem summation_by_parts {E : Type*} [Ring E] {a A b : ℕ → E} (ha : a = nabla A) {n : ℕ} : + cumsum (a * b) (n + 1) = A (n + 1) * b n - A 0 * b 0 - + cumsum (shift A * fun i => (b (i + 1) - b i)) n := by + have l1 : ∑ x ∈ Finset.range (n + 1), A (x + 1) * b x = ∑ x ∈ Finset.range n, + A (x + 1) * b x + A (n + 1) * b n := + Finset.sum_shift_back + have l2 : ∑ x ∈ Finset.range (n + 1), A x * b x = A 0 * b 0 + ∑ x ∈ Finset.range n, + A (x + 1) * b (x + 1) := + Finset.sum_shift_front + simp only [cumsum, ha, Pi.mul_apply, nabla, sub_mul, Finset.sum_sub_distrib, l1, l2, shift, + mul_sub] + abel + +theorem summation_by_parts' {E : Type*} [Ring E] {a b : ℕ → E} {n : ℕ} : + cumsum (a * b) (n + 1) = cumsum a (n + 1) * b n - cumsum (shift (cumsum a) * nabla b) n := by + change cumsum (a * b) (n + 1) = cumsum a (n + 1) * b n - + cumsum (shift (cumsum a) * (fun i : ℕ => b (i + 1) - b i)) n + simpa using summation_by_parts (a := a) (b := b) (A := cumsum a) (by simp) + +theorem summation_by_parts'' {E : Type*} [Ring E] {a b : ℕ → E} : + shift (cumsum (a * b)) = shift (cumsum a) * b - cumsum (shift (cumsum a) * nabla b) := by + ext n ; apply summation_by_parts' + +theorem summable_iff_bounded {u : ℕ → ℝ} (hu : 0 ≤ u) : + Summable u ↔ BoundedAtFilter atTop (cumsum u) := by + have l1 : (cumsum u =O[atTop] 1) ↔ _ := isBigO_one_nat_atTop_iff + have l2 n : ‖cumsum u n‖ = cumsum u n := by simpa using cumsum_nonneg hu n + simp only [BoundedAtFilter, l1, l2] + constructor <;> intro h <;> rcases h with ⟨C, h1⟩ + · exact ⟨C, fun n => sum_le_hasSum _ (fun i _ => hu i) h1⟩ + · exact summable_of_sum_range_le hu h1 + +theorem Filter.EventuallyEq.summable {u v : ℕ → ℝ} (h : u =ᶠ[atTop] v) (hu : Summable v) : + Summable u := + summable_of_isBigO_nat hu h.isBigO + +theorem summable_congr_ae {u v : ℕ → ℝ} (huv : u =ᶠ[atTop] v) : Summable u ↔ Summable v := by + exact ⟨CatalanPNT.Filter.EventuallyEq.summable huv.symm, + CatalanPNT.Filter.EventuallyEq.summable huv⟩ + +theorem BoundedAtFilter.add_const {u : ℕ → ℝ} {c : ℝ} : + BoundedAtFilter atTop (fun n => u n + c) ↔ BoundedAtFilter atTop u := by + have : u = fun n => (u n + c) + (-c) := by ext n ; ring + simp only [BoundedAtFilter] + constructor <;> intro h + on_goal 1 => rw [this] + all_goals { exact h.add (const_boundedAtFilter _ _) } + +theorem BoundedAtFilter.comp_add {u : ℕ → ℝ} {N : ℕ} : + BoundedAtFilter atTop (fun n => u (n + N)) ↔ BoundedAtFilter atTop u := by + simp only [BoundedAtFilter, isBigO_iff, norm_eq_abs, Pi.one_apply, one_mem, + CStarRing.norm_of_mem_unitary, mul_one, eventually_atTop] + constructor <;> intro hbound <;> rcases hbound with ⟨C, n₀, h⟩ <;> use C + · refine ⟨n₀ + N, fun n hn => ?_⟩ + obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le' (m := N) (n := n) (by grind) + exact h _ <| Nat.add_le_add_iff_right.mp hn + · exact ⟨n₀, fun n hn => h _ (by grind)⟩ + +theorem summable_iff_bounded' {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, 0 ≤ u n) : + Summable u ↔ BoundedAtFilter atTop (cumsum u) := by + obtain ⟨N, hu⟩ := eventually_atTop.mp hu + have e2 : cumsum (fun i ↦ u (i + N)) = fun n => cumsum u (n + N) - cumsum u N := by + ext n ; simp_rw [cumsum, add_comm _ N, Finset.sum_range_add] ; ring + rw [← summable_nat_add_iff N, summable_iff_bounded (fun n => hu _ <| Nat.le_add_left N n), e2] + simp_rw [sub_eq_add_neg, BoundedAtFilter.add_const, BoundedAtFilter.comp_add] + +theorem bounded_of_shift {u : ℕ → ℝ} (h : BoundedAtFilter atTop (shift u)) : + BoundedAtFilter atTop u := by + simp only [BoundedAtFilter, isBigO_iff, eventually_atTop] at h ⊢ + obtain ⟨C, N, hC⟩ := h + refine ⟨C, N + 1, fun n hn => ?_⟩ + simp only [shift] at hC + have r1 : n - 1 ≥ N := Nat.le_sub_one_of_lt hn + have r2 : n - 1 + 1 = n := Nat.sub_add_cancel (by omega) + simpa [r2] using hC (n - 1) r1 + +theorem dirichlet_test' {a b : ℕ → ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) + (hAb : BoundedAtFilter atTop (shift (cumsum a) * b)) (hbb : ∀ᶠ n in atTop, b (n + 1) ≤ b n) + (h : Summable (shift (cumsum a) * nnabla b)) : Summable (a * b) := by + have l1 : ∀ᶠ n in atTop, 0 ≤ (shift (cumsum a) * nnabla b) n := by + filter_upwards [hbb] with n hb + exact mul_nonneg (by simpa [shift] using cumsum_nonneg ha (n + 1)) (sub_nonneg.mpr hb) + rw [summable_iff_bounded (mul_nonneg ha hb)] + rw [summable_iff_bounded' l1] at h + apply bounded_of_shift + simpa only [summation_by_parts'', sub_eq_add_neg, neg_cumsum, ← mul_neg, neg_nabla] + using hAb.add h + +theorem exists_antitone_of_eventually {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, u (n + 1) ≤ u n) : + ∃ v : ℕ → ℝ, range v ⊆ range u ∧ Antitone v ∧ v =ᶠ[atTop] u := by + obtain ⟨N, hN⟩ := eventually_atTop.mp hu + let v (n : ℕ) := u (if n < N then N else n) + refine ⟨v, ?_, ?_, ?_⟩ + · intro x hx + rcases hx with ⟨n, hn⟩ + exact ⟨if n < N then N else n, hn⟩ + · refine antitone_nat_of_succ_le (fun n => ?_) + by_cases h : n < N + · by_cases h' : n + 1 < N <;> simp [v, h, h'] + have : n + 1 = N := by linarith + simp [this] + · have : ¬(n + 1 < N) := by linarith + simp only [this, ↓reduceIte, h, ge_iff_le, v] ; apply hN ; linarith + · have : ∀ᶠ n in atTop, ¬(n < N) := by simpa using ⟨N, fun b hb => by linarith⟩ + filter_upwards [this] with n hn ; simp [v, hn] + +theorem summable_inv_mul_log_sq : Summable (fun n : ℕ => (n * (Real.log n) ^ 2)⁻¹) := by + let u (n : ℕ) := (n * (Real.log n) ^ 2)⁻¹ + have l7 : ∀ᶠ n : ℕ in atTop, 1 ≤ Real.log n := + tendsto_atTop.mp (tendsto_log_atTop.comp tendsto_natCast_atTop_atTop) 1 + have l8 : ∀ᶠ n : ℕ in atTop, 1 ≤ n := eventually_ge_atTop 1 + have l9 : ∀ᶠ n in atTop, u (n + 1) ≤ u n := by + filter_upwards [l7, l8] with n l2 l8; dsimp [u]; gcongr <;> simp + obtain ⟨v, l1, l2, l3⟩ := exists_antitone_of_eventually l9 + rw [summable_congr_ae l3.symm] + have l4 (n : ℕ) : 0 ≤ v n := by obtain ⟨k, hk⟩ := l1 ⟨n, rfl⟩ ; rw [← hk] ; positivity + apply (summable_condensed_iff_of_nonneg l4 (fun _ _ _ a ↦ l2 a)).mp + suffices this : ∀ᶠ k : ℕ in atTop, 2 ^ k * v (2 ^ k) = ((k : ℝ) ^ 2)⁻¹ * ((Real.log 2) ^ 2)⁻¹ by + exact (summable_congr_ae this).mpr <| (Real.summable_nat_pow_inv.mpr one_lt_two).mul_right _ + have l5 : ∀ᶠ k in atTop, v (2 ^ k) = u (2 ^ k) := + l3.comp_tendsto <| tendsto_pow_atTop_atTop_of_one_lt Nat.le.refl + filter_upwards [l5, l8] with k l5 l8 + simp only [l5, mul_inv_rev, Nat.cast_pow, Nat.cast_ofNat, log_pow, u] + field_simp + +theorem tendsto_mul_add_atTop {a : ℝ} (ha : 0 < a) (b : ℝ) : + Tendsto (fun x => a * x + b) atTop atTop := + tendsto_atTop_add_const_right _ b (tendsto_id.const_mul_atTop ha) + +theorem isLittleO_const_of_tendsto_atTop {α : Type*} [Preorder α] (a : ℝ) {f : α → ℝ} + (hf : Tendsto f atTop atTop) : (fun _ => a) =o[atTop] f := by + simp [tendsto_norm_atTop_atTop.comp hf] + +theorem isLittleO_mul_add_sq (a b : ℝ) : (fun x => a * x + b) =o[atTop] (fun x => x ^ 2) := by + apply IsLittleO.add + · apply IsLittleO.const_mul_left ; simpa using isLittleO_pow_pow_atTop_of_lt (𝕜 := ℝ) one_lt_two + · apply isLittleO_const_of_tendsto_atTop _ <| tendsto_pow_atTop (by linarith) + +theorem log_mul_add_isBigO_log {a : ℝ} (ha : 0 < a) (b : ℝ) : + (fun x => Real.log (a * x + b)) =O[atTop] Real.log := by + apply IsBigO.of_bound (2 : ℕ) + have l2 : ∀ᶠ x : ℝ in atTop, 0 ≤ log x := tendsto_atTop.mp tendsto_log_atTop 0 + have l3 : ∀ᶠ x : ℝ in atTop, 0 ≤ log (a * x + b) := + tendsto_atTop.mp (tendsto_log_atTop.comp (tendsto_mul_add_atTop ha b)) 0 + have l5 : ∀ᶠ x : ℝ in atTop, 1 ≤ a * x + b := tendsto_atTop.mp (tendsto_mul_add_atTop ha b) 1 + have l1 : ∀ᶠ x : ℝ in atTop, a * x + b ≤ x ^ 2 := by + filter_upwards [(isLittleO_mul_add_sq a b).eventuallyLE, l5] with x r2 l5 + simpa [abs_eq_self.mpr (zero_le_one.trans l5)] using r2 + filter_upwards [l1, l2, l3, l5] with x l1 l2 l3 l5 + simpa [abs_eq_self.mpr l2, abs_eq_self.mpr l3, Real.log_pow] using + Real.log_le_log (by linarith) l1 + +theorem isBigO_log_mul_add {a : ℝ} (ha : 0 < a) (b : ℝ) : + Real.log =O[atTop] (fun x => Real.log (a * x + b)) := by + convert (log_mul_add_isBigO_log (b := -b / a) (inv_pos.mpr ha)).comp_tendsto + (tendsto_mul_add_atTop (b := b) ha) using 1 + · ext x + simp only [Function.comp_apply] + congr + field_simp + simp + · rfl + +theorem log_isbigo_log_div {d : ℝ} (hb : 0 < d) : + (fun n ↦ Real.log n) =O[atTop] (fun n ↦ Real.log (n / d)) := by + convert isBigO_log_mul_add (inv_pos.mpr hb) 0 using 1; simp only [add_zero]; field_simp + +theorem Asymptotics.IsBigO.add_isLittleO_right {f g : ℝ → ℝ} (h : g =o[atTop] f) : + f =O[atTop] (f + g) := by + exact h.right_isBigO_add' + +theorem Asymptotics.IsBigO.sq {α : Type*} [Preorder α] {f g : α → ℝ} (h : f =O[atTop] g) : + (fun n ↦ f n ^ 2) =O[atTop] (fun n => g n ^ 2) := + h.pow 2 + +theorem log_sq_isbigo_mul {a b : ℝ} (hb : 0 < b) : + (fun x ↦ Real.log x ^ 2) =O[atTop] (fun x ↦ a + Real.log (x / b) ^ 2) := by + apply (CatalanPNT.Asymptotics.IsBigO.sq (log_isbigo_log_div hb)).trans + simp_rw [add_comm a] + refine CatalanPNT.Asymptotics.IsBigO.add_isLittleO_right <| + isLittleO_const_of_tendsto_atTop _ ?_ + exact (tendsto_pow_atTop two_ne_zero).comp <| + tendsto_log_atTop.comp <| tendsto_id.atTop_div_const hb + +theorem log_add_div_isBigO_log (a : ℝ) {b : ℝ} (hb : 0 < b) : + (fun x ↦ Real.log ((x + a) / b)) =O[atTop] fun x ↦ Real.log x := by + convert log_mul_add_isBigO_log (inv_pos.mpr hb) (a / b) using 3 ; ring + +theorem log_add_one_sub_log_le {x : ℝ} (hx : 0 < x) : nabla Real.log x ≤ x⁻¹ := by + rw [nabla, ← Real.log_div (by linarith) hx.ne'] + calc + _ ≤ (x + 1) / x - 1 := Real.log_le_sub_one_of_pos (by positivity) + _ = x⁻¹ := by field_simp; ring + +theorem nabla_log_main : nabla Real.log =O[atTop] fun x ↦ 1 / x := by + apply IsBigO.of_bound 1 + filter_upwards [eventually_gt_atTop 0] with x l1 + have l2 : log x ≤ log (x + 1) := log_le_log l1 (by linarith) + simpa [nabla, abs_eq_self.mpr l1.le, abs_eq_self.mpr (sub_nonneg.mpr l2)] using + log_add_one_sub_log_le l1 + +theorem nabla_log {b : ℝ} (hb : 0 < b) : + nabla (fun x => Real.log (x / b)) =O[atTop] (fun x => 1 / x) := by + refine EventuallyEq.trans_isBigO ?_ nabla_log_main + filter_upwards [eventually_gt_atTop 0] with x l2 + rw [nabla, log_div (by linarith) (by linarith), log_div l2.ne.symm (by linarith), nabla] ; ring + +theorem nnabla_mul_log_sq (a : ℝ) {b : ℝ} (hb : 0 < b) : + nabla (fun x => x * (a + Real.log (x / b) ^ 2)) =O[atTop] (fun x => Real.log x ^ 2) := by + have l1 : nabla (fun n => n * (a + Real.log (n / b) ^ 2)) = fun n => + a + Real.log ((n + 1) / b) ^ 2 + + (n * (Real.log ((n + 1) / b) ^ 2 - Real.log (n / b) ^ 2)) := by + ext n ; simp [nabla] ; ring + have l2 := (isLittleO_const_of_tendsto_atTop a + ((tendsto_pow_atTop two_ne_zero).comp tendsto_log_atTop)).isBigO + have l3 := CatalanPNT.Asymptotics.IsBigO.sq (log_add_div_isBigO_log 1 hb) + have l4 : (fun x => Real.log ((x + 1) / b) + Real.log (x / b)) =O[atTop] Real.log := by + simpa using (log_add_div_isBigO_log _ hb).add (log_add_div_isBigO_log 0 hb) + have e2 : (fun x : ℝ => x * (Real.log x * (1 / x))) =ᶠ[atTop] Real.log := by + filter_upwards [eventually_ge_atTop 1] with x hx using by field_simp + have l5 : (fun n ↦ n * (Real.log n * (1 / n))) =O[atTop] (fun n ↦ (Real.log n) ^ 2) := + e2.trans_isBigO + (by simpa [Function.comp_def] using + (isLittleO_mul_add_sq 1 0).isBigO.comp_tendsto Real.tendsto_log_atTop) + simp_rw [l1, _root_.sq_sub_sq] + exact ((l2.add l3).add (isBigO_refl (·) atTop |>.mul (l4.mul (nabla_log hb)) |>.trans l5)) + +theorem nnabla_bound_aux1 (a : ℝ) {b : ℝ} (hb : 0 < b) : + Tendsto (fun x => x * (a + Real.log (x / b) ^ 2)) atTop atTop := + tendsto_id.atTop_mul_atTop₀ <| tendsto_atTop_add_const_left _ _ <| + (tendsto_pow_atTop two_ne_zero).comp <| tendsto_log_atTop.comp <| tendsto_id.atTop_div_const hb + +theorem nnabla_bound_aux2 (a : ℝ) {b : ℝ} (hb : 0 < b) : + ∀ᶠ x in atTop, 0 < x * (a + Real.log (x / b) ^ 2) := + (nnabla_bound_aux1 a hb).eventually (eventually_gt_atTop 0) + +theorem Real.log_eventually_gt_atTop (a : ℝ) : + ∀ᶠ x in atTop, a < Real.log x := + Real.tendsto_log_atTop.eventually (eventually_gt_atTop a) + +@[local gcongr] +theorem norm_lt_norm_of_nonneg (x y : ℝ) (hx : 0 ≤ x) (hxy : x ≤ y) : + ‖x‖ ≤ ‖y‖ := by + simp_rw [Real.norm_eq_abs] + apply abs_le_abs hxy + linarith + +theorem nnabla_bound_aux {x : ℝ} (hx : 0 < x) : + nnabla (fun n ↦ 1 / (n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2))) =O[atTop] + (fun n ↦ 1 / (Real.log n ^ 2 * n ^ 2)) := by + let d n : ℝ := n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2) + change (fun x_1 ↦ nnabla (fun n ↦ 1 / d n) x_1) =O[atTop] _ + have l2 : ∀ᶠ n in atTop, 0 < d n := (nnabla_bound_aux2 ((2 * π) ^ 2) hx) + have l3 : ∀ᶠ n in atTop, 0 < d (n + 1) := + (tendsto_atTop_add_const_right atTop (1 : ℝ) tendsto_id).eventually l2 + have l1 : ∀ᶠ n : ℝ in atTop, + nnabla (fun n ↦ 1 / d n) n = (d (n + 1) - d n) * (d n)⁻¹ * (d (n + 1))⁻¹ := by + filter_upwards [l2, l3] with n l2 l3 + rw [nnabla, one_div, one_div, inv_sub_inv l2.ne.symm l3.ne.symm, div_eq_mul_inv, mul_inv, + mul_assoc] + have l4 : (fun n => (d n)⁻¹) =O[atTop] (fun n => (n * (Real.log n) ^ 2)⁻¹) := by + apply IsBigO.inv_rev + · refine (isBigO_refl _ _).mul <| (log_sq_isbigo_mul hx) + · filter_upwards [Real.log_eventually_gt_atTop 0, eventually_gt_atTop 0] with x hx hx' + rw [← not_imp_not] + intro _ + positivity + have l5 : (fun n => (d (n + 1))⁻¹) =O[atTop] (fun n => (n * (Real.log n) ^ 2)⁻¹) := by + refine IsBigO.trans ?_ l4 + rw [isBigO_iff]; use 1 + have e3 : ∀ᶠ n in atTop, d n ≤ d (n + 1) := by + filter_upwards [eventually_ge_atTop x] with n hn + have e2 : 1 ≤ n / x := (one_le_div hx).mpr hn + have : 0 ≤ n := hx.le.trans hn + simp only [d] + gcongr <;> simp [Real.log_nonneg, *] + filter_upwards [l2, l3, e3] with n e1 e2 e3 + simp_rw [one_mul] + gcongr + have l6 : (fun n => d (n + 1) - d n) =O[atTop] (fun n => (Real.log n) ^ 2) := by + change nabla (fun n : ℝ => n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2)) + =O[atTop] (fun n => (Real.log n) ^ 2) + exact nnabla_mul_log_sq ((2 * π) ^ 2) hx + apply EventuallyEq.trans_isBigO l1 + apply ((l6.mul l4).mul l5).trans_eventuallyEq + filter_upwards [eventually_ge_atTop 2, Real.log_eventually_gt_atTop 0] with n hn hn' + field_simp + +theorem nnabla_bound (C : ℝ) {x : ℝ} (hx : 0 < x) : + nnabla (fun n => C / (1 + (Real.log (n / x) / (2 * π)) ^ 2) / n) =O[atTop] + (fun n => (n ^ 2 * (Real.log n) ^ 2)⁻¹) := by + field_simp + simp only [div_eq_mul_inv, mul_inv, nnabla_mul, one_mul] + apply IsBigO.const_mul_left + simpa [div_eq_mul_inv, mul_pow, mul_comm] using nnabla_bound_aux hx + +theorem cheby.bigO (h : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + cumsum (‖f ·‖) =O[atTop] ((↑) : ℕ → ℝ) := by + have l1 : 0 ≤ cumsum (‖f ·‖) := cumsum_nonneg (fun _ => norm_nonneg _) + obtain ⟨C, hC⟩ := h + apply isBigO_of_le' (c := C) atTop + intro n + rw [Real.norm_eq_abs, abs_eq_self.mpr (l1 n)] + simpa using hC n + +theorem limiting_fourier_lim1_aux + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hx : 0 < x) (C : ℝ) (hC : 0 ≤ C) : + Summable fun n ↦ ‖f n‖ / ↑n * (C / (1 + (1 / (2 * π) * Real.log (↑n / x)) ^ 2)) := by + let a (n : ℕ) := (C / (1 + (Real.log (↑n / x) / (2 * π)) ^ 2) / ↑n) + replace hcheby := cheby.bigO hcheby + have l1 : shift (cumsum (‖f ·‖)) =O[atTop] (fun n : ℕ => (↑(n + 1) : ℝ)) := + hcheby.comp_tendsto <| tendsto_add_atTop_nat 1 + have l2 : shift (cumsum (‖f ·‖)) =O[atTop] (fun n => (n : ℝ)) := + l1.trans + (by simpa using (isBigO_refl _ _).add <| isBigO_iff.mpr ⟨1, by simpa using ⟨1, by tauto⟩⟩) + have l5 : BoundedAtFilter atTop (fun n : ℕ => C / (1 + (Real.log (↑n / x) / (2 * π)) ^ 2)) := by + simp only [BoundedAtFilter] + field_simp + apply isBigO_of_le' (c := C) ; intro n + have : 0 ≤ 2 ^ 2 * π ^ 2 + Real.log (n / x) ^ 2 := by positivity + simp only [norm_div, norm_mul, norm_eq_abs, abs_eq_self.mpr hC, norm_pow, + abs_eq_self.mpr pi_nonneg, abs_eq_self.mpr this, Pi.one_apply, one_mem, + CStarRing.norm_of_mem_unitary, mul_one, ge_iff_le, Nat.abs_ofNat] + apply div_le_of_le_mul₀ this hC + rw [mul_add, ← mul_assoc] + apply le_add_of_le_of_nonneg le_rfl + positivity + have l3 : a =O[atTop] (fun n => 1 / (n : ℝ)) := by + convert IsBigO.mul l5 (isBigO_refl (fun n : ℕ => 1 / (n : ℝ)) _) using 1 + · ext n + simp [a, div_eq_mul_inv] + · ext n + simp + have l4 : nnabla a =O[atTop] (fun n : ℕ => (n ^ 2 * (Real.log n) ^ 2)⁻¹) := by + convert (nnabla_bound C hx).natCast_atTop ; simp [nnabla, a] + simp_rw [div_mul_eq_mul_div, mul_div_assoc, one_mul] + apply dirichlet_test' + · intro n ; exact norm_nonneg _ + · intro n ; positivity + · apply (l2.mul l3).trans_eventuallyEq + apply eventually_of_mem (Ici_mem_atTop 1) + intro x (hx : 1 ≤ x) + have : x ≠ 0 := Nat.one_le_iff_ne_zero.mp hx + simp [this] + · have : ∀ᶠ n : ℕ in atTop, x ≤ n := by simpa using eventually_ge_atTop ⌈x⌉₊ + filter_upwards [this] with n hn + have e1 : 0 < (n : ℝ) := by linarith + have e2 : 1 ≤ n / x := (one_le_div hx).mpr hn + have e3 := Nat.le_succ n + gcongr + refine div_nonneg (Real.log_nonneg e2) (by norm_num [pi_nonneg]) + · apply summable_of_isBigO_nat summable_inv_mul_log_sq + apply (l2.mul l4).trans_eventuallyEq + apply eventually_of_mem (Ici_mem_atTop 2) + intro x (hx : 2 ≤ x) + have : (x : ℝ) ≠ 0 := by simp ; linarith + have : Real.log x ≠ 0 := by + have ll : 2 ≤ (x : ℝ) := by simp [hx] + simp + grind + field_simp + +theorem limiting_fourier_lim1 + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (ψ : W21) (hx : 0 < x) : + Tendsto (fun σ' : ℝ ↦ + ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (n / x))) (𝓝[>] 1) + (𝓝 (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (n / x)))) := by + obtain ⟨C, hC⟩ := decay_bounds_cor ψ + have : 0 ≤ C := by simpa using (norm_nonneg _).trans (hC 0) + refine tendsto_tsum_of_dominated_convergence + (limiting_fourier_lim1_aux hcheby hx C this) (fun n => ?_) ?_ + · apply Tendsto.mul_const + by_cases h : n = 0 <;> simp only [term, h, ↓reduceIte, CharP.cast_eq_zero, div_zero, + tendsto_const_nhds_iff] + refine tendsto_const_nhds.div ?_ (by simp [h]) + simpa using ((continuous_ofReal.tendsto 1).mono_left nhdsWithin_le_nhds).const_cpow + · rw [eventually_nhdsWithin_iff] + apply Eventually.of_forall + intro σ' (hσ' : 1 < σ') n + rw [norm_mul, ← nterm_eq_norm_term] + refine mul_le_mul ?_ (hC _) (norm_nonneg _) (div_nonneg (norm_nonneg _) (Nat.cast_nonneg _)) + by_cases h : n = 0 <;> simp only [nterm, h, ↓reduceIte, CharP.cast_eq_zero, div_zero, le_refl] + have : 1 ≤ (n : ℝ) := by exact_mod_cast (show 1 ≤ n by omega) + refine div_le_div₀ (norm_nonneg _) le_rfl (by simpa [Nat.pos_iff_ne_zero]) ?_ + simpa using Real.rpow_le_rpow_of_exponent_le this hσ'.le + +theorem limiting_fourier_lim2_aux (x : ℝ) (C : ℝ) : + Integrable (fun t ↦ max |x| 1 * (C / (1 + (t / (2 * π)) ^ 2))) + (Measure.restrict volume (Ici (-Real.log x))) := by + simp_rw [div_eq_mul_inv C] + exact (((integrable_inv_one_add_sq.comp_div + (by simp [pi_ne_zero])).const_mul _).const_mul _).restrict + +theorem limiting_fourier_lim2 (A : ℝ) (ψ : W21) (hx : 1 ≤ x) : + Tendsto (fun σ' ↦ A * ↑(x ^ (1 - σ')) * + ∫ u in Ici (-Real.log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) + (𝓝[>] 1) (𝓝 (A * ∫ u in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)))) := by + obtain ⟨C, hC⟩ := decay_bounds_cor ψ + apply Tendsto.mul + · suffices h : Tendsto (fun σ' : ℝ ↦ ofReal (x ^ (1 - σ'))) (𝓝[>] 1) (𝓝 1) by + simpa using h.const_mul ↑A + suffices h : Tendsto (fun σ' : ℝ ↦ x ^ (1 - σ')) (𝓝[>] 1) (𝓝 1) from + (continuous_ofReal.tendsto 1).comp h + have : Tendsto (fun σ' : ℝ ↦ σ') (𝓝 1) (𝓝 1) := fun _ a ↦ a + have : Tendsto (fun σ' : ℝ ↦ 1 - σ') (𝓝[>] 1) (𝓝 0) := + tendsto_nhdsWithin_of_tendsto_nhds (by simpa using this.const_sub 1) + simpa using tendsto_const_nhds.rpow this (Or.inl (zero_lt_one.trans_le hx).ne.symm) + · refine tendsto_integral_filter_of_dominated_convergence _ ?_ ?_ + (limiting_fourier_lim2_aux x C) ?_ + · apply Eventually.of_forall ; intro σ' + apply Continuous.aestronglyMeasurable + have := continuous_FourierIntegral ψ + continuity + · apply eventually_of_mem (U := Ioo 1 2) + · apply Ioo_mem_nhdsGT_of_mem ; simp + · intro σ' hσ + have h1 := hσ.1 + have h2 := hσ.2 + rw [ae_restrict_iff' measurableSet_Ici] + apply Eventually.of_forall + intro t (ht : - Real.log x ≤ t) + rw [norm_mul] + have hdom_nonneg : 0 ≤ max |x| 1 := by + exact (abs_nonneg x).trans (le_max_left _ _) + refine mul_le_mul ?_ (hC _) (norm_nonneg _) hdom_nonneg + simp only [neg_mul, ofReal_exp, ofReal_neg, ofReal_mul, ofReal_sub, ofReal_one, norm_exp, + neg_re, mul_re, ofReal_re, sub_re, one_re, ofReal_im, sub_im, one_im, sub_self, mul_zero, + sub_zero] + have : -Real.log x * (σ' - 1) ≤ t * (σ' - 1) := mul_le_mul_of_nonneg_right ht (by linarith) + have : -(t * (σ' - 1)) ≤ Real.log x * (σ' - 1) := by simpa using neg_le_neg this + have := Real.exp_monotone this + apply this.trans + have l1 : σ' - 1 ≤ 1 := by linarith + have : 0 ≤ Real.log x := Real.log_nonneg hx + have := mul_le_mul_of_nonneg_left l1 this + refine (Real.exp_monotone this).trans ?_ + have hxabs : |x| = x := abs_of_nonneg (zero_le_one.trans hx) + calc + Real.exp (Real.log x * 1) = |x| := by + simpa [mul_one, hxabs] using (Real.exp_log (zero_lt_one.trans_le hx)) + _ ≤ max |x| 1 := le_max_left _ _ + · apply Eventually.of_forall + intro x + suffices h : Tendsto (fun n ↦ ((rexp (-x * (n - 1))) : ℂ)) (𝓝[>] 1) (𝓝 1) by + simpa using h.mul_const _ + apply Tendsto.mono_left ?_ nhdsWithin_le_nhds + suffices h : Continuous (fun n ↦ ((rexp (-x * (n - 1))) : ℂ)) by simpa using h.tendsto 1 + continuity + +theorem limiting_fourier_lim3 (hG : ContinuousOn G {s | 1 ≤ s.re}) (ψ : CS 2 ℂ) (hx : 1 ≤ x) : + Tendsto (fun σ' : ℝ ↦ ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I)) (𝓝[>] 1) + (𝓝 (∫ t : ℝ, G (1 + t * I) * ψ t * x ^ (t * I))) := by + by_cases hh : tsupport ψ = ∅ + · simp [tsupport_eq_empty_iff.mp hh] + obtain ⟨a₀, ha₀⟩ := Set.nonempty_iff_ne_empty.mpr hh + let S : Set ℂ := reProdIm (Icc 1 2) (tsupport ψ) + have l1 : IsCompact S := by + refine Metric.isCompact_iff_isClosed_bounded.mpr ⟨?_, ?_⟩ + · exact isClosed_Icc.reProdIm (isClosed_tsupport ψ) + · exact (Metric.isBounded_Icc 1 2).reProdIm ψ.h2.isBounded + have l2 : S ⊆ {s : ℂ | 1 ≤ s.re} := fun z hz => (mem_reProdIm.mp hz).1.1 + have l3 : ContinuousOn (‖G ·‖) S := (hG.mono l2).norm + have l4 : S.Nonempty := ⟨1 + a₀ * I, by simp [S, mem_reProdIm, ha₀]⟩ + obtain ⟨z, -, hmax⟩ := l1.exists_isMaxOn l4 l3 + let MG := ‖G z‖ + let bound (a : ℝ) : ℝ := MG * ‖ψ a‖ + apply tendsto_integral_filter_of_dominated_convergence (bound := bound) + · apply eventually_of_mem (U := Icc 1 2) (Icc_mem_nhdsGT_of_mem (by simp)) ; intro u hu + apply Continuous.aestronglyMeasurable + apply Continuous.mul + · exact (hG.comp_continuous (by fun_prop) (by simp [hu.1])).mul ψ.h1.continuous + · apply Continuous.const_cpow (by fun_prop) ; simp ; linarith + · apply eventually_of_mem (U := Icc 1 2) (Icc_mem_nhdsGT_of_mem (by simp)) + intro u hu + apply Eventually.of_forall ; intro v + by_cases h : v ∈ tsupport ψ + · have r1 : u + v * I ∈ S := by simp [S, mem_reProdIm, hu.1, hu.2, h] + have r2 := isMaxOn_iff.mp hmax _ r1 + have r4 : (x : ℂ) ≠ 0 := by simp ; linarith + have r5 : arg x = 0 := by simp [arg_eq_zero_iff] ; linarith + have r3 : ‖(x : ℂ) ^ (v * I)‖ = 1 := by simp [norm_cpow_of_ne_zero r4, r5] + simp_rw [norm_mul, r3, mul_one] + exact mul_le_mul_of_nonneg_right r2 (norm_nonneg _) + · have : v ∉ Function.support ψ := fun a ↦ h (subset_tsupport ψ a) + simp at this ; simp [this, bound] + · suffices h : Continuous bound by exact h.integrable_of_hasCompactSupport ψ.h2.norm.mul_left + have := ψ.h1.continuous ; fun_prop + · apply Eventually.of_forall ; intro t + apply Tendsto.mul_const + apply Tendsto.mul_const + refine (hG (1 + t * I) (by simp)).tendsto.comp <| tendsto_nhdsWithin_iff.mpr ⟨?_, ?_⟩ + · exact ((continuous_ofReal.tendsto _).add tendsto_const_nhds).mono_left nhdsWithin_le_nhds + · exact eventually_nhdsWithin_of_forall (fun x (hx : 1 < x) => by simp [hx.le]) + +theorem limiting_fourier (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 1 ≤ x) : + ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = + ∫ (t : ℝ), (G (1 + t * I)) * (ψ t) * x ^ (t * I) := by + have l1 := limiting_fourier_lim1 hcheby ψ (by linarith) + have l2 := limiting_fourier_lim2 A ψ hx + have l3 := limiting_fourier_lim3 hG ψ hx + apply tendsto_nhds_unique_of_eventuallyEq (l1.sub l2) l3 + simpa [eventuallyEq_nhdsWithin_iff, W21.ofCS2] using + Eventually.of_forall (limiting_fourier_aux hG' hf ψ hx) + +theorem limiting_cor_aux {f : ℝ → ℂ} : + Tendsto (fun x : ℝ ↦ ∫ t, f t * x ^ (t * I)) atTop (𝓝 0) := by + have l1 : ∀ᶠ x : ℝ in atTop, ∀ t : ℝ, x ^ (t * I) = exp (log x * t * I) := by + filter_upwards [eventually_ne_atTop 0, eventually_ge_atTop 0] with x hx hx' t + rw [Complex.cpow_def_of_ne_zero (ofReal_ne_zero.mpr hx), ofReal_log hx'] ; ring_nf + have l2 : ∀ᶠ x : ℝ in atTop, ∫ t, f t * x ^ (t * I) = ∫ t, f t * exp (log x * t * I) := by + filter_upwards [l1] with x hx + refine integral_congr_ae (Eventually.of_forall (fun x => by simp [hx])) + simp_rw [tendsto_congr' l2] + convert_to Tendsto (fun x => 𝓕 f (-Real.log x / (2 * π))) atTop (𝓝 0) + · funext x + rw [Real.fourier_real_eq_integral_exp_smul] + apply integral_congr_ae + filter_upwards [] with t + have hphase : -2 * π * t * (-Real.log x / (2 * π)) = Real.log x * t := by + field_simp + rw [hphase, ofReal_mul, smul_eq_mul] + exact mul_comm _ _ + refine (Real.zero_at_infty_fourier f).comp <| Tendsto.mono_right ?_ _root_.atBot_le_cocompact + exact (tendsto_neg_atBot_iff.mpr tendsto_log_atTop).atBot_mul_const (inv_pos.mpr two_pi_pos) + +theorem limiting_cor (ψ : CS 2 ℂ) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := by + apply limiting_cor_aux.congr' + filter_upwards [eventually_ge_atTop 1] with x hx using + limiting_fourier hcheby hG hG' hf ψ hx |>.symm + +end CatalanPNT diff --git a/PrimeNumberTheoremAnd/Erdos970.lean b/PrimeNumberTheoremAnd/Erdos970.lean new file mode 100644 index 0000000..2137759 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970.lean @@ -0,0 +1,19 @@ +import PrimeNumberTheoremAnd.Erdos970.Auxiliary +import PrimeNumberTheoremAnd.Erdos970.Consequences +import PrimeNumberTheoremAnd.Erdos970.Defs +import PrimeNumberTheoremAnd.Erdos970.EulerMaclaurin +import PrimeNumberTheoremAnd.Erdos970.Fourier +import PrimeNumberTheoremAnd.Erdos970.HadamardSupport +import PrimeNumberTheoremAnd.Erdos970.Mathlib.Algebra.Notation.Support +import PrimeNumberTheoremAnd.Erdos970.Mathlib.Analysis.Asymptotics.Asymptotics +import PrimeNumberTheoremAnd.Erdos970.Mathlib.Analysis.SpecialFunctions.Log.Basic +import PrimeNumberTheoremAnd.Erdos970.MellinCalculus +import PrimeNumberTheoremAnd.Erdos970.MertensClassical +import PrimeNumberTheoremAnd.Erdos970.Rectangle +import PrimeNumberTheoremAnd.Erdos970.ResidueCalcOnRectangles +import PrimeNumberTheoremAnd.Erdos970.SmoothExistence +import PrimeNumberTheoremAnd.Erdos970.Sobolev +import PrimeNumberTheoremAnd.Erdos970.Tactic.AdditiveCombination +import PrimeNumberTheoremAnd.Erdos970.Wiener +import PrimeNumberTheoremAnd.Erdos970.ZetaBounds +import PrimeNumberTheoremAnd.Erdos970.ZetaConj diff --git a/PrimeNumberTheoremAnd/Erdos970/Auxiliary.lean b/PrimeNumberTheoremAnd/Erdos970/Auxiliary.lean new file mode 100644 index 0000000..0273e54 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Auxiliary.lean @@ -0,0 +1,71 @@ +import Mathlib.Analysis.Complex.RealDeriv +import Mathlib.Analysis.InnerProductSpace.Basic + +namespace Erdos970 + +namespace Complex + +open _root_.Complex + +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 _ ↦ DifferentiableAt.comp_ofReal h.differentiableAt + +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 _ ↦ DifferentiableAt.ofReal_comp hf.differentiableAt + +open _root_.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₂⟩ := HasDerivAt.of_hasDerivAt_ofReal_comp H.hasDerivAt + 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] + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Consequences.lean b/PrimeNumberTheoremAnd/Erdos970/Consequences.lean new file mode 100644 index 0000000..4a72e0e --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Consequences.lean @@ -0,0 +1,2293 @@ +import Mathlib.NumberTheory.Harmonic.Bounds +import PrimeNumberTheoremAnd.Erdos970.Mathlib.Analysis.SpecialFunctions.Log.Basic +import PrimeNumberTheoremAnd.Erdos970.Defs +import PrimeNumberTheoremAnd.Erdos970.Wiener + +namespace Erdos970 + + +open ArithmeticFunction hiding log +open Nat hiding log +open _root_.Finset _root_.Erdos970.Finset +open BigOperators _root_.Filter _root_.Erdos970.Filter _root_.Real _root_.Erdos970.Real +open Classical _root_.Asymptotics _root_.Erdos970.Asymptotics MeasureTheory intervalIntegral +open scoped ArithmeticFunction.Moebius ArithmeticFunction.Omega Chebyshev + +open _root_.Set in +lemma Set.Ico_subset_Ico_of_Icc_subset_Icc {a b c d : ℝ} (h : Set.Icc a b ⊆ Set.Icc c d) : + Set.Ico a b ⊆ Set.Ico c d := by + intro z hz + have hz' := Set.Ico_subset_Icc_self.trans h hz + have hcd : c ≤ d := by + contrapose! hz' + rw [Icc_eq_empty_of_lt hz'] + exact notMem_empty _ + simp only [Set.mem_Ico, Set.mem_Icc] at * + refine ⟨hz'.1, hz'.2.eq_or_lt.resolve_left ?_⟩ + rintro rfl + apply hz.2.not_ge + have := h <| right_mem_Icc.mpr (hz.1.trans hz.2.le) + simp only [Set.mem_Icc] at this + exact this.2 + +lemma th43_b (x : ℝ) (hx : 2 ≤ x) : + Nat.primeCounting ⌊x⌋₊ = + θ x / log x + ∫ t in Set.Icc 2 x, θ t / (t * (Real.log t) ^ 2) := by + rw [integral_Icc_eq_integral_Ioc, ← intervalIntegral.integral_of_le hx] + exact Chebyshev.primeCounting_eq_theta_div_log_add_integral hx + +lemma finsum_range_eq_sum_range {R : Type*} [AddCommMonoid R] {f : ArithmeticFunction R} (x : ℝ) : + ∑ᶠ (n : ℕ) (_: n < x), f n = ∑ n ∈ range ⌈x⌉₊, f n := by + apply finsum_cond_eq_sum_of_cond_iff f + intros + simp only [mem_range] + exact Iff.symm Nat.lt_ceil + +lemma finsum_range_eq_sum_range' {R : Type*} [AddCommMonoid R] {f : ArithmeticFunction R} + (x : ℝ) : ∑ᶠ (n : ℕ) (_ : n ≤ x), f n = ∑ n ∈ Iic ⌊x⌋₊, f n := by + apply finsum_cond_eq_sum_of_cond_iff f + intro n h + simp only [mem_Iic] + exact Iff.symm <| Nat.le_floor_iff' + fun (hc : n = 0) ↦ (h : f n ≠ 0) <| (congrArg f hc).trans ArithmeticFunction.map_zero + +lemma log2_pos : 0 < log 2 := by + rw [Real.log_pos_iff zero_le_two] + exact one_lt_two + +theorem Asymptotics.IsEquivalent.add_isLittleO' {α : Type*} {β : Type*} [NormedAddCommGroup β] + {u : α → β} {v : α → β} {w : α → β} {l : Filter α} + (huv : Asymptotics.IsEquivalent l u v) (hwu : (w - u) =o[l] v) : + Asymptotics.IsEquivalent l w v := by + rw [← add_sub_cancel u w] + exact huv.add_isLittleO hwu + +theorem Asymptotics.IsEquivalent.add_isLittleO'' {α : Type*} {β : Type*} [NormedAddCommGroup β] + {u : α → β} {v : α → β} {w : α → β} {l : Filter α} + (huv : Asymptotics.IsEquivalent l u v) (hwu : (u - w) =o[l] v) : + Asymptotics.IsEquivalent l w v := by + rw [← sub_sub_self u w] + exact huv.sub_isLittleO hwu + +theorem WeakPNT' : Tendsto (fun N ↦ (∑ n ∈ Iic N, Λ n) / N) atTop (nhds 1) := by + have : (fun N ↦ (∑ n ∈ Iic N, Λ n) / N) = + (fun N ↦ (∑ n ∈ range N, Λ n)/N + Λ N / N) := by + ext N + have : N ∈ Iic N := mem_Iic.mpr (le_refl _) + rw [← Finset.sum_erase_add _ _ this, ← Nat.Iio_eq_range, Iic_erase] + exact add_div _ _ _ + + rw [this, ← add_zero 1] + apply Tendsto.add WeakPNT + convert squeeze_zero (f := fun N ↦ Λ N / N) (g := fun N ↦ log N / N) (t₀ := atTop) ?_ ?_ ?_ + · intro N + exact div_nonneg vonMangoldt_nonneg (cast_nonneg N) + · intro N + exact div_le_div_of_nonneg_right vonMangoldt_le_log (cast_nonneg N) + have := Real.tendsto_pow_log_div_pow_atTop 1 1 Real.zero_lt_one + simp only [rpow_one] at this + exact Tendsto.comp this tendsto_natCast_atTop_atTop + +theorem WeakPNT'' : ψ ~[atTop] (fun x ↦ x) := by + rw [(by rfl : ψ = (fun x ↦ ψ x))] + simp_rw [Chebyshev.psi_eq_sum_Icc] + apply IsEquivalent.trans (v := fun x ↦ (⌊x⌋₊:ℝ)) + · rw [isEquivalent_iff_tendsto_one] + · convert! Tendsto.comp WeakPNT' tendsto_nat_floor_atTop + infer_instance + rw [eventually_iff] + simp only [ne_eq, cast_eq_zero, floor_eq_zero, not_lt, mem_atTop_sets, + Set.mem_ofPred_eq] + use 1 + simp only [imp_self, implies_true] + apply IsLittleO.isEquivalent + rw [← isLittleO_neg_left] + apply IsLittleO.of_bound + intro ε hε + simp only [Pi.sub_apply, neg_sub, norm_eq_abs, eventually_atTop] + use ε⁻¹ + intro b hb + have hb' : 0 ≤ b := le_of_lt (lt_of_lt_of_le (inv_pos_of_pos hε) hb) + rw [abs_of_nonneg, abs_of_nonneg hb'] + · apply LE.le.trans _ ((inv_le_iff_one_le_mul₀' hε).mp hb) + linarith [Nat.lt_floor_add_one b] + rw [sub_nonneg] + exact floor_le hb' + +lemma isLittleO_sqrt_mul_log : (fun x : ℝ ↦ x.sqrt * x.log) =o[atTop] _root_.id := by + have : (fun x : ℝ ↦ x.sqrt * x.log) =o[atTop] fun x ↦ x := by + refine (isLittleO_mul_iff_isLittleO_div ?_).mpr ?_ + · filter_upwards [eventually_gt_atTop 0] with x hx; exact (sqrt_ne_zero hx.le).mpr hx.ne' + · convert! isLittleO_log_rpow_atTop (by norm_num : (0 : ℝ) < 1 / 2) using 2 with x + rw [div_sqrt, sqrt_eq_rpow] + exact this + +lemma tendsto_floor_add_one_div_self : Tendsto (fun x : ℝ ↦ (⌊x⌋₊ + 1 : ℝ) / x) atTop (nhds 1) := by + have h := Asymptotics.isEquivalent_nat_floor (R := ℝ) + have h' : IsEquivalent atTop (fun x : ℝ ↦ (⌊x⌋₊ : ℝ) + 1) _root_.id := + h.add_isLittleO (isLittleO_const_id_atTop 1) + rwa [isEquivalent_iff_tendsto_one + (by filter_upwards [eventually_gt_atTop 0] with x hx a; simp only [_root_.id] at a; linarith)] at h' + +lemma isTheta_self_div_const {c : ℝ} (hc : c ≠ 0) : (fun x : ℝ ↦ x) =Θ[atTop] fun x ↦ x / c := by + have : (fun x : ℝ ↦ x / c) = fun x ↦ c⁻¹ * x := by ext x; ring + exact this ▸ (isTheta_const_mul_left (inv_ne_zero hc)).mpr (isTheta_refl ..) |>.symm + +lemma filter_prime_Iic_eq_Icc (n : ℕ) : filter Prime (Iic n) = filter Prime (Icc 1 n) := by + ext p; simp only [mem_filter, mem_Iic, mem_Icc, and_congr_left_iff] + exact fun hp ↦ ⟨fun h ↦ ⟨hp.one_lt.le, h⟩, fun ⟨_, h⟩ ↦ h⟩ + +lemma Icc_zero_eq_insert (n : ℕ) : Icc 0 n = insert 0 (Icc 1 n) := by + ext m; simp [mem_Icc]; omega + +theorem chebyshev_asymptotic : θ ~[atTop] id := by + refine Asymptotics.IsEquivalent.add_isLittleO'' WeakPNT'' + (IsBigO.trans_isLittleO (g := fun x ↦ 2 * x.sqrt * x.log) ?_ ?_) + · rw [isBigO_iff']; refine ⟨1, one_pos, ?_⟩ + simp only [one_mul, eventually_atTop] + exact ⟨2, fun x hx ↦ by + rw [Pi.sub_apply, norm_eq_abs, norm_eq_abs, abs_of_nonneg (by bound : 0 ≤ 2 * √x * log x)] + exact (abs_of_nonneg (sub_nonneg.mpr (Chebyshev.theta_le_psi x))).symm ▸ + Chebyshev.abs_psi_sub_theta_le_sqrt_mul_log (by linarith : 1 ≤ x)⟩ + · simpa only [mul_assoc] using! isLittleO_sqrt_mul_log.const_mul_left 2 + +theorem chebyshev_asymptotic_finsum : + (fun x ↦ ∑ᶠ (p : ℕ) (_ : p ≤ x) (_ : Nat.Prime p), log p) ~[atTop] fun x ↦ x := by + have hReal : + (fun x : ℝ ↦ ∑ᶠ (p : ℕ) (_ : (p : ℝ) ≤ x) (_ : p.Prime), log (p : ℝ)) ~[atTop] + fun x ↦ x := by + have h x : ∑ᶠ (p : ℕ) (_ : (p : ℝ) ≤ x) (_ : p.Prime), log (p : ℝ) = θ x := by + rw [Chebyshev.theta_eq_sum_Icc] + have hfin : {p : ℕ | (p : ℝ) ≤ x ∧ p.Prime}.Finite := + (Iic ⌊x⌋₊).finite_toSet.subset fun p ⟨hpx, _⟩ ↦ mem_Iic.mpr (Nat.le_floor hpx) + calc ∑ᶠ (p : ℕ) (_ : (p : ℝ) ≤ x) (_ : p.Prime), log (p : ℝ) + = ∑ᶠ (p : ℕ) (_ : (p : ℝ) ≤ x ∧ p.Prime), log (p : ℝ) := + finsum_congr fun p ↦ by by_cases hp : p.Prime <;> simp [hp] + _ = ∑ p ∈ hfin.toFinset, log (p : ℝ) := finsum_mem_eq_finite_toFinset_sum _ hfin + _ = _ := sum_congr (by ext p; simp only [Set.Finite.mem_toFinset, Set.mem_ofPred_eq, + mem_filter, mem_Icc, and_congr_left_iff]; exact fun hp ↦ + ⟨fun hpx ↦ ⟨Nat.zero_le _, Nat.le_floor hpx⟩, fun ⟨_, hpn⟩ ↦ + (le_or_gt 0 x).elim + (fun hx ↦ (Nat.floor_le hx).trans' (Nat.cast_le.mpr hpn)) fun hx ↦ + absurd (Nat.le_zero.mp (Nat.floor_eq_zero.mpr (hx.trans_le zero_le_one) ▸ hpn)) + hp.ne_zero⟩) (fun _ _ ↦ rfl) + have heq : + (fun x : ℝ ↦ ∑ᶠ (p : ℕ) (_ : (p : ℝ) ≤ x) (_ : p.Prime), log (p : ℝ)) =ᶠ[atTop] θ := + Filter.Eventually.of_forall h + exact chebyshev_asymptotic.congr_left heq.symm + simp only [IsEquivalent, + show (fun n : ℕ ↦ ∑ᶠ (p : ℕ) (_ : p ≤ n) (_ : p.Prime), log (p : ℝ)) = + (fun x : ℝ ↦ ∑ᶠ (p : ℕ) (_ : (p : ℝ) ≤ x) (_ : p.Prime), log (p : ℝ)) ∘ Nat.cast + from funext fun _ ↦ finsum_congr fun _ ↦ by simp] + exact hReal.isLittleO.comp_tendsto tendsto_natCast_atTop_atTop + +theorem chebyshev_asymptotic' : + ∃ (f : ℝ → ℝ), + (∀ ε > (0 : ℝ), (f =o[atTop] fun t ↦ ε * t)) ∧ + (∀ (x : ℝ), 2 ≤ x → IntegrableOn f (Set.Icc 2 x)) ∧ + ∀ (x : ℝ), θ x = x + f x := by + have H := chebyshev_asymptotic + rw [IsEquivalent, isLittleO_iff] at H + let f := (fun x ↦ θ x - x) + have integrable (x : ℝ) (hx : 2 ≤ x) : IntegrableOn f (Set.Icc 2 x) := by + rw [IntegrableOn] + refine Integrable.sub ?_ (ContinuousOn.integrableOn_Icc (continuousOn_id' _)) + refine Chebyshev.integrableOn_theta_div_id_mul_log_sq x |>.mul_continuousOn (g' := fun t => t * log t ^ 2) + (ContinuousOn.mul (continuousOn_id' _) (ContinuousOn.pow (continuousOn_log |>.mono <| by + rintro t ⟨ht1, _⟩ + simp only [Set.mem_compl_iff, Set.mem_singleton_iff] + linarith) 2)) isCompact_Icc |>.congr_fun_ae ?_ + simp only [measurableSet_Icc, ae_restrict_eq, EventuallyEq, eventually_inf_principal] + refine .of_forall fun t ⟨ht1, _⟩ => ?_ + rw [div_mul_cancel₀] + simpa only [ne_eq, _root_.mul_eq_zero, OfNat.ofNat_ne_zero, not_false_eq_true, pow_eq_zero_iff, + log_eq_zero, or_self_left, not_or] using ⟨by linarith, by linarith, by linarith⟩ + refine ⟨f, fun ε hε ↦ ?_, integrable, ?_⟩ + · rw [isLittleO_iff] + intro c hc + specialize @H (c * ε) (mul_pos hc hε) + simp only [Pi.sub_apply, norm_eq_abs, mul_assoc, eventually_atTop, norm_mul, + abs_of_pos hε, f] at H ⊢ + exact H + refine fun r => by simp [f] + +theorem chebyshev_asymptotic'' : + ∃ (f : ℝ → ℝ), + (∀ ε > (0 : ℝ), (f =o[atTop] fun _ ↦ ε)) ∧ + (∀ (x : ℝ), 2 ≤ x → IntegrableOn f (Set.Icc 2 x)) ∧ + ∀ x > (0 : ℝ), θ x = x + x * (f x) := by + obtain ⟨f, hf1, inte, hf2⟩ := chebyshev_asymptotic' + refine ⟨fun t => f t / t, fun ε hε ↦ ?_, ?_, ?_⟩ + · simp only [isLittleO_iff, norm_eq_abs, norm_mul, eventually_atTop, + norm_div] at hf1 ⊢ + intro r hr + replace hf1 := hf1 ε hε + obtain ⟨N, hN⟩ := hf1 hr + use |N| + 1 + intro x hx + have hx' : |N| + 1 ≤ |x| := by rwa [abs_of_nonneg (a := x) (le_trans (by positivity) hx)] + rw [div_le_iff₀ (lt_of_lt_of_le (by positivity) hx'), mul_assoc] + exact hN x (le_trans (le_trans (le_abs_self N) (by linarith)) hx) + + · intro x hx + refine inte x hx |>.mul_continuousOn (g' := fun t : ℝ => t⁻¹) + (continuousOn_inv₀ |>.mono <| by + rintro t ⟨ht1, _⟩ + simp only [Set.mem_compl_iff, Set.mem_singleton_iff] + linarith) isCompact_Icc |>.congr_fun_ae <| .of_forall <| by simp [div_eq_mul_inv] + intro x hx + rw [hf2, mul_div_cancel₀] + linarith + +theorem primorial_bounds : + ∃ E : ℝ → ℝ, E =o[atTop] (fun x ↦ x) ∧ + ∀ x : ℝ, ∏ p ∈ (Iic ⌊x⌋₊).filter Nat.Prime, p = exp (x + E x) := by + use (fun x ↦ ∑ p ∈ (filter Nat.Prime (Iic ⌊x⌋₊)), log p - x) + constructor + · exact Asymptotics.IsEquivalent.isLittleO chebyshev_asymptotic + intro x + simp only [cast_prod, add_sub_cancel, exp_sum] + apply Finset.prod_congr rfl + intros x hx + rw[Real.exp_log] + rw[Finset.mem_filter] at hx + norm_cast + exact Nat.Prime.pos hx.right + +theorem primorial_bounds_finprod : + ∃ E : ℝ → ℝ, E =o[atTop] (fun x ↦ x) ∧ + ∀ x : ℝ, ∏ᶠ (p : ℕ) (_ : p ≤ x) (_ : Nat.Prime p), p = exp (x + E x) := by + obtain ⟨E, hE, hprod⟩ := primorial_bounds + refine ⟨E, hE, fun x ↦ ?_⟩ + have hfin : {p : ℕ | (p : ℝ) ≤ x ∧ p.Prime}.Finite := + (Iic ⌊x⌋₊).finite_toSet.subset fun p ⟨hpx, _⟩ ↦ mem_Iic.mpr <| le_floor hpx + have heq : ∏ᶠ (p : ℕ) (_ : (p : ℝ) ≤ x) (_ : p.Prime), p = + ∏ p ∈ (Iic ⌊x⌋₊).filter Prime, p := by + calc ∏ᶠ (p : ℕ) (_ : (p : ℝ) ≤ x) (_ : p.Prime), p + = ∏ᶠ (p : ℕ) (_ : (p : ℝ) ≤ x ∧ p.Prime), p := + finprod_congr fun p ↦ by by_cases hp : p.Prime <;> simp [hp] + _ = ∏ p ∈ hfin.toFinset, p := finprod_mem_eq_finite_toFinset_prod _ hfin + _ = _ := prod_congr (by ext p; simp only [Set.Finite.mem_toFinset, Set.mem_ofPred_eq, + mem_filter, mem_Iic, and_congr_left_iff]; exact fun hp ↦ + ⟨le_floor, fun hpn ↦ (le_or_gt 0 x).elim + (fun hx ↦ (Nat.floor_le hx).trans' (cast_le.mpr hpn)) fun hx ↦ + absurd (le_zero.mp (floor_eq_zero.mpr (hx.trans_le zero_le_one) ▸ hpn)) + hp.ne_zero⟩) (fun _ _ ↦ rfl) + simp only [heq, hprod] + +lemma continuousOn_log0 : + ContinuousOn (fun x ↦ -1 / (x * log x ^ 2)) {0, 1, -1}ᶜ := by + refine fun t ht ↦ ContinuousAt.continuousWithinAt ?_ + fun_prop (disch := simp_all) + +lemma continuousOn_log1 : ContinuousOn (fun x ↦ (log x ^ 2)⁻¹ * x⁻¹) {0, 1, -1}ᶜ := by + refine fun t ht ↦ ContinuousAt.continuousWithinAt ?_ + fun_prop (disch := simp_all) + +lemma integral_log_inv (a b : ℝ) (ha : 2 ≤ a) (hb : a ≤ b) : + ∫ t in a..b, (log t)⁻¹ = + ((log b)⁻¹ * b) - ((log a)⁻¹ * a) + + ∫ t in a..b, ((log t)^2)⁻¹ := by + rw [le_iff_lt_or_eq] at hb + rcases hb with hb | rfl; swap + · simp only [intervalIntegral.integral_same, sub_self, add_zero] + · have := intervalIntegral.integral_mul_deriv_eq_deriv_mul + (u := fun x => (log x)⁻¹) + (u' := fun x => -1 / (x * (log x)^2)) + (v := fun x => x) + (v' := fun _ => 1) (a := a) (b := b) + (fun x hx => by + rw [Set.uIcc_eq_union, Set.Icc_eq_empty (lt_iff_not_ge |>.1 hb), Set.union_empty] at hx + obtain ⟨hx1, _⟩ := hx + rw [show (-1 / (x * log x ^ 2)) = (-1 / log x ^ 2) * (x⁻¹) by + rw [mul_comm x]; field_simp] + apply HasDerivAt.comp + (h := fun t => log t) (h₂ := fun t => t⁻¹) (x := x) + · simpa using! HasDerivAt.inv (c := fun t : ℝ => t) (c' := 1) (x := log x) + (hasDerivAt_id' (log x)) + (by simp only [ne_eq, log_eq_zero, not_or]; refine ⟨?_, ?_, ?_⟩ <;> linarith) + · apply hasDerivAt_log; linarith) + (fun x _ => hasDerivAt_id' x) + (by + rw [intervalIntegrable_iff_integrableOn_Icc_of_le (le_of_lt hb)] + apply ContinuousOn.integrableOn_Icc + refine continuousOn_log0.mono fun x hx ↦ ?_ + simp only [Set.mem_Icc, Set.mem_compl_iff, Set.mem_insert_iff, Set.mem_singleton_iff, + not_or] at hx ⊢ + refine ⟨?_, ?_, ?_⟩ <;> linarith) + (by + constructor <;> + apply MeasureTheory.integrable_const) + simp only [mul_one] at this + rw [this] + simp_rw [neg_div, neg_mul] + rw [sub_eq_add_neg] + congr 1 + rw [intervalIntegral.integral_of_le (le_of_lt hb), + intervalIntegral.integral_of_le (le_of_lt hb), + ← MeasureTheory.integral_neg] + simp_rw [neg_neg] + refine integral_congr_ae ?_ + · rw [ae_restrict_eq, eventuallyEq_inf_principal_iff] + · refine .of_forall fun x hx => ?_ + simp only [Set.mem_Ioc, one_div, mul_inv_rev, mul_assoc] at hx ⊢ + rw [inv_mul_cancel₀, mul_one] + linarith + exact measurableSet_Ioc + +lemma integral_log_inv' (a b : ℝ) (ha : 2 ≤ a) (hb : a ≤ b) : + ∫ t in Set.Icc a b, (log t)⁻¹ = + ((log b)⁻¹ * b) - ((log a)⁻¹ * a) + + ∫ t in Set.Icc a b, ((log t)^2)⁻¹ := by + have := integral_log_inv a b ha hb + simp only [intervalIntegral.intervalIntegral_eq_integral_uIoc, ite_eq_left hb, Set.uIoc_of_le hb, + smul_eq_mul, one_mul] at this + rw [integral_Icc_eq_integral_Ioc, integral_Icc_eq_integral_Ioc] + rw [this] + +lemma integral_log_inv'' (a b : ℝ) (ha : 2 ≤ a) (hb : a ≤ b) : + (log a)⁻¹ * a + ∫ t in Set.Icc a b, (log t)⁻¹ = + ((log b)⁻¹ * b) + ∫ t in Set.Icc a b, ((log t)^2)⁻¹ := by + rw [integral_log_inv' a b ha hb] + group + +lemma integral_log_inv_pos (x : ℝ) (hx : 2 < x) : + 0 < ∫ t in Set.Icc 2 x, (log t)⁻¹ := by + classical + rw [MeasureTheory.integral_pos_iff_support_of_nonneg_ae] + · simp only [Function.support_inv, measurableSet_Icc, Measure.restrict_apply'] + rw [show Function.support log ∩ Set.Icc 2 x = Set.Icc 2 x by + rw [Set.inter_eq_right] + intro t ht + simp only [Set.mem_Icc, Function.mem_support, ne_eq, log_eq_zero, not_or] at ht ⊢ + exact ⟨by linarith, by linarith, by linarith⟩] + simpa + · simp only [measurableSet_Icc, ae_restrict_eq, EventuallyLE, eventually_inf_principal] + refine .of_forall fun t (ht : _ ∧ _) => ?_ + simpa only [Pi.zero_apply, inv_nonneg] using log_nonneg (by linarith) + · apply ContinuousOn.integrableOn_Icc + apply ContinuousOn.inv₀ + · exact (continuousOn_log).mono <| by aesop + + · rintro t ⟨ht, -⟩ + simp only [ne_eq, log_eq_zero, not_or] + exact ⟨by linarith, by linarith, by linarith⟩ + +lemma integral_log_inv_ne_zero (x : ℝ) (hx : 2 < x) : + ∫ t in Set.Icc 2 x, (log t)⁻¹ ≠ 0 := by + have := integral_log_inv_pos x hx + linarith + +lemma pi_asymp_aux (x : ℝ) (hx : 2 ≤ x) : Nat.primeCounting ⌊x⌋₊ = + (log x)⁻¹ * θ x + ∫ t in Set.Icc 2 x, θ t * (t * log t ^ 2)⁻¹ := by + rw [th43_b _ hx] + simp_rw [div_eq_mul_inv, Chebyshev.theta_eq_sum_Icc] + ring_nf! + +theorem pi_asymp'' : + (fun x => ((Nat.primeCounting ⌊x⌋₊ : ℝ) / ∫ t in Set.Icc 2 x, 1 / log t) - (1 : ℝ)) =o[atTop] + fun _ => (1 : ℝ) := by + obtain ⟨f, hf, f_int, hf'⟩ := chebyshev_asymptotic'' + have eq1 : ∀ᶠ (x : ℝ) in atTop, + ⌊x⌋₊.primeCounting = + (log x)⁻¹ * (x + x * f x) + + (∫ t in Set.Icc 2 x, + (t + t * f t) * (t * log t ^ 2)⁻¹) := by + filter_upwards [eventually_ge_atTop 2] with x hx + rw [pi_asymp_aux x hx, hf' x (by linarith)] + congr 1 + apply setIntegral_congr_fun measurableSet_Icc fun t ht ↦ ?_ + rw [hf' t (by grind)] + + replace eq1 : + ∀ᶠ (x : ℝ) in atTop, + ⌊x⌋₊.primeCounting = + (log x)⁻¹ * (x + x * f x) + + ((∫ t in Set.Icc 2 x, (log t ^ 2)⁻¹) + + (∫ t in Set.Icc 2 x, (f t) * (log t ^ 2)⁻¹)) := by + filter_upwards [eq1, eventually_ge_atTop 2] with x eq1 hx + rw [eq1] + congr + simp_rw [mul_inv_rev, add_mul] + rw [MeasureTheory.integral_add] + · congr 1 + all_goals + apply setIntegral_congr_fun measurableSet_Icc fun t ht ↦ ?_ + field [show t ≠ 0 by grind] + · apply IntegrableOn.mul_continuousOn + (hg := ContinuousOn.integrableOn_Icc <| continuousOn_id' _) + (hK := isCompact_Icc) + apply continuousOn_log1.mono ?_ + intro y h + simp only [Set.mem_Icc, Set.mem_compl_iff, Set.mem_insert_iff, + Set.mem_singleton_iff, not_or] at h ⊢ + exact ⟨by linarith, by linarith, by linarith⟩ + · rw [show (fun t ↦ t * f t * ((log t ^ 2)⁻¹ * t⁻¹)) = + fun t ↦ f t * (t * (log t ^ 2)⁻¹ * t⁻¹) by ext; ring] + apply IntegrableOn.mul_continuousOn (hK := isCompact_Icc) + · apply f_int x (by linarith) + · simp_rw [mul_assoc] + refine ContinuousOn.mul (continuousOn_id' (Set.Icc 2 x)) ?_ + apply continuousOn_log1.mono ?_ + intro y h + simp only [Set.mem_Icc, Set.mem_compl_iff, Set.mem_insert_iff, + Set.mem_singleton_iff, not_or] at h ⊢ + exact ⟨by linarith, by linarith, by linarith⟩ + + simp_rw [mul_add] at eq1 + simp_rw [show ∀ (x : ℝ), + (log x)⁻¹ * x + (log x)⁻¹ * (x * f x) + + ((∫ (t : ℝ) in Set.Icc 2 x, (log t ^ 2)⁻¹) + + ∫ (t : ℝ) in Set.Icc 2 x, f t * (log t ^ 2)⁻¹) = + ((log x)⁻¹ * x + (∫ (t : ℝ) in Set.Icc 2 x, (log t ^ 2)⁻¹)) + + ((log x)⁻¹ * (x * f x) + + ∫ (t : ℝ) in Set.Icc 2 x, f t * (log t ^ 2)⁻¹) + by intros; ring] at eq1 + + replace eq1 : + ∃ (C : ℝ), ∀ᶠ (x : ℝ) in atTop, + ⌊x⌋₊.primeCounting = + (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + ((log x)⁻¹ * (x * f x) + + ∫ (t : ℝ) in Set.Icc 2 x, f t * (log t ^ 2)⁻¹) + + C := by + use ((log 2)⁻¹ * 2) + filter_upwards [eq1, eventually_ge_atTop 2] with x eq1 hx + rw [eq1, ← integral_log_inv'' _ _ (by rfl) hx] + ring + replace eq1 : + ∃ (C : ℝ), ∀ᶠ (x : ℝ) in atTop, + (⌊x⌋₊.primeCounting / ∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) - 1 = + ((log x)⁻¹ * (x * f x) / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + (∫ (t : ℝ) in Set.Icc 2 x, f t * (log t ^ 2)⁻¹) / + (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹)) + + C / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) := by + obtain ⟨C, hC⟩ := eq1 + use C + filter_upwards [hC, eventually_gt_atTop 2] with x hC hx + rw [hC] + field [integral_log_inv_ne_zero] + simp_rw [isLittleO_iff] at hf + choose C hC using eq1 + simp_rw [← one_div] at hC + apply isLittleO_congr hC (by rfl) |>.mpr + have ineq1 (ε : ℝ) (hε : 0 < ε) (c : ℝ) (hc : 0 < c) : ∀ᶠ(x : ℝ) in atTop, + (log x)⁻¹ * x * |f x| ≤ c * ε * ((log x)⁻¹ * x) := by + filter_upwards [eventually_ge_atTop 2, hf ε hε hc] with x hx hM + simp only [norm_eq_abs] at hM + rw [abs_of_pos hε] at hM + rw [mul_comm (c * ε)] + gcongr + bound + have int_flog {a b : ℝ} (ha: 2 ≤ a) (hb : 2 ≤ b) : + IntegrableOn (fun t ↦ |f t| * (log t ^ 2)⁻¹) (Set.Icc a b) volume := by + apply IntegrableOn.mul_continuousOn + · apply Integrable.abs <| f_int b hb |>.mono (Set.Icc_subset_Icc_left ha) (by rfl) + · refine ContinuousOn.inv₀ (ContinuousOn.pow (continuousOn_log |>.mono ?_) 2) ?_ + · simp + grind + · intro t ht + simp only [Set.mem_Icc, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, + pow_eq_zero_iff, log_eq_zero, not_or] at ht ⊢ + exact ⟨by linarith, by linarith, by linarith⟩ + · exact isCompact_Icc + have int_inv_log_sq {a b : ℝ} (ha : 2 ≤ a) (hb : 2 ≤ b) : + IntegrableOn (fun t ↦ (log t ^ 2)⁻¹) (Set.Icc a b) volume := by + refine ContinuousOn.integrableOn_Icc <| + ContinuousOn.inv₀ (ContinuousOn.pow (continuousOn_log |>.mono ?_) 2) ?_ + · grind + · intro t ht + simp only [Set.mem_Icc, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, + pow_eq_zero_iff, log_eq_zero, not_or] at ht ⊢ + exact ⟨by linarith, by linarith, by linarith⟩ + simp_rw [eventually_atTop] at hf + choose M hM using hf + have ineq2 (ε : ℝ) (hε : 0 < ε) (c : ℝ) (hc : 0 < c) : + ∃ (D : ℝ), + ∀ᶠ (x : ℝ) in atTop, + |∫ (t : ℝ) in Set.Icc 2 x, f t * (log t ^ 2)⁻¹| ≤ + c * ε * ((∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) - (log x)⁻¹ * x) + D := by + use (((∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), |f t| * (log t ^ 2)⁻¹) - + c * ε * ∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), (log t ^ 2)⁻¹) + + c * ε * ((log 2)⁻¹ * 2)) + filter_upwards [eventually_gt_atTop (max 2 (M ε hε hc))] with x hx + calc _ + _ ≤ ∫ (t : ℝ) in Set.Icc 2 x, |f t * (log t ^ 2)⁻¹| := + norm_integral_le_integral_norm fun a ↦ f a * (log a ^ 2)⁻¹ + _ = ∫ (t : ℝ) in Set.Icc 2 x, |f t| * (log t ^ 2)⁻¹ := by + apply setIntegral_congr_fun measurableSet_Icc fun t ht ↦ ?_ + rw [abs_mul, abs_of_nonneg (a := (log t ^ 2)⁻¹)] + norm_num + apply pow_nonneg + exact log_nonneg <| by grind + _ = (∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), + |f t| * (log t ^ 2)⁻¹) + + (∫ (t : ℝ) in Set.Icc (max 2 (M ε hε hc)) x, + |f t| * (log t ^ 2)⁻¹) := by + rw [← setIntegral_union₀, Set.Icc_union_Icc_eq_Icc (le_max_left ..) hx.le] + · rw [AEDisjoint, Set.Icc_inter_Icc_eq_singleton (le_max_left ..) hx.le, volume_singleton] + · simp only [measurableSet_Icc, MeasurableSet.nullMeasurableSet] + · apply int_flog (by rfl) (le_max_left ..) + · apply int_flog (le_max_left ..) (le_trans (le_max_left ..) hx.le) + _ ≤ (∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), + |f t| * (log t ^ 2)⁻¹) + + (∫ (t : ℝ) in Set.Icc (max 2 (M ε hε hc)) x, + (c * ε) * (log t ^ 2)⁻¹) := by + gcongr 1 + apply setIntegral_mono_on + · apply int_flog (le_max_left ..) (le_trans (le_max_left ..) hx.le) + · rw [IntegrableOn, integrable_const_mul_iff] + · apply int_inv_log_sq (le_max_left ..) (le_trans (le_max_left ..) hx.le) + · simp only [isUnit_iff_ne_zero, ne_eq, _root_.mul_eq_zero, not_or] + exact ⟨by linarith, by linarith⟩ + · exact measurableSet_Icc + · intro t ht + simp only [Set.mem_Icc, sup_le_iff] at ht + apply mul_le_mul_of_nonneg_right + · refine hM ε hε hc t ht.1.2 |>.trans ?_ + simp only [norm_eq_abs, abs_of_pos hε, le_refl] + · norm_num + refine pow_nonneg (log_nonneg <| by linarith) 2 + _ = (∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), + |f t| * (log t ^ 2)⁻¹) + + ((c * ε) * ∫ (t : ℝ) in Set.Icc (max 2 (M ε hε hc)) x, (log t ^ 2)⁻¹) := by + congr 1 + exact integral_const_mul (c * ε) _ + _ = (∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), + |f t| * (log t ^ 2)⁻¹) + + ((c * ε) * + ((∫ (t : ℝ) in Set.Icc (max 2 (M ε hε hc)) x, (log t ^ 2)⁻¹) + + ((∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), (log t ^ 2)⁻¹)) - + ((∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), (log t ^ 2)⁻¹)))) := by + ring + _ = (∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), + |f t| * (log t ^ 2)⁻¹) + + ((c * ε) * + ((∫ (t : ℝ) in Set.Icc 2 x, (log t ^ 2)⁻¹) - + ((∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), (log t ^ 2)⁻¹)))) := by + congr 3 + rw [add_comm, ← setIntegral_union₀, Set.Icc_union_Icc_eq_Icc (le_max_left ..) hx.le] + · rw [AEDisjoint, Set.Icc_inter_Icc_eq_singleton (le_max_left ..) hx.le, + volume_singleton] + · simp only [measurableSet_Icc, MeasurableSet.nullMeasurableSet] + · apply int_inv_log_sq (by rfl) (le_max_left ..) + · apply int_inv_log_sq (le_max_left ..) (le_trans (le_max_left ..) hx.le) + _ = ((c * ε) * (∫ (t : ℝ) in Set.Icc 2 x, (log t ^ 2)⁻¹)) + + ((∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), + |f t| * (log t ^ 2)⁻¹) - + (c * ε) * (∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), (log t ^ 2)⁻¹)) := by + ring + _ = ((c * ε) * ((∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + ((log 2)⁻¹ * 2) - ((log x)⁻¹ * x))) + + ((∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), + |f t| * (log t ^ 2)⁻¹) - + (c * ε) * (∫ (t : ℝ) in Set.Icc 2 (max 2 (M ε hε hc)), (log t ^ 2)⁻¹)) := by + congr 2 + rw [integral_log_inv' _ _ (by rfl)] + · ring + · simp only [max_lt_iff] at hx + linarith + _ = _ := by ring + choose D hD using ineq2 + + have ineq4 (const : ℝ) (ε : ℝ) (hε : 0 < ε) : + ∀ᶠ x in atTop, |const / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹)| ≤ 1/2 * ε := by + obtain rfl|hconst := eq_or_ne const 0 + · filter_upwards with x + simp[hε.le] + have ineq (x : ℝ) (hx : 2 < x) := + calc (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + _ ≥ (∫ (_ : ℝ) in Set.Icc 2 x, (log x)⁻¹) := by + apply setIntegral_mono_on (integrable_const _) + · refine ContinuousOn.integrableOn_Icc <| + ContinuousOn.inv₀ (continuousOn_log |>.mono ?_) ?_ + · simp only [Set.subset_compl_singleton_iff, Set.mem_Icc, not_and, not_le, + isEmpty_Prop, ofNat_pos, IsEmpty.forall_iff] + · intro t ht + simp only [Set.mem_Icc, ne_eq, log_eq_zero, not_or] at ht ⊢ + exact ⟨by linarith, by linarith, by linarith⟩ + · exact measurableSet_Icc + · intro t ⟨ht1, ht2⟩ + gcongr + bound + _ = (x - 2) * (log x)⁻¹ := by + rw [MeasureTheory.integral_const] + simp only [MeasurableSet.univ, Measure.restrict_apply, Set.univ_inter, volume_Icc, + smul_eq_mul, mul_eq_mul_right_iff, ENNReal.toReal_ofReal_eq_iff, sub_nonneg, + inv_eq_zero, log_eq_zero, Measure.real] + refine Or.inl (le_of_lt hx) + + simp_rw [abs_div] + have ineq (x : ℝ) (hx : 2 < x) : + |const| / |∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹| ≤ + |const| / ((x - 2) * (log x)⁻¹) := by + apply div_le_div₀ (abs_nonneg _) (by rfl) + · apply mul_pos + · linarith + · norm_num + rw [Real.log_pos_iff] + · linarith + · linarith + · rw [abs_of_pos (integral_log_inv_pos _ hx)] + exact ineq x hx + have ineq (x : ℝ) (hx : 2 < x) : + |const| / |∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹| ≤ + |const| * (log x / ((x - 2))) := by + refine ineq x hx |>.trans <| le_of_eq ?_ + field_simp + have lim := Real.tendsto_pow_log_div_mul_add_atTop 1 (-2) 1 (by norm_num) + simp only [pow_one, one_mul, ← sub_eq_add_neg] at lim + rw [tendsto_atTop_nhds] at lim + specialize lim (Metric.ball 0 ((1/2) * ε / |const| : ℝ)) (by + simp only [Metric.mem_ball, dist_self] + apply _root_.div_pos + · linarith + · simpa only [abs_pos, ne_eq]) Metric.isOpen_ball + obtain ⟨M, hM⟩ := lim + rw [eventually_atTop] + refine ⟨max 3 M, ?_⟩ + intro x hx + simp only [Metric.mem_ball, dist_zero_right, max_le_iff, norm_eq_abs] at hM hx + refine ineq x (by linarith) |>.trans ?_ + specialize hM x hx.2 + rw [abs_of_nonneg (by + apply div_nonneg + · refine log_nonneg (by linarith) + · linarith)] at hM + have ineq' : |const| * (log x / (x - 2)) < |const| * ((1/2) * ε / |const|) := by + rw [mul_lt_mul_iff_right₀] + · exact hM + · simpa only [abs_pos, ne_eq] + rw [mul_div_cancel₀] at ineq' + · refine le_of_lt ineq' + · simpa only [ne_eq, abs_eq_zero] + rw [isLittleO_iff] + intro ε hε + specialize ineq4 (|D ε hε (1/2) (by linarith)| + |C|) ε hε + simp only [one_div, norm_eq_abs, norm_one, mul_one] + filter_upwards [eventually_gt_atTop 2, ineq4, ineq1 ε hε (1 / 2) (by norm_num), + hD ε hε (1 / 2) (by norm_num)] with x hx hB ineq1 hD + have := integral_log_inv_pos x (by linarith) |>.le + calc _ + _ ≤ |((log x)⁻¹ * (x * f x) / ∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹)| + + |(∫ (t : ℝ) in Set.Icc 2 x, f t * (log t ^ 2)⁻¹) / + ∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹| + + |C / ∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹| := by + apply abs_add_three + _ = |(log x)⁻¹ * (x * f x)| / |∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹| + + |(∫ (t : ℝ) in Set.Icc 2 x, f t * (log t ^ 2)⁻¹)| / + |∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹| + + |C| / |∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹| := by + rw [abs_div, abs_div, abs_div] + _ = |(log x)⁻¹ * (x * f x)| / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + |(∫ (t : ℝ) in Set.Icc 2 x, f t * (log t ^ 2)⁻¹)| / + (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + |C| / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) := by + repeat rw [abs_of_pos <| integral_log_inv_pos _ (by linarith)] + _ = ((log x)⁻¹ * x * |f x|) / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + |(∫ (t : ℝ) in Set.Icc 2 x, f t * (log t ^ 2)⁻¹)| / + (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + |C| / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) := by + congr + rw [abs_mul, abs_mul, abs_of_nonneg (by bound), abs_of_nonneg (by linarith), mul_assoc] + _ ≤ ((1/2) * ε * ((log x)⁻¹ * x)) / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + ((1/2) * ε * ((∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) - (log x)⁻¹ * x) + + D ε hε (1/2) (by linarith)) / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + |C| / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) := by + gcongr + _ = ((1/2) * ε * (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹)) / + (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) + + (D ε hε (1/2) (by linarith) + |C|) / (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) := by + ring + _ = (1/2) * ε + (D ε hε (1/2) (by linarith) + |C|) / + (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) := by + congr 1 + rw [mul_div_assoc, div_self, mul_one] + apply integral_log_inv_ne_zero + linarith + _ ≤ (1/2) * ε + (|D ε hε (1/2) (by linarith)| + |C|) / + (∫ (t : ℝ) in Set.Icc 2 x, (log t)⁻¹) := by + gcongr + apply le_abs_self + _ ≤ (1/2) * ε + (1/2) * ε := by + rw [abs_div, abs_of_nonneg, abs_of_pos (a := ∫ _ in _, _)] at hB + · gcongr + · apply integral_log_inv_pos; linarith + · positivity + _ = ε := by + field + +theorem pi_asymp : + ∃ c : ℝ → ℝ, c =o[atTop] (fun _ ↦ (1 : ℝ)) ∧ + ∀ᶠ (x : ℝ) in atTop, + Nat.primeCounting ⌊x⌋₊ = (1 + c x) * ∫ t in (2 : ℝ)..x, 1 / (log t) := by + refine ⟨_, pi_asymp'', ?_⟩ + filter_upwards [eventually_ge_atTop 3] with x hx + rw [intervalIntegral.integral_of_le (by linarith), + ← MeasureTheory.integral_Icc_eq_integral_Ioc] + field [(integral_log_inv_pos x (by linarith)).ne'] + +lemma inv_div_log_asy : ∃ c, ∀ᶠ (x : ℝ) in atTop, + ∫ (t : ℝ) in Set.Icc 2 x, 1 / log t ^ 2 ≤ c * (x / log x ^ 2) := by + have := Chebyshev.integral_one_div_log_sq_isBigO + rw [isBigO_iff] at this + obtain ⟨c, hc⟩ := this + use c + filter_upwards [hc, eventually_ge_atTop 2] with x hc hx + rw [integral_Icc_eq_integral_Ioc, ← intervalIntegral.integral_of_le hx] + apply le_trans (by apply le_norm_self) + nth_rewrite 2 [norm_of_nonneg (by positivity)] at hc + exact hc + +lemma integral_log_inv_pialt (x : ℝ) (hx : 4 ≤ x) : ∫ (t : ℝ) in Set.Icc 2 x, 1 / log t = + x / log x - 2 / log 2 + ∫ (t : ℝ) in Set.Icc 2 x, 1 / (log t) ^ 2 := by + have := integral_log_inv 2 x (by norm_num) (by linarith) + rw [MeasureTheory.integral_Icc_eq_integral_Ioc, + ← intervalIntegral.integral_of_le (by linarith [hx]), + MeasureTheory.integral_Icc_eq_integral_Ioc, + ← intervalIntegral.integral_of_le (by linarith [hx]), + ← mul_one_div, one_div, ← mul_one_div, one_div] + simp only [one_div, this, mul_comm] + +lemma integral_div_log_asymptotic : ∃ c : ℝ → ℝ, c =o[atTop] (fun _ ↦ (1:ℝ)) ∧ + ∀ᶠ (x : ℝ) in atTop, ∫ t in Set.Icc 2 x, 1 / (log t) = (1 + c x) * x / (log x) := by + obtain ⟨c, hc⟩ := inv_div_log_asy + use fun x => ((∫ (t : ℝ) in Set.Icc 2 x, 1 / log t ^ 2) - 2 / log 2) * log x / x + constructor + · simp_rw [mul_div_assoc, mul_comm] + apply isLittleO_mul_iff_isLittleO_div _|>.mpr + · simp_rw [one_div_div] + apply IsLittleO.sub + · apply IsBigO.trans_isLittleO (g := (fun x ↦ x / log x ^ 2)) + · rw [isBigO_iff] + use c + filter_upwards [eventually_ge_atTop 2, hc] with x hx hc + simp only [norm_eq_abs] + rwa [abs_of_nonneg, abs_of_nonneg] + · bound + · apply setIntegral_nonneg measurableSet_Icc fun t ht ↦ (by bound) + apply isLittleO_of_tendsto + · simp + apply tendsto_log_atTop.inv_tendsto_atTop.congr' + filter_upwards [eventually_ne_atTop 0] with x hx + simp only [Pi.inv_apply] + field + apply isLittleO_mul_iff_isLittleO_div _|>.mp + · conv => arg 2; ext; rw [mul_comm] + apply IsLittleO.const_mul_left isLittleO_log_id_atTop + · filter_upwards [eventually_ge_atTop 2] with x hx + simp; grind + filter_upwards [eventually_ge_atTop 2] with x hx + simp + grind + · filter_upwards [eventually_ge_atTop 4] with x hx + rw [integral_log_inv_pialt x hx] + field [show log x ≠ 0 by simp; grind] + +theorem pi_alt : ∃ c : ℝ → ℝ, c =o[atTop] (fun _ ↦ (1 : ℝ)) ∧ + ∀ x : ℝ, Nat.primeCounting ⌊x⌋₊ = (1 + c x) * x / log x := by + obtain ⟨f, hf, h⟩ := pi_asymp + obtain ⟨f', hf', h'⟩ := integral_div_log_asymptotic + use (fun x => (log x / x) * ⌊x⌋₊.primeCounting - 1) + constructor + · apply IsLittleO.congr' (f₁ := (fun x ↦ f x + f x * f' x + f' x)) _ _ (by rfl) + · apply IsLittleO.add _ hf' + apply IsLittleO.add hf + convert! hf.mul hf' + ring + · filter_upwards [eventually_ge_atTop 2, h, h'] with x hx h h' + rw [h, intervalIntegral.integral_of_le hx, ← integral_Icc_eq_integral_Ioc, h'] + have : log x ≠ 0 := by simp; grind + field + · intro x + obtain rfl|hx := eq_or_ne x 0 + · simp + obtain rfl|hx := eq_or_ne x 1 + · simp + obtain rfl|hx := eq_or_ne x (-1 : ℝ) + · simp + norm_num + have : log x ≠ 0 := by simp_all + field + +theorem pi_alt' : + (fun (x : ℝ) ↦ (primeCounting ⌊x⌋₊ : ℝ)) ~[atTop] (fun x ↦ x / log x) := by + obtain ⟨f, ⟨hf1, hf2⟩⟩ := pi_alt + simp_rw [hf2, IsEquivalent] + have : ((fun x ↦ (1 + f x) * x / log x) - fun x ↦ x / log x) = + (fun x ↦ f x * x / log x) := by + ext + simp + ring + rw [this] + convert hf1.mul_isBigO (f₂ := (fun x ↦ x / log x)) (g₂ := (fun x ↦ x /log x)) + (isBigO_refl ..) using 2 + all_goals ring + +lemma pi_nth_prime (n : ℕ) : + primeCounting (nth_prime n) = n + 1 := by + rw [primeCounting, primeCounting', count_nth_succ_of_infinite infinite_setOfPred_prime] + +lemma tendsto_nth_prime_atTop : Tendsto nth_prime atTop atTop := + nth_strictMono infinite_setOfPred_prime |>.tendsto_atTop + +lemma pi_nth_prime_asymp : + (fun n ↦ (nth_prime n) / (log (nth_prime n))) ~[atTop] (fun (n : ℕ) ↦ (n : ℝ)) := by + trans (fun (n : ℕ) ↦ ( n + 1 : ℝ)) + · have : Tendsto (fun n ↦ ((nth_prime n) : ℝ)) atTop atTop := by + apply tendsto_natCast_atTop_iff.mpr tendsto_nth_prime_atTop + convert! pi_alt'.comp_tendsto this |>.symm + simp only [Function.comp_apply, floor_natCast] + rw [pi_nth_prime] + norm_cast + · apply IsEquivalent.add_isLittleO (by rfl) + exact isLittleO_const_id_atTop (1 : ℝ) |>.natCast_atTop + +lemma log_nth_prime_asymp : (fun n ↦ log (nth_prime n)) ~[atTop] (fun n ↦ log n) := by + have := pi_nth_prime_asymp.log tendsto_natCast_atTop_atTop + · apply IsEquivalent.trans _ this + apply IsEquivalent.congr_right (v := (fun n ↦ log (nth_prime n) - log (log (nth_prime n)))) + swap + · filter_upwards with n + rw [log_div] + · exact_mod_cast prime_nth_prime n |>.ne_zero + · apply log_ne_zero.mpr ⟨?_, ?_, ?_⟩ + <;> norm_cast<;> linarith [prime_nth_prime n |>.two_le] + symm + apply IsEquivalent.sub_isLittleO (by rfl) + apply IsLittleO.comp_tendsto isLittleO_log_id_atTop + have : Tendsto (fun n ↦ ((nth_prime n) : ℝ)) atTop atTop := by + apply tendsto_natCast_atTop_iff.mpr tendsto_nth_prime_atTop + apply tendsto_log_atTop.comp this + +lemma nth_prime_asymp : (fun n ↦ ((nth_prime n) : ℝ)) ~[atTop] (fun n ↦ n * log n) := by + have := pi_nth_prime_asymp.mul log_nth_prime_asymp + convert! this using 1 + ext n + simp only [Pi.mul_apply] + have : log (nth_prime n) ≠ 0 :=by + apply log_ne_zero.mpr ⟨?_, ?_, ?_⟩ + <;> norm_cast<;> linarith [prime_nth_prime n |>.two_le] + field + +theorem pn_asymptotic : ∃ c : ℕ → ℝ, c =o[atTop] (fun _ ↦ (1 : ℝ)) ∧ + ∀ n : ℕ, n > 1 → nth_prime n = (1 + c n) * n * log n := by + let c : ℕ → ℝ := fun n ↦ (nth_prime n) / (n * log n) - 1 + refine ⟨c, ?_, ?_⟩ + swap + · intro n hn + have : log n ≠ 0 := by rw [Real.log_ne_zero]; rify at hn; grind + simp [c] + field_simp + apply isLittleO_of_tendsto + · simp + simp only [div_one] + unfold c + have := isEquivalent_iff_tendsto_one ?_|>.mp nth_prime_asymp + swap + · filter_upwards [eventually_ge_atTop 2] with n hn + simp + norm_cast + grind + convert! this.add_const (-1 : ℝ) using 2 + norm_num + +theorem pn_pn_plus_one : ∃ c : ℕ → ℝ, c =o[atTop] (fun _ ↦ (1 : ℝ)) ∧ + ∀ n : ℕ, nth_prime (n + 1) - nth_prime n = (c n) * nth_prime n := by + use (fun n => (nth_prime (n+1) - nth_prime n) / nth_prime n) + refine ⟨?_, ?_⟩ + · obtain ⟨k, k_o1, p_n_eq⟩ := pn_asymptotic + simp only [isLittleO_one_iff] + rw [Filter.tendsto_congr' (f₂ := fun n ↦ + ((1 + k (n+1))*(n+1)*log (n+1) - (1 + k n)*n*log n) / ((1 + k n)*n*log n))] + swap + · simp only [EventuallyEq, eventually_atTop] + use 2; intro n hn + rw [p_n_eq n (by linarith), p_n_eq (n+1) (by linarith)] + grind + simp_rw [sub_div] + have zero_eq_minus: (0 : ℝ) = 1 - 1 := by + simp + rw [zero_eq_minus] + apply Filter.Tendsto.sub + · conv => + arg 1 + intro n + equals ((1 + k (n + 1)) / (1 + k n) ) * ((↑n + 1) * log (↑n + 1) / (↑n * log ↑n)) => + field_simp + nth_rw 6 [← (one_mul 1)] + apply Filter.Tendsto.mul + · have one_div: nhds 1 = nhds ((1: ℝ) / 1) := by simp + rw [one_div] + apply Filter.Tendsto.div + · nth_rw 3 [← (AddMonoid.add_zero 1)] + apply Filter.Tendsto.add + · simp + · rw [Filter.tendsto_add_atTop_iff_nat] + rw [Asymptotics.isLittleO_iff_tendsto] at k_o1 + · simp only [div_one] at k_o1 + exact k_o1 + · simp + · nth_rw 2 [← (AddMonoid.add_zero 1)] + apply Filter.Tendsto.add + · simp + · rw [Asymptotics.isLittleO_iff_tendsto] at k_o1 + · simp only [div_one] at k_o1 + exact k_o1 + · simp + + simp + · conv => + arg 1 + intro x + equals ((↑x + 1) / x) * (log (↑x + 1) / (log ↑x)) => + field_simp + nth_rw 3 [← (one_mul 1)] + apply Filter.Tendsto.mul + · simp_rw [add_div] + nth_rw 2 [← (AddMonoid.add_zero 1)] + apply Filter.Tendsto.add + · rw [← Filter.tendsto_add_atTop_iff_nat 1] + field_simp + simp + · simp only [one_div] + exact tendsto_inv_atTop_nhds_zero_nat + · have log_eq: ∀ (n: ℕ), log (↑n + 1) = log ↑n + log (1 + 1/n) := by + intro n + by_cases n_eq_zero: n = 0 + · simp [n_eq_zero] + · calc + _ = log (n * (1 + 1 / n)) := by field_simp + _ = log n + log (1 + 1/n) := by + rw [Real.log_mul] + · simpa + · simp only [one_div, ne_eq] + positivity + + simp_rw [log_eq] + simp_rw [add_div] + nth_rw 3 [← (AddMonoid.add_zero 1)] + apply Filter.Tendsto.add + · rw [← Filter.tendsto_add_atTop_iff_nat 2] + have log_not_zero: ∀ n: ℕ, log (n + 2) ≠ 0 := by + intro n + simp only [ne_eq, log_eq_zero, not_or] + refine ⟨?_, ?_, ?_⟩ + · norm_cast + · norm_cast + simp + · norm_cast + simp [log_not_zero] + · rw [← Filter.tendsto_add_atTop_iff_nat 2] + apply squeeze_zero (g := fun (n: ℕ) => (log 2 / log (n + 2))) + · intro n + have log_plus_nonzero: 0 ≤ log (1 + 1 / ↑(n + 2)) := by + apply log_nonneg + simp only [cast_add, cast_ofNat, one_div, le_add_iff_nonneg_right, inv_nonneg] + norm_cast + simp only [le_add_iff_nonneg_left, _root_.zero_le] + exact div_nonneg log_plus_nonzero (log_natCast_nonneg (n + 2)) + · intro n + norm_cast + have log_le_2: log (1 + 1 / ↑(n + 2)) ≤ log 2 := by + apply Real.log_le_log + · positivity + · have two_eq_one_plus_one: (2 : ℝ) = 1 + 1 := by + norm_num + rw [two_eq_one_plus_one] + simp only [cast_add, cast_ofNat, one_div, add_le_add_iff_left, ge_iff_le] + apply inv_le_one_of_one_le₀ + linarith + + rw [div_le_div_iff_of_pos_right] + · exact log_le_2 + · apply Real.log_pos + norm_cast + simp + · apply Filter.Tendsto.div_atTop (l := atTop) (a := log 2) + · simp + · norm_cast + have shift_fn := + Filter.tendsto_add_atTop_iff_nat (f := fun n => log (n)) (l := atTop) 2 + rw [shift_fn] + apply Filter.Tendsto.comp Real.tendsto_log_atTop + exact tendsto_natCast_atTop_atTop + + · have eventually_nonzero: ∃ t, t > 2 ∧ ∀ n, 1 + k (n + t) ≠ 0 := by + rw [Asymptotics.isLittleO_iff_tendsto] at k_o1 + · rw [NormedAddGroup.tendsto_nhds_zero] at k_o1 + specialize k_o1 ((1 : ℝ) / 2) + simp only [one_div, gt_iff_lt, inv_pos, ofNat_pos, div_one, norm_eq_abs, eventually_atTop, forall_const] at k_o1 + obtain ⟨a, ha⟩ := k_o1 + use (a + 3) + refine ⟨by simp, ?_⟩ + intro n + specialize ha (n + (a + 3)) + have a_le_plus: a ≤ n + (a + 3) := by omega + simp only [a_le_plus, forall_const] at ha + + by_contra! + rw [add_eq_zero_iff_eq_neg] at this + rw [← abs_neg] at ha + rw [← this] at ha + simp only [abs_one] at ha + have two_inv_lt := inv_lt_one_of_one_lt₀ (a := (2 : ℝ)) (by simp) + linarith + · simp + + obtain ⟨t, t_gt_2, ht⟩ := eventually_nonzero + rw [← Filter.tendsto_add_atTop_iff_nat t] + have denom_nonzero: ∀ n, ((1 + k (n + t)) * ↑(n + t) * log ↑(n + t)) ≠ 0 := by + intro n + simp only [cast_add, ne_eq, _root_.mul_eq_zero, log_eq_zero, not_or] + refine ⟨⟨?_, ?_⟩, ?_, ?_⟩ + · exact ht n + · norm_cast + omega + · norm_cast + omega + · refine ⟨?_, by norm_cast⟩ + norm_cast + omega + conv => + arg 1 + intro n + rw [div_self (denom_nonzero n)] + simp + · intro n + have nth_nonzero: nth_prime n ≠ 0 := by + exact Nat.Prime.ne_zero (prime_nth_prime n) + simp [nth_nonzero] + +lemma prime_in_gap' (a b : ℕ) (h : a.primeCounting < b.primeCounting) + : ∃ (p : ℕ), p.Prime ∧ (a + 1) ≤ p ∧ p < (b + 1) := by + obtain ⟨p, hp, pp⟩ := exists_of_count_lt_count h + exact ⟨p, pp, hp.left, hp.right⟩ + +lemma prime_in_gap (a b : ℝ) (ha : 0 < a) + (h : ⌊a⌋₊.primeCounting < ⌊b⌋₊.primeCounting) + : ∃(p : ℕ), p.Prime ∧ a < p ∧ p ≤ b := by + + have hab : ⌊a⌋₊ < ⌊b⌋₊ := Monotone.reflect_lt Nat.monotone_primeCounting h + obtain ⟨w, h, ha, hb⟩ := prime_in_gap' ⌊a⌋₊ ⌊b⌋₊ h + refine ⟨w, h, lt_of_floor_lt ha, ?_⟩ + have : a < b := by + by_contra h + cases lt_or_eq_of_le <| le_of_not_gt h with + | inl hh => linarith [floor_le_floor <| le_of_lt hh] + | inr hh => + rw [hh] at hab + rwa [←lt_self_iff_false ⌊a⌋₊] + by_contra h + have : ⌊b⌋₊ < w := floor_lt (by linarith) |>.mpr (lt_of_not_ge h) + have : ⌊b⌋₊ + 1 ≤ w := by linarith + linarith + +lemma bound_f_second_term (f : ℝ → ℝ) (hf : Tendsto f atTop (nhds 0)) (δ : ℝ) (hδ : δ > 0) : + ∀ᶠ x : ℝ in atTop, (1 + f x) < (1 + δ) := by + have bound_one_plus_f: ∀ y: ℝ, ∀ z: ℝ, |f y| < z → 1 + (f y) < 1 + z := by + intro y z hf + by_cases f_pos: 0 < f y + · rw [abs_of_pos f_pos] at hf + linarith + · rw [not_lt] at f_pos + rw [abs_of_nonpos f_pos] at hf + linarith + + have f_small := NormedAddGroup.tendsto_nhds_zero.mp hf δ hδ + simp only [norm_eq_abs, eventually_atTop] at f_small + obtain ⟨p, hp⟩ := f_small + + let a := ((max 1 p) : ℝ) + have ha: ∀ b: ℝ, a ≤ b → |f b| < δ := by + intro b hb + have b_ge_p: p ≤ b := by + have a_ge_p: p ≤ a := by simp [a] + linarith + exact hp b b_ge_p + + rw [Filter.eventually_atTop] + + use a + intro b hb + exact bound_one_plus_f b δ (ha b (by linarith)) + +lemma bound_f_first_term {ε : ℝ} (hε : 0 < ε) (f : ℝ → ℝ) + (hf : Tendsto f atTop (nhds 0)) (δ : ℝ) (hδ : δ > 0) : + ∀ᶠ x: ℝ in atTop, (1 + f ((1 + ε) * x)) > (1 - δ) := by + have bound_one_plus_f: ∀ y: ℝ, ∀ z: ℝ, |f y| < z → 1 + (f y) > 1 - z := by + intro y z hf + by_cases f_pos: 0 < f y + · rw [abs_of_pos f_pos] at hf + linarith + · rw [not_lt] at f_pos + rw [abs_of_nonpos f_pos] at hf + linarith + + have f_small := NormedAddGroup.tendsto_nhds_zero.mp hf δ hδ + simp only [norm_eq_abs, eventually_atTop] at f_small + obtain ⟨p, hp⟩ := f_small + + let a := ((max 1 p) : ℝ) + have ha: ∀ b: ℝ, a ≤ b → |f b| < δ := by + intro b hb + have b_ge_p: p ≤ b := by + have a_ge_p: p ≤ a := by simp [a] + linarith + exact hp b b_ge_p + + rw [Filter.eventually_atTop] + + use a + intro b hb + + have a_pos: 0 < a := by + simp [a] + + have pos_mul: ∀ x y z : ℝ, 0 < x → 0 < y → 1 < z → x ≤ y → x < y * z := by + intro x y z _ hy hz hlt + have y_lt: y < y * z := by + exact (lt_mul_iff_one_lt_right hy).mpr hz + linarith + + have mul_increase: a ≤ (1 + ε) * b := by + simp only [ a] at hb + have a_le := pos_mul a b (1 + ε) a_pos (by linarith) (by linarith) (by linarith) + linarith + + exact bound_one_plus_f ((1 + ε) * b) δ (ha ((1 + ε) * b) mul_increase) + +lemma smaller_terms {ε : ℝ} (hε : 0 < ε) (f : ℝ → ℝ) (hf : Tendsto f atTop (nhds 0)) (δ : ℝ) + (hδ : δ > 0) : + ∀ᶠ x : ℝ in atTop, (1 - δ) * ((1 + ε) * x / (Real.log ((1 + ε) * x))) < + (1 + f ((1 + ε) * x)) * ((1 + ε) * x / (Real.log ((1 + ε) * x))) := by + have first_term := bound_f_first_term hε f hf δ hδ + simp only [gt_iff_lt, eventually_atTop] at first_term + obtain ⟨p, hp⟩ := first_term + simp only [eventually_atTop] + let a := max p 1 + have ha: ∀ (b : ℝ), a ≤ b → 1 - δ < 1 + f ((1 + ε) * b) := by + intro b hb + have a_ge_p: p ≤ a := by + simp [a] + specialize hp b (by linarith) + exact hp + use a + intro b hb + rw [mul_lt_mul_iff_left₀] + · exact ha b hb + · simp only [sup_le_iff, a] at hb + have b_ge_one: 1 ≤ b := hb.2 + have log_pos: Real.log ((1 + ε) *b) > 0 := by + have one_pplus_pos: 1 < (1 + ε) := by linarith + refine (Real.log_pos_iff ?_).mpr ?_ + · positivity + · exact one_lt_mul_of_lt_of_le one_pplus_pos b_ge_one + + positivity + +lemma second_smaller_terms (f : ℝ → ℝ) (hf : Tendsto f atTop (nhds 0)) (δ : ℝ) (hδ : δ > 0) : + ∀ᶠ x : ℝ in atTop, + (1 + δ) * (x / Real.log x) > (1 + f x) * (x / Real.log x) := by + have first_term := bound_f_second_term f hf δ hδ + + simp only [_root_.add_lt_add_iff_left, eventually_atTop] at first_term + obtain ⟨p, hp⟩ := first_term + simp only [gt_iff_lt, eventually_atTop] + let a := max p 2 + have ha: ∀ (b : ℝ), a ≤ b → 1 + δ > 1 + f ( b) := by + intro b hb + have a_ge_p: p <= a := by simp [a] + specialize hp b (by linarith) + linarith + use a + intro b hb + specialize ha b hb + have rhs_nonzero: b / log ( b) > 0 := by + simp only [sup_le_iff, a] at hb + obtain ⟨_, hb2⟩ := hb + have log_pos: Real.log (b) > 0 := by + refine (Real.log_pos_iff ?_).mpr ?_ + · positivity + · linarith + positivity + rw [mul_lt_mul_iff_left₀] + · exact ha + · linarith + +lemma x_log_x_atTop : Filter.Tendsto (fun x => x / Real.log x) Filter.atTop Filter.atTop := by + have inv_log_x_div := Filter.Tendsto.comp (f := fun x => Real.log x / x) (g := fun x => x⁻¹) + (x := Filter.atTop) (y := (nhdsWithin 0 (Set.Ioi 0))) (z := Filter.atTop) ?_ ?_ + · simp_rw [Function.comp_def, inv_div] at inv_log_x_div + exact inv_log_x_div + · exact tendsto_inv_nhdsGT_zero (𝕜 := ℝ) + · rw [tendsto_nhdsWithin_iff] + refine ⟨?_, ?_⟩ + · have log_div_x := Real.tendsto_pow_log_div_mul_add_atTop 1 0 1 (by simp) + simp only [pow_one, one_mul, add_zero] at log_div_x + exact log_div_x + · simp only [Set.mem_Ioi, eventually_atTop] + use 2 + intro x hx + have log_pos: 0 < Real.log x := by + refine (Real.log_pos_iff ?_).mpr ?_ <;> linarith + positivity + +lemma tendsto_by_squeeze (ε : ℝ) (hε : ε > 0) : + Tendsto (fun (x : ℝ) => (Nat.primeCounting ⌊(1 + ε) * x⌋₊ : ℝ) - + (Nat.primeCounting ⌊x⌋₊ : ℝ)) atTop atTop := by + obtain ⟨c, hc, pi_x_eq⟩ := pi_alt + rw [Asymptotics.isLittleO_iff_tendsto (by simp)] at hc + conv => + arg 1 + intro x + rw [pi_x_eq] + rw [pi_x_eq] + simp only [div_one] at hc + + let d: ℝ := ε/(2*(2 + ε)) + have hd: 0 < d := by positivity + have first_helper := smaller_terms hε c hc (d) hd + have second_helper := second_smaller_terms c hc d hd + + apply Filter.tendsto_atTop_mono' (f₁ := fun x => ( + ((1 - d) * ((1 + ε) * x / log ((1 + ε) * x))) + - + ((1 + d) * (x / log x))) + ) + · rw [Filter.EventuallyLE] + + simp only [eventually_atTop] at first_helper + simp only [gt_iff_lt, eventually_atTop] at second_helper + + obtain ⟨a1, ha1⟩ := first_helper + obtain ⟨a2, ha2⟩ := second_helper + + simp only [eventually_atTop] + + use (max a1 a2) + intro b hb + + have lt_compare: ∀ a b c d : ℝ, a < c ∧ b > d → a - b ≤ c - d := by + intro a b c d h_lt + obtain ⟨a_lt, b_gt⟩ := h_lt + linarith + + apply lt_compare + simp only [ sup_le_iff] at hb + specialize ha1 b hb.1 + specialize ha2 b hb.2 + field_simp + field_simp at ha1 ha2 + exact ⟨ha1, ha2⟩ + · rw [← Filter.tendsto_comp_val_Ioi_atTop (a := 1)] + have log_split: ∀ x: Set.Ioi 1, x.val / log ((1 + ε) * x.val) = + x.val / (log (1 + ε) + log (x.val)) := by + intro x + have x_ge_one: 1 < x.val := Set.mem_Ioi.mp x.property + rw [Real.log_mul (by linarith) (by linarith)] + + have log_factor: ∀ x: Set.Ioi 1, x.val / (log (1 + ε) + log (x.val)) = + x.val / ((1 + (log (1 + ε)/(log x.val))) * (log x.val)) := by + intro x + have : log (x.val) ≠ 0 := by + have pos := Real.log_pos x.property + linarith + field_simp + rw [add_comm] + + conv at log_factor => + intro x + rhs + rw [div_mul_eq_div_mul_one_div] + + conv => + arg 1 + intro x + lhs + rw [mul_div_assoc] + rw [log_split x] + + conv => + arg 1 + intro x + lhs + rw [log_factor] + + suffices Tendsto (fun x : Set.Ioi (1 : ℝ) ↦ (1 - d) * ((1 + ε) * x) / + ((1 + log (1 + ε) / log x) * log x) - (1 + d) * x / log x) atTop atTop by + field_simp at this ⊢ + exact this + conv => + arg 1 + intro x + rw [sub_eq_add_neg] + rw [← neg_div] + rw [div_add_div] + · skip + tactic => + simp only [ne_eq, _root_.mul_eq_zero, log_eq_zero, not_or] + have x_pos := x.property + simp_rw [Set.Ioi, Set.mem_ofPred_eq] at x_pos + refine ⟨?_, by linarith, by linarith, by linarith⟩ + have log_num_pos: 0 < log (1 + ε) := by + exact Real.log_pos (by linarith) + have log_denom_pos: 0 < log x := by + exact Real.log_pos x.property + positivity + tactic => + have pos := Real.log_pos (x.property) + linarith + + conv => + arg 1 + intro x + equals ↑x * (log ↑x * ((1 + ε) * (1 - d)) - + (1 + log (1 + ε) / log ↑x) * ((1 + d) * log ↑x)) / + (log ↑x * ((1 + log (1 + ε) / log ↑x) * log ↑x)) => + ring + + simp only [mul_div_mul_comm] + conv => + arg 1 + intro x + rw [mul_comm] + + apply Filter.Tendsto.pos_mul_atTop (C := (1 + ε) * (1 - d) - (1 + d)) + · simp only [d, sub_pos] + field_simp + ring_nf + rw [add_assoc] + rw [add_lt_add_iff_left] + apply lt_of_sub_pos + ring_nf + positivity + · conv => + arg 1 + intro x + lhs + rhs + equals (log x.val) * ((1 + log (1 + ε) / log ↑x) * ((1 + d))) => + ring + + simp_rw [← mul_sub] + conv => + arg 1 + intro x + rhs + rw [mul_comm] + + simp only [mul_div_mul_comm] + conv => + arg 1 + intro x + lhs + equals 1 => + have log_pos := Real.log_pos x.property + field_simp + + simp only [one_mul] + conv => + arg 3 + equals nhds (((1 + ε) * (1 - d) - (1 + d)) / 1) => simp + + apply Filter.Tendsto.div + · apply Filter.Tendsto.sub + · simp + · conv => + arg 3 + equals nhds (1 * (1 + d)) => simp + apply Filter.Tendsto.mul + · conv => + arg 3 + equals nhds (1 + 0) => simp + apply Filter.Tendsto.add + · simp + · apply Filter.Tendsto.div_atTop (a := log (1 + ε)) + · simp + · simp only [tendsto_comp_val_Ioi_atTop] + exact tendsto_log_atTop + · simp + · conv => + arg 3 + equals nhds (1 + 0) => simp + apply Filter.Tendsto.add + · simp + · apply Filter.Tendsto.div_atTop (a := log (1 + ε)) + · simp + · simp only [tendsto_comp_val_Ioi_atTop] + exact tendsto_log_atTop + · simp + · let x_div_log (x: ℝ) := x / Real.log x + conv => + arg 1 + equals (fun (x : Set.Ioi 1) => x_div_log x.val) => rfl + + rw [Filter.tendsto_comp_val_Ioi_atTop (a := 1)] + exact x_log_x_atTop + +theorem prime_between {ε : ℝ} (hε : 0 < ε) : + ∀ᶠ x : ℝ in atTop, ∃ p : ℕ, Nat.Prime p ∧ x < p ∧ p < (1 + ε) * x := by + have squeeze := tendsto_by_squeeze (ε/2) (by linarith) + rw [Filter.tendsto_iff_forall_eventually_mem] at squeeze + specialize squeeze (Set.Ici 1) (by exact Ici_mem_atTop 1) + simp only [Set.mem_Ici, eventually_atTop] at squeeze + obtain ⟨a, ha⟩ := squeeze + rw [eventually_atTop] + use (max a 1) + intro b hb + rw [sup_le_iff] at hb + specialize ha b hb.1 + + have val_lt : (⌊b⌋₊.primeCounting : ℝ) < ⌊(1 + ε/2) * b⌋₊.primeCounting := by linarith + norm_cast at val_lt + + have jump := prime_in_gap b ((1 + ε/2) * b) (by linarith) val_lt + obtain ⟨p, hp, b_lt_p, p_le⟩ := jump + have p_lt: p < (1 + ε) * b := by + linarith + use p + +theorem sum_mobius_div_self_le (N : ℕ) : |∑ n ∈ range N, μ n / (n : ℚ)| ≤ 1 := by + cases N with + | zero => simp only [range_zero, sum_empty, abs_zero, zero_le_one] + | succ N => + + obtain rfl | hN := N.eq_zero_or_pos + · simp + + have h_sum : 1 = (∑ d ∈ range (N + 1), (μ d / d : ℚ)) * N - ∑ d ∈ range (N + 1), + μ d * Int.fract (N / d : ℚ) := calc + (1 : ℚ) = ∑ m ∈ Ioc 0 N, ∑ d ∈ m.divisors, μ d := by + have (x : ℕ) (hx : x ∈ Ioc 0 N) : ∑ d ∈ divisors x, μ d = if x = 1 then 1 else 0 := by + rw [mem_Ioc] at hx + rw [← coe_mul_zeta_apply, moebius_mul_coe_zeta, one_apply] + rw [sum_congr rfl this] + simp [hN.ne'] + _ = ∑ d ∈ range (N + 1), μ d * (N / d : ℕ) := by + simp_rw [← coe_mul_zeta_apply, ArithmeticFunction.sum_Ioc_mul_zeta_eq_sum] + rw [range_eq_Ico, ← Finset.insert_Ico_add_one_left_eq_Ico (add_one_pos _), + sum_insert (by simp), Ico_add_one_add_one_eq_Ioc] + simp + _ = ∑ d ∈ range (N + 1), (μ d : ℚ) * ⌊(N / d : ℚ)⌋ := by + simp_rw [Rat.floor_natCast_div_natCast] + simp [← Int.natCast_ediv] + _ = (∑ d ∈ range (N + 1), (μ d / d : ℚ)) * N - ∑ d ∈ range (N + 1), + μ d * Int.fract (N / d : ℚ) := by + simp_rw [sum_mul, ← sum_sub_distrib, mul_comm_div, ← mul_sub, Int.self_sub_fract] + rw [eq_sub_iff_add_eq, eq_comm, ← eq_div_iff (by norm_num [Nat.pos_iff_ne_zero.mp hN])] at h_sum + + have hf' (d : ℕ) : |Int.fract ((N : ℚ) / d)| < 1 := by + rw [abs_of_nonneg (Int.fract_nonneg _)] + exact Int.fract_lt_one _ + have h_bound : |∑ d ∈ range (N + 1), μ d * Int.fract ((N : ℚ) / d)| ≤ N - 1 := by + + rw [range_eq_Ico, ← Finset.insert_Ico_add_one_left_eq_Ico (by simp), sum_insert (by simp), + ArithmeticFunction.map_zero, Int.cast_zero, zero_mul, zero_add, + Finset.Ico_add_one_right_eq_Icc, zero_add] + + rw [← Ico_insert_right hN, sum_insert (by simp), div_self (by simp; grind), Int.fract_one, + mul_zero, zero_add] + + have (d : ℕ) : |μ d * Int.fract ((N : ℚ) / d)| ≤ 1 := by + rw [abs_mul, ← one_mul 1] + refine mul_le_mul ?_ (hf' _).le (abs_nonneg _) zero_le_one + norm_cast + exact abs_moebius_le_one + apply (abs_sum_le_sum_abs _ _).trans + apply (sum_le_sum fun d _ ↦ this d).trans + simp [cast_sub (one_le_iff_ne_zero.mpr hN.ne')] + + rw [h_sum, abs_le] + rw [abs_le, neg_sub] at h_bound + constructor + <;> simp only [le_div_iff₀, div_le_iff₀, cast_pos.mpr hN] + <;> linarith [h_bound.left] + +lemma sum_mobius_mul_floor (x : ℝ) (hx : 1 ≤ x) : + ∑ n ∈ Iic ⌊x⌋₊, (ArithmeticFunction.moebius n : ℝ) * (⌊x/n⌋ : ℝ) = 1 := by + norm_cast + convert ArithmeticFunction.sum_Ioc_mul_zeta_eq_sum μ ⌊x⌋₊ |>.symm using 1 + · rw [Iic_eq_Icc, bot_eq_zero, ← add_sum_Ioc_eq_sum_Icc (by simp)] + simp only [ArithmeticFunction.map_zero, CharP.cast_eq_zero, div_zero, Int.floor_zero, mul_zero, + zero_add, Int.natCast_ediv] + refine sum_congr rfl fun n hn ↦ ?_ + congr + norm_cast + rw [← floor_div_natCast, Int.natCast_floor_eq_floor] + positivity + · simpa [moebius_mul_coe_zeta, one_apply] + +noncomputable def mu_log : ArithmeticFunction ℝ := + ⟨(fun n ↦ μ n * ArithmeticFunction.log n), (by simp)⟩ + +lemma mu_log_apply (n : ℕ) : mu_log n = μ n * ArithmeticFunction.log n := by + rfl + +lemma mu_log_mul_zeta : mu_log * ArithmeticFunction.zeta = -Λ := by + ext n + rw [coe_mul_zeta_apply] + simp_rw [mu_log_apply] + rw [sum_moebius_mul_log_eq] + rfl + +lemma mu_log_eq_mu_mul_neg_lambda : mu_log = μ * -Λ := by + rw [← mu_log_mul_zeta, mul_comm, mul_assoc, coe_zeta_mul_coe_moebius, mul_one] + +lemma sum_mu_Lambda (x : ℝ) : ∑ n ∈ Iic ⌊x⌋₊, (μ n : ℝ) * log n = - ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Psi (x/k) := by + rw [Iic_eq_Icc, bot_eq_zero, ← add_sum_Ioc_eq_sum_Icc (by simp), ← add_sum_Ioc_eq_sum_Icc (by simp)] + simp only [ArithmeticFunction.map_zero, Int.cast_zero, CharP.cast_eq_zero, log_zero, mul_zero, + zero_add, div_zero, zero_mul] + simp_rw [← log_apply, ← mu_log_apply, mu_log_eq_mu_mul_neg_lambda] + rw [sum_Ioc_mul_eq_sum_sum, ← sum_neg_distrib] + refine sum_congr rfl fun n hn ↦ ?_ + simp_rw [ArithmeticFunction.neg_apply, sum_neg_distrib] + ring_nf + congr 2 + unfold Psi + congr + rw [← floor_div_natCast] + rfl + +lemma M_log_identity (x : ℝ) (hx : 1 ≤ x) : M x * log x = ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * (log (x/k) - Psi (x/k)) := by + have h_log_identity : ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log (x / k) = (∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ)) * Real.log x - ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log k := by + rw [Finset.sum_mul _ _ _] + rw [← Finset.sum_sub_distrib] ; refine Finset.sum_congr rfl fun i hi => ?_ ; by_cases hi' : i = 0 <;> simp +decide [*, Real.log_div, ne_of_gt (zero_lt_one.trans_le hx)] ; ring + generalize_proofs at * + have h_log_identity' : ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log k = -∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Psi (x / k) := by + convert sum_mu_Lambda x using 1 + have h_psi_identity : + (∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Psi (x / k)) = + -∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log k := by + simpa [neg_neg] using (congrArg Neg.neg h_log_identity').symm + unfold M + symm + calc + (∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * (Real.log (x / k) - Psi (x / k))) = + (∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log (x / k)) - + ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Psi (x / k) := by + simp [mul_sub, Finset.sum_sub_distrib] + _ = ((∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ)) * Real.log x - + ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log k) - + ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Psi (x / k) := by + simp [h_log_identity] + _ = ((∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ)) * Real.log x - + ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log k) - + (-∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log k) := by + simp [h_psi_identity] + _ = (∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ)) * Real.log x := by ring + +noncomputable def R (x : ℝ) : ℝ := Psi x - x + +lemma R_isLittleO : R =o[atTop] id := by + have h_pnt : (fun x => Psi x - x) =o[atTop] (fun x => x) := by + have h_psi : (fun x => Psi x) ~[atTop] (fun x => x) := by + simpa [Psi] using! WeakPNT'' + exact h_psi + convert! h_pnt using 1 + +lemma sum_mobius_div_isBigO : (fun x : ℝ => ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * (x / k)) =O[atTop] id := by + have h_abs : ∀ x : ℝ, 1 ≤ x → |∑ n ∈ Iic ⌊x⌋₊, (μ n : ℝ) / n| ≤ 1 := by + intros x hx + have h_sum : ∑ n ∈ Finset.Iic ⌊x⌋₊, (μ n : ℝ) / n = ∑ n ∈ Finset.range (⌊x⌋₊ + 1), (μ n : ℝ) / n := by + rw [Finset.range_eq_Ico] ; rfl + have := sum_mobius_div_self_le (⌊x⌋₊ + 1) ; simp_all +decide [Finset.sum_range_succ'] + norm_cast at * + rw [Asymptotics.isBigO_iff] + use 1; filter_upwards [Filter.eventually_ge_atTop 1] with x hx; simp_all +decide [div_eq_mul_inv, mul_assoc, mul_comm] + simpa only [← Finset.mul_sum _ _ _, abs_mul] using mul_le_of_le_one_right (abs_nonneg x) (h_abs x hx) + +lemma sum_log_div_isBigO : (fun x : ℝ => ∑ k ∈ Iic ⌊x⌋₊, log (x / k)) =O[atTop] id := by + have h_sum_log : ∀ x : ℝ, 1 ≤ x → |∑ k ∈ Finset.Iic ⌊x⌋₊, Real.log (x / k)| ≤ 2 * x := by + have h_sum_log_le_x : ∀ x : ℝ, 1 ≤ x → ∑ k ∈ Finset.Icc 1 ⌊x⌋₊, Real.log (x / k) ≤ x := by + intro x hx + have h_sum_log : ∑ k ∈ Finset.Icc 1 ⌊x⌋₊, Real.log (x / (k : ℝ)) ≤ Real.log (x ^ ⌊x⌋₊ / Nat.factorial ⌊x⌋₊) := by + rw [← Real.log_prod] + · norm_num [Finset.prod_div_distrib] + erw [← Nat.cast_prod, Finset.prod_Ico_id_eq_factorial] + · exact fun n hn => div_ne_zero (by positivity) (Nat.cast_ne_zero.mpr <| by linarith [Finset.mem_Icc.mp hn]) + have h_exp_bound : x ^ ⌊x⌋₊ / Nat.factorial ⌊x⌋₊ ≤ Real.exp x := by + have h_term : x ^ ⌊x⌋₊ / (⌊x⌋₊! : ℝ) ≤ ∑' k : ℕ, x ^ k / (k ! : ℝ) := by + exact Summable.le_tsum (show Summable _ from Real.summable_pow_div_factorial x) ⌊x⌋₊ (fun _ _ => by positivity) + simpa [Real.exp_eq_exp_ℝ, NormedSpace.exp_eq_tsum_div] using h_term + exact h_sum_log.trans (Real.log_le_iff_le_exp (by positivity) |>.2 h_exp_bound) + intros x hx + have h_sum_eq : ∑ k ∈ Finset.Iic ⌊x⌋₊, Real.log (x / k) = ∑ k ∈ Finset.Icc 1 ⌊x⌋₊, Real.log (x / k) := by + erw [Finset.sum_Ico_eq_sub _ _] <;> norm_num + erw [Finset.sum_Ico_eq_sub _ _] <;> norm_num + rw [abs_of_nonneg] <;> linarith [h_sum_log_le_x x hx, show 0 ≤ ∑ k ∈ Finset.Icc 1 ⌊x⌋₊, Real.log (x / k) from Finset.sum_nonneg fun _ _ => Real.log_nonneg <| by rw [le_div_iff₀ <| Nat.cast_pos.mpr <| by linarith [Finset.mem_Icc.mp ‹_›]] ; linarith [Nat.floor_le <| show 0 ≤ x by linarith, show (↑‹ℕ› : ℝ) ≤ ⌊x⌋₊ by exact_mod_cast Finset.mem_Icc.mp ‹_› |>.2]] + rw [Asymptotics.isBigO_iff] + exact ⟨2, Filter.eventually_atTop.mpr ⟨1, fun x hx => le_trans (h_sum_log x hx) (by norm_num [abs_of_nonneg (by linarith : 0 ≤ x)])⟩⟩ + +lemma R_locally_bounded (K : ℝ) (hK : 0 ≤ K) : ∃ C, ∀ y ∈ Set.Icc 0 K, |R y| ≤ C := by + have hR_bounded : BddAbove (Set.image (fun y => |R y|) (Set.Icc 0 K)) := by + have hR_bounded : ∀ y ∈ Set.Icc 0 K, |R y| ≤ ∑ p ∈ Iic ⌊K⌋₊, log p + K := by + intro y hy + simp only [R, Psi, Chebyshev.psi_eq_sum_Icc] + refine abs_sub_le_iff.mpr ⟨?_, ?_⟩ + · refine le_trans (sub_le_self _ hy.1) ?_ + refine le_trans (Finset.sum_le_sum_of_subset_of_nonneg (Finset.Iic_subset_Iic.mpr <| Nat.floor_mono hy.2) fun ?_ ?_ ?_ => ?_) ?_ + · exact vonMangoldt_nonneg + · refine le_add_of_le_of_nonneg (Finset.sum_le_sum fun i hi => ?_) hK + exact vonMangoldt_le_log + · refine le_trans ?_ (le_add_of_nonneg_left ?_) + · exact le_trans (sub_le_self _ <| Finset.sum_nonneg fun _ _ => by exact_mod_cast ArithmeticFunction.vonMangoldt_nonneg) hy.2 + · exact Finset.sum_nonneg fun _ _ => Real.log_natCast_nonneg _ + exact ⟨_, Set.forall_mem_image.2 hR_bounded⟩ + exact ⟨hR_bounded.choose, fun y hy => hR_bounded.choose_spec <| Set.mem_image_of_mem _ hy⟩ + +lemma sum_bounded_of_linear_bound {f : ℝ → ℝ} {ε C : ℝ} (hε : 0 ≤ ε) (hC : 0 ≤ C) (h : ∀ y, 1 ≤ y → |f y| ≤ ε * y + C) (x : ℝ) (hx : 1 ≤ x) : + ∑ k ∈ Icc 1 ⌊x⌋₊, |f (x / k)| ≤ ε * x * (log x + 1) + C * x := by + have h_sum_bound : ∑ k ∈ Finset.Icc 1 ⌊x⌋₊, |f (x / k)| ≤ ε * x * ∑ k ∈ Finset.Icc 1 ⌊x⌋₊, (1 / (k : ℝ)) + C * ⌊x⌋₊ := by + have h_sum_bound : ∀ k ∈ Finset.Icc 1 ⌊x⌋₊, |f (x / k)| ≤ ε * x / k + C := by + exact fun k hk => by simpa only [mul_div_assoc] using! h (x / k) (by rw [le_div_iff₀ (Nat.cast_pos.mpr <| Finset.mem_Icc.mp hk |>.1)] ; nlinarith [Nat.floor_le (show 0 ≤ x by positivity), show (k : ℝ) ≤ ⌊x⌋₊ by exact_mod_cast Finset.mem_Icc.mp hk |>.2]) + convert! Finset.sum_le_sum h_sum_bound using 1 ; norm_num [div_eq_mul_inv, Finset.mul_sum _ _ _, Finset.sum_add_distrib, mul_comm] + have h_harmonic : ∀ n : ℕ, 1 ≤ n → ∑ k ∈ Finset.Icc 1 n, (1 / (k : ℝ)) ≤ Real.log n + 1 := by + intro n _hn + have h := harmonic_le_one_add_log n + simpa [harmonic_eq_sum_Icc, Rat.cast_sum, Rat.cast_inv, Rat.cast_natCast, + one_div, add_comm, add_left_comm, add_assoc] using h + have h_harmonic_x : + ∑ k ∈ Finset.Icc 1 ⌊x⌋₊, (1 / (k : ℝ)) ≤ Real.log x + 1 := by + refine (h_harmonic _ <| Nat.floor_pos.mpr hx).trans ?_ + have hlog : Real.log (⌊x⌋₊ : ℝ) ≤ Real.log x := by + refine Real.log_le_log (Nat.cast_pos.mpr <| Nat.floor_pos.mpr hx) ?_ + exact Nat.floor_le (by positivity) + simpa using add_le_add_right hlog 1 + have h_term1 : ε * x * (∑ k ∈ Finset.Icc 1 ⌊x⌋₊, (1 / (k : ℝ))) ≤ ε * x * (Real.log x + 1) := by + refine mul_le_mul_of_nonneg_left h_harmonic_x ?_ + exact mul_nonneg hε (by positivity) + have h_term2 : C * (⌊x⌋₊ : ℝ) ≤ C * x := by + refine mul_le_mul_of_nonneg_left ?_ hC + exact Nat.floor_le (by positivity) + exact h_sum_bound.trans (add_le_add h_term1 h_term2) + +lemma sum_abs_R_isLittleO : (fun x : ℝ => ∑ k ∈ Iic ⌊x⌋₊, |R (x / k)|) =o[atTop] (fun x => x * log x) := by + have h_eps : ∀ ε > 0, ∃ x₀ : ℝ, ∀ x ≥ x₀, (∑ k ∈ Finset.Icc 1 ⌊x⌋₊, |R (x / k)|) ≤ ε * x * Real.log x := by + intro ε hε_pos + obtain ⟨A, hA⟩ : ∃ A : ℝ, 0 < A ∧ ∀ y ≥ A, |R y| ≤ (ε / 2) * y := by + have := R_isLittleO + rw [Asymptotics.isLittleO_iff] at this + norm_num at * + exact Exists.elim (this (half_pos hε_pos)) fun A hA => ⟨Max.max A 1, by positivity, fun y hy => by simpa only [abs_of_nonneg (by linarith [le_max_right A 1] : 0 ≤ y)] using hA y (le_trans (le_max_left A 1) hy)⟩ + obtain ⟨C_A, hC_A⟩ : ∃ C_A : ℝ, ∀ y ∈ Set.Icc 0 A, |R y| ≤ C_A := by + exact ⟨_, fun y hy => R_locally_bounded A hA.1.le |> Classical.choose_spec |> fun h => h y hy⟩ + have h_sum_bound : ∀ x ≥ max A 2, (∑ k ∈ Finset.Icc 1 ⌊x⌋₊, |R (x / k)|) ≤ (ε / 2) * x * (Real.log x + 1) + C_A * x := by + intros x hx + have h_sum_bound : ∀ y ≥ 1, |R y| ≤ (ε / 2) * y + C_A := by + intros y hy + by_cases hyA : y ≥ A + · exact le_add_of_le_of_nonneg (hA.right y hyA) (by + exact le_trans (abs_nonneg _) (hC_A 0 ⟨by norm_num, by linarith⟩)) + · exact le_add_of_nonneg_of_le (by + positivity) (hC_A y ⟨by + linarith, by + linarith⟩) + have := sum_bounded_of_linear_bound (show 0 ≤ ε / 2 by positivity) (show 0 ≤ C_A by exact le_trans (abs_nonneg _) (hC_A 0 ⟨by norm_num, by linarith⟩)) (fun y hy => h_sum_bound y hy) x (by linarith [le_max_right A 2]) ; aesop + obtain ⟨x₀, hx₀⟩ : ∃ x₀ : ℝ, ∀ x ≥ x₀, (ε / 2) * (Real.log x + 1) + C_A ≤ ε * Real.log x := by + exact ⟨Real.exp (2 * (C_A / ε + 1)), fun x hx => by nlinarith [Real.log_exp (2 * (C_A / ε + 1)), Real.log_le_log (by positivity) hx, mul_div_cancel₀ C_A hε_pos.ne']⟩ + exact ⟨Max.max x₀ (Max.max A 2), fun x hx => le_trans (h_sum_bound x (le_trans (le_max_right _ _) hx)) (by nlinarith [hx₀ x (le_trans (le_max_left _ _) hx), le_max_right x₀ (Max.max A 2), le_max_left x₀ (Max.max A 2), le_max_right A 2, le_max_left A 2, Real.log_nonneg (show x ≥ 1 by linarith [le_max_right x₀ (Max.max A 2), le_max_left x₀ (Max.max A 2), le_max_right A 2, le_max_left A 2])])⟩ + rw [Asymptotics.isLittleO_iff_tendsto'] + · have h_sum_eq : ∀ x : ℝ, x ≥ 1 → (∑ k ∈ Finset.Iic ⌊x⌋₊, |R (x / k)|) = (∑ k ∈ Finset.Icc 1 ⌊x⌋₊, |R (x / k)|) := by + intro x hx + have h0 : (0 : ℕ) ∈ Finset.Iic ⌊x⌋₊ := by simp [Finset.mem_Iic] + have hI : (Finset.Iic ⌊x⌋₊).erase 0 = Finset.Icc 1 ⌊x⌋₊ := by + ext n + simp [Finset.mem_Iic, Finset.mem_Icc, Nat.one_le_iff_ne_zero, and_comm] + rw [← Finset.sum_erase_add (Finset.Iic ⌊x⌋₊) (fun k => |R (x / k)|) h0] + simp [hI, R, Psi, Chebyshev.psi_eq_sum_Icc] + rw [Metric.tendsto_nhds] + simp +zetaDelta only [gt_iff_lt, ge_iff_le, dist_zero_right, norm_div, norm_eq_abs, norm_mul, + eventually_atTop] at * + intro ε hε; obtain ⟨x₀, hx₀⟩ := h_eps (ε / 2) (half_pos hε) ; use Max.max x₀ 2; intro x hx; rw [abs_of_nonneg (Finset.sum_nonneg fun _ _ => abs_nonneg _), abs_of_nonneg (by linarith [le_max_right x₀ 2]), abs_of_nonneg (Real.log_nonneg (by linarith [le_max_right x₀ 2]))] ; rw [div_lt_iff₀] <;> nlinarith [hx₀ x (le_trans (le_max_left x₀ 2) hx), Real.log_pos (by linarith [le_max_right x₀ 2] : 1 < x), mul_pos (by linarith [le_max_right x₀ 2] : 0 < x) (Real.log_pos (by linarith [le_max_right x₀ 2] : 1 < x)), h_sum_eq x (by linarith [le_max_right x₀ 2])] + · filter_upwards [Filter.eventually_gt_atTop 1] with x hx hx' using absurd hx' (by nlinarith [Real.log_pos hx]) + +lemma R_linear_bound (ε : ℝ) (hε : 0 < ε) : ∃ C, 0 ≤ C ∧ ∀ y, 1 ≤ y → |R y| ≤ ε * y + C := by + obtain ⟨A, hA⟩ : ∃ A : ℝ, 0 < A ∧ ∀ y : ℝ, A ≤ y → |R y| ≤ ε * y := by + have := R_isLittleO.def hε + rw [Filter.eventually_atTop] at this; rcases this with ⟨A, hA⟩ ; exact ⟨Max.max A 1, by positivity, fun y hy => by simpa [abs_of_nonneg (show 0 ≤ y by linarith [le_max_right A 1])] using hA y (le_trans (le_max_left A 1) hy)⟩ + obtain ⟨CA, hCA⟩ : ∃ CA : ℝ, ∀ y ∈ Set.Icc 0 A, |R y| ≤ CA := by + exact R_locally_bounded A hA.1.le |> fun ⟨CA, hCA⟩ => ⟨CA, fun y hy => hCA y hy⟩ + exact ⟨Max.max CA 0, by positivity, fun y hy => if hy' : y ≤ A then le_trans (hCA y ⟨by linarith, by linarith⟩) (by linarith [le_max_left CA 0, le_max_right CA 0, show 0 ≤ ε * y by nlinarith]) else le_trans (hA.2 y (by linarith)) (by linarith [le_max_left CA 0, le_max_right CA 0, show 0 ≤ ε * y by nlinarith])⟩ + +lemma sum_abs_R_isLittleO' : (fun x : ℝ => ∑ k ∈ Iic ⌊x⌋₊, |R (x / k)|) =o[atTop] (fun x => x * log x) := by + apply sum_abs_R_isLittleO + +lemma M_isLittleO : M =o[atTop] id := by + have h_identity : ∀ x ≥ 1, M x * Real.log x = ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * (Real.log (x / k) - Psi (x / k)) := by + exact fun x a => M_log_identity x a + have h_term1 : (fun x => ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log (x / k)) =O[atTop] id := by + have h_abs : ∀ x ≥ 1, |∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log (x / k)| ≤ ∑ k ∈ Iic ⌊x⌋₊, Real.log (x / k) := by + intros x hx + have h_abs : ∀ k ∈ Iic ⌊x⌋₊, |(μ k : ℝ) * Real.log (x / k)| ≤ Real.log (x / k) := by + intros k hk + have h_abs : |(μ k : ℝ)| ≤ 1 := by + norm_num [ArithmeticFunction.moebius] + split_ifs <;> norm_num + by_cases hk0 : k = 0 + · rw [hk0] ; norm_num [ArithmeticFunction.map_zero, Nat.cast_zero, Real.log_zero, div_zero, abs_zero] + · have hx_pos : 0 < x := by positivity + have hk_pos : 0 < (k : ℝ) := by positivity + rw [Real.log_div hx_pos.ne' hk_pos.ne'] + simp only [abs_mul, ge_iff_le] + simp_all only [ge_iff_le, mem_Iic] + exact le_trans (mul_le_of_le_one_left (abs_nonneg _) h_abs) (by rw [abs_of_nonneg] ; exact sub_nonneg_of_le <| Real.log_le_log hk_pos (Nat.cast_le.mpr hk |>.trans (Nat.floor_le hx_pos.le))) + exact le_trans (Finset.abs_sum_le_sum_abs _ _) (Finset.sum_le_sum h_abs) + have h_sum_log : (fun x => ∑ k ∈ Iic ⌊x⌋₊, Real.log (x / k)) =O[atTop] id := by + convert sum_log_div_isBigO using 1 + rw [Asymptotics.isBigO_iff] at * + exact ⟨h_sum_log.choose, by filter_upwards [h_sum_log.choose_spec, Filter.eventually_ge_atTop 1] with x hx₁ hx₂ using le_trans (h_abs x hx₂) (le_trans (le_abs_self _) hx₁)⟩ + have h_term2 : (fun x => ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * (x / k)) =O[atTop] id := by + convert sum_mobius_div_isBigO using 1 + have h_term3 : (fun x => ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * R (x / k)) =o[atTop] (fun x => x * Real.log x) := by + have h_abs : ∀ x ≥ 1, |∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * R (x / k)| ≤ ∑ k ∈ Iic ⌊x⌋₊, |R (x / k)| := by + intros x hx + have h_abs : ∀ k ∈ Iic ⌊x⌋₊, |(μ k : ℝ) * R (x / k)| ≤ |R (x / k)| := by + norm_num [abs_mul] + intro k hk; exact mul_le_of_le_one_left (abs_nonneg _) (mod_cast by exact abs_moebius_le_one) + exact le_trans (Finset.abs_sum_le_sum_abs _ _) (Finset.sum_le_sum h_abs) + have h_sum_abs_R : (fun x => ∑ k ∈ Iic ⌊x⌋₊, |R (x / k)|) =o[atTop] (fun x => x * Real.log x) := by + exact sum_abs_R_isLittleO + rw [Asymptotics.isLittleO_iff] at * + intro c hc; filter_upwards [h_sum_abs_R hc, Filter.eventually_ge_atTop 1] with x hx₁ hx₂; exact le_trans (h_abs x hx₂) (le_trans (le_abs_self _) hx₁) + have h_combined : (fun x => M x * Real.log x) =o[atTop] (fun x => x * Real.log x) := by + have h_combined : (fun x => M x * Real.log x) = (fun x => ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * Real.log (x / k)) - (fun x => ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * (x / k)) - (fun x => ∑ k ∈ Iic ⌊x⌋₊, (μ k : ℝ) * R (x / k)) := by + ext x; by_cases hx : 1 ≤ x <;> simp_all +decide only [ge_iff_le, mul_sub, sum_sub_distrib, not_le, Pi.sub_apply] + · simp +decide [sub_sub, mul_sub, Finset.sum_sub_distrib, Psi, R] + · unfold M R; norm_num [Nat.floor_eq_zero.mpr hx] + norm_num [Finset.Iic_eq_Icc] + rw [h_combined] + refine Asymptotics.IsLittleO.sub ?_ h_term3 + refine Asymptotics.IsLittleO.sub ?_ ?_ + · refine h_term1.trans_isLittleO ?_ + rw [Asymptotics.isLittleO_iff_tendsto'] <;> norm_num + · norm_num [← div_div] + exact le_trans (Filter.Tendsto.div_atTop (tendsto_const_nhds.congr' (by filter_upwards [Filter.eventually_ne_atTop 0] with x hx; aesop)) (Real.tendsto_log_atTop)) (by norm_num) + · exact ⟨2, by rintro x hx (rfl | rfl | rfl) <;> norm_num at hx⟩ + · refine h_term2.trans_isLittleO ?_ + rw [Asymptotics.isLittleO_iff_tendsto'] <;> norm_num + · norm_num [← div_div] + exact le_trans (Filter.Tendsto.div_atTop (tendsto_const_nhds.congr' (by filter_upwards [Filter.eventually_ne_atTop 0] with x hx; aesop)) (Real.tendsto_log_atTop)) (by norm_num) + · exact ⟨2, by rintro x hx (rfl | rfl | rfl) <;> linarith⟩ + rw [Asymptotics.isLittleO_iff_tendsto'] at * + · refine h_combined.congr' (by filter_upwards [Filter.eventually_gt_atTop 1] with x hx using by rw [mul_div_mul_right _ _ (ne_of_gt <| Real.log_pos hx)] ; rfl) + · filter_upwards [Filter.eventually_gt_atTop 1] with x hx hx' using absurd hx' <| ne_of_gt <| mul_pos (by positivity) <| Real.log_pos hx + · filter_upwards [Filter.eventually_gt_atTop 1] with x hx hx' using by nlinarith [Real.log_pos hx] + · filter_upwards [Filter.eventually_gt_atTop 0] with x hx hx' using absurd hx' hx.ne' + +lemma M_isLittleO' : M =o[atTop] id := by + exact M_isLittleO + +theorem mu_pnt : (fun x : ℝ ↦ ∑ n ∈ range ⌊x⌋₊, μ n) =o[atTop] fun x ↦ x := by + have h_moebius_sum : (fun x : ℝ => ∑ n ∈ Finset.range ⌊x⌋₊, (μ n : ℝ)) =o[atTop] (fun x : ℝ => x) := by + have h_bound : (fun x : ℝ => ∑ n ∈ Finset.range ⌊x⌋₊, (μ n : ℝ)) =o[atTop] (fun x : ℝ => x) := by + have h_sum : (fun x : ℝ => ∑ n ∈ Finset.range (⌊x⌋₊ + 1), (μ n : ℝ)) =o[atTop] (fun x : ℝ => x) := by + have h_moebius_sum : (fun x : ℝ => ∑ n ∈ Finset.Iic ⌊x⌋₊, (μ n : ℝ)) =o[atTop] (fun x : ℝ => x) := by + convert! M_isLittleO using 1 + simpa only [Finset.range_eq_Ico] using! h_moebius_sum + have h_mu_floor : (fun x : ℝ => (μ ⌊x⌋₊ : ℝ)) =o[atTop] (fun x : ℝ => x) := by + rw [Asymptotics.isLittleO_iff_tendsto'] <;> norm_num + · refine squeeze_zero_norm (a := fun x : ℝ => 1 / |x|) ?_ ?_ + · intro x; norm_num [abs_div] + exact mul_le_of_le_one_left (by positivity) (mod_cast by exact abs_moebius_le_one) + · exact tendsto_const_nhds.div_atTop (tendsto_norm_atTop_atTop) + · exact ⟨1, by intros; linarith⟩ + simpa [Finset.sum_range_succ] using h_sum.sub h_mu_floor + convert h_bound using 1 + rw [Asymptotics.isLittleO_iff] at * + simp_all +decide [Norm.norm] + +lemma lambda_eq_sum_sq_dvd_mu (n : ℕ) (hn : n ≠ 0) : + ((-1 : ℝ) ^ (Ω n)) = ∑ d ∈ (Icc 1 n).filter (fun d => d^2 ∣ n), (μ (n / d^2) : ℝ) := by + set a : ℕ → ℕ := fun p => Nat.factorization n p with ha + have hn_factor : n = ∏ p ∈ Nat.primeFactors n, p ^ a p := by + exact Eq.symm ( Nat.prod_factorization_pow_eq_self hn ); + have h_sum_factor : (∑ d ∈ Finset.filter (fun d => d^2 ∣ n) (Finset.Icc 1 n), (μ (n / d^2) : ℝ)) = (∏ p ∈ Nat.primeFactors n, (∑ d ∈ Finset.range (a p / 2 + 1), (μ (p^(a p - 2 * d)) : ℝ))) := by + have h_mult : ∀ {m n : ℕ}, Nat.gcd m n = 1 → (∑ d ∈ Finset.filter (fun d => d^2 ∣ m * n) (Finset.Icc 1 (m * n)), (μ (m * n / d^2) : ℝ)) = (∑ d ∈ Finset.filter (fun d => d^2 ∣ m) (Finset.Icc 1 m), (μ (m / d^2) : ℝ)) * (∑ d ∈ Finset.filter (fun d => d^2 ∣ n) (Finset.Icc 1 n), (μ (n / d^2) : ℝ)) := by + intros m n h_coprime + have h_filter : Finset.filter (fun d => d^2 ∣ m * n) (Finset.Icc 1 (m * n)) = Finset.image (fun (d : ℕ × ℕ) => d.1 * d.2) (Finset.filter (fun d => d^2 ∣ m) (Finset.Icc 1 m) ×ˢ Finset.filter (fun d => d^2 ∣ n) (Finset.Icc 1 n)) := by + ext d + simp only [mem_filter, mem_Icc, mem_image, mem_product, Prod.exists] + constructor + · intro h + obtain ⟨d1, d2, hd1, hd2, hd⟩ : ∃ d1 d2 : ℕ, d1^2 ∣ m ∧ d2^2 ∣ n ∧ d = d1 * d2 := by + have h_factor : d^2 ∣ m * n → ∃ d1 d2 : ℕ, d1^2 ∣ m ∧ d2^2 ∣ n ∧ d = d1 * d2 := by + intro h_div + obtain ⟨d1, d2, hd1, hd2, hd⟩ : ∃ d1 d2 : ℕ, d1 ∣ m ∧ d2 ∣ n ∧ d = d1 * d2 := by + exact Exists.imp ( by tauto ) ( Nat.dvd_mul.mp ( dvd_of_mul_left_dvd h_div ) ); + refine ⟨ d1, d2, ?_, ?_, hd ⟩ + · apply Nat.Coprime.dvd_of_dvd_mul_right + · exact Nat.Coprime.pow_left 2 (Nat.Coprime.coprime_dvd_left hd1 h_coprime) + · exact dvd_trans (pow_dvd_pow_of_dvd (hd.symm ▸ dvd_mul_right _ _) 2) h_div + · subst hd + apply Nat.Coprime.dvd_of_dvd_mul_left + · exact Nat.Coprime.pow_left _ (Nat.Coprime.symm <| Nat.Coprime.coprime_dvd_right hd2 h_coprime) + · exact dvd_trans ⟨d1 ^ 2, by ring⟩ h_div + exact h_factor h.2; + refine ⟨ d1, d2, ?_, ?_ ⟩ <;> norm_num [ hd ] + exact ⟨ ⟨ ⟨ Nat.pos_of_ne_zero ( by rintro rfl; linarith ), Nat.le_of_dvd ( Nat.pos_of_ne_zero ( by rintro rfl; linarith ) ) ( dvd_of_mul_left_dvd hd1 ) ⟩, hd1 ⟩, ⟨ Nat.pos_of_ne_zero ( by rintro rfl; linarith ), Nat.le_of_dvd ( Nat.pos_of_ne_zero ( by rintro rfl; linarith ) ) ( dvd_of_mul_left_dvd hd2 ) ⟩, hd2 ⟩; + · intro h + rcases h with ⟨ a, b, ⟨ ⟨ ⟨ ha₁, ha₂ ⟩, ha₃ ⟩, ⟨ ⟨ hb₁, hb₂ ⟩, hb₃ ⟩ ⟩, rfl ⟩ ; exact ⟨ ⟨ by nlinarith, by nlinarith ⟩, by convert Nat.mul_dvd_mul ha₃ hb₃ using 1 ; ring ⟩ ; + rw [ h_filter, Finset.sum_image ]; + · rw [ Finset.sum_product, Finset.sum_mul ]; + simp +decide only [Finset.mul_sum _ _ _]; + refine Finset.sum_congr rfl fun x hx => Finset.sum_congr rfl fun y hy => ?_ + rw [show m * n / (x * y) ^ 2 = (m / x ^ 2) * (n / y ^ 2) by + have hx' : x ^ 2 ∣ m := by + simpa only [sq] using (Finset.mem_filter.mp hx).2 + have hy' : y ^ 2 ∣ n := by + simpa only [sq] using (Finset.mem_filter.mp hy).2 + simpa [mul_pow, mul_assoc, mul_left_comm, mul_comm] using + (Nat.div_mul_div_comm (a := m) (b := x ^ 2) (c := n) (d := y ^ 2) hx' hy').symm] + norm_cast + apply ArithmeticFunction.IsMultiplicative.map_mul_of_coprime; + · exact ArithmeticFunction.isMultiplicative_moebius; + · exact Nat.Coprime.coprime_dvd_left ( Nat.div_dvd_of_dvd <| Finset.mem_filter.mp hx |>.2 ) <| Nat.Coprime.coprime_dvd_right ( Nat.div_dvd_of_dvd <| Finset.mem_filter.mp hy |>.2 ) h_coprime; + · intros x hx y hy; simp +contextual only [ne_eq, coe_product, coe_filter, mem_Icc, Set.mem_prod, Set.mem_ofPred_eq] at *; + intro hxy + have h_eq1 : x.1 = y.1 := by + exact Nat.dvd_antisymm ( by exact Nat.Coprime.dvd_of_dvd_mul_right ( show Nat.Coprime ( x.1 ) ( y.2 ) from Nat.Coprime.coprime_dvd_left ( dvd_of_mul_left_dvd hx.1.2 ) <| Nat.Coprime.coprime_dvd_right ( dvd_of_mul_left_dvd hy.2.2 ) h_coprime ) <| hxy.symm ▸ dvd_mul_right _ _ ) ( by exact Nat.Coprime.dvd_of_dvd_mul_right ( show Nat.Coprime ( y.1 ) ( x.2 ) from Nat.Coprime.coprime_dvd_left ( dvd_of_mul_left_dvd hy.1.2 ) <| Nat.Coprime.coprime_dvd_right ( dvd_of_mul_left_dvd hx.2.2 ) h_coprime ) <| hxy.symm ▸ dvd_mul_right _ _ ) + have h_eq2 : x.2 = y.2 := by + nlinarith + exact Prod.ext h_eq1 h_eq2; + have h_prod : (∑ d ∈ Finset.filter (fun d => d^2 ∣ n) (Finset.Icc 1 n), (μ (n / d^2) : ℝ)) = (∏ p ∈ Nat.primeFactors n, (∑ d ∈ Finset.filter (fun d => d^2 ∣ p^(a p)) (Finset.Icc 1 (p^(a p))), (μ (p^(a p) / d^2) : ℝ))) := by + have h_prod : ∀ {S : Finset ℕ}, (∀ p ∈ S, Nat.Prime p) → (∑ d ∈ Finset.filter (fun d => d^2 ∣ ∏ p ∈ S, p^(a p)) (Finset.Icc 1 (∏ p ∈ S, p^(a p))), (μ ((∏ p ∈ S, p^(a p)) / d^2) : ℝ)) = (∏ p ∈ S, (∑ d ∈ Finset.filter (fun d => d^2 ∣ p^(a p)) (Finset.Icc 1 (p^(a p))), (μ (p^(a p) / d^2) : ℝ))) := by + intro S hS; induction S using Finset.induction <;> norm_num at *; + · norm_num [ Finset.sum_filter ]; + · rw [ Finset.prod_insert ‹_›, h_mult ]; + · rw [ Finset.prod_insert ‹_›, ‹ ( ∀ p ∈ _, Nat.Prime p ) → ∑ d ∈ Finset.Icc 1 ( ∏ p ∈ _, p ^ a p ) with d ^ 2 ∣ ∏ p ∈ _, p ^ a p, ( μ ( ( ∏ p ∈ _, p ^ a p ) / d ^ 2 ) : ℝ ) = ∏ p ∈ _, ∑ d ∈ Finset.Icc 1 ( p ^ a p ) with d ^ 2 ∣ p ^ a p, ( μ ( p ^ a p / d ^ 2 ) : ℝ ) › hS.2 ]; + · exact Nat.Coprime.prod_right fun p hp => Nat.coprime_pow_primes _ _ hS.1 ( hS.2 p hp ) <| by rintro rfl; exact ‹¬_› hp; + convert h_prod fun p hp => Nat.prime_of_mem_primeFactors hp; + have h_divisors : ∀ p ∈ Nat.primeFactors n, Finset.filter (fun d => d^2 ∣ p^(a p)) (Finset.Icc 1 (p^(a p))) = Finset.image (fun k => p^k) (Finset.Icc 0 (a p / 2)) := by + intro p hp + ext d + simp only [mem_filter, mem_Icc, mem_image, _root_.zero_le, true_and] + constructor; + · intro hd; + have : d ∣ p ^ a p := dvd_of_mul_left_dvd hd.2; ( rw [ Nat.dvd_prime_pow ( Nat.prime_of_mem_primeFactors hp ) ] at this; obtain ⟨ k, hk ⟩ := this; use k; simp +decide only [ hk, and_true ] at hd ⊢; ); + rw [ Nat.le_div_iff_mul_le zero_lt_two ] ; rw [ ← pow_mul ] at hd ; exact Nat.le_of_not_lt fun h => absurd ( Nat.le_of_dvd ( pow_pos ( Nat.pos_of_mem_primeFactors hp ) _ ) hd.2 ) ( by exact not_le_of_gt ( pow_lt_pow_right₀ ( Nat.Prime.one_lt ( Nat.prime_of_mem_primeFactors hp ) ) ( by linarith ) ) ) ; + · rintro ⟨ k, hk₁, rfl ⟩ ; exact ⟨ ⟨ Nat.one_le_pow _ _ ( Nat.pos_of_mem_primeFactors hp ), Nat.pow_le_pow_right ( Nat.pos_of_mem_primeFactors hp ) ( by omega ) ⟩, by rw [ ← pow_mul ] ; exact pow_dvd_pow _ ( by omega ) ⟩ ; + rw [ h_prod, Finset.prod_congr rfl ]; + intro p hp; rw [ show ( Finset.filter ( fun d => d ^ 2 ∣ p ^ a p ) ( Finset.Icc 1 ( p ^ a p ) ) ) = Finset.image ( fun k => p ^ k ) ( Finset.Icc 0 ( a p / 2 ) ) from h_divisors p hp ] ; rw [ Finset.sum_image ] <;> norm_num [ pow_mul', Nat.div_eq_of_lt ] ; + · rw [Finset.range_eq_Ico, ← Order.succ_eq_add_one, Finset.Ico_succ_right_eq_Icc] + refine Finset.sum_congr rfl ?_ + intro x hx + rw [← pow_mul', Nat.mul_comm] + have hx_pos : 0 < p ^ (x * 2) := pow_pos (Nat.pos_of_mem_primeFactors hp) _ + have hx_eq : p ^ a p = p ^ (a p - x * 2) * p ^ (x * 2) := by + rw [← pow_add, Nat.sub_add_cancel (by linarith [Finset.mem_Icc.mp hx, Nat.div_mul_le_self (a p) 2])] + rw [Nat.div_eq_of_eq_mul_left hx_pos hx_eq] + · exact fun x hx y hy hxy => Nat.pow_right_injective ( Nat.Prime.one_lt ( Nat.prime_of_mem_primeFactors hp ) ) hxy; + have h_inner_sum : ∀ p ∈ Nat.primeFactors n, (∑ d ∈ Finset.range (a p / 2 + 1), (μ (p^(a p - 2 * d)) : ℝ)) = (-1 : ℝ) ^ (a p) := by + intro p hp + have h_inner_sum_cases : ∀ d ∈ Finset.range (a p / 2 + 1), (μ (p^(a p - 2 * d)) : ℝ) = if a p - 2 * d = 0 then 1 else if a p - 2 * d = 1 then -1 else 0 := by + simp +zetaDelta only [ne_eq, mem_primeFactors, mem_range] at * + intro d hd + rcases k : (n.factorization p - 2 * d) with (_ | _ | k) + · simp +decide only [pow_zero, isUnit_iff_eq_one, IsUnit.squarefree, moebius_apply_of_squarefree, Int.reduceNeg, + cardFactors_one, Int.cast_one, ↓reduceIte] + · simp +decide only [zero_add, pow_one, ↓reduceIte] + norm_num [hp.1, ArithmeticFunction.moebius] + exact hp.1.squarefree + · simp +decide only [Nat.add_eq_zero_iff, and_false, and_self, ↓reduceIte, Nat.add_eq_right, Int.cast_eq_zero] + exact + ArithmeticFunction.moebius_eq_zero_of_not_squarefree + (by rw [Nat.squarefree_pow_iff] <;> norm_num [hp.1.ne_one, hp.1.ne_zero]) + rw [ Finset.sum_congr rfl h_inner_sum_cases ] ; norm_num [ Finset.sum_ite ] ; rcases Nat.even_or_odd' ( a p ) with ⟨ k, hk | hk ⟩ <;> norm_num [ hk, pow_add, pow_mul ] + · ring_nf + norm_num [ show ∀ x : ℕ, k * 2 - x * 2 = 0 ↔ x ≥ k by intro x; exact ⟨ fun hx => by contrapose! hx; exact Nat.ne_of_gt <| Nat.sub_pos_of_lt <| by linarith, fun hx => Nat.sub_eq_zero_of_le <| by linarith ⟩ ]; + have h_first : + Finset.filter (fun x => k ≤ x) (Finset.range (k + 1)) = {k} := by + ext x + simp + omega + have h_second : + Finset.filter (fun x => k * 2 - x * 2 = 1) + (Finset.filter (fun x => ¬2 * k - 2 * x = 0) (Finset.range (k + 1))) = ∅ := by + ext x + simp + omega + rw [h_first, h_second] + norm_num + · ring_nf + norm_num [ Nat.add_div ]; + rw [ Finset.card_eq_zero.mpr ] <;> norm_num; + · rw [ Finset.card_eq_one ] ; use k ; ext x ; norm_num ; omega; + · intros; omega; + rw [ h_sum_factor, Finset.prod_congr rfl h_inner_sum ]; + rw [ Finset.prod_pow_eq_pow_sum ]; + rw [ ArithmeticFunction.cardFactors_apply ]; + rw [ ← Multiset.coe_card, ← Multiset.toFinset_sum_count_eq ]; + norm_num +zetaDelta [Nat.primeFactorsList_count_eq] + +lemma sum_lambda_eq_sum_mu_div_sq (N : ℕ) : + ∑ n ∈ Finset.Icc 1 N, ((-1 : ℝ) ^ (Ω n)) = + ∑ d ∈ Finset.Icc 1 (Nat.sqrt N), ∑ k ∈ Finset.Icc 1 (N / d^2), (μ k : ℝ) := by + have h_sum_rewrite : ∑ n ∈ Finset.Icc 1 N, (-1 : ℝ) ^ (Ω n) = ∑ n ∈ Finset.Icc 1 N, ∑ d ∈ (Finset.Icc 1 N).filter (fun d => d^2 ∣ n), (μ (n / d^2) : ℝ) := by + have h_sum_rewrite : ∀ n ∈ Finset.Icc 1 N, (-1 : ℝ) ^ (Ω n) = ∑ d ∈ (Finset.Icc 1 N).filter (fun d => d^2 ∣ n), (μ (n / d^2) : ℝ) := by + intro n hn + have h_lambda_eq : ((-1 : ℝ) ^ (Ω n)) = ∑ d ∈ (Finset.Icc 1 n).filter (fun d => d^2 ∣ n), (μ (n / d^2) : ℝ) := by + convert lambda_eq_sum_sq_dvd_mu n ( by linarith [ Finset.mem_Icc.mp hn ] ) using 1; + rw [ h_lambda_eq, Finset.sum_subset ]; + · exact fun x hx => Finset.mem_filter.mpr ⟨ Finset.mem_Icc.mpr ⟨ Finset.mem_Icc.mp ( Finset.mem_filter.mp hx |>.1 ) |>.1, by linarith [ Finset.mem_Icc.mp ( Finset.mem_filter.mp hx |>.1 ) |>.2, Finset.mem_Icc.mp hn |>.2 ] ⟩, Finset.mem_filter.mp hx |>.2 ⟩; + · simp +zetaDelta only [mem_Icc, mem_filter, not_and, and_imp, Int.cast_eq_zero] at * + exact fun x hx₁ hx₂ hx₃ hx₄ => False.elim <| hx₄ hx₁ ( by nlinarith [ Nat.le_of_dvd ( by linarith ) hx₃ ] ) hx₃; + exact Finset.sum_congr rfl h_sum_rewrite; + rw [ h_sum_rewrite, Finset.sum_sigma' ]; + have h_reindex : ∑ x ∈ (Finset.Icc 1 N).sigma fun (n : ℕ) => {d ∈ Finset.Icc 1 N | d ^ 2 ∣ n}, (μ (x.fst / x.snd ^ 2) : ℝ) = ∑ d ∈ Finset.Icc 1 (Nat.sqrt N), ∑ k ∈ Finset.Icc 1 (N / d ^ 2), (μ k : ℝ) := by + have : Finset.filter (fun x => x.snd ^ 2 ∣ x.fst) (Finset.Icc 1 N ×ˢ Finset.Icc 1 N) = Finset.biUnion (Finset.Icc 1 (Nat.sqrt N)) (fun d => Finset.image (fun k => (d ^ 2 * k, d)) (Finset.Icc 1 (N / d ^ 2))) := by + ext ⟨n, d⟩ + simp only [Finset.mem_filter, Finset.mem_product, Finset.mem_Icc, Finset.mem_biUnion, Finset.mem_image, Prod.mk.injEq] + constructor + · intro ⟨⟨⟨hn1, hn2⟩, hd1, hd2⟩, hdiv⟩ + exact ⟨d, ⟨hd1, by rw [Nat.le_sqrt]; nlinarith [Nat.le_of_dvd (by linarith) hdiv]⟩, n / d ^ 2, ⟨Nat.div_pos (Nat.le_of_dvd (by linarith) hdiv) (by nlinarith), Nat.div_le_div_right hn2⟩, Nat.mul_div_cancel' hdiv, rfl⟩ + · rintro ⟨a, ⟨ha₁, ha₂⟩, b, ⟨hb₁, hb₂⟩, hn, hd⟩ + rw [← hn, ← hd] + exact ⟨⟨⟨by nlinarith, by nlinarith [Nat.div_mul_le_self N (a ^ 2)]⟩, ha₁, by nlinarith [Nat.sqrt_le N]⟩, dvd_mul_right _ _⟩ + rw [ Finset.sum_sigma' ]; + apply Finset.sum_bij (fun x _ => ⟨x.snd, x.fst / x.snd ^ 2⟩); + · simp_all +decide only [Finset.ext_iff, mem_filter, mem_product, mem_Icc, mem_biUnion, mem_image, Prod.forall, + Prod.mk.injEq, ↓existsAndEq, and_true, exists_and_left, mem_sigma, true_and, and_imp] + exact fun x hx₁ hx₂ hx₃ hx₄ hx₅ => ⟨ by nlinarith [ Nat.le_of_dvd ( by linarith ) hx₅, Nat.lt_succ_sqrt N ], Nat.div_pos ( Nat.le_of_dvd ( by linarith ) hx₅ ) ( by positivity ), Nat.div_le_div_right hx₂ ⟩; + · simp +contextual [ Finset.mem_sigma, Finset.mem_filter ]; + aesop; + · simp +zetaDelta only [mem_sigma, mem_Icc, mem_filter, exists_prop, Sigma.exists, and_imp] at * + exact fun b hb₁ hb₂ hb₃ hb₄ => ⟨ b.fst ^ 2 * b.snd, b.fst, ⟨ ⟨ by nlinarith, by nlinarith [ Nat.div_mul_le_self N ( b.fst ^ 2 ) ] ⟩, ⟨ by nlinarith, by nlinarith [ Nat.div_mul_le_self N ( b.fst ^ 2 ) ] ⟩, by norm_num ⟩, by simp +decide [ Nat.mul_div_cancel_left _ ( by nlinarith : 0 < b.fst ^ 2 ) ] ⟩; + · aesop; + convert h_reindex using 1 + +lemma sum_mu_div_sq_isLittleO : (fun N : ℕ ↦ ∑ d ∈ Finset.Icc 1 (Nat.sqrt N), ∑ k ∈ Finset.Icc 1 (N / d^2), (μ k : ℝ)) =o[atTop] (fun N ↦ (N : ℝ)) := by + have h_sum_rewrite : ∀ N : ℕ, (∑ d ∈ Finset.Icc 1 (Nat.sqrt N), (∑ k ∈ Finset.Icc 1 (N / d^2), (μ k : ℝ))) = (∑ d ∈ Finset.Icc 1 (Nat.sqrt N), (M (N / d^2) : ℝ)) := by + intro N + simp only [M] + refine Finset.sum_congr rfl ?_ + intro x hx + erw [ Finset.sum_Ico_eq_sub _ ] <;> norm_num [ Finset.sum_range_succ' ]; + rw [ show ⌊ ( N : ℝ ) / x ^ 2⌋₊ = N / x ^ 2 from Nat.floor_eq_iff ( by positivity ) |>.2 ⟨ by rw [ le_div_iff₀ ( by norm_cast; nlinarith [ Finset.mem_Icc.mp hx ] ) ] ; norm_cast; linarith [ Nat.div_mul_le_self N ( x ^ 2 ) ], by rw [ div_lt_iff₀ ( by norm_cast; nlinarith [ Finset.mem_Icc.mp hx ] ) ] ; norm_cast; linarith [ Nat.div_add_mod N ( x ^ 2 ), Nat.mod_lt N ( show x ^ 2 > 0 by nlinarith [ Finset.mem_Icc.mp hx ] ) ] ⟩ ] ; erw [ Finset.sum_Ico_eq_sub _ ] <;> norm_num [ Finset.sum_range_succ' ] ; + have h_bound : ∀ ε > 0, ∃ N₀ : ℕ, ∀ N ≥ N₀, ∀ d ∈ Finset.Icc 1 (Nat.sqrt N), |M (N / d^2)| ≤ ε * (N / d^2) + N₀ := by + have h_bound : ∀ ε > 0, ∃ C : ℝ, ∀ x : ℝ, 1 ≤ x → |M x| ≤ ε * x + C := by + have h_bound : ∀ ε > 0, ∃ C : ℝ, ∀ x : ℝ, 1 ≤ x → |M x| ≤ ε * x + C := by + intro ε hε + have := M_isLittleO' + rw [ Asymptotics.isLittleO_iff ] at this; + norm_num +zetaDelta at *; + obtain ⟨ a, ha ⟩ := this hε; + obtain ⟨C, hC⟩ : ∃ C : ℝ, ∀ x ∈ Set.Icc 1 a, |M x| ≤ C := by + have h_bounded : BddAbove (Set.image (fun x => |M x|) (Set.Icc 1 a)) := by + have h_bounded : BddAbove (Set.image (fun x => |∑ n ∈ Finset.Iic ⌊x⌋₊, (μ n : ℝ)|) (Set.Icc 1 a)) := by + have h_finite : Set.Finite (Set.image (fun x => ⌊x⌋₊) (Set.Icc 1 a)) := by + exact Set.finite_iff_bddAbove.mpr ⟨ ⌊a⌋₊, Set.forall_mem_image.mpr fun x hx => Nat.floor_mono hx.2 ⟩ + have h_bounded : BddAbove (Set.image (fun n : ℕ => |∑ k ∈ Finset.Iic n, (μ k : ℝ)|) (Set.image (fun x => ⌊x⌋₊) (Set.Icc 1 a))) := by + exact Set.Finite.bddAbove <| h_finite.image _; + exact ⟨ h_bounded.choose, Set.forall_mem_image.2 fun x hx => h_bounded.choose_spec <| Set.mem_image_of_mem _ <| Set.mem_image_of_mem _ hx ⟩; + convert! h_bounded using 1; + exact ⟨ h_bounded.choose, fun x hx => h_bounded.choose_spec ⟨ x, hx, rfl ⟩ ⟩; + exact ⟨ Max.max C 0, fun x hx => if hx' : x ≤ a then le_trans ( hC x ⟨ hx, hx' ⟩ ) ( le_max_left _ _ ) |> le_trans <| le_add_of_nonneg_left <| by positivity else le_trans ( ha x <| le_of_not_ge hx' ) <| by rw [ abs_of_nonneg <| by linarith ] ; exact le_add_of_nonneg_right <| by positivity ⟩; + assumption; + intro ε hε + obtain ⟨C, hC⟩ := h_bound ε hε + refine ⟨⌈C⌉₊ + 1, ?_⟩ + intro N hN d hd + specialize hC (N / d ^ 2) + rcases eq_or_ne d 0 with rfl | hd0 + · simp_all +decide only [gt_iff_lt, ge_iff_le, mem_Icc, _root_.zero_le, and_true] + · simp_all +decide only [gt_iff_lt, ge_iff_le, mem_Icc, ne_eq, cast_add, cast_one] + exact + le_trans + (hC <| + by + rw [le_div_iff₀ <| by positivity] + nlinarith [show (d : ℝ) ^ 2 ≤ N by norm_cast; nlinarith [Nat.sqrt_le N]]) + (by linarith [Nat.le_ceil C]) + have h_sum_bound : ∀ ε > 0, ∃ N₀ : ℕ, ∀ N ≥ N₀, |∑ d ∈ Finset.Icc 1 (Nat.sqrt N), M (N / d^2)| ≤ ε * N * (∑' k : ℕ, (1 : ℝ) / (k^2)) + N₀ * Nat.sqrt N := by + intros ε hε_pos + obtain ⟨N₀, hN₀⟩ := h_bound ε hε_pos + use N₀ + intro N hN + have h_sum_bound : |∑ d ∈ Finset.Icc 1 (Nat.sqrt N), M (N / d^2)| ≤ ∑ d ∈ Finset.Icc 1 (Nat.sqrt N), (ε * (N / d^2) + N₀) := by + exact le_trans ( Finset.abs_sum_le_sum_abs _ _ ) ( Finset.sum_le_sum fun x hx => hN₀ N hN x hx ); + refine le_trans h_sum_bound ?_; + norm_num [ Finset.sum_add_distrib, Finset.mul_sum _ _ _, mul_assoc, mul_comm, mul_left_comm, div_eq_mul_inv ]; + rw [ ← Finset.mul_sum _ _ _, ← Finset.mul_sum _ _ _ ]; + exact mul_le_mul_of_nonneg_left ( mul_le_mul_of_nonneg_left ( Summable.sum_le_tsum ( Finset.Icc 1 N.sqrt ) ( fun _ _ => by positivity ) ( by simp ) ) ( Nat.cast_nonneg _ ) ) hε_pos.le; + rw [ Asymptotics.isLittleO_iff ]; + intro c hc + obtain ⟨ε, hε_pos, hε⟩ : ∃ ε > 0, ε * (∑' k : ℕ, (1 : ℝ) / (k^2)) < c / 2 := by + exact ⟨ ( c / 2 ) / ( ∑' k : ℕ, 1 / ( k : ℝ ) ^ 2 + 1 ), div_pos ( half_pos hc ) ( add_pos_of_nonneg_of_pos ( tsum_nonneg fun _ => by positivity ) zero_lt_one ), by rw [ div_mul_eq_mul_div, div_lt_iff₀ ] <;> nlinarith [ show 0 ≤ ∑' k : ℕ, 1 / ( k : ℝ ) ^ 2 from tsum_nonneg fun _ => by positivity ] ⟩; + obtain ⟨ N₀, hN₀ ⟩ := h_sum_bound ε hε_pos; + obtain ⟨N₁, hN₁⟩ : ∃ N₁ : ℕ, ∀ N ≥ N₁, N₀ * Nat.sqrt N ≤ (c / 2) * N := by + have h_sqrt_growth : ∃ N₁ : ℕ, ∀ N ≥ N₁, (N₀ : ℝ) * Real.sqrt N ≤ (c / 2) * N := by + have h_sqrt_bound : Filter.Tendsto (fun N : ℕ => (N₀ : ℝ) * Real.sqrt N / N) Filter.atTop (nhds 0) := by + simpa [ mul_div_assoc, Real.sqrt_div_self ] using tendsto_const_nhds.mul ( tendsto_inv_atTop_nhds_zero_nat.sqrt ) + exact Filter.eventually_atTop.mp ( h_sqrt_bound.eventually ( gt_mem_nhds <| show 0 < c / 2 by positivity ) ) |> fun ⟨ N₁, hN₁ ⟩ ↦ ⟨ N₁ + 1, fun N hN ↦ by have := hN₁ N ( by linarith ) ; rw [ div_lt_iff₀ ] at this <;> nlinarith [ show ( N : ℝ ) ≥ N₁ + 1 by exact_mod_cast hN ] ⟩; + exact ⟨ h_sqrt_growth.choose, fun N hN => le_trans ( mul_le_mul_of_nonneg_left ( Real.le_sqrt_of_sq_le <| mod_cast Nat.sqrt_le' _ ) <| Nat.cast_nonneg _ ) <| h_sqrt_growth.choose_spec N hN ⟩; + filter_upwards [ Filter.eventually_ge_atTop N₀, Filter.eventually_ge_atTop N₁ ] with N hN₀' hN₁' using by rw [ Real.norm_of_nonneg ( Nat.cast_nonneg _ ) ] ; rw [ h_sum_rewrite ] ; exact le_trans ( hN₀ _ hN₀' ) ( by nlinarith [ hN₁ _ hN₁', show ( N : ℝ ) ≥ 0 by positivity ] ) ; + +theorem lambda_pnt : (fun x : ℝ ↦ ∑ n ∈ range ⌊x⌋₊, (-1)^(Ω n)) =o[atTop] fun x ↦ x := by + have h_lambda_pnt : (fun N : ℕ => ∑ n ∈ Finset.range N, (-1 : ℝ) ^ (Nat.factorization n).sum (fun p k => k)) =o[Filter.atTop] (fun N : ℕ => (N : ℝ)) := by + have h_lambda_pnt : (fun N : ℕ => ∑ n ∈ Finset.Icc 1 N, (-1 : ℝ) ^ (Nat.factorization n).sum (fun p k => k)) =o[Filter.atTop] (fun N : ℕ => (N : ℝ)) := by + have h_lambda_pnt : (fun N : ℕ => ∑ d ∈ Finset.Icc 1 (Nat.sqrt N), ∑ k ∈ Finset.Icc 1 (N / d^2), (μ k : ℝ)) =o[Filter.atTop] (fun N : ℕ => (N : ℝ)) := by + exact sum_mu_div_sq_isLittleO + convert h_lambda_pnt using 2; + convert sum_lambda_eq_sum_mu_div_sq _; + exact Eq.symm cardFactors_eq_sum_factorization + have h_lambda_pnt : (fun N : ℕ => ∑ n ∈ Finset.range (N + 1), (-1 : ℝ) ^ (Nat.factorization n).sum (fun p k => k)) =o[Filter.atTop] (fun N : ℕ => (N : ℝ)) := by + rw [ Asymptotics.isLittleO_iff_tendsto' ] at * <;> norm_num at *; + · convert h_lambda_pnt.add ( show Filter.Tendsto ( fun x : ℕ => ( 1 : ℝ ) / x ) Filter.atTop ( nhds 0 ) from tendsto_const_nhds.div_atTop tendsto_natCast_atTop_atTop ) using 2 <;> norm_num [ Finset.sum_Ico_eq_sum_range ]; + erw [ Finset.sum_Ico_eq_sub _ _ ] <;> norm_num [ Finset.sum_range_succ' ] ; ring_nf; + · exact ⟨ 1, by aesop ⟩; + · exact ⟨ 1, by aesop ⟩; + simp_all +decide only [Finset.sum_range_succ] + have := h_lambda_pnt.sub ( show ( fun N : ℕ => ( -1 : ℝ ) ^ N.factorization.sum fun p k => k ) =o[Filter.atTop] fun N : ℕ => ( N : ℝ ) from ?_ ); + · aesop; + · rw [ Asymptotics.isLittleO_iff_tendsto' ] <;> norm_num; + · exact tendsto_zero_iff_norm_tendsto_zero.mpr ( by simpa using tendsto_inv_atTop_nhds_zero_nat ); + · exact ⟨ 1, fun n hn => by positivity ⟩; + have h_floor : (fun x : ℝ => ∑ n ∈ Finset.range ⌊x⌋₊, (-1 : ℝ) ^ (Nat.factorization n).sum (fun p k => k)) =o[Filter.atTop] (fun x : ℝ => (⌊x⌋₊ : ℝ)) := by + rw [ Asymptotics.isLittleO_iff_tendsto' ] at * <;> norm_num at *; + · exact h_lambda_pnt.comp <| tendsto_nat_floor_atTop; + · exact ⟨ 1, by aesop ⟩; + · exact ⟨ 1, by intros; linarith ⟩; + rw [ Asymptotics.isLittleO_iff ] at *; + intro c hc + filter_upwards [h_floor (half_pos hc), Filter.eventually_gt_atTop 1] with x hx₁ hx₂ + refine le_trans ?_ (le_trans hx₁ ?_) + · norm_num [ Norm.norm ]; + convert le_rfl using 2; + congr! 2; + exact Eq.symm cardFactors_eq_sum_factorization + · norm_num [ abs_of_nonneg, Nat.floor_le, hx₂.le ]; + rw [ abs_of_nonneg ( by positivity ) ] ; nlinarith [ Nat.floor_le ( by positivity : 0 ≤ x ) ] + +lemma sum_mobius_floor (x : ℝ) (hx : 1 ≤ x) : ∑ n ∈ Icc 1 ⌊x⌋₊, (μ n : ℝ) * ⌊x / n⌋ = 1 := by + classical + have h := sum_mobius_mul_floor x hx + have h0 : (0 : ℕ) ∈ Iic ⌊x⌋₊ := by simp [Finset.mem_Iic] + have hI : (Iic ⌊x⌋₊).erase 0 = Icc 1 ⌊x⌋₊ := by + ext n + simp [Finset.mem_Iic, Finset.mem_Icc, Nat.one_le_iff_ne_zero, and_comm] + rw [← Finset.sum_erase_add (Iic ⌊x⌋₊) (fun n => (μ n : ℝ) * (⌊x / n⌋ : ℝ)) h0] at h + simpa [hI] using h + +lemma sum_mobius_floor_tail_isLittleO (K : ℕ) (hK : 0 < K) : + (fun x : ℝ => ∑ n ∈ Finset.Ioc ⌊x/K⌋₊ ⌊x⌋₊, (μ n : ℝ) * (⌊x / (n : ℝ)⌋ : ℝ)) =o[atTop] fun x => x := by + have h_group : ∀ x : ℝ, x ≥ 1 → ∑ n ∈ Finset.Ioc ⌊x / (K : ℝ)⌋₊ ⌊x⌋₊, (μ n : ℝ) * ⌊x / n⌋ = ∑ k ∈ Finset.Ico 1 K, k * (∑ n ∈ Finset.Ioc ⌊x / (k + 1 : ℝ)⌋₊ ⌊x / (k : ℝ)⌋₊, (μ n : ℝ)) := by + intro x hx + have h_group : ∑ n ∈ Finset.Ioc ⌊x / (K : ℝ)⌋₊ ⌊x⌋₊, (μ n : ℝ) * ⌊x / n⌋ = ∑ k ∈ Finset.Ico 1 K, ∑ n ∈ Finset.Ioc ⌊x / (k + 1 : ℝ)⌋₊ ⌊x / (k : ℝ)⌋₊, (μ n : ℝ) * k := by + have h_group : Finset.Ioc ⌊x / (K : ℝ)⌋₊ ⌊x⌋₊ = Finset.biUnion (Finset.Ico 1 K) (fun k => Finset.Ioc (⌊x / (k + 1 : ℝ)⌋₊) (⌊x / (k : ℝ)⌋₊)) := by + ext n + simp only [mem_Ioc, mem_biUnion, mem_Ico] + constructor + · intro hn + refine ⟨⌊x / n⌋₊, ?_, ?_, ?_⟩ + all_goals generalize_proofs at * + · rw [Nat.floor_lt', div_lt_iff₀] <;> norm_num <;> try linarith [show (n : ℝ) ≥ 1 by norm_cast; linarith] + exact ⟨by rw [le_div_iff₀ (Nat.cast_pos.mpr <| by linarith)] ; nlinarith [Nat.floor_le (show 0 ≤ x by linarith), Nat.lt_floor_add_one x, show (n : ℝ) ≤ ⌊x⌋₊ by exact_mod_cast hn.2], by rw [Nat.floor_lt (by positivity)] at *; rw [div_lt_iff₀ (by positivity)] at *; norm_num at *; linarith⟩ + · rw [Nat.floor_lt', div_lt_iff₀] <;> norm_num <;> try linarith [Nat.lt_floor_add_one (x / n)] + nlinarith [Nat.lt_floor_add_one (x / n), show (n : ℝ) ≥ 1 by norm_cast; linarith, div_mul_cancel₀ x (show (n : ℝ) ≠ 0 by norm_cast; linarith)] + · refine Nat.le_floor ?_ + rw [le_div_iff₀] <;> norm_num + · exact le_trans (mul_le_mul_of_nonneg_left (Nat.floor_le (by positivity)) (Nat.cast_nonneg _)) (by rw [mul_div_cancel₀ _ (Nat.cast_ne_zero.mpr <| by linarith)]) + · exact Nat.floor_pos.mpr (by rw [le_div_iff₀ (Nat.cast_pos.mpr <| pos_of_gt hn.1)] ; nlinarith [Nat.floor_le (show 0 ≤ x by positivity), Nat.lt_floor_add_one x, show (n : ℝ) ≤ ⌊x⌋₊ by exact_mod_cast hn.2, div_mul_cancel₀ x (show (K : ℝ) ≠ 0 by positivity)]) + · field_simp + rintro ⟨a, ⟨ha₁, ha₂⟩, ha₃, ha₄⟩ + refine ⟨lt_of_le_of_lt ?_ ha₃, ha₄.trans ?_⟩ + · gcongr ; norm_cast + · exact Nat.floor_mono <| div_le_self (by positivity) <| mod_cast ha₁ + rw [h_group, Finset.sum_biUnion] + · refine Finset.sum_congr rfl fun k hk => Finset.sum_congr rfl fun n hn => ?_ + simp +zetaDelta only [ge_iff_le, mem_Ico, mem_Ioc, mul_eq_mul_left_iff, Int.cast_eq_zero] at * + rw [Nat.floor_lt (by positivity), Nat.le_floor_iff (by positivity)] at * + exact Or.inl <| mod_cast Int.floor_eq_iff.mpr ⟨by rw [le_div_iff₀ <| Nat.cast_pos.mpr <| Nat.pos_of_ne_zero <| by rintro rfl; norm_num at hn; linarith [show x / (k + 1 : ℝ) > 0 by positivity]] ; norm_num; nlinarith [show (k : ℝ) ≥ 1 by norm_cast; linarith, div_mul_cancel₀ x (show (k : ℝ) ≠ 0 by norm_cast; linarith), div_mul_cancel₀ x (show (k + 1 : ℝ) ≠ 0 by positivity)], by rw [div_lt_iff₀ <| Nat.cast_pos.mpr <| Nat.pos_of_ne_zero <| by rintro rfl; norm_num at hn; linarith [show x / (k + 1 : ℝ) > 0 by positivity]] ; norm_num; nlinarith [show (k : ℝ) ≥ 1 by norm_cast; linarith, div_mul_cancel₀ x (show (k : ℝ) ≠ 0 by norm_cast; linarith), div_mul_cancel₀ x (show (k + 1 : ℝ) ≠ 0 by positivity)]⟩ + · intros k hk l hl hkl; simp_all +decide [Finset.disjoint_left] + field_simp + intro a ha₁ ha₂ ha₃; contrapose! hkl + rw [Nat.le_floor_iff (by positivity), Nat.floor_lt (by positivity)] at * + rw [div_lt_iff₀ (by positivity), le_div_iff₀ (by norm_cast; linarith)] at * + exact Nat.le_antisymm (Nat.le_of_lt_succ <| by { rw [← @Nat.cast_lt ℝ] ; push_cast; nlinarith }) (Nat.le_of_lt_succ <| by { rw [← @Nat.cast_lt ℝ] ; push_cast; nlinarith }) + simpa only [mul_comm, Finset.mul_sum _ _ _] using h_group + have h_M_x_over_k : ∀ k : ℕ, 1 ≤ k → k < K → (fun x : ℝ => ∑ n ∈ Finset.Ioc ⌊x / (k + 1 : ℝ)⌋₊ ⌊x / (k : ℝ)⌋₊, (μ n : ℝ)) =o[atTop] (fun x => x) := by + have h_M : (fun x : ℝ => ∑ n ∈ Finset.Icc 1 ⌊x⌋₊, (μ n : ℝ)) =o[atTop] (fun x => x) := by + have h_M : (fun x : ℝ => ∑ n ∈ Finset.range ⌊x⌋₊, (μ n : ℝ)) =o[atTop] (fun x => x) := by + refine Asymptotics.IsLittleO.of_norm_left ?_ + simpa only [← Int.norm_cast_real, Int.cast_sum] using mu_pnt.norm_left + have h_M : (fun x : ℝ => ∑ n ∈ Finset.range (⌊x⌋₊ + 1), (μ n : ℝ)) =o[atTop] (fun x => x) := by + simp_all +decide only [ge_iff_le, Finset.sum_range_succ] + refine h_M.add ?_ + rw [Asymptotics.isLittleO_iff_tendsto] <;> norm_num + refine squeeze_zero_norm' (a := fun x : ℝ => 1 / |x|) ?_ ?_ + · norm_num [abs_div] + exact ⟨1, fun x hx => mul_le_of_le_one_left (by positivity) (mod_cast by exact abs_moebius_le_one)⟩ + · exact tendsto_const_nhds.div_atTop (tendsto_norm_atTop_atTop) + convert! h_M.sub (show (fun x : ℝ => (μ 0 : ℝ)) =o[Filter.atTop] fun x : ℝ => x from ?_) using 2 <;> norm_num [Finset.sum_range_succ'] + erw [Finset.sum_Ico_eq_sub _ _] <;> norm_num [Finset.sum_range_succ'] + intros k hk_pos hk_lt_K + have h_M_x_over_k : (fun x : ℝ => ∑ n ∈ Finset.Ioc ⌊x / (k + 1 : ℝ)⌋₊ ⌊x / (k : ℝ)⌋₊, (μ n : ℝ)) = (fun x : ℝ => ∑ n ∈ Finset.Icc 1 ⌊x / (k : ℝ)⌋₊, (μ n : ℝ)) - (fun x : ℝ => ∑ n ∈ Finset.Icc 1 ⌊x / (k + 1 : ℝ)⌋₊, (μ n : ℝ)) := by + ext x + simp only [Pi.sub_apply] + rw [eq_sub_iff_add_eq'] + simp only [show Finset.Icc (1 : ℕ) (⌊x / (↑k + 1)⌋₊) = Finset.Ioc (0 : ℕ) (⌊x / (↑k + 1)⌋₊) by + simpa using (Finset.Icc_add_one_left_eq_Ioc (a := (0 : ℕ)) (b := ⌊x / (↑k + 1)⌋₊)), + show Finset.Icc (1 : ℕ) (⌊x / ↑k⌋₊) = Finset.Ioc (0 : ℕ) (⌊x / ↑k⌋₊) by + simpa using (Finset.Icc_add_one_left_eq_Ioc (a := (0 : ℕ)) (b := ⌊x / ↑k⌋₊))] + rw [Finset.sum_Ioc_consecutive] <;> norm_num + + by_cases hx : 0 ≤ x <;> simp_all +decide only [ge_iff_le, floor_div_natCast, not_le] + · rw [Nat.le_div_iff_mul_le (by positivity)] + exact Nat.le_floor <| by push_cast; nlinarith [Nat.floor_le (show 0 ≤ x / (k + 1) by positivity), Nat.lt_floor_add_one (x / (k + 1)), mul_div_cancel₀ x (by positivity : (k + 1 : ℝ) ≠ 0)] + · rw [Nat.floor_of_nonpos (div_nonpos_of_nonpos_of_nonneg hx.le (by positivity)), Nat.floor_of_nonpos hx.le] ; norm_num + rw [h_M_x_over_k] + refine Asymptotics.IsLittleO.sub ?_ ?_ + · field_simp + refine h_M.comp_tendsto (Filter.tendsto_id.atTop_mul_const (by positivity)) |> fun h => h.trans_isBigO ?_ + exact Asymptotics.isBigO_iff.mpr ⟨(k : ℝ) ⁻¹, Filter.eventually_atTop.mpr ⟨1, fun x hx => by simp +decide ; ring_nf; norm_num [show k ≠ 0 by linarith]⟩⟩ + · have := h_M.comp_tendsto (show Filter.Tendsto (fun x : ℝ => x / (k + 1)) Filter.atTop Filter.atTop from Filter.tendsto_id.atTop_div_const (by positivity)) + rw [Asymptotics.isLittleO_iff] at * + intro c hc; filter_upwards [this (show 0 < c * (k + 1) by positivity), Filter.eventually_gt_atTop 0] with x hx₁ hx₂; simp_all +decide only [ge_iff_le, norm_eq_abs, eventually_atTop, Function.comp_apply, norm_div, cast_nonneg, + zero_le_one, add_nonneg, abs_of_nonneg] + exact hx₁.trans (by rw [mul_assoc, mul_div_cancel₀ _ (by positivity)]) + have h_sum_o_x : (fun x : ℝ => ∑ k ∈ Finset.Ico 1 K, (k : ℝ) * (∑ n ∈ Finset.Ioc ⌊x / (k + 1 : ℝ)⌋₊ ⌊x / (k : ℝ)⌋₊, (μ n : ℝ))) =o[atTop] (fun x => x) := by + rw [Asymptotics.isLittleO_iff_tendsto'] + · have h_sum_little_o : ∀ k ∈ Finset.Ico 1 K, Filter.Tendsto (fun x : ℝ => (∑ n ∈ Finset.Ioc ⌊x / (k + 1 : ℝ)⌋₊ ⌊x / (k : ℝ)⌋₊, (μ n : ℝ)) / x) Filter.atTop (nhds 0) := by + intro k hk; specialize h_M_x_over_k k (Finset.mem_Ico.mp hk |>.1) (Finset.mem_Ico.mp hk |>.2) ; rw [Asymptotics.isLittleO_iff_tendsto'] at h_M_x_over_k <;> aesop + simpa [Finset.sum_div _ _ _, mul_div_assoc] using tendsto_finsetSum _ fun k hk => h_sum_little_o k hk |> Filter.Tendsto.const_mul _ + · filter_upwards [Filter.eventually_gt_atTop 0] with x hx hx' using absurd hx' hx.ne' + exact h_sum_o_x.congr' + (by filter_upwards [Filter.eventually_ge_atTop 1] with x hx using by rw [h_group x hx]) + (by norm_num) + +lemma sum_mobius_div_approx (x : ℝ) (K : ℕ) (hK : 0 < K) (hx : 1 ≤ x) : + |x * (∑ n ∈ Icc 1 ⌊x/K⌋₊, (μ n : ℝ) / n) - 1| ≤ x/K + |∑ n ∈ Ioc ⌊x/K⌋₊ ⌊x⌋₊, (μ n : ℝ) * (⌊x / (n : ℝ)⌋ : ℝ)| := by + have h_split : ∑ n ∈ Finset.Icc 1 ⌊x⌋₊, (μ n : ℝ) * ⌊x / (n : ℝ)⌋ = (∑ n ∈ Finset.Icc 1 ⌊x / (K : ℝ)⌋₊, (μ n : ℝ) * ⌊x / (n : ℝ)⌋) + (∑ n ∈ Finset.Ioc ⌊x / (K : ℝ)⌋₊ ⌊x⌋₊, (μ n : ℝ) * ⌊x / (n : ℝ)⌋) := by + erw [Finset.sum_Ioc_consecutive] <;> norm_num + · rfl + · exact Nat.floor_mono <| div_le_self (by positivity) <| mod_cast hK + have h_floor : ∑ n ∈ Finset.Icc 1 ⌊x / (K : ℝ)⌋₊, (μ n : ℝ) * ⌊x / (n : ℝ)⌋ = x * ∑ n ∈ Finset.Icc 1 ⌊x / (K : ℝ)⌋₊, (μ n : ℝ) / (n : ℝ) - ∑ n ∈ Finset.Icc 1 ⌊x / (K : ℝ)⌋₊, (μ n : ℝ) * (x / (n : ℝ) - ⌊x / (n : ℝ)⌋) := by + rw [Finset.mul_sum _ _ _] ; rw [← Finset.sum_sub_distrib] ; exact Finset.sum_congr rfl fun _ _ => by ring + have h_bound : |∑ n ∈ Finset.Icc 1 ⌊x / (K : ℝ)⌋₊, (μ n : ℝ) * (x / (n : ℝ) - ⌊x / (n : ℝ)⌋)| ≤ ⌊x / (K : ℝ)⌋₊ := by + have h_bound : ∀ n ∈ Finset.Icc 1 ⌊x / (K : ℝ)⌋₊, |(μ n : ℝ) * (x / (n : ℝ) - ⌊x / (n : ℝ)⌋)| ≤ 1 := by + norm_num [abs_mul] + exact fun n hn₁ hn₂ => + (mul_le_of_le_one_left (abs_nonneg _) + (mod_cast by exact abs_moebius_le_one)).trans + (abs_le.mpr ⟨by linarith [Int.fract_nonneg (x / n)], + by linarith [Int.fract_lt_one (x / n)]⟩) + exact le_trans (Finset.abs_sum_le_sum_abs _ _) (le_trans (Finset.sum_le_sum h_bound) (by norm_num)) + have h_sum_floor : ∑ n ∈ Finset.Icc 1 ⌊x⌋₊, (μ n : ℝ) * ⌊x / (n : ℝ)⌋ = 1 := by + convert sum_mobius_floor x hx using 1 + cases abs_cases (x * ∑ n ∈ Finset.Icc 1 ⌊x / (K : ℝ) ⌋₊, (μ n : ℝ) / n - 1) <;> cases abs_cases (∑ n ∈ Finset.Ioc ⌊x / (K : ℝ) ⌋₊ ⌊x⌋₊, (μ n : ℝ) * ⌊x / (n : ℝ) ⌋) <;> linarith [abs_le.mp h_bound, Nat.floor_le (show 0 ≤ x / (K : ℝ) by positivity), Nat.lt_floor_add_one (x / (K : ℝ))] + +theorem mu_pnt_alt : (fun x : ℝ ↦ ∑ n ∈ range ⌊x⌋₊, (μ n : ℝ) / n) =o[atTop] fun _ ↦ (1 : ℝ) := by + rw [Asymptotics.isLittleO_iff_tendsto'] <;> norm_num + have h_sum_zero : Filter.Tendsto (fun x : ℝ => ∑ n ∈ Finset.Icc 1 ⌊x⌋₊, (μ n : ℝ) / n) Filter.atTop (nhds 0) := by + set S : ℝ → ℝ := fun y => ∑ n ∈ Finset.Icc 1 ⌊y⌋₊, (μ n : ℝ) / n + have h_bound : ∀ K : ℕ, 0 < K → ∀ x : ℝ, 1 ≤ x → |S (x / K)| ≤ 1 / K + 1 / x + |∑ n ∈ Finset.Ioc ⌊x / K⌋₊ ⌊x⌋₊, (μ n : ℝ) * (⌊x / (n : ℝ)⌋ : ℝ)| / x := by + intros K hK x hx + have h_approx : |x * S (x / K) - 1| ≤ x / K + |∑ n ∈ Finset.Ioc ⌊x / K⌋₊ ⌊x⌋₊, (μ n : ℝ) * (⌊x / (n : ℝ)⌋ : ℝ)| := by + convert sum_mobius_div_approx x K hK hx using 1 + rw [abs_le] at * + ring_nf at * + constructor <;> nlinarith [inv_pos.2 (by positivity : 0 < x), mul_inv_cancel₀ (by positivity : x ≠ 0), abs_nonneg (∑ n ∈ Finset.Ioc ⌊ (K : ℝ) ⁻¹ * x⌋₊ ⌊x⌋₊, (μ n : ℝ) * ⌊x * (n : ℝ) ⁻¹⌋)] + have h_tail_zero : ∀ K : ℕ, 0 < K → Filter.Tendsto (fun x : ℝ => |∑ n ∈ Finset.Ioc ⌊x / K⌋₊ ⌊x⌋₊, (μ n : ℝ) * (⌊x / (n : ℝ)⌋ : ℝ)| / x) Filter.atTop (nhds 0) := by + intro K hK + have h_tail_zero : Filter.Tendsto (fun x : ℝ => |∑ n ∈ Finset.Ioc ⌊x / K⌋₊ ⌊x⌋₊, (μ n : ℝ) * (⌊x / (n : ℝ)⌋ : ℝ)| / x) Filter.atTop (nhds 0) := by + have := sum_mobius_floor_tail_isLittleO K hK + rw [Asymptotics.isLittleO_iff_tendsto'] at this + · simpa [abs_div] using this.abs.congr' (by filter_upwards [Filter.eventually_gt_atTop 0] with x hx using by rw [abs_div, abs_of_nonneg hx.le]) + · filter_upwards [Filter.eventually_gt_atTop 0] with x hx hx' using absurd hx' hx.ne' + convert h_tail_zero using 1 + have h_eps : ∀ ϵ > 0, ∃ Y : ℝ, ∀ y ≥ Y, |S y| < ϵ := by + intros ϵ hϵ_pos + obtain ⟨K, hK_pos, hK⟩ : ∃ K : ℕ, 0 < K ∧ 1 / (K : ℝ) < ϵ / 3 := by + exact ⟨⌊ϵ⁻¹ * 3⌋₊ + 1, Nat.succ_pos _, by rw [div_lt_iff₀] <;> push_cast <;> nlinarith [Nat.lt_floor_add_one (ϵ⁻¹ * 3), mul_inv_cancel₀ hϵ_pos.ne']⟩ + obtain ⟨Y, hY⟩ : ∃ Y : ℝ, ∀ x ≥ Y, |S (x / K)| < ϵ := by + have h_tail_zero : Filter.Tendsto (fun x : ℝ => 1 / (K : ℝ) + 1 / x + |∑ n ∈ Finset.Ioc ⌊x / K⌋₊ ⌊x⌋₊, (μ n : ℝ) * (⌊x / (n : ℝ)⌋ : ℝ)| / x) Filter.atTop (nhds (1 / (K : ℝ))) := by + simpa using Filter.Tendsto.add (tendsto_const_nhds.add (tendsto_inv_atTop_zero)) (h_tail_zero K hK_pos) + exact Filter.eventually_atTop.mp (h_tail_zero.eventually (gt_mem_nhds <| by linarith)) |> fun ⟨Y, hY⟩ ↦ ⟨Max.max Y 1, fun x hx ↦ lt_of_le_of_lt (h_bound K hK_pos x <| le_trans (le_max_right _ _) hx) <| hY x <| le_trans (le_max_left _ _) hx⟩ + use Y / K; intros y hy; specialize hY (y * K) (by nlinarith [show (K : ℝ) ≥ 1 by norm_cast, div_mul_cancel₀ Y (by positivity : (K : ℝ) ≠ 0)]) ; simp_all +decide [ne_of_gt] + exact Metric.tendsto_atTop.mpr fun ε hε => by simpa using h_eps ε hε + have h_sum_zero : Filter.Tendsto (fun x : ℝ => ∑ n ∈ Finset.range (⌊x⌋₊ + 1), (μ n : ℝ) / n) Filter.atTop (nhds 0) := by + convert h_sum_zero using 2 ; erw [Finset.sum_Ico_eq_sub _ _] <;> norm_num [Finset.sum_range_succ'] + simpa [Finset.sum_range_succ] using h_sum_zero.sub (show Filter.Tendsto (fun x : ℝ => (μ ⌊x⌋₊ : ℝ) / ⌊x⌋₊) Filter.atTop (nhds 0) from tendsto_zero_iff_norm_tendsto_zero.mpr <| squeeze_zero (fun _ => by positivity) (fun x => by simpa using div_le_div_of_nonneg_right (show |(μ ⌊x⌋₊ : ℝ)| ≤ 1 from mod_cast by { unfold ArithmeticFunction.moebius; aesop }) <| Nat.cast_nonneg _) <| tendsto_inv_atTop_zero.comp <| tendsto_natCast_atTop_atTop.comp <| tendsto_nat_floor_atTop) + +theorem chebyshev_asymptotic_pnt + {q : ℕ} {a : ℕ} (hq : q ≥ 1) (ha : a.Coprime q) (ha' : a < q) : + (fun x ↦ ∑ p ∈ filter Nat.Prime (Iic ⌊x⌋₊), if p % q = a then log p else 0) ~[atTop] + fun x ↦ x / q.totient := by + let ψ_aq : ℝ → ℝ := fun x ↦ ∑ n ∈ Icc 1 ⌊x⌋₊, if n % q = a then Λ n else 0 + have htot_pos : (0 : ℝ) < q.totient := cast_pos.mpr (totient_pos.mpr hq) + have hψ_equiv : ψ_aq ~[atTop] fun x ↦ x / q.totient := by + have hW := WeakPNT_AP hq ha ha' + simp only [cumsum, ← Iio_eq_range] at hW + have hψ_eq x : ψ_aq x = ∑ n ∈ Iio (⌊x⌋₊ + 1), if n % q = a then Λ n else 0 := by + simp only [ψ_aq, show Icc 1 ⌊x⌋₊ = (Iio (⌊x⌋₊ + 1)).filter (1 ≤ ·) by + ext n; simp [mem_Icc, mem_filter]; tauto, sum_filter] + refine sum_congr rfl fun n _ ↦ ?_ + by_cases hn : 1 ≤ n <;> simp only [hn, ↓reduceIte] + push Not at hn; interval_cases n; simp + refine (isEquivalent_iff_tendsto_one ?_).mpr ?_ + · filter_upwards [eventually_ge_atTop 1] with x hx; exact div_ne_zero (by linarith) htot_pos.ne' + have hlim1 : Tendsto (fun x : ℝ ↦ (∑ n ∈ Iio (⌊x⌋₊ + 1), if n % q = a then Λ n else 0) / + (⌊x⌋₊ + 1 : ℝ)) atTop (nhds (1 / q.totient)) := by + have heq : (fun x : ℝ ↦ (∑ n ∈ Iio (⌊x⌋₊ + 1), if n % q = a then Λ n else 0) / + (⌊x⌋₊ + 1 : ℝ)) = (fun N ↦ (∑ n ∈ Iio N, if n % q = a then Λ n else 0) / N) ∘ + (fun x : ℝ ↦ ⌊x⌋₊ + 1) := by ext x; simp [Function.comp_apply] + exact heq ▸ hW.comp ((tendsto_add_atTop_nat 1).comp tendsto_nat_floor_atTop) + have hgoal_eq : (ψ_aq / fun x ↦ x / (q.totient : ℝ)) = + fun x ↦ ψ_aq x / x * q.totient := by ext x; simp only [Pi.div_apply, div_div_eq_mul_div]; ring + rw [hgoal_eq, show (1 : ℝ) = 1 / q.totient * 1 * q.totient by field_simp] + refine Tendsto.mul ?_ tendsto_const_nhds + have heq' : (fun x ↦ ψ_aq x / x) =ᶠ[atTop] + fun x ↦ (∑ n ∈ Iio (⌊x⌋₊ + 1), if n % q = a then Λ n else 0) / (⌊x⌋₊ + 1 : ℝ) * ((⌊x⌋₊ + 1 : ℝ) / x) := by + filter_upwards [eventually_gt_atTop 0] with x hx + simp only [hψ_eq]; field_simp + exact Tendsto.congr' heq'.symm (hlim1.mul tendsto_floor_add_one_div_self) + refine Asymptotics.IsEquivalent.add_isLittleO'' hψ_equiv + (IsBigO.trans_isLittleO (g := fun x ↦ 2 * x.sqrt * x.log) ?_ ?_) + · rw [isBigO_iff']; refine ⟨1, one_pos, eventually_atTop.mpr ⟨2, fun x hx ↦ ?_⟩⟩ + simp only [Pi.sub_apply, norm_eq_abs, one_mul] + have hdiff_nonneg : 0 ≤ ψ_aq x - ∑ p ∈ filter Nat.Prime (Iic ⌊x⌋₊), if p % q = a then log p else 0 := by + simp only [ψ_aq, sub_nonneg] + calc (∑ p ∈ filter Nat.Prime (Iic ⌊x⌋₊), if p % q = a then log p else (0 : ℝ)) + ≤ ∑ p ∈ filter Nat.Prime (Iic ⌊x⌋₊), if p % q = a then Λ p else (0 : ℝ) := + sum_le_sum fun p hp ↦ by split_ifs <;> simp [vonMangoldt_apply_prime (mem_filter.mp hp).2] + _ ≤ ∑ n ∈ Icc 1 ⌊x⌋₊, if n % q = a then Λ n else (0 : ℝ) := + sum_le_sum_of_subset_of_nonneg + (fun p hp ↦ by simp only [mem_filter, mem_Iic, mem_Icc] at hp ⊢; exact ⟨hp.2.one_lt.le, hp.1⟩) + (fun n _ _ ↦ by split_ifs <;> [exact vonMangoldt_nonneg; rfl]) + have hdiff_le : ψ_aq x - (∑ p ∈ filter Nat.Prime (Iic ⌊x⌋₊), if p % q = a then log p else (0 : ℝ)) ≤ ψ x - θ x := by + simp only [ψ_aq, Chebyshev.psi_eq_sum_Icc, Chebyshev.theta_eq_sum_Icc] + conv_rhs => rw [Icc_zero_eq_insert, sum_insert (by simp : (0 : ℕ) ∉ Icc 1 ⌊x⌋₊), + show Λ 0 = 0 by simp only [ArithmeticFunction.map_zero], zero_add, + show filter Nat.Prime (insert 0 (Icc 1 ⌊x⌋₊)) = filter Nat.Prime (Icc 1 ⌊x⌋₊) by + simp [filter_insert, Nat.not_prime_zero]] + rw [filter_prime_Iic_eq_Icc, ← sum_filter_add_sum_filter_not (Icc 1 ⌊x⌋₊) Nat.Prime, + show (∑ p ∈ filter Nat.Prime (Icc 1 ⌊x⌋₊), if p % q = a then log p else (0 : ℝ)) = + ∑ p ∈ filter Nat.Prime (Icc 1 ⌊x⌋₊), if p % q = a then Λ p else (0 : ℝ) from + sum_congr rfl fun p hp ↦ by simp only [mem_filter] at hp; split_ifs <;> simp [vonMangoldt_apply_prime hp.2], + ← sum_filter_add_sum_filter_not (Icc 1 ⌊x⌋₊) Nat.Prime, + show (∑ p ∈ filter Nat.Prime (Icc 1 ⌊x⌋₊), Λ p) = ∑ p ∈ filter Nat.Prime (Icc 1 ⌊x⌋₊), log p from + sum_congr rfl fun p hp ↦ vonMangoldt_apply_prime (mem_filter.mp hp).2] + have h1 : (∑ n ∈ (Icc 1 ⌊x⌋₊).filter (¬Nat.Prime ·), if n % q = a then Λ n else (0 : ℝ)) ≤ + ∑ n ∈ (Icc 1 ⌊x⌋₊).filter (¬Nat.Prime ·), Λ n := + sum_le_sum fun n _ ↦ by split_ifs <;> [exact le_refl _; exact vonMangoldt_nonneg] + linarith + rw [abs_of_nonneg hdiff_nonneg, abs_of_nonneg (by bound)] + exact hdiff_le.trans ((le_abs_self _).trans (Chebyshev.abs_psi_sub_theta_le_sqrt_mul_log (by linarith))) + · simpa only [mul_assoc] using + (isLittleO_sqrt_mul_log.const_mul_left 2).trans_isTheta (isTheta_self_div_const htot_pos.ne') + +theorem dirichlet_thm {q : ℕ} {a : ℕ} (hq : q ≥ 1) (ha : Nat.Coprime a q) (ha' : a < q) : + Infinite { p // p.Prime ∧ p % q = a } := by + have : {p | p.Prime ∧ p % q = a}.Infinite := by + have : {p | p.Prime ∧ p ≡ a [MOD q]}.Infinite := by + have := @infinite_setOfPred_prime_and_eq_mod + specialize @this q <| NeZero.of_pos hq + simp_all only [isUnit_iff_exists_inv, forall_exists_index, ← ZMod.natCast_eq_natCast_iff] + exact this (IsUnit.exists_right_inv (show IsUnit (a : ZMod q) from by + rwa [ZMod.isUnit_iff_coprime])).choose (IsUnit.exists_right_inv (show IsUnit (a : ZMod q) + from by rwa [ZMod.isUnit_iff_coprime])).choose_spec + exact this.mono fun p hp ↦ ⟨hp.1, by simpa [ModEq, mod_eq_of_lt ha'] using hp.2⟩ + exact Set.infinite_coe_iff.mpr this + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Defs.lean b/PrimeNumberTheoremAnd/Erdos970/Defs.lean new file mode 100644 index 0000000..e595955 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Defs.lean @@ -0,0 +1,201 @@ +import PrimeNumberTheoremAnd.Erdos970.Fourier +import Mathlib.NumberTheory.Chebyshev + +namespace Erdos970 + +open ArithmeticFunction hiding log +open Nat hiding log +open Finset Topology +open BigOperators Filter Real Classical Asymptotics +open MeasureTheory intervalIntegral +open scoped ArithmeticFunction.Moebius +open scoped ArithmeticFunction.Omega Chebyshev + +noncomputable abbrev nth_prime (n : ℕ) : ℕ := + Nat.nth Nat.Prime n + +noncomputable abbrev nth_prime' (n : ℕ) : ℕ := + Nat.nth Nat.Prime (n - 1) + +noncomputable abbrev Psi (x : ℝ) : ℝ := ψ x + +noncomputable def M (x : ℝ) : ℝ := + ∑ n ∈ Iic ⌊x⌋₊, (μ n : ℝ) + +noncomputable abbrev nth_prime_gap (n : ℕ) : ℕ := + nth_prime (n + 1) - nth_prime n + +def prime_gap_record (p g : ℕ) : Prop := + ∃ n, nth_prime n = p ∧ nth_prime_gap n = g ∧ + ∀ k, nth_prime k < p → nth_prime_gap k < g + +open Classical in + +noncomputable def first_gap (g : ℕ) : ℕ := + if h : ∃ n, nth_prime_gap n = g then + nth_prime (Nat.find h) + else 0 + +def first_gap_record (g P : ℕ) : Prop := + first_gap g = P ∧ + ∀ g' ∈ Finset.Ico 1 g, + Even g' ∨ g' = 1 → first_gap g' ∈ Set.Ico 1 P + +def HasPrimeInInterval (x h : ℝ) : Prop := + ∃ p : ℕ, Nat.Prime p ∧ x < p ∧ p ≤ x + h + +def HasPrimeInInterval.log_thm (X₀ : ℝ) (k : ℝ) := + ∀ x ≥ X₀, HasPrimeInInterval x (x / (log x) ^ k) + +noncomputable def pi (x : ℝ) : ℝ := + Nat.primeCounting ⌊x⌋₊ + +noncomputable def pi_star (x : ℝ) : ℝ := + ∑' (k : ℕ), pi (x ^ (1 / (k + 1 : ℝ))) / (k + 1 : ℝ) + +noncomputable def li (x : ℝ) : ℝ := + lim ((𝓝[>] (0 : ℝ)).map (fun ε ↦ + ∫ t in Set.diff (Set.Ioc 0 x) (Set.Ioo (1 - ε) (1 + ε)), + 1 / log t)) + +noncomputable def Li (x : ℝ) : ℝ := ∫ t in 2..x, 1 / log t + +noncomputable def Eψ (x : ℝ) : ℝ := |ψ x - x| / x + +noncomputable def admissible_bound (A B C R : ℝ) (x : ℝ) := + A * (log x / R) ^ B * exp (-C * (log x / R) ^ ((1 : ℝ) / (2 : ℝ))) + +def Eψ.classicalBound (A B C R x₀ : ℝ) : Prop := + ∀ x ≥ x₀, Eψ x ≤ admissible_bound A B C R x + +def Eψ.bound (ε x₀ : ℝ) : Prop := ∀ x ≥ x₀, Eψ x ≤ ε + +def Eψ.numericalBound (x₀ : ℝ) (ε : ℝ → ℝ) : Prop := + Eψ.bound (ε x₀) x₀ + +noncomputable def Eπ (x : ℝ) : ℝ := + |pi x - Li x| / (x / log x) + +noncomputable def Eπ_star (x : ℝ) : ℝ := + |pi_star x - Li x| / (x / log x) + +noncomputable def Eθ (x : ℝ) : ℝ := |θ x - x| / x + +def Eθ.classicalBound (A B C R x₀ : ℝ) : Prop := + ∀ x ≥ x₀, Eθ x ≤ admissible_bound A B C R x + +def Eθ.numericalBound (x₀ : ℝ) (ε : ℝ → ℝ) : Prop := + ∀ x ≥ x₀, Eθ x ≤ ε x₀ + +def Eπ.classicalBound (A B C R x₀ : ℝ) : Prop := + ∀ x ≥ x₀, Eπ x ≤ admissible_bound A B C R x + +def Eπ.bound (ε x₀ : ℝ) : Prop := ∀ x ≥ x₀, Eπ x ≤ ε + +def Eπ.numericalBound (x₀ : ℝ) (ε : ℝ → ℝ) : Prop := + Eπ.bound (ε x₀) x₀ + +def Eπ.vinogradovBound (A B C x₀ : ℝ) : Prop := + ∀ x ≥ x₀, Eπ x ≤ + A * (log x) ^ B * exp (-C * (log x) ^ ((3 : ℝ) / 5) / (log (log x)) ^ ((1 : ℝ) / 5)) + +def Eπ_star.classicalBound (A B C R x₀ : ℝ) : Prop := + ∀ x ≥ x₀, Eπ_star x ≤ admissible_bound A B C R x + +def Eπ_star.bound (ε x₀ : ℝ) : Prop := + ∀ x ≥ x₀, Eπ_star x ≤ ε + +def Eπ_star.numericalBound (x₀ : ℝ) (ε : ℝ → ℝ) : Prop := + Eπ_star.bound (ε x₀) x₀ + +def Eπ_star.vinogradovBound (A B C x₀ : ℝ) : Prop := + ∀ x ≥ x₀, Eπ_star x ≤ + A * (log x) ^ B * exp (-C * (log x) ^ ((3 : ℝ) / 5) / (log (log x)) ^ ((1 : ℝ) / 5)) + +lemma admissible_bound.mono + (A B C R : ℝ) (hA : 0 < A) (hB : 0 < B) + (hC : 0 < C) (hR : 0 < R) : + AntitoneOn (admissible_bound A B C R) + (Set.Ici (exp (R * (2 * B / C) ^ 2))) := by + intro a ha b _ hab + simp only [admissible_bound, mul_assoc] + have hua : (2 * B / C) ^ 2 ≤ log a / R := by + rw [le_div_iff₀ hR, mul_comm ((2 * B / C) ^ 2), ← log_exp (R * (2 * B / C) ^ 2)] + exact log_le_log (exp_pos _) (Set.mem_Ici.mp ha) + have huab : log a / R ≤ log b / R := + div_le_div_of_nonneg_right + (log_le_log ((exp_pos _).trans_le (Set.mem_Ici.mp ha)) hab) hR.le + have hua₀ : 0 < log a / R := + lt_of_lt_of_le (by positivity) hua + apply mul_le_mul_of_nonneg_left _ hA.le + rw [rpow_def_of_pos (hua₀.trans_le huab), rpow_def_of_pos hua₀, + ← exp_add, ← exp_add, exp_le_exp] + let sa := (log a / R) ^ ((1 : ℝ) / 2) + let sb := (log b / R) ^ ((1 : ℝ) / 2) + rw [show log (log b / R) = 2 * log sb from by + grind [log_rpow (hua₀.trans_le huab) ((1 : ℝ) / 2)], + show log (log a / R) = 2 * log sa from by + grind [log_rpow hua₀ ((1 : ℝ) / 2)]] + have hsab : sa ≤ sb := + rpow_le_rpow (le_trans (by positivity) hua) huab (by positivity) + have : 2 * B / C ≤ sa := by + rw [show (2 * B / C : ℝ) = ((2 * B / C) ^ 2) ^ ((1 : ℝ) / 2) from by + rw [← rpow_natCast _ 2, ← rpow_mul (by positivity)] + norm_num [rpow_one]] + exact rpow_le_rpow (by positivity) hua (by positivity) + suffices h : AntitoneOn (fun t ↦ 2 * B * log t - C * t) (Set.Ici (2 * B / C)) by + grind [h (Set.mem_Ici.mpr this) (Set.mem_Ici.mpr (this.trans hsab)) hsab] + apply antitoneOn_of_deriv_nonpos (convex_Ici _) + · exact ((continuousOn_const.mul (continuousOn_log.mono fun t ht ↦ + ne_of_gt ((div_pos (by positivity) hC).trans_le ht))).sub + (continuousOn_const.mul continuousOn_id)) + · intro t ht + rw [interior_Ici] at ht + exact (((hasDerivAt_log ((div_pos (by positivity) hC).trans ht).ne').const_mul _).sub + ((hasDerivAt_id t).const_mul C)).differentiableAt.differentiableWithinAt + · intro t ht + rw [interior_Ici] at ht + have hdt : HasDerivAt (fun t ↦ 2 * B * log t - C * t) (2 * B * t⁻¹ - C * 1) t := + ((hasDerivAt_log ((div_pos (by positivity) hC).trans ht).ne').const_mul _).sub + ((hasDerivAt_id t).const_mul C) + rw [hdt.deriv, mul_one, sub_nonpos, ← div_eq_mul_inv, + div_le_iff₀ ((div_pos (by positivity) hC).trans ht)] + linarith [(div_lt_iff₀ hC).mp ht, mul_comm C t] + +lemma Eψ.classicalBound.to_numericalBound + (A B C R x₀ x₁ : ℝ) (hA : 0 < A) (hB : 0 < B) + (hC : 0 < C) (hR : 0 < R) + (hEψ : Eψ.classicalBound A B C R x₀) + (hx₁ : x₁ ≥ max x₀ (Real.exp (R * (2 * B / C) ^ 2))) : + Eψ.numericalBound x₁ (fun x ↦ admissible_bound A B C R x) := + fun x hx ↦ + le_trans (hEψ x (le_trans (le_max_left ..) (le_trans hx₁ hx))) + (admissible_bound.mono A B C R hA hB hC hR + (Set.mem_Ici.mpr (le_trans (le_max_right ..) hx₁)) + (Set.mem_Ici.mpr (le_trans (le_max_right ..) (le_trans hx₁ hx))) hx) + +lemma Eθ.classicalBound.to_numericalBound + (A B C R x₀ x₁ : ℝ) (hA : 0 < A) (hB : 0 < B) + (hC : 0 < C) (hR : 0 < R) + (hEθ : Eθ.classicalBound A B C R x₀) + (hx₁ : x₁ ≥ max x₀ (Real.exp (R * (2 * B / C) ^ 2))) : + Eθ.numericalBound x₁ (fun x ↦ admissible_bound A B C R x) := + fun x hx ↦ + le_trans (hEθ x (le_trans (le_max_left ..) (le_trans hx₁ hx))) + (admissible_bound.mono A B C R hA hB hC hR + (Set.mem_Ici.mpr (le_trans (le_max_right ..) hx₁)) + (Set.mem_Ici.mpr (le_trans (le_max_right ..) (le_trans hx₁ hx))) hx) + +lemma Eπ.classicalBound.to_numericalBound + (A B C R x₀ x₁ : ℝ) (hA : 0 < A) (hB : 0 < B) + (hC : 0 < C) (hR : 0 < R) + (hEπ : Eπ.classicalBound A B C R x₀) + (hx₁ : x₁ ≥ max x₀ (Real.exp (R * (2 * B / C) ^ 2))) : + Eπ.numericalBound x₁ (fun x ↦ admissible_bound A B C R x) := + fun x hx ↦ + le_trans (hEπ x (le_trans (le_max_left ..) (le_trans hx₁ hx))) + (admissible_bound.mono A B C R hA hB hC hR + (Set.mem_Ici.mpr (le_trans (le_max_right ..) hx₁)) + (Set.mem_Ici.mpr (le_trans (le_max_right ..) (le_trans hx₁ hx))) hx) + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/EulerMaclaurin.lean b/PrimeNumberTheoremAnd/Erdos970/EulerMaclaurin.lean new file mode 100644 index 0000000..ecfb419 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/EulerMaclaurin.lean @@ -0,0 +1,75 @@ +import Mathlib.NumberTheory.AbelSummation + +namespace Erdos970 + +open Finset Interval MeasureTheory + +variable {𝕜 : Type*} [RCLike 𝕜] {f : ℝ → 𝕜} {a b : ℝ} + +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 Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Fourier.lean b/PrimeNumberTheoremAnd/Erdos970/Fourier.lean new file mode 100644 index 0000000..32fe27c --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Fourier.lean @@ -0,0 +1,181 @@ +import Mathlib.Analysis.Distribution.SchwartzSpace.Deriv +import Mathlib.MeasureTheory.Integral.IntegralEqImproper +import Mathlib.Topology.ContinuousMap.Bounded.Basic +import Mathlib.Order.Filter.ZeroAndBoundedAtFilter +import Mathlib.Analysis.Fourier.FourierTransformDeriv +import PrimeNumberTheoremAnd.Erdos970.Sobolev + +namespace Erdos970 + +open FourierTransform Real Complex MeasureTheory Filter Topology BoundedContinuousFunction + SchwartzMap VectorFourier BigOperators + +local instance {E : Type*} : Coe (E → ℝ) (E → ℂ) := ⟨fun f n => f n⟩ + +section lemmas + +@[simp] +theorem nnnorm_eq_of_mem_circle (z : Circle) : ‖z.val‖₊ = 1 := NNReal.coe_eq_one.mp (by simp) + +@[simp] +theorem nnnorm_circle_smul (z : Circle) (s : ℂ) : ‖z • s‖₊ = ‖s‖₊ := by + simp [show z • s = z.val * s from rfl] + +noncomputable def e (u : ℝ) : ℝ →ᵇ ℂ where + toFun v := 𝐞 (-v * u) + map_bounded' := + ⟨2, fun x y => (dist_le_norm_add_norm _ _).trans (by simp [one_add_one_eq_two])⟩ + +@[simp] lemma e_apply (u : ℝ) (v : ℝ) : e u v = 𝐞 (-v * u) := rfl + +theorem hasDerivAt_e {u x : ℝ} : HasDerivAt (e u) (-2 * π * u * I * e u x) x := by + have l2 : HasDerivAt (fun v => -v * u) (-u) x := by + simpa only [neg_mul_comm] using hasDerivAt_mul_const (-u) + convert! (hasDerivAt_fourierChar (-x * u)).scomp x l2 using 1 + change _ = ((-u : ℝ) : ℂ) * _ + simp ; ring + +lemma fourierIntegral_deriv_aux2 (e : ℝ →ᵇ ℂ) {f : ℝ → ℂ} (hf : Integrable f) : + Integrable (⇑e * f) := + hf.bdd_mul e.continuous.aestronglyMeasurable (ae_of_all _ e.norm_coe_le_norm) + +@[simp] lemma F_neg {f : ℝ → ℂ} {u : ℝ} : 𝓕 (fun x => -f x) u = - 𝓕 f u := by + simp [fourier_eq, integral_neg] + +@[simp] lemma F_add {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) (x : ℝ) : + 𝓕 (fun x => f x + g x) x = 𝓕 f x + 𝓕 g x := by + have : Continuous fun p : ℝ × ℝ ↦ ((innerₗ ℝ) p.1) p.2 := continuous_inner + have := fourierIntegral_add continuous_fourierChar this hf hg + exact congr_fun this x + +@[simp] lemma F_sub {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) (x : ℝ) : + 𝓕 (fun x => f x - g x) x = 𝓕 f x - 𝓕 g x := by + simpa [sub_eq_add_neg, Pi.neg_def] using F_add hf hg.neg x + +@[simp] lemma F_mul {f : ℝ → ℂ} {c : ℂ} {u : ℝ} : + 𝓕 (fun x => c * f x) u = c * 𝓕 f u := by + exact congr_fun (VectorFourier.fourierIntegral_const_smul 𝐞 _ _ f c) u + +end lemmas + +theorem fourierIntegral_self_add_deriv_deriv (f : W21) (u : ℝ) : + (1 + u ^ 2) * 𝓕 (f : ℝ → ℂ) u = + 𝓕 (fun u : ℝ => (f u - (1 / (4 * π ^ 2)) * deriv^[2] f u : ℂ)) u := by + have l1 : Integrable (fun x => (((π : ℂ) ^ 2)⁻¹ * 4⁻¹) * deriv (deriv f) x) := by + apply Integrable.const_mul ; simpa [iteratedDeriv_succ] using f.integrable le_rfl + have l4 : Differentiable ℝ f := f.differentiable + have l5 : Differentiable ℝ (deriv f) := f.deriv.differentiable + simp [f.hf, l1, add_mul, Real.fourier_deriv f.hf' l5 f.hf'', Real.fourier_deriv f.hf l4 f.hf'] + field_simp [pi_ne_zero] ; ring_nf ; simp + +@[simp] lemma deriv_ofReal : deriv ofReal = fun _ => 1 := by + ext x ; exact ((hasDerivAt_id x).ofReal_comp).deriv + +lemma tendsto_intervalIntegral_zero_of_uniform_norm_bound + {f : ℝ → ℝ → ℂ} {lo hi : ℝ} {B : ℝ → ℝ} + (hB : Filter.Tendsto (fun T : ℝ => B T * |hi - lo|) Filter.atTop (nhds 0)) + (hf : ∀ᶠ T in Filter.atTop, ∀ x ∈ Set.uIoc lo hi, ‖f T x‖ ≤ B T) : + Filter.Tendsto (fun T : ℝ => ∫ x in lo..hi, f T x) Filter.atTop (nhds 0) := by + rw [tendsto_zero_iff_norm_tendsto_zero] + refine squeeze_zero' (Eventually.of_forall fun T => norm_nonneg _) ?_ hB + filter_upwards [hf] with T hT + exact intervalIntegral.norm_integral_le_of_norm_le_const (fun x hx => hT x hx) + +lemma tendsto_const_mul_log_add_two_div_add_two_atTop (K : ℝ) : + Filter.Tendsto (fun T : ℝ => K * (Real.log (T + 2) / (T + 2))) + Filter.atTop (nhds 0) := by + have h0 : Filter.Tendsto (fun x : ℝ => Real.log x / x) Filter.atTop (nhds 0) := by + simpa using (Real.tendsto_pow_log_div_mul_add_atTop 1 0 1 (by norm_num : (1 : ℝ) ≠ 0)) + have hshift : Filter.Tendsto (fun T : ℝ => Real.log (T + 2) / (T + 2)) + Filter.atTop (nhds 0) := by + have := h0.comp (tendsto_atTop_add_const_right Filter.atTop 2 tendsto_id) + simpa [Function.comp_def] using this + simpa using hshift.const_mul K + +lemma norm_fourier_le_integral_deriv_div + (g : ℝ → ℂ) (hg : Integrable g) (hdiff : Differentiable ℝ g) + (hg' : Integrable (deriv g)) {w : ℝ} (hw : w ≠ 0) : + ‖𝓕 g w‖ ≤ (∫ x, ‖deriv g x‖ ∂volume) / ((2 * Real.pi) * |w|) := by + have hmul : + 𝓕 (deriv g) w = (2 * Real.pi * Complex.I * (w : ℂ)) * 𝓕 g w := by + have h := congrFun (Real.fourier_deriv hg hdiff hg') w + simpa [smul_eq_mul, mul_assoc] using h + have h_fourier : + ‖𝓕 (deriv g) w‖ ≤ ∫ x, ‖deriv g x‖ ∂volume := by + exact VectorFourier.norm_fourierIntegral_le_integral_norm 𝐞 volume (innerₗ ℝ) + (deriv g) w + have hleft : + ((2 * Real.pi) * |w|) * ‖𝓕 g w‖ = + ‖(2 * Real.pi * Complex.I * (w : ℂ)) * 𝓕 g w‖ := by + have htwopi : ‖(2 * ↑Real.pi : ℂ)‖ = 2 * Real.pi := by + rw [norm_mul, Complex.norm_two, Complex.norm_of_nonneg Real.pi_pos.le] + have hwc : ‖(w : ℂ)‖ = |w| := by rw [norm_real, Real.norm_eq_abs] + rw [norm_mul, norm_mul, norm_mul, htwopi, norm_I, hwc] + ring + have hmain : ((2 * Real.pi) * |w|) * ‖𝓕 g w‖ ≤ ∫ x, ‖deriv g x‖ ∂volume := by + rw [hleft, ← hmul] + exact h_fourier + have hpos : 0 < (2 * Real.pi) * |w| := by + positivity + exact (le_div_iff₀ hpos).mpr (by simpa [mul_comm, mul_left_comm, mul_assoc] using hmain) + +lemma norm_oscillatory_integral_le_integral_deriv_div + (g : ℝ → ℂ) (hg : Integrable g) (hdiff : Differentiable ℝ g) + (hg' : Integrable (deriv g)) {T : ℝ} (hT : 0 < T) : + ‖∫ y, g y * exp ((T : ℂ) * Complex.I * (y : ℂ)) ∂volume‖ ≤ + (∫ x, ‖deriv g x‖ ∂volume) / T := by + have hw : -T / (2 * Real.pi) ≠ 0 := by + exact div_ne_zero (neg_ne_zero.mpr hT.ne') (mul_ne_zero two_ne_zero Real.pi_ne_zero) + have hfourier := norm_fourier_le_integral_deriv_div g hg hdiff hg' hw + have heq : + (∫ y, g y * exp ((T : ℂ) * Complex.I * (y : ℂ)) ∂volume) = + 𝓕 g (-T / (2 * Real.pi)) := by + rw [Real.fourier_real_eq_integral_exp_smul] + apply integral_congr_ae + filter_upwards with y + rw [smul_eq_mul] + rw [mul_comm (g y)] + congr 1 + congr 1 + push_cast + field_simp [Real.pi_ne_zero] + rw [heq] + refine hfourier.trans_eq ?_ + congr 1 + have hden : (2 * Real.pi) * |-T / (2 * Real.pi)| = T := by + have htwopi_pos : 0 < 2 * Real.pi := by positivity + have hneg : -T / (2 * Real.pi) < 0 := div_neg_of_neg_of_pos (neg_neg_of_pos hT) htwopi_pos + rw [abs_of_neg hneg] + field_simp [Real.pi_ne_zero] + rw [hden] + +lemma norm_oscillatory_integral_le_integral_deriv_div_abs + (g : ℝ → ℂ) (hg : Integrable g) (hdiff : Differentiable ℝ g) + (hg' : Integrable (deriv g)) {T : ℝ} (hT : T ≠ 0) : + ‖∫ y, g y * exp ((T : ℂ) * Complex.I * (y : ℂ)) ∂volume‖ ≤ + (∫ x, ‖deriv g x‖ ∂volume) / |T| := by + have hw : -T / (2 * Real.pi) ≠ 0 := by + exact div_ne_zero (neg_ne_zero.mpr hT) (mul_ne_zero two_ne_zero Real.pi_ne_zero) + have hfourier := norm_fourier_le_integral_deriv_div g hg hdiff hg' hw + have heq : + (∫ y, g y * exp ((T : ℂ) * Complex.I * (y : ℂ)) ∂volume) = + 𝓕 g (-T / (2 * Real.pi)) := by + rw [Real.fourier_real_eq_integral_exp_smul] + apply integral_congr_ae + filter_upwards with y + rw [smul_eq_mul] + rw [mul_comm (g y)] + congr 1 + congr 1 + push_cast + field_simp [Real.pi_ne_zero] + rw [heq] + refine hfourier.trans_eq ?_ + congr 1 + have hden : (2 * Real.pi) * |-T / (2 * Real.pi)| = |T| := by + have htwopi_pos : 0 < 2 * Real.pi := by positivity + rw [abs_div, abs_neg, abs_of_pos htwopi_pos] + field_simp [Real.pi_ne_zero] + rw [hden] + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/HadamardSupport.lean b/PrimeNumberTheoremAnd/Erdos970/HadamardSupport.lean new file mode 100644 index 0000000..8c19850 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/HadamardSupport.lean @@ -0,0 +1,6805 @@ +import Mathlib + +namespace Erdos970 + +section HadamardAssemblyScope + +section HadamardSourceScope00 + +open scoped BigOperators + +namespace Real + +open _root_.Real + +lemma pow_div_one_sub_le_two_mul {r : ℝ} (hr : 0 ≤ r) (hrhalf : r ≤ 1 / 2) (m : ℕ) : + r ^ (m + 1) / (1 - r) ≤ 2 * r ^ (m + 1) := by + have hpow : 0 ≤ r ^ (m + 1) := pow_nonneg hr _ + have hhalf' : (1 / 2 : ℝ) ≤ 1 - r := by linarith + calc + r ^ (m + 1) / (1 - r) ≤ r ^ (m + 1) / (1 / 2 : ℝ) := by + exact div_le_div_of_nonneg_left hpow (by positivity) hhalf' + _ = 2 * r ^ (m + 1) := by ring + +end Real + +namespace Complex + +open _root_.Complex + +open scoped BigOperators in + +lemma neg_log_one_sub_eq_tsum {z : ℂ} (hz : ‖z‖ < 1) : + -log (1 - z) = ∑' n : ℕ, z ^ (n + 1) / (n + 1) := by + have h := hasSum_taylorSeries_neg_log hz + rw [← h.tsum_eq, h.summable.tsum_eq_zero_add] + simp only [pow_zero, Nat.cast_zero, div_zero, zero_add, Nat.cast_add, Nat.cast_one] + +noncomputable +def partialLogSum (m : ℕ) (z : ℂ) : ℂ := + -logTaylor (m + 1) (-z) + +@[simp] +lemma partialLogSum_zero (z : ℂ) : partialLogSum 0 z = 0 := by + simp [partialLogSum, logTaylor_succ, logTaylor_zero] + +@[simp] +lemma partialLogSum_at_zero (m : ℕ) : partialLogSum m 0 = 0 := by + simp [partialLogSum, logTaylor_at_zero] + +lemma logTaylor_succ_neg (n : ℕ) (z : ℂ) : + logTaylor (n + 1) (-z) = logTaylor n (-z) - z ^ n / n := by + rw [logTaylor_succ, Pi.add_apply] + have hsign : (-1 : ℂ) ^ (n + 1) * (-z) ^ n = -z ^ n := by + have hzpow : (-z) ^ n = (((-1 : ℂ) * z) ^ n) := by simp + rw [hzpow, mul_pow, ← mul_assoc, ← pow_add] + have hpow : (-1 : ℂ) ^ (n + 1 + n) = (-1 : ℂ) := by + rw [show n + 1 + n = 2 * n + 1 by omega, pow_add, pow_mul] + norm_num + rw [hpow] + ring + rw [show (-1 : ℂ) ^ (n + 1) * (-z) ^ n / n = -(z ^ n / n) by + rw [hsign] + ring] + abel + +lemma logTaylor_neg_eq_neg_sum (m : ℕ) (z : ℂ) : + logTaylor (m + 1) (-z) = -∑ k ∈ Finset.range m, z ^ (k + 1) / (k + 1) := by + induction m with + | zero => + simp [logTaylor_succ, logTaylor_zero] + | succ m hm => + rw [logTaylor_succ_neg, hm, Finset.sum_range_succ] + have hcast : ((m + 1 : ℕ) : ℂ) = (1 + (m : ℂ)) := by + simp [Nat.cast_add, Nat.cast_one, add_comm] + rw [hcast] + ring_nf + +lemma partialLogSum_eq_sum (m : ℕ) (z : ℂ) : + partialLogSum m z = ∑ k ∈ Finset.range m, z ^ (k + 1) / (k + 1) := by + simpa [partialLogSum] using congrArg Neg.neg (logTaylor_neg_eq_neg_sum m z) + +lemma hasDerivAt_partialLogSum (m : ℕ) (z : ℂ) : + HasDerivAt (partialLogSum m) (∑ j ∈ Finset.range m, z ^ j) z := by + cases m with + | zero => + have hzero : partialLogSum 0 = fun _ : ℂ ↦ (0 : ℂ) := by + funext w + exact partialLogSum_zero w + simpa [hzero] using (hasDerivAt_const z (c := (0 : ℂ))) + | succ m => + have hsum : + (∑ j ∈ Finset.range (m + 1), z ^ j) = + ∑ j ∈ Finset.range (m + 1), (-1) ^ j * (-z) ^ j := by + refine Finset.sum_congr rfl ?_ + intro j hj + symm + calc + (-1 : ℂ) ^ j * (-z) ^ j = (-1 : ℂ) ^ j * (((-1 : ℂ) * z) ^ j) := by simp + _ = ((-1 : ℂ) ^ j * (-1 : ℂ) ^ j) * z ^ j := by rw [mul_pow]; ring + _ = z ^ j := by + rw [← pow_add, show j + j = 2 * j by omega, pow_mul] + norm_num + rw [hsum] + simpa [partialLogSum] using! + (((hasDerivAt_logTaylor (m + 1) (-z)).comp z (hasDerivAt_neg z)).neg) + +lemma differentiable_partialLogSum (m : ℕ) : + Differentiable ℂ (fun z : ℂ => partialLogSum m z) := by + intro z + exact (hasDerivAt_partialLogSum m z).differentiableAt + +noncomputable +def logTail (m : ℕ) (z : ℂ) : ℂ := + ∑' k, z ^ (m + 1 + k) / (m + 1 + k) + +lemma summable_logTail {z : ℂ} (hz : ‖z‖ < 1) (m : ℕ) : + Summable (fun k => z ^ (m + 1 + k) / ((m + 1 + k) : ℂ)) := by + have h_geom : Summable (fun k : ℕ => ‖z‖ ^ k) := + summable_geometric_of_lt_one (norm_nonneg z) hz + refine Summable.of_norm_bounded (g := fun k => ‖z‖ ^ k) h_geom ?_ + intro k + rw [norm_div, norm_pow] + have h1 : (1 : ℝ) ≤ (m + 1 + k : ℝ) := by + have : (0 : ℝ) ≤ (m + k : ℝ) := by positivity + nlinarith + have hnorm : ‖(↑m + 1 + ↑k : ℂ)‖ = (m + 1 + k : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (Complex.norm_natCast (m + 1 + k)) + rw [hnorm] + calc + ‖z‖ ^ (m + 1 + k) / (m + 1 + k : ℝ) ≤ ‖z‖ ^ (m + 1 + k) := by + exact div_le_self (pow_nonneg (norm_nonneg z) _) h1 + _ = ‖z‖ ^ (m + 1) * ‖z‖ ^ k := by rw [pow_add] + _ ≤ 1 * ‖z‖ ^ k := by + refine mul_le_mul_of_nonneg_right ?_ (pow_nonneg (norm_nonneg z) k) + exact pow_le_one₀ (norm_nonneg z) (le_of_lt hz) + _ = ‖z‖ ^ k := one_mul _ + +lemma norm_logTail_le {z : ℂ} (hz : ‖z‖ < 1) (m : ℕ) : + ‖logTail m z‖ ≤ ‖z‖ ^ (m + 1) / (1 - ‖z‖) := by + dsimp only [logTail] + have h_rhs_summable : Summable (fun k => ‖z‖ ^ (m + 1 + k)) := by + simpa [pow_add] using + (summable_geometric_of_lt_one (norm_nonneg z) hz).mul_left (‖z‖ ^ (m + 1)) + have h_norm_summable : Summable (fun k => ‖z ^ (m + 1 + k) / ((m + 1 + k) : ℂ)‖) := by + refine Summable.of_nonneg_of_le (fun _ => norm_nonneg _) ?_ h_rhs_summable + intro k + rw [norm_div, norm_pow] + have hnorm : ‖(↑m + 1 + ↑k : ℂ)‖ = (m + 1 + k : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (Complex.norm_natCast (m + 1 + k)) + rw [hnorm] + have hm : 1 ≤ (m + 1 + k : ℝ) := by + have : (0 : ℝ) ≤ (m + k : ℝ) := by positivity + nlinarith + exact div_le_self (pow_nonneg (norm_nonneg z) _) hm + calc + ‖∑' k, z ^ (m + 1 + k) / ((m + 1 + k) : ℂ)‖ + ≤ ∑' k, ‖z ^ (m + 1 + k) / ((m + 1 + k) : ℂ)‖ := + norm_tsum_le_tsum_norm h_norm_summable + _ ≤ ∑' k, ‖z‖ ^ (m + 1 + k) := by + refine h_norm_summable.tsum_le_tsum ?_ h_rhs_summable + intro k + rw [norm_div, norm_pow] + have hm : 1 ≤ (m + 1 + k : ℝ) := by + have : (0 : ℝ) ≤ (m + k : ℝ) := by positivity + nlinarith + have hnorm : ‖(↑m + 1 + ↑k : ℂ)‖ = (m + 1 + k : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (Complex.norm_natCast (m + 1 + k)) + rw [hnorm] + exact div_le_self (pow_nonneg (norm_nonneg z) _) hm + _ = ‖z‖ ^ (m + 1) / (1 - ‖z‖) := by + have h_eq : + (fun k => ‖z‖ ^ (m + 1 + k)) = fun k => ‖z‖ ^ (m + 1) * ‖z‖ ^ k := by + ext k + rw [pow_add] + rw [h_eq, tsum_mul_left] + have h_geom := hasSum_geometric_of_lt_one (norm_nonneg z) hz + rw [h_geom.tsum_eq, div_eq_mul_inv] + +lemma norm_logTail_le_two_mul_norm_pow {z : ℂ} (hz : ‖z‖ < 1) (hzhalf : ‖z‖ ≤ 1 / 2) (m : ℕ) : + ‖logTail m z‖ ≤ 2 * ‖z‖ ^ (m + 1) := + (norm_logTail_le hz m).trans (Real.pow_div_one_sub_le_two_mul (norm_nonneg z) hzhalf m) + +lemma norm_partialLogSum_le_nat_mul_max_one_norm_pow (m : ℕ) (z : ℂ) : + ‖partialLogSum m z‖ ≤ (m : ℝ) * max 1 (‖z‖ ^ m) := by + have hsum : + ‖partialLogSum m z‖ ≤ ∑ k ∈ Finset.range m, ‖z ^ (k + 1) / (k + 1)‖ := by + rw [partialLogSum_eq_sum] + exact norm_sum_le _ _ + have hterm : ∀ k ∈ Finset.range m, ‖z ^ (k + 1) / (k + 1)‖ ≤ max 1 (‖z‖ ^ m) := by + intro k hk + rw [norm_div, norm_pow] + have hk1 : (1 : ℝ) ≤ (k : ℝ) + 1 := by + have hk1_nat : (1 : ℕ) ≤ k + 1 := Nat.succ_le_succ (Nat.zero_le k) + exact_mod_cast hk1_nat + have hdenom : ‖((k : ℂ) + 1)‖ = (k : ℝ) + 1 := by + simpa [Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (Complex.norm_natCast (k + 1)) + have hk_le : k + 1 ≤ m := Nat.succ_le_iff.2 (Finset.mem_range.1 hk) + have hpow_le : ‖z‖ ^ (k + 1) ≤ max 1 (‖z‖ ^ m) := by + have hz0 : 0 ≤ ‖z‖ := norm_nonneg z + by_cases hz1 : ‖z‖ ≤ (1 : ℝ) + · have : ‖z‖ ^ (k + 1) ≤ 1 := by exact pow_le_one₀ hz0 hz1 + exact this.trans (le_max_left _ _) + · have hz1' : (1 : ℝ) ≤ ‖z‖ := le_of_lt (lt_of_not_ge hz1) + have : ‖z‖ ^ (k + 1) ≤ ‖z‖ ^ m := pow_le_pow_right₀ hz1' hk_le + exact this.trans (le_max_right _ _) + calc + ‖z‖ ^ (k + 1) / ‖((k : ℂ) + 1)‖ = ‖z‖ ^ (k + 1) / ((k : ℝ) + 1) := by simp [hdenom] + _ ≤ ‖z‖ ^ (k + 1) := by + exact div_le_self (pow_nonneg (norm_nonneg z) _) hk1 + _ ≤ max 1 (‖z‖ ^ m) := hpow_le + have hsum_le : + (∑ k ∈ Finset.range m, ‖z ^ (k + 1) / (k + 1)‖) ≤ + ∑ _k ∈ Finset.range m, max 1 (‖z‖ ^ m) := + Finset.sum_le_sum (fun k hk => hterm k hk) + have hcard : ∑ _k ∈ Finset.range m, max 1 (‖z‖ ^ m) = (m : ℝ) * max 1 (‖z‖ ^ m) := by + simp [Finset.sum_const] + exact hsum.trans (hsum_le.trans_eq hcard) + +lemma neg_log_one_sub_eq_partialLogSum_add_logTail {z : ℂ} (hz : ‖z‖ < 1) (m : ℕ) : + -log (1 - z) = partialLogSum m z + logTail m z := by + let f : ℕ → ℂ := fun k ↦ z ^ (k + 1) / ((k : ℂ) + 1) + have h_summable : Summable f := by + simpa [f, Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (summable_logTail hz 0) + have h_decomp := h_summable.sum_add_tsum_nat_add m + rw [neg_log_one_sub_eq_tsum hz, partialLogSum_eq_sum, ← h_decomp] + congr 1 + dsimp only [logTail] + refine tsum_congr fun k ↦ ?_ + simp only [f, Nat.cast_add] + ring_nf + +end Complex +end HadamardSourceScope00 + +section HadamardSourceScope01 + +noncomputable section + +namespace Complex + +open _root_.Complex + +variable {z : ℂ} + +@[bound] +theorem neg_norm_le_re (z : ℂ) : -‖z‖ ≤ z.re := + neg_le_of_abs_le (abs_re_le_norm z) + +lemma norm_inv_pow_le_one_of_one_le_norm (u : ℂ) (n : ℕ) (hu : (1 : ℝ) ≤ ‖u‖) : + ‖(u ^ n)⁻¹‖ ≤ 1 := by + have hge : (1 : ℝ) ≤ ‖u ^ n‖ := by + rw [Complex.norm_pow] + exact one_le_pow₀ hu + calc ‖(u ^ n)⁻¹‖ = ‖(1 : ℂ) / u ^ n‖ := by rw [inv_eq_one_div] + _ = 1 / ‖u ^ n‖ := by + have hone : ‖(1 : ℂ)‖ = (1 : ℝ) := by simp + rw [Complex.norm_div, hone] + _ ≤ 1 := by simpa [one_div] using inv_le_one_of_one_le₀ hge + +end Complex +end +end HadamardSourceScope01 + +section HadamardSourceScope02 + +noncomputable section + +open scoped BigOperators +open Set + +namespace Complex + +open _root_.Complex + +def weierstrassFactor (m : ℕ) (z : ℂ) : ℂ := + (1 - z) * exp (partialLogSum m z) + +lemma weierstrassFactor_def (m : ℕ) (z : ℂ) : + weierstrassFactor m z = (1 - z) * exp (partialLogSum m z) := by + simp [weierstrassFactor] + +@[simp] +lemma weierstrassFactor_at_zero (m : ℕ) : weierstrassFactor m 0 = 1 := by + simp [weierstrassFactor, partialLogSum_at_zero] + +lemma weierstrassFactor_eq_zero_iff (m : ℕ) (z : ℂ) : + weierstrassFactor m z = 0 ↔ z = 1 := by + constructor + · intro hz + rw [weierstrassFactor] at hz + rcases mul_eq_zero.mp hz with h1 | h2 + · exact (sub_eq_zero.mp h1).symm + · exact absurd h2 (exp_ne_zero _) + · rintro rfl + simp [weierstrassFactor] + +lemma weierstrassFactor_ne_zero_iff (m : ℕ) (z : ℂ) : + weierstrassFactor m z ≠ 0 ↔ z ≠ 1 := by + simpa [ne_eq] using (not_congr (weierstrassFactor_eq_zero_iff (m := m) (z := z))) + +lemma weierstrassFactor_ne_zero_of_ne_one (m : ℕ) {z : ℂ} (hz : z ≠ 1) : + weierstrassFactor m z ≠ 0 := + (weierstrassFactor_ne_zero_iff (m := m) (z := z)).2 hz + +lemma differentiable_weierstrassFactor (m : ℕ) : + Differentiable ℂ (fun z : ℂ => weierstrassFactor m z) := by + simpa [weierstrassFactor] using! + ((differentiable_const (c := (1 : ℂ))).sub differentiable_id).mul + (differentiable_exp.comp (differentiable_partialLogSum m)) + +theorem analyticOrderAt_weierstrassFactor_div_self (m : ℕ) {a : ℂ} (ha : a ≠ 0) : + analyticOrderAt (fun z : ℂ => weierstrassFactor m (z / a)) a = (1 : ℕ∞) := by + set F : ℂ → ℂ := fun z => weierstrassFactor m (z / a) + have hF : AnalyticAt ℂ F a := by + have hdiv : Differentiable ℂ (fun z : ℂ => z / a) := by + simp [div_eq_mul_inv] + have hdiff : Differentiable ℂ F := (differentiable_weierstrassFactor m).comp hdiv + exact Differentiable.analyticAt (f := F) hdiff a + let g : ℂ → ℂ := fun z => (-a⁻¹) * Complex.exp (partialLogSum m (z / a)) + have hg : AnalyticAt ℂ g a := by + have hdiv : Differentiable ℂ (fun z : ℂ => z / a) := by + simp [div_eq_mul_inv] + have hpls : Differentiable ℂ (fun z : ℂ => partialLogSum m (z / a)) := + (differentiable_partialLogSum m).comp hdiv + have hexp : Differentiable ℂ (fun z : ℂ => Complex.exp (partialLogSum m (z / a))) := + (Complex.differentiable_exp).comp hpls + have hdiffg : Differentiable ℂ g := by + simpa [g] using hexp.const_mul (-a⁻¹ : ℂ) + exact Differentiable.analyticAt (f := g) hdiffg a + have hg0 : g a ≠ 0 := by + have hconst : (-a⁻¹ : ℂ) ≠ 0 := by simp [ha] + have hexp0 : Complex.exp (partialLogSum m (a / a)) ≠ 0 := + Complex.exp_ne_zero (partialLogSum m (a / a)) + simpa [g] using mul_ne_zero hconst hexp0 + refine (hF.analyticOrderAt_eq_natCast (n := 1)).2 ?_ + refine ⟨g, hg, hg0, ?_⟩ + refine Filter.Eventually.of_forall ?_ + intro z + have hlin : (1 - z / a) = (z - a) * (-a⁻¹) := by + have h1 : (1 : ℂ) = a * a⁻¹ := by simp [ha] + simp [div_eq_mul_inv, h1] + ring + simp only [F, g, pow_one, smul_eq_mul] + rw [weierstrassFactor_def] + simp [hlin, mul_assoc] + +lemma weierstrassFactor_eq_exp_neg_tail (m : ℕ) {z : ℂ} (hz : ‖z‖ < 1) (hz1 : z ≠ 1) : + weierstrassFactor m z = exp (-logTail m z) := by + unfold weierstrassFactor + have hz_ne_1 : 1 - z ≠ 0 := sub_ne_zero.mpr hz1.symm + rw [← exp_log hz_ne_1, ← Complex.exp_add] + have hsum : log (1 - z) + partialLogSum m z = -logTail m z := by + have hdecomp := neg_log_one_sub_eq_partialLogSum_add_logTail hz m + calc + log (1 - z) + partialLogSum m z + = log (1 - z) + (partialLogSum m z + logTail m z) - logTail m z := by ring + _ = log (1 - z) + (-log (1 - z)) - logTail m z := by rw [hdecomp] + _ = -logTail m z := by ring + simp [hsum] + +theorem weierstrassFactor_sub_one_pow_bound {m : ℕ} {z : ℂ} (hz : ‖z‖ ≤ 1 / 2) : + ‖weierstrassFactor m z - 1‖ ≤ 4 * ‖z‖ ^ (m + 1) := by + by_cases hm : m = 0 + · subst hm + have hmain : ‖(1 - z) - 1‖ ≤ 4 * ‖z‖ ^ 1 := by + have h : (1 - z) - 1 = -z := by ring + calc + ‖(1 - z) - 1‖ = ‖-z‖ := by simp [h] + _ = ‖z‖ := norm_neg z + _ = ‖z‖ ^ 1 := by simp + _ ≤ 4 * ‖z‖ ^ 1 := by nlinarith [pow_nonneg (norm_nonneg z) 1] + simpa [weierstrassFactor] using hmain + · have hz_lt : ‖z‖ < 1 := lt_of_le_of_lt hz (by norm_num) + by_cases hz1 : z = 1 + · exfalso; rw [hz1] at hz; norm_num at hz + have h_eq : weierstrassFactor m z = exp (-logTail m z) := + weierstrassFactor_eq_exp_neg_tail m hz_lt hz1 + rw [h_eq] + have h_tail_bound := norm_logTail_le_two_mul_norm_pow hz_lt hz m + have hw_le_one : ‖-logTail m z‖ ≤ 1 := by + simp only [norm_neg] + have : ‖logTail m z‖ ≤ 1 := by + have hm_pos : 0 < m := Nat.pos_of_ne_zero hm + have h2 : 2 ≤ m + 1 := by + exact Nat.succ_le_succ (Nat.succ_le_iff.2 hm_pos) + have hpow : (‖z‖ ^ (m + 1)) ≤ (‖z‖ ^ 2) := by + have hz1' : ‖z‖ ≤ 1 := by nlinarith [hz] + have hz0' : 0 ≤ ‖z‖ := norm_nonneg z + exact pow_le_pow_of_le_one hz0' hz1' h2 + have hmul : 2 * ‖z‖ ^ (m + 1) ≤ 2 * ‖z‖ ^ 2 := by gcongr + have hsq : 2 * ‖z‖ ^ 2 ≤ 1 := by + have hz0 : 0 ≤ ‖z‖ := norm_nonneg z + have hz_sq : ‖z‖ ^ 2 ≤ (1 / 2 : ℝ) ^ 2 := pow_le_pow_left₀ hz0 hz 2 + nlinarith + exact (h_tail_bound.trans hmul).trans hsq + linarith + have h_exp_sub_one : ‖exp (-logTail m z) - 1‖ ≤ 2 * ‖-logTail m z‖ := + Complex.norm_exp_sub_one_le hw_le_one + simp only [norm_neg] at h_exp_sub_one + calc + ‖exp (-logTail m z) - 1‖ ≤ 2 * ‖logTail m z‖ := h_exp_sub_one + _ ≤ 2 * (2 * ‖z‖ ^ (m + 1)) := by gcongr + _ = 4 * ‖z‖ ^ (m + 1) := by ring + +lemma log_norm_weierstrassFactor_ge_log_norm_one_sub_sub (m : ℕ) (z : ℂ) : + Real.log ‖1 - z‖ - ‖partialLogSum m z‖ ≤ Real.log ‖weierstrassFactor m z‖ := by + by_cases hz1 : z = (1 : ℂ) + · subst hz1 + simp [weierstrassFactor] + set S : ℂ := partialLogSum m z + have hS : weierstrassFactor m z = (1 - z) * Complex.exp S := by + simp [weierstrassFactor, S] + have hnorm_pos : 0 < ‖(1 : ℂ) - z‖ := + norm_pos_iff.mpr (sub_ne_zero.mpr (Ne.symm hz1)) + have hlog : + Real.log ‖weierstrassFactor m z‖ = Real.log ‖1 - z‖ + S.re := by + have hne : ‖(1 : ℂ) - z‖ ≠ 0 := ne_of_gt hnorm_pos + calc + Real.log ‖weierstrassFactor m z‖ + = Real.log (‖(1 : ℂ) - z‖ * ‖Complex.exp S‖) := by + simp [hS] + _ = Real.log ‖(1 : ℂ) - z‖ + Real.log ‖Complex.exp S‖ := by + simpa using (Real.log_mul hne (ne_of_gt (by simp))) + _ = Real.log ‖(1 : ℂ) - z‖ + S.re := by + simp [Complex.norm_exp, Real.log_exp] + _ = Real.log ‖1 - z‖ + S.re := by simp [sub_eq_add_neg, add_comm] + have hre : S.re ≥ -‖S‖ := Complex.neg_norm_le_re S + have : Real.log ‖weierstrassFactor m z‖ ≥ Real.log ‖1 - z‖ - ‖S‖ := by + linarith [hlog, hre] + simpa [S] using this + +lemma log_norm_weierstrassFactor_ge_neg_two_pow {m : ℕ} {z : ℂ} (hz : ‖z‖ ≤ (1 / 2 : ℝ)) : + (-2 : ℝ) * ‖z‖ ^ (m + 1) ≤ Real.log ‖weierstrassFactor m z‖ := by + have hz_lt : ‖z‖ < (1 : ℝ) := lt_of_le_of_lt hz (by norm_num) + have hz1 : z ≠ (1 : ℂ) := by + intro h + have : (1 : ℝ) ≤ (1 / 2 : ℝ) := by + simpa [h] using hz + norm_num at this + have hEq : weierstrassFactor m z = Complex.exp (-logTail m z) := + weierstrassFactor_eq_exp_neg_tail m hz_lt hz1 + have hlog : + Real.log ‖weierstrassFactor m z‖ = (-logTail m z).re := by + simp [hEq, Complex.norm_exp, Real.log_exp] + have hre : (-logTail m z).re ≥ -‖logTail m z‖ := by + simpa [norm_neg] using Complex.neg_norm_le_re (-logTail m z) + have htail := norm_logTail_le_two_mul_norm_pow hz_lt hz m + have : (-logTail m z).re ≥ (-2 : ℝ) * ‖z‖ ^ (m + 1) := by + calc + (-logTail m z).re ≥ -‖logTail m z‖ := hre + _ ≥ (-2 : ℝ) * ‖z‖ ^ (m + 1) := by + nlinarith [htail] + simpa [hlog, mul_assoc, mul_left_comm, mul_comm] using this + +end Complex +end +end HadamardSourceScope02 + +section HadamardSourceScope03 + +noncomputable section + +open Filter Topology + +namespace Complex + +open _root_.Complex + +theorem logDeriv_weierstrassFactor_one_div {a z : ℂ} (ha : a ≠ 0) (hz : z ≠ a) : + logDeriv (fun w : ℂ => weierstrassFactor 1 (w / a)) z = + 1 / (z - a) + 1 / a := by + have hE : + (fun w : ℂ => weierstrassFactor 1 (w / a)) = + fun w : ℂ => (1 - w / a) * exp (w / a) := by + ext w + simp [weierstrassFactor_def, partialLogSum_eq_sum] + have hf : (1 - z / a) ≠ 0 := by + intro hzero + have hdiv : z / a = 1 := by + exact (sub_eq_zero.mp hzero).symm + exact hz ((div_eq_one_iff_eq ha).1 hdiv) + rw [hE, logDeriv_fun_mul z hf (exp_ne_zero (z / a)) (by fun_prop) (by fun_prop)] + have hleft : logDeriv (fun w : ℂ => 1 - w / a) z = 1 / (z - a) := by + rw [logDeriv_apply] + have hderiv : deriv (fun w : ℂ => 1 - w / a) z = -(1 / a) := by + simp [one_div] + rw [hderiv] + have haz : -z + a ≠ 0 := by + simpa [sub_eq_add_neg, add_comm] using sub_ne_zero.mpr (Ne.symm hz) + field_simp [ha, sub_ne_zero.mpr hz, haz] + have haz' : a - z ≠ 0 := sub_ne_zero.mpr (Ne.symm hz) + have hza : z - a = -(a - z) := by ring + rw [hza] + field_simp [haz'] + have hright : logDeriv (fun w : ℂ => exp (w / a)) z = 1 / a := by + rw [logDeriv_apply] + have hderiv : deriv (fun w : ℂ => exp (w / a)) z = + exp (z / a) * (1 / a) := by + simp [one_div] + rw [hderiv] + field_simp [exp_ne_zero (z / a)] + rw [hleft, hright] + +end Complex +end +end HadamardSourceScope03 + +section HadamardSourceScope04 + +open Filter Topology Set + +namespace MeromorphicOn + +open _root_.MeromorphicOn + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {U K : Set 𝕜} {z : 𝕜} + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + +lemma divisor_support_inter_compact_finite (f : 𝕜 → E) {U K : Set 𝕜} + (hK : IsCompact K) (hKU : K ⊆ U) : + (K ∩ (MeromorphicOn.divisor f U).support).Finite := by + classical + set D : Function.locallyFinsuppWithin U ℤ := MeromorphicOn.divisor f U + have hloc : + ∀ x ∈ K, ∃ V : Set 𝕜, V ∈ 𝓝 x ∧ Set.Finite (V ∩ D.support) := by + intro x hxK + rcases D.supportLocallyFiniteWithinDomain x (hKU hxK) with ⟨V, hV, hfin⟩ + exact ⟨V, hV, hfin⟩ + choose V hVnhds hVfin using hloc + rcases hK.elim_nhds_subcover' (U := fun x hx => V x hx) (hU := fun x hx => hVnhds x hx) with + ⟨t, ht⟩ + have hsub : + K ∩ D.support ⊆ ⋃ x ∈ t, (V (x : 𝕜) x.2 ∩ D.support) := by + intro y hy + rcases hy with ⟨hyK, hyS⟩ + have hycov : y ∈ ⋃ x ∈ t, V (x : 𝕜) x.2 := ht hyK + rcases Set.mem_iUnion.1 hycov with ⟨x, hycov'⟩ + rcases Set.mem_iUnion.1 hycov' with ⟨hxT, hyV⟩ + refine Set.mem_iUnion.2 ⟨x, Set.mem_iUnion.2 ?_⟩ + exact ⟨hxT, ⟨hyV, hyS⟩⟩ + have hfinU : Set.Finite (⋃ x ∈ t, (V (x : 𝕜) x.2 ∩ D.support)) := by + classical + refine (t.finite_toSet).biUnion ?_ + intro x hx + simpa using (hVfin (x : 𝕜) x.2) + exact hfinU.subset hsub + +end MeromorphicOn +end HadamardSourceScope04 + +section HadamardSourceScope05 + +open Set + +namespace Complex.Hadamard + +open _root_.Complex + +def divisorZeroIndex (f : ℂ → ℂ) (U : Set ℂ) : Type := + Σ z : ℂ, Fin (Int.toNat (MeromorphicOn.divisor f U z)) + +abbrev divisorZeroIndex₀ (f : ℂ → ℂ) (U : Set ℂ) : Type := + {p : divisorZeroIndex f U // p.1 ≠ 0} + +abbrev divisorZeroIndex₀Val {f : ℂ → ℂ} {U : Set ℂ} (p : divisorZeroIndex₀ f U) : ℂ := + p.1.1 + +@[simp] +lemma divisorZeroIndex₀Val_ne_zero {f : ℂ → ℂ} {U : Set ℂ} (p : divisorZeroIndex₀ f U) : + divisorZeroIndex₀Val p ≠ 0 := p.2 + +@[simp] +lemma divisorZeroIndex₀Val_mem_divisor_support {f : ℂ → ℂ} {U : Set ℂ} + (p : divisorZeroIndex₀ f U) : + MeromorphicOn.divisor f U (divisorZeroIndex₀Val p) ≠ 0 := by + have hn : + Int.toNat (MeromorphicOn.divisor f U (divisorZeroIndex₀Val p)) ≠ 0 := by + intro h0 + have q0 : Fin 0 := by + simpa [divisorZeroIndex₀Val, h0] using p.1.2 + exact Fin.elim0 q0 + intro hdiv + have : Int.toNat (MeromorphicOn.divisor f U (divisorZeroIndex₀Val p)) = 0 := by + simp [hdiv] + exact hn this + +noncomputable def divisorCanonicalProduct (m : ℕ) (f : ℂ → ℂ) (U : Set ℂ) (z : ℂ) : ℂ := + ∏' p : divisorZeroIndex₀ f U, weierstrassFactor m (z / divisorZeroIndex₀Val p) + +@[simp] +lemma divisorCanonicalProduct_zero (m : ℕ) (f : ℂ → ℂ) (U : Set ℂ) : + divisorCanonicalProduct m f U 0 = 1 := by + simp [divisorCanonicalProduct] + +end Complex.Hadamard +end HadamardSourceScope05 + +section HadamardSourceScope06 + +namespace Complex + +open _root_.Complex + +section UniformMul + +theorem _root_.Erdos970.TendstoUniformlyOn.mul_left_bounded {ι : Type*} {p : Filter ι} {K : Set ℂ} + {F : ι → ℂ → ℂ} {f : ℂ → ℂ} {h : ℂ → ℂ} + (hF : TendstoUniformlyOn F f p K) (hh : ∃ C, ∀ z ∈ K, ‖h z‖ ≤ C) : + TendstoUniformlyOn (fun n z => h z * F n z) (fun z => h z * f z) p K := by + intro u hu + rcases Metric.mem_uniformity_dist.1 hu with ⟨ε, hεpos, hεu⟩ + rcases hh with ⟨C, hC⟩ + set C' : ℝ := max C 1 + have hC'pos : 0 < C' := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + have hC' : ∀ z ∈ K, ‖h z‖ ≤ C' := fun z hz => le_trans (hC z hz) (le_max_left _ _) + have hv : {p : ℂ × ℂ | dist p.1 p.2 < ε / C'} ∈ uniformity ℂ := + Metric.mem_uniformity_dist.2 ⟨ε / C', div_pos hεpos hC'pos, fun _ _ hab => hab⟩ + have hF' : ∀ᶠ n in p, ∀ z : ℂ, z ∈ K → dist (f z) (F n z) < ε / C' := hF _ hv + filter_upwards [hF'] with n hn z hzK + have hn' : ‖f z - F n z‖ < ε / C' := by simpa [dist_eq_norm] using hn z hzK + have hle : ‖h z‖ * ‖f z - F n z‖ ≤ C' * ‖f z - F n z‖ := + mul_le_mul_of_nonneg_right (hC' z hzK) (norm_nonneg _) + have hlt : C' * ‖f z - F n z‖ < C' * (ε / C') := mul_lt_mul_of_pos_left hn' hC'pos + have hnorm : + ‖h z * f z - h z * F n z‖ = ‖h z‖ * ‖f z - F n z‖ := by + calc + ‖h z * f z - h z * F n z‖ = ‖h z * (f z - F n z)‖ := by simp [mul_sub] + _ = ‖h z‖ * ‖f z - F n z‖ := by simp + have hdist : dist (h z * f z) (h z * F n z) < ε := by + rw [dist_eq_norm, hnorm] + have hlt' : ‖h z‖ * ‖f z - F n z‖ < ε := by + calc + ‖h z‖ * ‖f z - F n z‖ ≤ C' * ‖f z - F n z‖ := hle + _ < C' * (ε / C') := hlt + _ = ε := by field_simp [hC'pos.ne'] + exact hlt' + exact hεu hdist + +end UniformMul + +end Complex +end HadamardSourceScope06 + +section HadamardSourceScope07 + +open Filter _root_.Function _root_.Complex _root_.Erdos970.Complex Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +open _root_.Complex + +lemma finite_divisorZeroIndex₀_subtype_norm_le {f : ℂ → ℂ} {U : Set ℂ} (B : ℝ) + (hBU : Metric.closedBall (0 : ℂ) B ⊆ U) : + Finite {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ B} := by + set D : Function.locallyFinsuppWithin U ℤ := MeromorphicOn.divisor f U + have hK : IsCompact (Metric.closedBall (0 : ℂ) B) := isCompact_closedBall _ _ + have hpts0 : ((Metric.closedBall (0 : ℂ) B) ∩ D.support).Finite := + MeromorphicOn.divisor_support_inter_compact_finite (f := f) (U := U) + (K := Metric.closedBall (0 : ℂ) B) hK hBU + set pts : Set ℂ := ((Metric.closedBall (0 : ℂ) B) ∩ D.support) \ {0} + have hpts : pts.Finite := hpts0.sdiff + let : Fintype pts := hpts.fintype + let T : Type := Σ z : pts, Fin (Int.toNat (D z.1)) + have : Finite T := by infer_instance + let F : + {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ B} → T := fun p => + ⟨⟨divisorZeroIndex₀Val p.1, by + have hball : divisorZeroIndex₀Val p.1 ∈ Metric.closedBall (0 : ℂ) B := by + simpa [Metric.mem_closedBall, dist_zero_right] using p.2 + have hsupport : divisorZeroIndex₀Val p.1 ∈ D.support := by + have hne_toNat : + Int.toNat (MeromorphicOn.divisor f U (divisorZeroIndex₀Val p.1)) ≠ 0 := by + intro h0 + have hpfin : + Fin (Int.toNat (MeromorphicOn.divisor f U (divisorZeroIndex₀Val p.1))) := by + simpa [D] using p.1.1.2 + have : Fin 0 := by simpa [h0] using hpfin + exact Fin.elim0 this + have hne_D : D (divisorZeroIndex₀Val p.1) ≠ 0 := by + intro hD0 + apply hne_toNat + simp [D, hD0] + simp [D, Function.locallyFinsuppWithin.support, Function.support] + have hne0 : divisorZeroIndex₀Val p.1 ≠ 0 := divisorZeroIndex₀Val_ne_zero p.1 + exact ⟨⟨hball, hsupport⟩, by simp [Set.mem_singleton_iff]⟩⟩, + p.1.1.2⟩ + refine Finite.of_injective F ?_ + intro p q hpq + apply Subtype.ext + apply Subtype.ext + have h' := (Sigma.mk.inj_iff.1 hpq) + have hz : divisorZeroIndex₀Val p.1 = divisorZeroIndex₀Val q.1 := congrArg Subtype.val h'.1 + apply (Sigma.mk.inj_iff).2 + refine ⟨hz, ?_⟩ + exact h'.2 + +lemma divisorZeroIndex₀_norm_le_finite {f : ℂ → ℂ} {U : Set ℂ} (B : ℝ) + (hBU : Metric.closedBall (0 : ℂ) B ⊆ U) : + ({p : divisorZeroIndex₀ f U | ‖divisorZeroIndex₀Val p‖ ≤ B} : Set _).Finite := by + let s : Set (divisorZeroIndex₀ f U) := {p | ‖divisorZeroIndex₀Val p‖ ≤ B} + have : Finite (↥s) := + finite_divisorZeroIndex₀_subtype_norm_le (f := f) (U := U) B hBU + exact Set.toFinite s + +lemma norm_div_le_half_of_norm_le_of_two_mul_lt {z a : ℂ} {R : ℝ} + (hR : 0 < R) (hz : ‖z‖ ≤ R) (ha : (2 * R : ℝ) < ‖a‖) : + ‖z / a‖ ≤ (1 / 2 : ℝ) := by + have h2R_pos : 0 < (2 * R : ℝ) := by nlinarith [hR] + have hinv : ‖a‖⁻¹ < (2 * R)⁻¹ := by + simpa [one_div] using one_div_lt_one_div_of_lt h2R_pos ha + have hmul_le : ‖z‖ * ‖a‖⁻¹ ≤ R * ‖a‖⁻¹ := + mul_le_mul_of_nonneg_right hz (inv_nonneg.2 (norm_nonneg a)) + have hmul_lt : R * ‖a‖⁻¹ < R * (2 * R)⁻¹ := + mul_lt_mul_of_pos_left hinv hR + have hRhalf : R * (2 * R)⁻¹ = (1 / 2 : ℝ) := by + have hRne : (R : ℝ) ≠ 0 := hR.ne' + rw [show R * (2 * R)⁻¹ = R / (2 * R) by simp [div_eq_mul_inv]] + field_simp [hRne] + have hnorm : ‖z / a‖ = ‖z‖ * ‖a‖⁻¹ := by + simp [div_eq_mul_inv] + exact le_of_lt <| by + calc + ‖z / a‖ = ‖z‖ * ‖a‖⁻¹ := hnorm + _ ≤ R * ‖a‖⁻¹ := hmul_le + _ < R * (2 * R)⁻¹ := hmul_lt + _ = (1 / 2 : ℝ) := hRhalf + +theorem summable_logDerivTerms_divisorZeroIndex₀_of_summable_inv_sq + {f : ℂ → ℂ} {z : ℂ} + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (2 : ℕ))) + (hz : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), z ≠ divisorZeroIndex₀Val p) : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + 1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := by + let R : ℝ := max ‖z‖ 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + have hzle : ‖z‖ ≤ R := le_max_left _ _ + let u : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (2 * R) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (2 : ℕ)) + have hu : Summable u := h_sum.mul_left (2 * R) + refine hu.of_norm_bounded_eventually ?_ + have h_big : + ∀ᶠ p : divisorZeroIndex₀ f (Set.univ : Set ℂ) in Filter.cofinite, + (2 * R : ℝ) < ‖divisorZeroIndex₀Val p‖ := by + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ + 2 * R} : Set _).Finite := by + have : Metric.closedBall (0 : ℂ) (2 * R) ⊆ (Set.univ : Set ℂ) := by simp + exact divisorZeroIndex₀_norm_le_finite + (f := f) (U := (Set.univ : Set ℂ)) (B := 2 * R) this + have := hfin.eventually_cofinite_notMem + filter_upwards [this] with p hp + have : ¬ ‖divisorZeroIndex₀Val p‖ ≤ 2 * R := by simpa using hp + exact lt_of_not_ge this + filter_upwards [h_big] with p hp + let a : ℂ := divisorZeroIndex₀Val p + have ha0 : a ≠ 0 := divisorZeroIndex₀Val_ne_zero p + have hza0 : z - a ≠ 0 := sub_ne_zero.mpr (hz p) + have hterm : 1 / (z - a) + 1 / a = z / (a * (z - a)) := by + field_simp [ha0, hza0] + ring + have htri : ‖a‖ ≤ ‖z‖ + ‖z - a‖ := by + have hraw : ‖a‖ ≤ ‖z‖ + ‖a - z‖ := by + have h := norm_add_le z (a - z) + simpa [a, sub_eq_add_neg, add_assoc, add_left_comm, add_comm] using h + simpa [norm_sub_rev] using hraw + have hza_lower : ‖a‖ / 2 ≤ ‖z - a‖ := by + nlinarith [htri, hzle, hp] + have hnorm : ‖1 / (z - a) + 1 / a‖ ≤ (2 * R) * (‖a‖⁻¹ ^ (2 : ℕ)) := by + rw [hterm, norm_div, norm_mul] + have ha_norm_pos : 0 < ‖a‖ := norm_pos_iff.mpr ha0 + have hza_norm_pos : 0 < ‖z - a‖ := norm_pos_iff.mpr hza0 + rw [div_eq_mul_inv] + calc + ‖z‖ * (‖a‖ * ‖z - a‖)⁻¹ + = ‖z‖ * ‖a‖⁻¹ * ‖z - a‖⁻¹ := by + field_simp [ha_norm_pos.ne', hza_norm_pos.ne'] + _ ≤ R * ‖a‖⁻¹ * ‖z - a‖⁻¹ := by + gcongr + _ ≤ R * ‖a‖⁻¹ * (2 * ‖a‖⁻¹) := by + gcongr + have hhalf_pos : 0 < ‖a‖ / 2 := by positivity + have hinv : ‖z - a‖⁻¹ ≤ (‖a‖ / 2)⁻¹ := by + simpa [one_div] using one_div_le_one_div_of_le hhalf_pos hza_lower + have hhalf_inv : (‖a‖ / 2)⁻¹ = 2 * ‖a‖⁻¹ := by field_simp [ha_norm_pos.ne'] + simpa [hhalf_inv] using hinv + _ = (2 * R) * (‖a‖⁻¹ ^ (2 : ℕ)) := by ring + simpa [u, a] using hnorm + +theorem hasProdUniformlyOn_divisorCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) {K : Set ℂ} (hK : IsCompact K) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + HasProdUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) K := by + rcases (isBounded_iff_forall_norm_le.1 hK.isBounded) with ⟨R0, hR0⟩ + set R : ℝ := max R0 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + have hnormK : ∀ z ∈ K, ‖z‖ ≤ R := fun z hzK => le_trans (hR0 z hzK) (le_max_left _ _) + let g : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p z => weierstrassFactor m (z / divisorZeroIndex₀Val p) - 1 + let u : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (4 * R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) + have hu : Summable u := h_sum.mul_left (4 * R ^ (m + 1)) + have h_big : + ∀ᶠ p : divisorZeroIndex₀ f (Set.univ : Set ℂ) in Filter.cofinite, + (2 * R : ℝ) < ‖divisorZeroIndex₀Val p‖ := by + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ 2 * R} : + Set _).Finite := by + have : Metric.closedBall (0 : ℂ) (2 * R) ⊆ (Set.univ : Set ℂ) := by simp + exact divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) (B := 2 * R) this + have := hfin.eventually_cofinite_notMem + filter_upwards [this] with p hp + have : ¬ ‖divisorZeroIndex₀Val p‖ ≤ 2 * R := by simpa using hp + exact lt_of_not_ge this + have hBound : + ∀ᶠ p in Filter.cofinite, ∀ z ∈ K, ‖g p z‖ ≤ u p := by + filter_upwards [h_big] with p hp z hzK + have hzle : ‖z‖ ≤ R := hnormK z hzK + have hz_div : ‖z / divisorZeroIndex₀Val p‖ ≤ (1 / 2 : ℝ) := by + exact norm_div_le_half_of_norm_le_of_two_mul_lt hRpos hzle hp + have hE : + ‖weierstrassFactor m (z / divisorZeroIndex₀Val p) - 1‖ ≤ + 4 * ‖z / divisorZeroIndex₀Val p‖ ^ (m + 1) := + weierstrassFactor_sub_one_pow_bound (m := m) (z := z / divisorZeroIndex₀Val p) hz_div + have hz_pow : + ‖z / divisorZeroIndex₀Val p‖ ^ (m + 1) ≤ + (R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + have : ‖z / divisorZeroIndex₀Val p‖ = ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + rw [this] + have : (‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹) ^ (m + 1) = + ‖z‖ ^ (m + 1) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + simp [mul_pow] + rw [this] + have hzle_pow : ‖z‖ ^ (m + 1) ≤ R ^ (m + 1) := + pow_le_pow_left₀ (norm_nonneg z) hzle (m + 1) + gcongr + dsimp [g, u] + nlinarith [hE, hz_pow] + have hcts : ∀ p, ContinuousOn (g p) K := by + intro p + have hcontE : Continuous (fun z : ℂ => weierstrassFactor m z) := + (differentiable_weierstrassFactor m).continuous + have hdiv : Continuous fun z : ℂ => z / divisorZeroIndex₀Val p := by + simpa [div_eq_mul_inv] using! (continuous_id.mul continuous_const) + have hcont : Continuous fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) := + hcontE.comp hdiv + simpa only [g] using hcont.continuousOn.fun_sub continuous_const.continuousOn + have hprod : + HasProdUniformlyOn (fun p z ↦ 1 + g p z) (fun z ↦ ∏' p, (1 + g p z)) K := by + simpa using + Summable.hasProdUniformlyOn_one_add (f := g) (u := u) (K := K) hK hu hBound hcts + simpa [g, divisorCanonicalProduct, sub_eq_add_neg, add_assoc, add_left_comm, add_comm] + using! hprod + +theorem hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + (Set.univ : Set ℂ) := by + refine hasProdLocallyUniformlyOn_of_forall_compact + (f := fun p z => weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (g := divisorCanonicalProduct m f (Set.univ : Set ℂ)) + (s := (Set.univ : Set ℂ)) isOpen_univ ?_ + intro K hKU hK + simpa using + (hasProdUniformlyOn_divisorCanonicalProduct_univ (m := m) (f := f) (K := K) hK h_sum) + +theorem differentiableOn_divisorCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + DifferentiableOn ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) (Set.univ : Set ℂ) := by + have hloc : + TendstoLocallyUniformlyOn + (fun (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) => + ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + Filter.atTop (Set.univ : Set ℂ) := by + simpa [HasProdLocallyUniformlyOn] using + (hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum) + have hF : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in Filter.atTop, + DifferentiableOn ℂ + (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (Set.univ : Set ℂ) := by + refine Filter.Eventually.of_forall ?_ + intro s + have hdiff : + Differentiable ℂ + (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) := by + let F : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p z => weierstrassFactor m (z / divisorZeroIndex₀Val p) + have hF' : ∀ p ∈ s, Differentiable ℂ (F p) := by + intro p hp + have hdiv : Differentiable ℂ (fun z : ℂ => z / divisorZeroIndex₀Val p) := by + have : Differentiable ℂ (fun z : ℂ => z * ((divisorZeroIndex₀Val p)⁻¹)) := + (differentiable_id : Differentiable ℂ (fun z : ℂ => z)).mul_const + ((divisorZeroIndex₀Val p)⁻¹) + simp [div_eq_mul_inv] + exact (differentiable_weierstrassFactor m).comp hdiv + simpa [F] using (Differentiable.fun_finsetProd (𝕜 := ℂ) (f := F) (u := s) hF') + simpa using hdiff.differentiableOn + have : (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))).NeBot := + Filter.atTop_neBot + exact hloc.differentiableOn hF isOpen_univ + +theorem differentiableAt_divisorCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) (z : ℂ) : + DifferentiableAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := + ((differentiableOn_divisorCanonicalProduct_univ m f h_sum) z (by simp)).differentiableAt + (by simp) + +theorem logDeriv_divisorCanonicalProduct_one_eq_tsum + {f : ℂ → ℂ} {z : ℂ} + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (2 : ℕ))) + (hz : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), z ≠ divisorZeroIndex₀Val p) + (hprod_ne : divisorCanonicalProduct 1 f (Set.univ : Set ℂ) z ≠ 0) : + logDeriv (divisorCanonicalProduct 1 f (Set.univ : Set ℂ)) z = + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := by + let Φ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p w => weierstrassFactor 1 (w / divisorZeroIndex₀Val p) + have hf : ∀ p, Φ p z ≠ 0 := by + intro p + have hp0 : divisorZeroIndex₀Val p ≠ 0 := divisorZeroIndex₀Val_ne_zero p + refine weierstrassFactor_ne_zero_of_ne_one 1 ?_ + intro h + exact hz p ((div_eq_one_iff_eq hp0).1 h) + have hd : ∀ p, DifferentiableOn ℂ (Φ p) (Set.univ : Set ℂ) := by + intro p + have hdiv : Differentiable ℂ (fun w : ℂ => w / divisorZeroIndex₀Val p) := by + have : Differentiable ℂ (fun w : ℂ => w * ((divisorZeroIndex₀Val p)⁻¹)) := + (differentiable_id : Differentiable ℂ (fun w : ℂ => w)).mul_const + ((divisorZeroIndex₀Val p)⁻¹) + simp [div_eq_mul_inv] + exact ((differentiable_weierstrassFactor 1).comp hdiv).differentiableOn + have hm' : Summable fun p => logDeriv (Φ p) z := by + have hm : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + 1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := + summable_logDerivTerms_divisorZeroIndex₀_of_summable_inv_sq h_sum hz + refine hm.congr ?_ + intro p + have hp0 : divisorZeroIndex₀Val p ≠ 0 := divisorZeroIndex₀Val_ne_zero p + simpa [Φ] using + (Complex.logDeriv_weierstrassFactor_one_div + (a := divisorZeroIndex₀Val p) (z := z) hp0 (hz p)).symm + have htend : MultipliableLocallyUniformlyOn Φ (Set.univ : Set ℂ) := by + have hprod := hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ + (m := 1) (f := f) h_sum + simpa [Φ, divisorCanonicalProduct] using hprod.multipliableLocallyUniformlyOn + have hnez : (∏' p, Φ p z) ≠ 0 := by + simpa [Φ, divisorCanonicalProduct] using hprod_ne + have hlog : logDeriv (∏' p, Φ p ·) z = ∑' p, logDeriv (Φ p) z := + logDeriv_tprod_eq_tsum (s := (Set.univ : Set ℂ)) isOpen_univ (by simp) + hf hd hm' htend hnez + calc + logDeriv (divisorCanonicalProduct 1 f (Set.univ : Set ℂ)) z + = ∑' p, logDeriv (Φ p) z := by + simpa [Φ, divisorCanonicalProduct] using! hlog + _ = ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := by + refine tsum_congr fun p => ?_ + have hp0 : divisorZeroIndex₀Val p ≠ 0 := divisorZeroIndex₀Val_ne_zero p + simpa [Φ] using + Complex.logDeriv_weierstrassFactor_one_div + (a := divisorZeroIndex₀Val p) (z := z) hp0 (hz p) + +end Complex.Hadamard +end HadamardSourceScope07 + +section HadamardSourceScope09 + +noncomputable section + +open Set +open scoped Topology BigOperators + +namespace Complex.Hadamard + +open _root_.Complex + +lemma divisor_univ_eq_analyticOrderNatAt_int {f : ℂ → ℂ} (hf : Differentiable ℂ f) (z : ℂ) : + MeromorphicOn.divisor f (Set.univ : Set ℂ) z = (analyticOrderNatAt f z : ℤ) := by + have hmero : MeromorphicOn f (Set.univ : Set ℂ) := by + intro w hw + exact (Differentiable.analyticAt (f := f) hf w).meromorphicAt + simp only + [MeromorphicOn.divisor_apply hmero (by simp : z ∈ (Set.univ : Set ℂ)), analyticOrderNatAt] + have han : AnalyticAt ℂ f z := Differentiable.analyticAt (f := f) hf z + cases h : analyticOrderAt f z with + | top => + simp [han.meromorphicOrderAt_eq, h] + | coe n => + simp [han.meromorphicOrderAt_eq, h] + +theorem divisorZeroIndex₀_fiber_finite (f : ℂ → ℂ) (z₀ : ℂ) : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | divisorZeroIndex₀Val p = z₀} : + Set _).Finite := by + have hsub : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | divisorZeroIndex₀Val p = z₀} : Set _) + ⊆ ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ ‖z₀‖} : + Set _) := by + intro p hp + have : divisorZeroIndex₀Val p = z₀ := hp + simp [this] + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ ‖z₀‖} : + Set _).Finite := by + have : Metric.closedBall (0 : ℂ) ‖z₀‖ ⊆ (Set.univ : Set ℂ) := by simp + simpa using (divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) + (B := ‖z₀‖) this) + exact hfin.subset hsub + +def divisorZeroIndex₀FiberFinset (f : ℂ → ℂ) (z₀ : ℂ) : + Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + (divisorZeroIndex₀_fiber_finite (f := f) z₀).toFinset + +@[simp] +lemma mem_divisorZeroIndex₀FiberFinset (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) : + p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ ↔ divisorZeroIndex₀Val p = z₀ := by + simp [divisorZeroIndex₀FiberFinset] + +theorem eventually_atTop_subset_fiberFinset + (f : ℂ → ℂ) (z₀ : ℂ) : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in (Filter.atTop : Filter _), + divisorZeroIndex₀FiberFinset (f := f) z₀ ⊆ s := by + refine (Filter.eventually_atTop.2 ?_) + refine ⟨divisorZeroIndex₀FiberFinset (f := f) z₀, ?_⟩ + intro s hs + exact hs + +lemma divisorZeroIndex₀FiberFinset_card_eq_toNat_divisor (f : ℂ → ℂ) {z₀ : ℂ} (hz₀ : z₀ ≠ 0) : + (divisorZeroIndex₀FiberFinset (f := f) z₀).card = + Int.toNat (MeromorphicOn.divisor f (Set.univ : Set ℂ) z₀) := by + let S : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := {p | divisorZeroIndex₀Val p = z₀} + have hS : S.Finite := divisorZeroIndex₀_fiber_finite (f := f) z₀ + set n : ℕ := Int.toNat (MeromorphicOn.divisor f (Set.univ : Set ℂ) z₀) + have hcard : Nat.card S = n := by + classical + have : Fintype S := hS.fintype + + let e : S ≃ Fin n := + { toFun := by + intro x + rcases x with ⟨p, hp⟩ + rcases p with ⟨⟨z, q⟩, hz⟩ + have hzEq : z = z₀ := by simpa [divisorZeroIndex₀Val] using! hp + subst hzEq + simpa [n] using q + invFun := by + intro q + refine ⟨⟨⟨z₀, ?_⟩, hz₀⟩, ?_⟩ + · simpa [n] using q + · simp [S, divisorZeroIndex₀Val] + left_inv := by + rintro ⟨p, hp⟩ + rcases p with ⟨⟨z, q⟩, hz⟩ + have hzEq : z = z₀ := by simpa [divisorZeroIndex₀Val] using! hp + subst hzEq + (ext; rfl) + right_inv := by + intro q + rfl } + have h := Nat.card_congr (α := S) (β := Fin n) e + simpa using (h.trans (by simp)) + have hSncard : S.ncard = n := by + simpa [Nat.card_coe_set_eq] using hcard + have hto : hS.toFinset = divisorZeroIndex₀FiberFinset (f := f) z₀ := by + rfl + have htoFinset : S.ncard = (divisorZeroIndex₀FiberFinset (f := f) z₀).card := by + have h' : S.ncard = hS.toFinset.card := Set.ncard_eq_toFinset_card S hS + simpa [hto] using h' + exact htoFinset.symm.trans hSncard + +lemma divisorZeroIndex₀FiberFinset_card_eq_analyticOrderNatAt + {f : ℂ → ℂ} (hf : Differentiable ℂ f) {z₀ : ℂ} (hz₀ : z₀ ≠ 0) : + (divisorZeroIndex₀FiberFinset (f := f) z₀).card = analyticOrderNatAt f z₀ := by + have hdiv : + MeromorphicOn.divisor f (Set.univ : Set ℂ) z₀ = (analyticOrderNatAt f z₀ : ℤ) := + divisor_univ_eq_analyticOrderNatAt_int (f := f) hf z₀ + have htoNat : Int.toNat (MeromorphicOn.divisor f (Set.univ : Set ℂ) z₀) = + analyticOrderNatAt f z₀ := by + simp [hdiv] + exact (divisorZeroIndex₀FiberFinset_card_eq_toNat_divisor (f := f) (z₀ := z₀) hz₀).trans htoNat + +lemma not_mem_divisorZeroIndex₀FiberFinset_iff_val_ne + {f : ℂ → ℂ} (z₀ : ℂ) (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) : + p ∉ divisorZeroIndex₀FiberFinset (f := f) z₀ ↔ divisorZeroIndex₀Val p ≠ z₀ := by + simp [mem_divisorZeroIndex₀FiberFinset] + +end Complex.Hadamard +end +end HadamardSourceScope09 + +section HadamardSourceScope10 + +open Filter _root_.Function _root_.Complex _root_.Erdos970.Complex Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +open _root_.Complex + +noncomputable def divisorComplementFactor + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) : ℂ := by + classical + exact if p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ then (1 : ℂ) + else weierstrassFactor m (z / divisorZeroIndex₀Val p) + +@[simp] +theorem divisorComplementFactor_eq_one_of_mem + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) + (hp : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀) : + divisorComplementFactor m f z₀ p z = 1 := by + classical + simp [divisorComplementFactor, hp] + +@[simp] +theorem divisorComplementFactor_eq_weierstrassFactor_of_not_mem + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) + (hp : p ∉ divisorZeroIndex₀FiberFinset (f := f) z₀) : + divisorComplementFactor m f z₀ p z = + weierstrassFactor m (z / divisorZeroIndex₀Val p) := by + classical + simp [divisorComplementFactor, hp] + +lemma divisorComplementFactor_def + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) : + divisorComplementFactor m f z₀ p z = + if divisorZeroIndex₀Val p = z₀ then (1 : ℂ) + else weierstrassFactor m (z / divisorZeroIndex₀Val p) := by + classical + by_cases h : divisorZeroIndex₀Val p = z₀ + · have hp : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ := by + simpa [mem_divisorZeroIndex₀FiberFinset] using h + simp [divisorComplementFactor_eq_one_of_mem, hp, h] + · have hp : p ∉ divisorZeroIndex₀FiberFinset (f := f) z₀ := by + intro hmem + exact h ((mem_divisorZeroIndex₀FiberFinset f z₀ p).1 hmem) + simp [divisorComplementFactor_eq_weierstrassFactor_of_not_mem, hp, h] + +noncomputable def divisorPartialProduct (m : ℕ) (f : ℂ → ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) : ℂ := + ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p) + +theorem differentiable_weierstrassFactor_divisorZeroIndex₀ (m : ℕ) {f : ℂ → ℂ} + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) : + Differentiable ℂ (fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p)) := by + have hdiv : Differentiable ℂ (fun z : ℂ => z / divisorZeroIndex₀Val p) := by + simp [div_eq_mul_inv] + exact (differentiable_weierstrassFactor m).comp hdiv + +theorem differentiable_divisorPartialProduct (m : ℕ) (f : ℂ → ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) : + Differentiable ℂ (divisorPartialProduct m f s) := by + let Φ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p z => weierstrassFactor m (z / divisorZeroIndex₀Val p) + have hΦ : ∀ p ∈ s, Differentiable ℂ (Φ p) := by + intro p _hp + exact differentiable_weierstrassFactor_divisorZeroIndex₀ m p + simpa [divisorPartialProduct, Φ] using! + (Differentiable.fun_finsetProd (𝕜 := ℂ) (f := Φ) (u := s) hΦ) + +theorem analyticAt_divisorPartialProduct (m : ℕ) (f : ℂ → ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z₀ : ℂ) : + AnalyticAt ℂ (divisorPartialProduct m f s) z₀ := + (differentiable_divisorPartialProduct m f s).analyticAt z₀ + +noncomputable def divisorComplementPartialProduct + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) : ℂ := + ∏ p ∈ s, divisorComplementFactor m f z₀ p z + +@[simp] +lemma divisorComplementPartialProduct_def + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) : + divisorComplementPartialProduct m f z₀ s z = + ∏ p ∈ s, if divisorZeroIndex₀Val p = z₀ then (1 : ℂ) + else weierstrassFactor m (z / divisorZeroIndex₀Val p) := by + simp [divisorComplementPartialProduct, divisorComplementFactor, + mem_divisorZeroIndex₀FiberFinset] + +theorem differentiable_divisorComplementPartialProduct + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) : + Differentiable ℂ (divisorComplementPartialProduct m f z₀ s) := by + let Φ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p z => divisorComplementFactor m f z₀ p z + have hΦ : ∀ p ∈ s, Differentiable ℂ (Φ p) := by + intro p _hp + by_cases hpF : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ + · have hΦp : Φ p = fun _ => (1 : ℂ) := by + ext z + simp only [Φ, divisorComplementFactor_eq_one_of_mem m f z₀ p z hpF] + rw [hΦp] + exact differentiable_const (1 : ℂ) + · have hΦp : Φ p = fun z => weierstrassFactor m (z / divisorZeroIndex₀Val p) := by + ext z + simp only [Φ, divisorComplementFactor_eq_weierstrassFactor_of_not_mem m f z₀ p z hpF] + rw [hΦp] + exact differentiable_weierstrassFactor_divisorZeroIndex₀ m p + have hEq : (fun z : ℂ => ∏ p ∈ s, Φ p z) = + divisorComplementPartialProduct m f z₀ s := by + ext z + simp [Φ, divisorComplementPartialProduct] + have : Differentiable ℂ (fun z : ℂ => ∏ p ∈ s, Φ p z) := by + simpa using (Differentiable.fun_finsetProd (𝕜 := ℂ) (f := Φ) (u := s) hΦ) + simpa [hEq] using this + +noncomputable def divisorComplementCanonicalProduct + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) (z : ℂ) : ℂ := + ∏' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), divisorComplementFactor m f z₀ p z + +theorem hasProdUniformlyOn_divisorComplementCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) {K : Set ℂ} (hK : IsCompact K) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + HasProdUniformlyOn (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + divisorComplementFactor m f z₀ p z) (divisorComplementCanonicalProduct m f z₀) + K := by + rcases (isBounded_iff_forall_norm_le.1 hK.isBounded) with ⟨R0, hR0⟩ + set R : ℝ := max R0 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + have hnormK : ∀ z ∈ K, ‖z‖ ≤ R := fun z hzK => le_trans (hR0 z hzK) (le_max_left _ _) + let term : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := fun p z => + divisorComplementFactor m f z₀ p z + let g : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := fun p z => term p z - 1 + let u : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (4 * R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) + have hu : Summable u := h_sum.mul_left (4 * R ^ (m + 1)) + have h_big : + ∀ᶠ p : divisorZeroIndex₀ f (Set.univ : Set ℂ) in Filter.cofinite, + (2 * R : ℝ) < ‖divisorZeroIndex₀Val p‖ := by + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ 2 * R} : + Set _).Finite := by + have : Metric.closedBall (0 : ℂ) (2 * R) ⊆ (Set.univ : Set ℂ) := by simp + exact divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) (B := 2 * R) this + have := hfin.eventually_cofinite_notMem + filter_upwards [this] with p hp + have : ¬ ‖divisorZeroIndex₀Val p‖ ≤ 2 * R := by simpa using hp + exact lt_of_not_ge this + have hBound : + ∀ᶠ p in Filter.cofinite, ∀ z ∈ K, ‖g p z‖ ≤ u p := by + filter_upwards [h_big] with p hp z hzK + by_cases hpF : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ + · have hval : divisorZeroIndex₀Val p = z₀ := + (mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := z₀) p).1 hpF + have hu0 : 0 ≤ u p := by + dsimp [u] + refine mul_nonneg ?_ ?_ + · nlinarith [pow_nonneg (show 0 ≤ R from le_of_lt hRpos) (m + 1)] + · exact pow_nonneg (inv_nonneg.2 (norm_nonneg _)) (m + 1) + simp [g, term, divisorComplementFactor, hval, hu0, sub_eq_add_neg] + · have hzle : ‖z‖ ≤ R := hnormK z hzK + have hz_div : ‖z / divisorZeroIndex₀Val p‖ ≤ (1 / 2 : ℝ) := by + have h2R_pos : 0 < (2 * R : ℝ) := by nlinarith [hRpos] + have hinv : ‖divisorZeroIndex₀Val p‖⁻¹ < (2 * R)⁻¹ := by + simpa [one_div] using (one_div_lt_one_div_of_lt h2R_pos hp) + have hmul_le : ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ ≤ R * ‖divisorZeroIndex₀Val p‖⁻¹ := by + refine mul_le_mul_of_nonneg_right hzle ?_ + exact inv_nonneg.2 (norm_nonneg _) + have hmul_lt : R * ‖divisorZeroIndex₀Val p‖⁻¹ < R * (2 * R)⁻¹ := + mul_lt_mul_of_pos_left hinv hRpos + have hlt : ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ < R * (2 * R)⁻¹ := + lt_of_le_of_lt hmul_le hmul_lt + have hRhalf : R * (2 * R)⁻¹ = (1 / 2 : ℝ) := by + have hRne : (R : ℝ) ≠ 0 := hRpos.ne' + have : R * (2 * R)⁻¹ = R / (2 * R) := by simp [div_eq_mul_inv] + rw [this] + field_simp [hRne] + have hnorm : ‖z / divisorZeroIndex₀Val p‖ = ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + have hzlt : ‖z / divisorZeroIndex₀Val p‖ < (1 / 2 : ℝ) := by + calc + ‖z / divisorZeroIndex₀Val p‖ = ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := hnorm + _ < R * (2 * R)⁻¹ := hlt + _ = (1 / 2 : ℝ) := hRhalf + exact le_of_lt hzlt + have hE : ‖weierstrassFactor m (z / divisorZeroIndex₀Val p) - 1‖ ≤ + 4 * ‖z / divisorZeroIndex₀Val p‖ ^ (m + 1) := + weierstrassFactor_sub_one_pow_bound (m := m) (z := z / divisorZeroIndex₀Val p) hz_div + have hz_pow : ‖z / divisorZeroIndex₀Val p‖ ^ (m + 1) ≤ + (R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + have : ‖z / divisorZeroIndex₀Val p‖ = ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + rw [this] + have : (‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹) ^ (m + 1) = + ‖z‖ ^ (m + 1) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + simp [mul_pow] + rw [this] + have hzle_pow : ‖z‖ ^ (m + 1) ≤ R ^ (m + 1) := + pow_le_pow_left₀ (norm_nonneg z) hzle (m + 1) + gcongr + dsimp [g, term, u] + simp [divisorComplementFactor, hpF] at * + nlinarith [hE, hz_pow] + have hcts : ∀ p, ContinuousOn (g p) K := by + intro p + by_cases hpF : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ + · have hval : divisorZeroIndex₀Val p = z₀ := + (mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := z₀) p).1 hpF + simpa [g, term, divisorComplementFactor, hval, sub_eq_add_neg, add_assoc, add_left_comm, + add_comm] using + (continuousOn_const : ContinuousOn (fun _ : ℂ => (0 : ℂ)) K) + · have hvalne : divisorZeroIndex₀Val p ≠ z₀ := + (not_mem_divisorZeroIndex₀FiberFinset_iff_val_ne (f := f) z₀ p).1 hpF + have hcontE : Continuous (fun z : ℂ => weierstrassFactor m z) := + (differentiable_weierstrassFactor m).continuous + have hdiv : Continuous fun z : ℂ => z / divisorZeroIndex₀Val p := by + simpa [div_eq_mul_inv] using! (continuous_id.mul continuous_const) + have hcont : Continuous fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) := + hcontE.comp hdiv + have : ContinuousOn (fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) - 1) K := + (hcont.continuousOn.sub continuous_const.continuousOn) + simpa [g, term, divisorComplementFactor, mem_divisorZeroIndex₀FiberFinset, hvalne] using this + have hprod : + HasProdUniformlyOn (fun p z ↦ 1 + g p z) (fun z ↦ ∏' p, (1 + g p z)) K := by + simpa using + Summable.hasProdUniformlyOn_one_add (f := g) (u := u) (K := K) hK hu hBound hcts + have hterm : + HasProdUniformlyOn (fun p z ↦ term p z) (fun z ↦ ∏' p, term p z) K := by + simpa [g, sub_eq_add_neg, add_assoc, add_left_comm, add_comm] using hprod + refine hterm.congr_right ?_ + intro z hz + simp [term, divisorComplementCanonicalProduct, divisorComplementFactor] + +theorem hasProdLocallyUniformlyOn_divisorComplementCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + divisorComplementFactor m f z₀ p z) + (divisorComplementCanonicalProduct m f z₀) + (Set.univ : Set ℂ) := by + refine hasProdLocallyUniformlyOn_of_forall_compact + (f := fun p z => divisorComplementFactor m f z₀ p z) + (g := divisorComplementCanonicalProduct m f z₀) (s := (Set.univ : Set ℂ)) + isOpen_univ ?_ + intro K hKU hK + simpa using + (hasProdUniformlyOn_divisorComplementCanonicalProduct_univ (m := m) (f := f) (z₀ := z₀) + (K := K) hK h_sum) + +theorem tendstoLocallyUniformlyOn_divisorComplementPartialProduct_univ + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + divisorComplementPartialProduct m f z₀ s) + (divisorComplementCanonicalProduct m f z₀) + Filter.atTop + (Set.univ : Set ℂ) := by + have hprod : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + divisorComplementFactor m f z₀ p z) + (divisorComplementCanonicalProduct m f z₀) + (Set.univ : Set ℂ) := + hasProdLocallyUniformlyOn_divisorComplementCanonicalProduct_univ (m := m) (f := f) + (z₀ := z₀) h_sum + have h : + TendstoLocallyUniformlyOn + (fun (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) => + ∏ p ∈ s, + if divisorZeroIndex₀Val p = z₀ then (1 : ℂ) + else weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorComplementCanonicalProduct m f z₀) + Filter.atTop + (Set.univ : Set ℂ) := by + simpa [HasProdLocallyUniformlyOn, divisorComplementFactor, mem_divisorZeroIndex₀FiberFinset] + using hprod + refine h.congr (G := fun s z => divisorComplementPartialProduct m f z₀ s z) ?_ + intro s z hz + simp [divisorComplementPartialProduct_def] + +theorem differentiableOn_divisorComplementCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + DifferentiableOn ℂ (divisorComplementCanonicalProduct m f z₀) (Set.univ : Set ℂ) := by + have hloc : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + divisorComplementPartialProduct m f z₀ s) + (divisorComplementCanonicalProduct m f z₀) + Filter.atTop + (Set.univ : Set ℂ) := + tendstoLocallyUniformlyOn_divisorComplementPartialProduct_univ (m := m) (f := f) + (z₀ := z₀) h_sum + have hF : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in Filter.atTop, + DifferentiableOn ℂ (divisorComplementPartialProduct m f z₀ s) (Set.univ : Set ℂ) := by + refine Filter.Eventually.of_forall ?_ + intro s + exact (differentiable_divisorComplementPartialProduct m f z₀ s).differentiableOn + have : (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))).NeBot := + Filter.atTop_neBot + exact hloc.differentiableOn hF isOpen_univ + +lemma divisorPartialProduct_eq_fiber_mul_complement_of_subset + (m : ℕ) (f : ℂ → ℂ) (z₀ z : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hs : divisorZeroIndex₀FiberFinset (f := f) z₀ ⊆ s) : + divisorPartialProduct m f s z = + divisorPartialProduct m f (divisorZeroIndex₀FiberFinset (f := f) z₀) z * + divisorComplementPartialProduct m f z₀ s z := by + classical + let fiber : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + divisorZeroIndex₀FiberFinset (f := f) z₀ + let P : divisorZeroIndex₀ f (Set.univ : Set ℂ) → Prop := fun p => p ∈ fiber + let term : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ := + fun p => weierstrassFactor m (z / divisorZeroIndex₀Val p) + have hfilter : s.filter P = fiber := by + ext p + constructor + · intro hp + exact (Finset.mem_filter.mp hp).2 + · intro hp + exact Finset.mem_filter.mpr ⟨hs hp, hp⟩ + have hsplit : + (∏ p ∈ s with P p, term p) * (∏ p ∈ s with ¬ P p, term p) = ∏ p ∈ s, term p := by + simpa [term] using + (Finset.prod_filter_mul_prod_filter_not (s := s) (p := P) (f := term)) + have hP : (∏ p ∈ s with P p, term p) = divisorPartialProduct m f fiber z := by + have hg : ∀ x ∈ s \ fiber, (if x ∈ fiber then term x else (1 : ℂ)) = 1 := by + intro x hx + have hxnot : x ∉ fiber := (Finset.mem_sdiff.mp hx).2 + simp [hxnot] + have hfg : + ∀ x ∈ fiber, term x = (if x ∈ fiber then term x else (1 : ℂ)) := by + intro x hx + simp [hx] + have hsub := (Finset.prod_subset_one_on_sdiff (s₁ := fiber) (s₂ := s) + (f := term) (g := fun x => if x ∈ fiber then term x else (1 : ℂ)) hs hg hfg) + simpa [divisorPartialProduct, term, P, fiber, Finset.prod_filter] using hsub.symm + have hnotP : (∏ p ∈ s with ¬ P p, term p) = divisorComplementPartialProduct m f z₀ s z := by + simp [divisorComplementPartialProduct, divisorComplementFactor, term, P, fiber, + Finset.prod_filter, mem_divisorZeroIndex₀FiberFinset] + have hsplit' : ∏ p ∈ s, term p = (∏ p ∈ s with P p, term p) * (∏ p ∈ s with ¬ P p, term p) := + hsplit.symm + calc + divisorPartialProduct m f s z + = ∏ p ∈ s, term p := by simp [divisorPartialProduct, term] + _ = (∏ p ∈ s with P p, term p) * (∏ p ∈ s with ¬ P p, term p) := hsplit' + _ = divisorPartialProduct m f fiber z * divisorComplementPartialProduct m f z₀ s z := by + simp [hP, hnotP, fiber] + +end Complex.Hadamard +end HadamardSourceScope10 + +section HadamardSourceScope11 + +noncomputable section + +open _root_.Complex _root_.Erdos970.Complex Filter _root_.Function Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +open _root_.Complex + +theorem analyticOrderAt_finset_prod_weierstrassFactor_divisorZeroIndex₀ + (m : ℕ) (f : ℂ → ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z₀ : ℂ) : + analyticOrderAt (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + z₀ = ((s.filter (fun p => divisorZeroIndex₀Val p = z₀)).card : ℕ∞) := by + classical + refine Finset.induction_on s ?base ?step + · simp [analyticOrderAt_eq_zero] + · intro p s hp hs + by_cases hEq : divisorZeroIndex₀Val p = z₀ + · have hp0 : divisorZeroIndex₀Val p ≠ 0 := p.property + have han_fac : + AnalyticAt ℂ (fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p)) z₀ := by + exact (differentiable_weierstrassFactor_divisorZeroIndex₀ m p).analyticAt z₀ + have han_rest : AnalyticAt ℂ (fun z : ℂ => ∏ q ∈ s, weierstrassFactor m + (z / divisorZeroIndex₀Val q)) z₀ := by + simpa [divisorPartialProduct] using! analyticAt_divisorPartialProduct m f s z₀ + let fac : ℂ → ℂ := fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) + let rest : ℂ → ℂ := fun z : ℂ => ∏ q ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val q) + have hmul : + analyticOrderAt (fac * rest) z₀ = + analyticOrderAt fac z₀ + analyticOrderAt rest z₀ := by + simpa [fac, rest] using (analyticOrderAt_mul (z₀ := z₀) han_fac han_rest) + have hcard : + (Finset.filter (fun q => divisorZeroIndex₀Val q = z₀) (insert p s)).card = + (Finset.filter (fun q => divisorZeroIndex₀Val q = z₀) s).card + 1 := by + simp [hEq, hp, Finset.filter_insert] + have hfac : analyticOrderAt fac z₀ = (1 : ℕ∞) := by + simpa [fac, hEq] using + (analyticOrderAt_weierstrassFactor_div_self (m := m) (a := divisorZeroIndex₀Val p) hp0) + have hrest : analyticOrderAt rest z₀ = ((s.filter + (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simpa [rest] using hs + have hcongr : + (fun z : ℂ => ∏ q ∈ insert p s, weierstrassFactor m (z / divisorZeroIndex₀Val q)) + =ᶠ[𝓝 z₀] (fac * rest) := by + refine Filter.Eventually.of_forall ?_ + intro z + simp [fac, rest, Finset.prod_insert, hp, Pi.mul_apply] + calc + analyticOrderAt (fun z : ℂ => ∏ q ∈ insert p s, weierstrassFactor m + (z / divisorZeroIndex₀Val q)) z₀ = analyticOrderAt (fac * rest) z₀ := by + simpa using (analyticOrderAt_congr hcongr) + _ = analyticOrderAt fac z₀ + analyticOrderAt rest z₀ := hmul + _ = (1 : ℕ∞) + ((s.filter (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simp [hfac, hrest] + _ = (((insert p s).filter (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simp [hcard, Nat.add_comm] + · have han_fac : + AnalyticAt ℂ (fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p)) z₀ := by + exact (differentiable_weierstrassFactor_divisorZeroIndex₀ m p).analyticAt z₀ + have hfac0 : analyticOrderAt (fun z : ℂ => weierstrassFactor m + (z / divisorZeroIndex₀Val p)) z₀ = 0 := by + have hp0 : divisorZeroIndex₀Val p ≠ 0 := p.property + have hval : weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) ≠ 0 := by + have : (z₀ / divisorZeroIndex₀Val p) ≠ 1 := by + intro h1 + have : z₀ = divisorZeroIndex₀Val p := by + have : z₀ = (z₀ / divisorZeroIndex₀Val p) * (divisorZeroIndex₀Val p) := by + simp [div_eq_mul_inv] + simpa [h1, div_eq_mul_inv, hp0] using this + exact hEq (this.symm) + exact (weierstrassFactor_ne_zero_iff m (z₀ / divisorZeroIndex₀Val p)).2 this + simpa using (han_fac.analyticOrderAt_eq_zero).2 (by simpa using hval) + have hcard : + (Finset.filter (fun q => divisorZeroIndex₀Val q = z₀) (insert p s)).card = + (Finset.filter (fun q => divisorZeroIndex₀Val q = z₀) s).card := by + simp [hEq, Finset.filter_insert] + have han_rest : AnalyticAt ℂ (fun z : ℂ => ∏ q ∈ s, weierstrassFactor m + (z / divisorZeroIndex₀Val q)) z₀ := by + simpa [divisorPartialProduct] using! analyticAt_divisorPartialProduct m f s z₀ + let fac : ℂ → ℂ := fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) + let rest : ℂ → ℂ := fun z : ℂ => ∏ q ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val q) + have hmul : + analyticOrderAt (fac * rest) z₀ = + analyticOrderAt fac z₀ + analyticOrderAt rest z₀ := by + simpa [fac, rest] using (analyticOrderAt_mul (z₀ := z₀) han_fac han_rest) + have hcongr : + (fun z : ℂ => ∏ q ∈ insert p s, weierstrassFactor m (z / divisorZeroIndex₀Val q)) + =ᶠ[𝓝 z₀] (fac * rest) := by + refine Filter.Eventually.of_forall ?_ + intro z + simp [fac, rest, Finset.prod_insert, hp, Pi.mul_apply] + calc + analyticOrderAt (fun z : ℂ => ∏ q ∈ insert p s, weierstrassFactor m + (z / divisorZeroIndex₀Val q)) z₀ + = analyticOrderAt (fac * rest) z₀ := by + simpa using (analyticOrderAt_congr hcongr) + _ = analyticOrderAt rest z₀ := by + calc + analyticOrderAt (fac * rest) z₀ = analyticOrderAt fac z₀ + + analyticOrderAt rest z₀ := hmul + _ = analyticOrderAt rest z₀ := by + have hfac0' : analyticOrderAt fac z₀ = 0 := by + simpa [fac] using hfac0 + simp [hfac0'] + _ = ((s.filter (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simpa [rest] using hs + _ = (((insert p s).filter (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simpa using congrArg (fun n : ℕ => (n : ℕ∞)) hcard.symm + +theorem analyticOrderAt_partialProduct_eq_fiberCard_of_subset + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hs : divisorZeroIndex₀FiberFinset (f := f) z₀ ⊆ s) : + analyticOrderAt + (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + z₀ = ((divisorZeroIndex₀FiberFinset (f := f) z₀).card : ℕ∞) := by + have h := + analyticOrderAt_finset_prod_weierstrassFactor_divisorZeroIndex₀ + (m := m) (f := f) (s := s) (z₀ := z₀) + have hfilter : + s.filter (fun p => divisorZeroIndex₀Val p = z₀) = + divisorZeroIndex₀FiberFinset (f := f) z₀ := by + ext p + constructor + · intro hp' + have hpv : divisorZeroIndex₀Val p = z₀ := (Finset.mem_filter.mp hp').2 + simpa [mem_divisorZeroIndex₀FiberFinset] using hpv + · intro hp_fiber + have hpv : divisorZeroIndex₀Val p = z₀ := + (mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := z₀) p).1 hp_fiber + have hps : p ∈ s := hs (by simpa [mem_divisorZeroIndex₀FiberFinset] using hpv) + exact Finset.mem_filter.2 ⟨hps, hpv⟩ + simpa [hfilter] using h + +theorem exists_analyticAt_eq_pow_smul_of_partialProduct_contains_fiber + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hs : divisorZeroIndex₀FiberFinset (f := f) z₀ ⊆ s) : + ∃ g : ℂ → ℂ, + AnalyticAt ℂ g z₀ ∧ g z₀ ≠ 0 ∧ + (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + =ᶠ[𝓝 z₀] + fun z : ℂ => (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card • g z := by + let F : ℂ → ℂ := fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p) + have hF_ana : AnalyticAt ℂ F z₀ := by + simpa [F, divisorPartialProduct] using! analyticAt_divisorPartialProduct m f s z₀ + have hOrder : + analyticOrderAt F z₀ = + ((divisorZeroIndex₀FiberFinset (f := f) z₀).card : ℕ∞) := by + simpa [F] using + (analyticOrderAt_partialProduct_eq_fiberCard_of_subset (m := m) + (f := f) (z₀ := z₀) (s := s) hs) + refine (hF_ana.analyticOrderAt_eq_natCast (n := (divisorZeroIndex₀FiberFinset + (f := f) z₀).card)).1 ?_ + simp [hOrder] + +end Complex.Hadamard +end +end HadamardSourceScope11 + +section HadamardSourceScope12 + +open Filter _root_.Function _root_.Complex _root_.Erdos970.Complex Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +open _root_.Complex + +theorem tendstoLocallyUniformlyOn_divisorPartialProduct_univ + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => divisorPartialProduct m f s) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + Filter.atTop + (Set.univ : Set ℂ) := by + have hprod : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + (Set.univ : Set ℂ) := + hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + simpa [HasProdLocallyUniformlyOn, divisorPartialProduct] using! hprod + +theorem tendstoUniformlyOn_divisorPartialProduct_div_pow_sub + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) (k : ℕ) {K : Set ℂ} (hK : IsCompact K) (hKz : ∀ z ∈ K, z ≠ z₀) : + TendstoUniformlyOn + (fun s z => (divisorPartialProduct m f s z) / (z - z₀) ^ k) + (fun z => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ k) + (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))) + K := by + have hloc : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => divisorPartialProduct m f s) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + Filter.atTop + K := + (tendstoLocallyUniformlyOn_divisorPartialProduct_univ (m := m) (f := f) h_sum).mono + (by intro z hz; simp) + have hunif : + TendstoUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => divisorPartialProduct m f s) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + Filter.atTop + K := + (tendstoLocallyUniformlyOn_iff_tendstoUniformlyOn_of_compact hK).1 hloc + let h : ℂ → ℂ := fun z => ((z - z₀) ^ k)⁻¹ + have hh : ∃ C, ∀ z ∈ K, ‖h z‖ ≤ C := by + have hcont : ContinuousOn h K := by + have hpow : ContinuousOn (fun z : ℂ => (z - z₀) ^ k) K := by + fun_prop + refine hpow.inv₀ ?_ + intro z hz + have hz0 : z - z₀ ≠ 0 := sub_ne_zero.mpr (hKz z hz) + exact pow_ne_zero k hz0 + have hKimg : IsCompact (h '' K) := hK.image_of_continuousOn hcont + rcases (isBounded_iff_forall_norm_le.1 hKimg.isBounded) with ⟨C, hC⟩ + refine ⟨C, ?_⟩ + intro z hz + exact hC (h z) ⟨z, hz, rfl⟩ + have hunif' := + (TendstoUniformlyOn.mul_left_bounded (p := (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f + (Set.univ : Set ℂ))))) + (K := K) + (F := fun s z => divisorPartialProduct m f s z) + (f := fun z => divisorCanonicalProduct m f (Set.univ : Set ℂ) z) + (h := h) + hunif hh) + simpa [h, div_eq_mul_inv, mul_comm, mul_left_comm, mul_assoc] using hunif' + +theorem tendstoLocallyUniformlyOn_divisorPartialProduct_div_pow_sub + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) (k : ℕ) : + TendstoLocallyUniformlyOn + (fun s z => (divisorPartialProduct m f s z) / (z - z₀) ^ k) + (fun z => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ k) + (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))) + ((Set.univ : Set ℂ) \ {z₀}) := by + have hopen : IsOpen ((Set.univ : Set ℂ) \ {z₀}) := by + have hset : ((Set.univ : Set ℂ) \ {z₀}) = ({z₀} : Set ℂ)ᶜ := by + ext z + simp + simp [hset] + refine (tendstoLocallyUniformlyOn_iff_forall_isCompact hopen).2 ?_ + intro K hKsub hK + have hKz : ∀ z ∈ K, z ≠ z₀ := by + intro z hzK + have : z ∈ (Set.univ : Set ℂ) \ {z₀} := hKsub hzK + exact by simpa [Set.mem_sdiff, Set.mem_singleton_iff] using this.2 + exact tendstoUniformlyOn_divisorPartialProduct_div_pow_sub + (m := m) (f := f) h_sum (z₀ := z₀) (k := k) (hK := hK) hKz + +open Filter + +theorem exists_ball_eq_divisorCanonicalProduct_div_pow_eq + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : + ∃ ε > 0, ∃ u : ℂ → ℂ, AnalyticAt ℂ u z₀ ∧ + u z₀ ≠ 0 ∧ + ∀ z : ℂ, z ∈ Metric.ball z₀ ε → z ≠ z₀ → + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card = + (divisorComplementCanonicalProduct m f z₀ z) * u z := by + let fiber : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + divisorZeroIndex₀FiberFinset (f := f) z₀ + have hfib : ∃ u : ℂ → ℂ, AnalyticAt ℂ u z₀ ∧ u z₀ ≠ 0 ∧ + (fun z : ℂ => divisorPartialProduct m f fiber z) =ᶠ[𝓝 z₀] + fun z : ℂ => (z - z₀) ^ fiber.card • u z := by + simpa [fiber, divisorPartialProduct] using + (exists_analyticAt_eq_pow_smul_of_partialProduct_contains_fiber (m := m) (f := f) (z₀ := z₀) + (s := fiber) (by rfl : fiber ⊆ fiber)) + rcases hfib with ⟨u, huA, hu0, huEq⟩ + have hmem : {z : ℂ | divisorPartialProduct m f fiber z = + (z - z₀) ^ fiber.card • u z} ∈ 𝓝 z₀ := huEq + rcases Metric.mem_nhds_iff.1 hmem with ⟨ε, hε, hball⟩ + refine ⟨ε, hε, u, huA, hu0, ?_⟩ + have hq : + TendstoLocallyUniformlyOn (fun s z => (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card) + (fun z => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ fiber.card) + (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))) + ((Set.univ : Set ℂ) \ {z₀}) := + tendstoLocallyUniformlyOn_divisorPartialProduct_div_pow_sub + (m := m) (f := f) (h_sum := h_sum) (z₀ := z₀) (k := fiber.card) + have hcomp : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + divisorComplementPartialProduct m f z₀ s) + (divisorComplementCanonicalProduct m f z₀) + Filter.atTop + (Set.univ : Set ℂ) := + tendstoLocallyUniformlyOn_divisorComplementPartialProduct_univ (m := m) (f := f) + (z₀ := z₀) h_sum + intro z hz hzne + have hz' : z ∈ ((Set.univ : Set ℂ) \ {z₀}) := by + refine ⟨by simp, ?_⟩ + simpa [Set.mem_singleton_iff] using hzne + have hF : Tendsto (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card) (Filter.atTop : Filter _) + (𝓝 ((divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ fiber.card)) := + hq.tendsto_at hz' + have hG0 : Tendsto (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + divisorComplementPartialProduct m f z₀ s z) (Filter.atTop : Filter _) + (𝓝 (divisorComplementCanonicalProduct m f z₀ z)) := + hcomp.tendsto_at (by simp : z ∈ (Set.univ : Set ℂ)) + have hG : Tendsto (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + (divisorComplementPartialProduct m f z₀ s z) * u z) (Filter.atTop : Filter _) + (𝓝 ((divisorComplementCanonicalProduct m f z₀ z) * u z)) := + (hG0.mul tendsto_const_nhds) + have hsub : ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in (Filter.atTop : Filter _), + fiber ⊆ s := eventually_atTop_subset_fiberFinset (f := f) z₀ + have heq_eventually : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in (Filter.atTop : Filter _), + (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card + = (divisorComplementPartialProduct m f z₀ s z) * u z := by + filter_upwards [hsub] with s hs + have hsplit : + divisorPartialProduct m f s z = + divisorPartialProduct m f fiber z * divisorComplementPartialProduct m f z₀ s z := by + simpa [fiber] using + (divisorPartialProduct_eq_fiber_mul_complement_of_subset (m := m) (f := f) (z₀ := z₀) + (z := z) (s := s) hs) + have hfibz : + divisorPartialProduct m f fiber z = (z - z₀) ^ fiber.card • u z := by + exact hball hz + have hzpow : (z - z₀) ^ fiber.card ≠ 0 := + pow_ne_zero _ (sub_ne_zero.mpr hzne) + set a : ℂ := (z - z₀) ^ fiber.card + have ha : a ≠ 0 := by simpa [a] using hzpow + set c : ℂ := divisorComplementPartialProduct m f z₀ s z with hc + rw [hsplit, hfibz, smul_eq_mul] + calc + ((a * u z) * c) / a + = (a * (u z * c)) / a := by simp [mul_assoc] + _ = u z * c := by + simpa [mul_assoc] using (mul_div_cancel_left₀ (u z * c) ha) + _ = c * u z := by ac_rfl + _ = (divisorComplementPartialProduct m f z₀ s z) * u z := by + simp [c] + have hG' : + Tendsto + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card) + (Filter.atTop : Filter _) + (𝓝 ((divisorComplementCanonicalProduct m f z₀ z) * u z)) := by + have heq' : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in (Filter.atTop : Filter _), + (divisorComplementPartialProduct m f z₀ s z) * u z + = (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card := by + filter_upwards [heq_eventually] with s hs + exact hs.symm + exact (hG.congr' heq') + exact tendsto_nhds_unique hF hG' + +theorem bddAbove_norm_divisorCanonicalProduct_div_pow_puncturedBall + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : ∃ r > 0, BddAbove (norm ∘ (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) '' + ((Metric.ball z₀ r) \ {z₀})) := by + rcases exists_ball_eq_divisorCanonicalProduct_div_pow_eq (m := m) (f := f) (h_sum := h_sum) + (z₀ := z₀) with ⟨ε, hε, u, huA, hu0, hEq⟩ + have huC : ContinuousAt u z₀ := huA.continuousAt + have hpre : {z : ℂ | ‖u z - u z₀‖ < 1} ∈ 𝓝 z₀ := by + have : u ⁻¹' Metric.ball (u z₀) (1 : ℝ) ∈ 𝓝 z₀ := + huC.preimage_mem_nhds (Metric.ball_mem_nhds (u z₀) (by norm_num)) + simpa [Metric.ball, dist_eq_norm, Set.preimage] using this + rcases Metric.mem_nhds_iff.1 hpre with ⟨r0, hr0pos, hr0sub⟩ + set r : ℝ := min (ε / 2) r0 + have hrpos : 0 < r := lt_min (by nlinarith [hε]) hr0pos + have hr_lt_ε : r < ε := lt_of_le_of_lt (min_le_left _ _) (by nlinarith [hε]) + have huBound : ∀ z ∈ Metric.ball z₀ r, ‖u z‖ ≤ ‖u z₀‖ + 1 := by + intro z hz + have hz0 : z ∈ Metric.ball z₀ r0 := by + have : r ≤ r0 := min_le_right _ _ + exact Metric.ball_subset_ball this hz + have hdiff : ‖u z - u z₀‖ < 1 := hr0sub hz0 + have htri : ‖u z‖ ≤ ‖u z - u z₀‖ + ‖u z₀‖ := by + simpa [sub_eq_add_neg, add_assoc] using + (norm_add_le (u z - u z₀) (u z₀)) + have : ‖u z‖ ≤ 1 + ‖u z₀‖ := le_trans htri (by nlinarith [le_of_lt hdiff]) + nlinarith [this] + have hdiffC : + DifferentiableOn ℂ (divisorComplementCanonicalProduct m f z₀) (Set.univ : Set ℂ) := + differentiableOn_divisorComplementCanonicalProduct_univ (m := m) (f := f) (z₀ := z₀) h_sum + have hcontC : ContinuousOn (divisorComplementCanonicalProduct m f z₀) (Metric.closedBall z₀ r) := + (hdiffC.continuousOn).mono (by intro z hz; simp) + have hK : IsCompact (Metric.closedBall z₀ r) := isCompact_closedBall _ _ + rcases (isBounded_iff_forall_norm_le.1 (hK.image_of_continuousOn hcontC).isBounded) with ⟨C, hC⟩ + refine ⟨r, hrpos, ⟨C * (‖u z₀‖ + 1), ?_⟩⟩ + rintro _ ⟨z, hzset, rfl⟩ + rcases hzset with ⟨hzr, hzne⟩ + have hz_in_ε : z ∈ Metric.ball z₀ ε := Metric.ball_subset_ball hr_lt_ε.le hzr + have hz_ne : z ≠ z₀ := by simpa [Set.mem_singleton_iff] using hzne + have hq : + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card + = divisorComplementCanonicalProduct m f z₀ z * u z := + hEq z hz_in_ε hz_ne + have hCz : ‖divisorComplementCanonicalProduct m f z₀ z‖ ≤ C := by + have hzK : z ∈ Metric.closedBall z₀ r := Metric.mem_closedBall.2 (le_of_lt hzr) + exact hC _ ⟨z, hzK, rfl⟩ + have huZ : ‖u z‖ ≤ ‖u z₀‖ + 1 := huBound z hzr + have hCnonneg : 0 ≤ C := le_trans (norm_nonneg _) hCz + have hmul : ‖divisorComplementCanonicalProduct m f z₀ z * u z‖ ≤ C * (‖u z₀‖ + 1) := by + calc + ‖divisorComplementCanonicalProduct m f z₀ z * u z‖ + = ‖divisorComplementCanonicalProduct m f z₀ z‖ * ‖u z‖ := by simp + _ ≤ C * (‖u z₀‖ + 1) := by + exact mul_le_mul hCz huZ (norm_nonneg _) hCnonneg + simpa [Function.comp, hq] using hmul + +theorem divisorComplementCanonicalProduct_ne_zero_at + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + divisorComplementCanonicalProduct m f z₀ z₀ ≠ 0 := by + let Φ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ := + fun p => if divisorZeroIndex₀Val p = z₀ then (1 : ℂ) + else weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ := fun p => Φ p - 1 + have hΦ_ne : ∀ p, Φ p ≠ 0 := by + intro p + by_cases hp : divisorZeroIndex₀Val p = z₀ + · simp [Φ, hp] + · have hval : divisorZeroIndex₀Val p ≠ z₀ := hp + have hz : z₀ / divisorZeroIndex₀Val p ≠ (1 : ℂ) := by + intro h + by_cases hp0 : divisorZeroIndex₀Val p = 0 + · have : z₀ / divisorZeroIndex₀Val p = (0 : ℂ) := by simp [hp0] + have h01 := h + rw [this] at h01 + exact (show False from (by simpa using (show (0 : ℂ) ≠ (1 : ℂ) from by simp) h01)) + · have : z₀ = divisorZeroIndex₀Val p := (div_eq_one_iff_eq hp0).1 h + exact hval this.symm + have hE : weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) ≠ 0 := by + intro h0 + have : z₀ / divisorZeroIndex₀Val p = (1 : ℂ) := + (weierstrassFactor_eq_zero_iff (m := m) (z := z₀ / divisorZeroIndex₀Val p)).1 h0 + exact hz this + simp [Φ, hp, hE] + have hz0_le : ‖z₀‖ ≤ max ‖z₀‖ 1 := le_max_left _ _ + set R : ℝ := max ‖z₀‖ 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + let u : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (4 * R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) + have hu : Summable u := h_sum.mul_left (4 * R ^ (m + 1)) + have h_big : + ∀ᶠ p : divisorZeroIndex₀ f (Set.univ : Set ℂ) in Filter.cofinite, + (2 * R : ℝ) < ‖divisorZeroIndex₀Val p‖ := by + have hfin : ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ + 2 * R} : Set _).Finite := by + have : Metric.closedBall (0 : ℂ) (2 * R) ⊆ (Set.univ : Set ℂ) := by simp + exact divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) (B := 2 * R) this + have := hfin.eventually_cofinite_notMem + filter_upwards [this] with p hp + have : ¬ ‖divisorZeroIndex₀Val p‖ ≤ 2 * R := by simpa using hp + exact lt_of_not_ge this + have hBound : + ∀ᶠ p in Filter.cofinite, ‖a p‖ ≤ u p := by + filter_upwards [h_big] with p hp + have ha_pos : 0 < ‖divisorZeroIndex₀Val p‖ := lt_trans (by nlinarith [hRpos]) hp + have hz_div : ‖z₀ / divisorZeroIndex₀Val p‖ ≤ (1 / 2 : ℝ) := by + have h2R_pos : 0 < (2 * R : ℝ) := by nlinarith [hRpos] + have hinv : ‖divisorZeroIndex₀Val p‖⁻¹ < (2 * R)⁻¹ := by + simpa [one_div] using (one_div_lt_one_div_of_lt h2R_pos hp) + have hmul_le : ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ ≤ R * ‖divisorZeroIndex₀Val p‖⁻¹ := by + refine mul_le_mul_of_nonneg_right ?_ (inv_nonneg.2 (norm_nonneg _)) + exact hz0_le + have hmul_lt : R * ‖divisorZeroIndex₀Val p‖⁻¹ < R * (2 * R)⁻¹ := + mul_lt_mul_of_pos_left hinv hRpos + have hlt : ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ < R * (2 * R)⁻¹ := + lt_of_le_of_lt hmul_le hmul_lt + have hRhalf : R * (2 * R)⁻¹ = (1 / 2 : ℝ) := by + have hRne : (R : ℝ) ≠ 0 := hRpos.ne' + have : R * (2 * R)⁻¹ = R / (2 * R) := by simp [div_eq_mul_inv] + rw [this] + field_simp [hRne] + have hnorm : ‖z₀ / divisorZeroIndex₀Val p‖ = ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + have hzlt : ‖z₀ / divisorZeroIndex₀Val p‖ < (1 / 2 : ℝ) := by + calc + ‖z₀ / divisorZeroIndex₀Val p‖ = ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := hnorm + _ < R * (2 * R)⁻¹ := hlt + _ = (1 / 2 : ℝ) := hRhalf + exact le_of_lt hzlt + have hE : + ‖weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) - 1‖ ≤ + 4 * ‖z₀ / divisorZeroIndex₀Val p‖ ^ (m + 1) := + weierstrassFactor_sub_one_pow_bound (m := m) (z := z₀ / divisorZeroIndex₀Val p) hz_div + have hz_pow : + ‖z₀ / divisorZeroIndex₀Val p‖ ^ (m + 1) ≤ + (R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + have : ‖z₀ / divisorZeroIndex₀Val p‖ = ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + rw [this] + have : (‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹) ^ (m + 1) = + ‖z₀‖ ^ (m + 1) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + simp [mul_pow] + rw [this] + have hzle_pow : ‖z₀‖ ^ (m + 1) ≤ R ^ (m + 1) := + pow_le_pow_left₀ (norm_nonneg z₀) hz0_le (m + 1) + gcongr + have hp_ne : divisorZeroIndex₀Val p ≠ z₀ := by + intro h + have : ‖divisorZeroIndex₀Val p‖ ≤ R := by + simp [h, R] + exact (not_lt_of_ge this) (lt_trans (by nlinarith [hRpos]) hp) + have ha : ‖a p‖ = ‖weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) - 1‖ := by + simp [a, Φ, hp_ne, sub_eq_add_neg] + calc + ‖a p‖ = ‖weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) - 1‖ := ha + _ ≤ 4 * ‖z₀ / divisorZeroIndex₀Val p‖ ^ (m + 1) := by + simpa [sub_eq_add_neg, add_comm] using hE + _ ≤ 4 * (R ^ (m + 1) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) := by + gcongr + _ = u p := by + simp [u, mul_assoc, mul_comm] + have hsum_norm : Summable (fun p => ‖a p‖) := by + refine (Summable.of_norm_bounded_eventually (E := ℝ) (f := fun p => ‖a p‖) (g := u) hu ?_) + filter_upwards [hBound] with p hp + simpa [Real.norm_eq_abs, abs_of_nonneg (norm_nonneg (a p))] using hp + have htprod_ne : + (∏' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (1 + a p)) ≠ 0 := + tprod_one_add_ne_zero_of_summable (R := ℂ) (f := a) (hf := fun p => by + simpa [a, Φ, add_sub_cancel] using hΦ_ne p) hsum_norm + have : (∏' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (1 + a p)) = + divisorComplementCanonicalProduct m f z₀ z₀ := by + simp [a, Φ, divisorComplementCanonicalProduct, divisorComplementFactor_def] + exact by + intro h0 + exact htprod_ne (by simpa [this] using h0) + +end Complex.Hadamard +end HadamardSourceScope12 + +section HadamardSourceScope13 + +open Filter _root_.Function _root_.Complex _root_.Erdos970.Complex Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +open _root_.Complex + +theorem differentiableOn_divisorPartialProduct_div_pow_sub + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) (k : ℕ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) : + DifferentiableOn ℂ (fun z : ℂ => (divisorPartialProduct m f s z) / (z - z₀) ^ k) + ((Set.univ : Set ℂ) \ {z₀}) := by + have hdiff_prod : DifferentiableOn ℂ (divisorPartialProduct m f s) (Set.univ : Set ℂ) := by + exact (differentiable_divisorPartialProduct m f s).differentiableOn + have hdiff_den : DifferentiableOn ℂ (fun z : ℂ => (z - z₀) ^ k) ((Set.univ : Set ℂ) \ {z₀}) := by + have : Differentiable ℂ (fun z : ℂ => (z - z₀) ^ k) := by + fun_prop + exact this.differentiableOn + by_cases hk : k = 0 + · subst hk + simpa [pow_zero] using! (hdiff_prod.mono (by intro z hz; exact hz.1)) + · have hne : ∀ z ∈ ((Set.univ : Set ℂ) \ {z₀}), (fun z : ℂ => (z - z₀) ^ k) z ≠ 0 := by + intro z hz + have hz' : z ≠ z₀ := by + simpa [Set.mem_sdiff, Set.mem_singleton_iff] using hz.2 + exact pow_ne_zero _ (sub_ne_zero.mpr hz') + have hdiff_inv : + DifferentiableOn ℂ (fun z : ℂ => ((z - z₀) ^ k)⁻¹) ((Set.univ : Set ℂ) \ {z₀}) := + hdiff_den.inv hne + simpa [div_eq_mul_inv] using! (hdiff_prod.mono (by intro z hz; exact hz.1)).mul hdiff_inv + +theorem differentiableOn_divisorCanonicalProduct_div_pow_sub + (m : ℕ) (f : ℂ → ℂ) (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) (k : ℕ) : DifferentiableOn ℂ + (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ k) + ((Set.univ : Set ℂ) \ {z₀}) := by + have hopen : IsOpen ((Set.univ : Set ℂ) \ {z₀}) := by + have hset : ((Set.univ : Set ℂ) \ {z₀}) = ({z₀} : Set ℂ)ᶜ := by + ext z; simp + simp [hset] + have hconv := + tendstoLocallyUniformlyOn_divisorPartialProduct_div_pow_sub + (m := m) (f := f) h_sum (z₀ := z₀) (k := k) + refine hconv.differentiableOn ?_ hopen + refine Filter.Eventually.of_forall ?_ + intro s + exact differentiableOn_divisorPartialProduct_div_pow_sub (m := m) (f := f) (z₀ := z₀) (k := k) s + +theorem differentiableOn_update_limUnder_divisorCanonicalProduct_div_pow + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : ∃ r > 0, DifferentiableOn ℂ (Function.update + (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) z₀ + (limUnder (𝓝[≠] z₀) (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card))) + (Metric.ball z₀ r) := by + rcases bddAbove_norm_divisorCanonicalProduct_div_pow_puncturedBall (m := m) (f := f) + (h_sum := h_sum) (z₀ := z₀) with ⟨r, hrpos, hbdd⟩ + refine ⟨r, hrpos, ?_⟩ + have hnhds : Metric.ball z₀ r ∈ 𝓝 z₀ := Metric.ball_mem_nhds z₀ hrpos + have hdiff : DifferentiableOn ℂ (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + ((Metric.ball z₀ r) \ {z₀}) := by + have hglob := + differentiableOn_divisorCanonicalProduct_div_pow_sub + (m := m) (f := f) h_sum (z₀ := z₀) + (k := (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + refine hglob.mono ?_ + intro z hz + exact ⟨by simp, hz.2⟩ + have hb : BddAbove (norm ∘ (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) '' + ((Metric.ball z₀ r) \ {z₀})) := hbdd + simpa using + (Complex.differentiableOn_update_limUnder_of_bddAbove (f := fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + (s := Metric.ball z₀ r) (c := z₀) hnhds hdiff hb) + +theorem analyticAt_update_limUnder_divisorCanonicalProduct_div_pow + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : AnalyticAt ℂ (Function.update (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) z₀ + (limUnder (𝓝[≠] z₀) (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card))) + z₀ := by + rcases + differentiableOn_update_limUnder_divisorCanonicalProduct_div_pow + (m := m) (f := f) h_sum (z₀ := z₀) with ⟨r, hrpos, hdiff⟩ + let g : ℂ → ℂ := + Function.update + (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + z₀ + (limUnder (𝓝[≠] z₀) fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + have hcont : ContinuousAt g z₀ := + (hdiff.differentiableAt (Metric.ball_mem_nhds z₀ hrpos)).continuousAt + have hd : + ∀ᶠ z in 𝓝[≠] z₀, DifferentiableAt ℂ g z := by + have hballWithin : Metric.ball z₀ r ∈ 𝓝[≠] z₀ := by + refine mem_nhdsWithin_iff_exists_mem_nhds_inter.2 ?_ + refine ⟨Metric.ball z₀ r, Metric.ball_mem_nhds z₀ hrpos, ?_⟩ + intro z hz + exact hz.1 + filter_upwards [hballWithin] with z hz + exact (hdiff z hz).differentiableAt (Metric.isOpen_ball.mem_nhds hz) + simpa [g] using Complex.analyticAt_of_differentiable_on_punctured_nhds_of_continuousAt hd hcont + +theorem exists_analyticAt_divisorCanonicalProduct_quotient + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : + ∃ q : ℂ → ℂ, + AnalyticAt ℂ q z₀ ∧ + q z₀ = + limUnder (𝓝[≠] z₀) (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) ∧ + ∀ z : ℂ, z ≠ z₀ → + q z = + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card := by + let q : ℂ → ℂ := + Function.update + (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + z₀ + (limUnder (𝓝[≠] z₀) fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + refine ⟨q, ?_, ?_, ?_⟩ + · simpa [q] using + analyticAt_update_limUnder_divisorCanonicalProduct_div_pow + (m := m) (f := f) (h_sum := h_sum) (z₀ := z₀) + · simp [q] + · intro z hz + simp [q, Function.update_of_ne hz] + +theorem analyticOrderNatAt_divisorCanonicalProduct_eq_fiber_card + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z₀ = + (divisorZeroIndex₀FiberFinset (f := f) z₀).card := by + set k : ℕ := (divisorZeroIndex₀FiberFinset (f := f) z₀).card + let F : ℂ → ℂ := divisorCanonicalProduct m f (Set.univ : Set ℂ) + let q0 : ℂ → ℂ := fun z => F z / (z - z₀) ^ k + rcases exists_analyticAt_divisorCanonicalProduct_quotient + (m := m) (f := f) (h_sum := h_sum) (z₀ := z₀) with + ⟨q, hqA, hq_self, hq_ne⟩ + have hdiff_univ : DifferentiableOn ℂ F (Set.univ : Set ℂ) := + differentiableOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + have han : AnalyticAt ℂ F z₀ := by + refine (Complex.analyticAt_iff_eventually_differentiableAt).2 ?_ + refine Filter.Eventually.of_forall ?_ + intro z + have : DifferentiableWithinAt ℂ F (Set.univ : Set ℂ) z := hdiff_univ z (by simp) + exact this.differentiableAt (by simp) + rcases + exists_ball_eq_divisorCanonicalProduct_div_pow_eq (m := m) (f := f) (h_sum := h_sum) + (z₀ := z₀) + with ⟨ε, hε, u, huA, hu0, hEq⟩ + let g : ℂ → ℂ := fun z => (divisorComplementCanonicalProduct m f z₀ z) * u z + have hcompDiff : DifferentiableOn ℂ (divisorComplementCanonicalProduct m f z₀) + (Set.univ : Set ℂ) := + differentiableOn_divisorComplementCanonicalProduct_univ (m := m) (f := f) (z₀ := z₀) h_sum + have hcompCont : ContinuousAt (divisorComplementCanonicalProduct m f z₀) z₀ := + (hcompDiff z₀ (by simp)).differentiableAt (by simp) |>.continuousAt + have hgCont : ContinuousAt g z₀ := (hcompCont.mul huA.continuousAt) + have hg0 : g z₀ ≠ 0 := by + have hcomp0 : divisorComplementCanonicalProduct m f z₀ z₀ ≠ 0 := + divisorComplementCanonicalProduct_ne_zero_at (m := m) (f := f) (z₀ := z₀) h_sum + exact mul_ne_zero hcomp0 hu0 + have hne_mem : ∀ᶠ z in 𝓝[≠] z₀, z ∈ (({z₀} : Set ℂ)ᶜ) := + Filter.eventually_of_mem + (self_mem_nhdsWithin : (({z₀} : Set ℂ)ᶜ) ∈ 𝓝[≠] z₀) (fun _ hz => hz) + have hne : ∀ᶠ z in 𝓝[≠] z₀, z ≠ z₀ := by + filter_upwards [hne_mem] with z hz + simpa [Set.mem_compl_singleton_iff] using hz + have ht_q0 : Tendsto q0 (𝓝[≠] z₀) (𝓝 (g z₀)) := by + have hball : ∀ᶠ z in 𝓝[≠] z₀, z ∈ Metric.ball z₀ ε := + Filter.eventually_of_mem + (mem_nhdsWithin_of_mem_nhds (Metric.ball_mem_nhds z₀ hε)) (fun _ hz => hz) + have heq : q0 =ᶠ[𝓝[≠] z₀] g := by + filter_upwards [hball, hne] with z hz hzne + have hq := hEq z hz hzne + simpa [q0, F, k, g, smul_eq_mul] using hq + exact (hgCont.continuousWithinAt.tendsto.congr' heq.symm) + have hlim : limUnder (𝓝[≠] z₀) q0 = g z₀ := ht_q0.limUnder_eq + have hq0 : q z₀ ≠ 0 := by + have hq_self' : q z₀ = limUnder (𝓝[≠] z₀) q0 := by + simpa [q0, F, k] using hq_self + have : q z₀ = g z₀ := hq_self'.trans hlim + exact this.symm ▸ hg0 + have heq_punct : (fun z : ℂ => F z) =ᶠ[𝓝[≠] z₀] fun z : ℂ => (z - z₀) ^ k • q z := by + filter_upwards [hne] with z hz + have hzpow : (z - z₀) ^ k ≠ 0 := pow_ne_zero _ (sub_ne_zero.mpr hz) + have hq : q z = q0 z := by simpa [q0, F, k] using hq_ne z hz + have hmul : (z - z₀) ^ k * q0 z = F z := by + calc + (z - z₀) ^ k * q0 z + = (((z - z₀) ^ k) * F z) / ((z - z₀) ^ k) := by + simp [q0, div_eq_mul_inv, mul_assoc] + _ = F z := by + simpa [mul_assoc] using (mul_div_cancel_left₀ (F z) hzpow) + have : F z = (z - z₀) ^ k * q z := by + calc + F z = (z - z₀) ^ k * q0 z := hmul.symm + _ = (z - z₀) ^ k * q z := by simp [hq] + simpa [smul_eq_mul] using this + have hcontF : ContinuousAt F z₀ := + (hdiff_univ z₀ (by simp)).differentiableAt (by simp) |>.continuousAt + have hcontq : ContinuousAt q z₀ := hqA.continuousAt + have h_at_z0 : F z₀ = (z₀ - z₀) ^ k • q z₀ := by + have ht1 : Tendsto F (𝓝[≠] z₀) (𝓝 (F z₀)) := hcontF.continuousWithinAt.tendsto + have hpow : + Tendsto (fun z : ℂ => (z - z₀) ^ k) (𝓝[≠] z₀) (𝓝 ((z₀ - z₀) ^ k)) := + ((continuousAt_id.sub continuousAt_const).pow k).continuousWithinAt.tendsto + have ht2 : + Tendsto (fun z : ℂ => (z - z₀) ^ k • q z) (𝓝[≠] z₀) + (𝓝 ((z₀ - z₀) ^ k • q z₀)) := + hpow.mul (hcontq.continuousWithinAt.tendsto) + have ht2' : Tendsto F (𝓝[≠] z₀) (𝓝 ((z₀ - z₀) ^ k • q z₀)) := + ht2.congr' heq_punct.symm + exact tendsto_nhds_unique ht1 ht2' + have hfac : ∀ᶠ z in 𝓝 z₀, F z = (z - z₀) ^ k • q z := by + have hball1 : Metric.ball z₀ 1 ∈ 𝓝 z₀ := Metric.ball_mem_nhds z₀ (by norm_num) + have hball1' : ∀ᶠ z in 𝓝 z₀, z ∈ Metric.ball z₀ 1 := + Filter.eventually_of_mem hball1 (fun _ hz => hz) + filter_upwards [hball1'] with z _hz + by_cases hz0 : z = z₀ + · subst hz0 + simpa using h_at_z0 + · have hzpow : (z - z₀) ^ k ≠ 0 := pow_ne_zero _ (sub_ne_zero.mpr hz0) + have hq : q z = q0 z := by simpa [q0, F, k] using hq_ne z hz0 + have hmul : (z - z₀) ^ k * q0 z = F z := by + calc + (z - z₀) ^ k * q0 z + = (((z - z₀) ^ k) * F z) / ((z - z₀) ^ k) := by + simp [q0, div_eq_mul_inv, mul_assoc] + _ = F z := by + simpa [mul_assoc] using (mul_div_cancel_left₀ (F z) hzpow) + have : F z = (z - z₀) ^ k * q z := by + calc + F z = (z - z₀) ^ k * q0 z := hmul.symm + _ = (z - z₀) ^ k * q z := by simp [hq] + simpa [smul_eq_mul] using this + have hk' : analyticOrderAt F z₀ = k := + (han.analyticOrderAt_eq_natCast (n := k)).2 ⟨q, hqA, hq0, hfac⟩ + have hkNat : analyticOrderNatAt F z₀ = k := by + simp [analyticOrderNatAt, hk'] + simpa [F, k] using hkNat + +theorem analyticOrderNatAt_divisorCanonicalProduct_eq_analyticOrderNatAt + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + {z₀ : ℂ} (hz₀ : z₀ ≠ 0) : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z₀ = + analyticOrderNatAt f z₀ := by + have hcp : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z₀ = + (divisorZeroIndex₀FiberFinset (f := f) z₀).card := + analyticOrderNatAt_divisorCanonicalProduct_eq_fiber_card (m := m) (f := f) (h_sum := h_sum) + (z₀ := z₀) + have hfib : + (divisorZeroIndex₀FiberFinset (f := f) z₀).card = analyticOrderNatAt f z₀ := + divisorZeroIndex₀FiberFinset_card_eq_analyticOrderNatAt (hf := hf) (z₀ := z₀) hz₀ + simpa [hfib] using hcp + +end Complex.Hadamard +end HadamardSourceScope13 + +section HadamardSourceScope14 + +namespace Complex.Hadamard + +open _root_.Complex + +open scoped Topology +open Set + +lemma analyticOrderAt_ne_top_of_exists_ne_zero {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (hnot : ∃ z : ℂ, f z ≠ 0) : + ∀ z : ℂ, analyticOrderAt f z ≠ ⊤ := by + rcases hnot with ⟨z1, hz1⟩ + have hf_an : AnalyticOnNhd ℂ f (Set.univ : Set ℂ) := by + intro z hz + exact (Differentiable.analyticAt (f := f) hf z) + have hz1_not_top : analyticOrderAt f z1 ≠ ⊤ := by + have : analyticOrderAt f z1 = 0 := + (hf.analyticAt z1).analyticOrderAt_eq_zero.2 hz1 + simp [this] + intro z + exact AnalyticOnNhd.analyticOrderAt_ne_top_of_isPreconnected (hf := hf_an) + (U := (Set.univ : Set ℂ)) (x := z1) (y := z) (by simpa using isPreconnected_univ) + (by simp) (by simp) hz1_not_top + +lemma no_zero_on_sphere_of_forall_val_norm_ne + {f : ℂ → ℂ} (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + {B r : ℝ} (hrpos : 0 < r) (hBr : r ≤ B) (hr_not : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖ ≤ B → r ≠ ‖divisorZeroIndex₀Val p‖) : + ∀ u : ℂ, ‖u‖ = r → f u ≠ 0 := by + intro u hur + have hu0 : u ≠ 0 := by + intro hu0 + subst hu0 + have : (0 : ℝ) = r := by simpa using hur + exact (ne_of_gt hrpos) this.symm + intro hfu0 + have hnotTop : analyticOrderAt f u ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (f := f) hf hnot u + have hord_ne0 : analyticOrderNatAt f u ≠ 0 := by + intro h0 + have hEN : (analyticOrderNatAt f u : ENat) = 0 := by simp [h0] + have hAt0 : analyticOrderAt f u = 0 := by + have hcast : (analyticOrderNatAt f u : ENat) = analyticOrderAt f u := + Nat.cast_analyticOrderNatAt (f := f) (z₀ := u) hnotTop + simpa [hcast] using hEN + have han : AnalyticAt ℂ f u := Differentiable.analyticAt (f := f) hf u + exact ((han.analyticOrderAt_eq_zero).1 hAt0) hfu0 + have hcard_pos : 0 < (divisorZeroIndex₀FiberFinset (f := f) u).card := by + have hcard := + divisorZeroIndex₀FiberFinset_card_eq_analyticOrderNatAt (hf := hf) (z₀ := u) hu0 + have : 0 < analyticOrderNatAt f u := Nat.pos_of_ne_zero hord_ne0 + simpa [hcard] using this + rcases Finset.card_pos.mp hcard_pos with ⟨p, hp⟩ + have hpval : divisorZeroIndex₀Val p = u := + (mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := u) p).1 hp + have hpB : ‖divisorZeroIndex₀Val p‖ ≤ B := by + have : ‖divisorZeroIndex₀Val p‖ = r := by simp [hpval, hur] + simpa [this] using hBr + have : r ≠ ‖divisorZeroIndex₀Val p‖ := hr_not p hpB + exact this (by simp [hpval, hur]) + +theorem analyticOrderAt_divisorCanonicalProduct_eq_fiber_card + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z₀ = + ((divisorZeroIndex₀FiberFinset (f := f) z₀).card : ℕ∞) := by + let F : ℂ → ℂ := divisorCanonicalProduct m f (Set.univ : Set ℂ) + have hNat : + analyticOrderNatAt F z₀ = (divisorZeroIndex₀FiberFinset (f := f) z₀).card := by + simpa [F] using + (analyticOrderNatAt_divisorCanonicalProduct_eq_fiber_card + (m := m) (f := f) (h_sum := h_sum) (z₀ := z₀)) + have hdiffOn : DifferentiableOn ℂ F (Set.univ : Set ℂ) := by + simpa [F] using differentiableOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + have hdiff : Differentiable ℂ F := by + intro z + exact (hdiffOn z (by simp)).differentiableAt (by simp) + have hnotTop : analyticOrderAt F z₀ ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (hf := hdiff) + ⟨0, by simp [F, divisorCanonicalProduct_zero]⟩ z₀ + have hcast : (analyticOrderNatAt F z₀ : ℕ∞) = analyticOrderAt F z₀ := + Nat.cast_analyticOrderNatAt (f := F) (z₀ := z₀) hnotTop + have hNatCast : + (analyticOrderNatAt F z₀ : ℕ∞) = + ((divisorZeroIndex₀FiberFinset (f := f) z₀).card : ℕ∞) := by + simp [hNat] + simpa [F, hcast] using hNatCast + +theorem divisorCanonicalProduct_ne_zero_of_forall_ne + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + {z : ℂ} (hz : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), z ≠ divisorZeroIndex₀Val p) : + divisorCanonicalProduct m f (Set.univ : Set ℂ) z ≠ 0 := by + let F : ℂ → ℂ := divisorCanonicalProduct m f (Set.univ : Set ℂ) + have hfiber_empty : divisorZeroIndex₀FiberFinset (f := f) z = ∅ := by + ext p + constructor + · intro hp + exact False.elim (hz p ((mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := z) p).1 hp).symm) + · intro hp + simp at hp + have horder : + analyticOrderAt F z = (0 : ℕ∞) := by + have h := + analyticOrderAt_divisorCanonicalProduct_eq_fiber_card + (m := m) (f := f) (h_sum := h_sum) (z₀ := z) + simpa [F, hfiber_empty] using h + have han : AnalyticAt ℂ F z := by + refine (Complex.analyticAt_iff_eventually_differentiableAt).2 ?_ + refine Filter.Eventually.of_forall ?_ + intro w + exact (((differentiableOn_divisorCanonicalProduct_univ m f h_sum) w + (by simp)).differentiableAt (by simp)) + exact (han.analyticOrderAt_eq_zero).1 horder + +theorem logDeriv_divisorCanonicalProduct_one_eq_tsum_of_forall_ne + {f : ℂ → ℂ} {z : ℂ} + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (2 : ℕ))) + (hz : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), z ≠ divisorZeroIndex₀Val p) : + logDeriv (divisorCanonicalProduct 1 f (Set.univ : Set ℂ)) z = + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := + logDeriv_divisorCanonicalProduct_one_eq_tsum h_sum hz + (divisorCanonicalProduct_ne_zero_of_forall_ne 1 f h_sum hz) + +end Hadamard +end Complex +end HadamardSourceScope14 + +section HadamardSourceScope16 + +namespace Complex.Hadamard + +open _root_.Complex + +open Filter Topology Set _root_.Complex _root_.Erdos970.Complex + +open scoped BigOperators Topology + +noncomputable def hadamardDenom (m : ℕ) (f : ℂ → ℂ) (z : ℂ) : ℂ := + z ^ (analyticOrderNatAt f 0) * divisorCanonicalProduct m f (Set.univ : Set ℂ) z + +theorem differentiable_divisorCanonicalProduct_univ (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + Differentiable ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) := by + intro z + have hdiffOn : + DifferentiableOn ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) (Set.univ : Set ℂ) := + differentiableOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + exact (hdiffOn z (by simp)).differentiableAt (by simp) + +theorem analyticAt_divisorCanonicalProduct_univ (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) (z : ℂ) : + AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := + (differentiable_divisorCanonicalProduct_univ m f h_sum).analyticAt z + +theorem differentiable_hadamardDenom (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + Differentiable ℂ (hadamardDenom m f) := by + have hcprod : Differentiable ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) := by + exact differentiable_divisorCanonicalProduct_univ m f h_sum + simpa [hadamardDenom] using! (differentiable_id.pow (analyticOrderNatAt f 0)).mul hcprod + +theorem hadamardDenom_ne_zero_at {m : ℕ} {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (hnot : ∃ z : ℂ, f z ≠ 0) (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) {z : ℂ} (hz : f z ≠ 0) : hadamardDenom m f z ≠ 0 := by + have hf_not_top : ∀ w : ℂ, analyticOrderAt f w ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (hf := hf) hnot + have han_f : AnalyticAt ℂ f z := hf.analyticAt z + have horder_f : analyticOrderNatAt f z = 0 := by + have : analyticOrderAt f z = 0 := (han_f.analyticOrderAt_eq_zero).2 hz + have hcast : (analyticOrderNatAt f z : ℕ∞) = analyticOrderAt f z := + Nat.cast_analyticOrderNatAt (f := f) (z₀ := z) (hf_not_top z) + have : (analyticOrderNatAt f z : ℕ∞) = 0 := by simp [hcast, this] + exact_mod_cast this + have han_cprod : AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := by + exact analyticAt_divisorCanonicalProduct_univ m f h_sum z + by_cases hz0 : z = 0 + · subst hz0 + have hord0 : analyticOrderNatAt f 0 = 0 := by simpa using horder_f + simp [hadamardDenom, hord0, divisorCanonicalProduct_zero] + · have hp : z ^ (analyticOrderNatAt f 0) ≠ 0 := pow_ne_zero _ hz0 + have hcprod_order : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z = 0 := by + simpa [horder_f] using + (analyticOrderNatAt_divisorCanonicalProduct_eq_analyticOrderNatAt (m := m) (hf := hf) + (h_sum := h_sum) (z₀ := z) hz0) + have hcprod_ne : divisorCanonicalProduct m f (Set.univ : Set ℂ) z ≠ 0 := by + have hcprod_entire : + Differentiable ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) := by + exact differentiable_divisorCanonicalProduct_univ m f h_sum + have hcprod_not_top : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (hf := hcprod_entire) + ⟨0, by simp [divisorCanonicalProduct_zero]⟩ z + have hcprod_cast : + (analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z : ℕ∞) = + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := + Nat.cast_analyticOrderNatAt + (f := divisorCanonicalProduct m f (Set.univ : Set ℂ)) (z₀ := z) hcprod_not_top + have : analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z = 0 := by + have : + (analyticOrderNatAt + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z : ℕ∞) = 0 := by + exact_mod_cast hcprod_order + simp [hcprod_cast] at this + simpa using this + exact (han_cprod.analyticOrderAt_eq_zero).1 this + exact mul_ne_zero hp hcprod_ne + +lemma analyticOrderNatAt_divisorCanonicalProduct_zero + (m : ℕ) (f : ℂ → ℂ) (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 = 0 := by + have hcprod_entire : + Differentiable ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) := by + exact differentiable_divisorCanonicalProduct_univ m f h_sum + have hcprod_not_top : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (hf := hcprod_entire) + ⟨0, by simp [divisorCanonicalProduct_zero]⟩ 0 + have hcprodA : AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 := + hcprod_entire.analyticAt 0 + have hcprod0 : divisorCanonicalProduct m f (Set.univ : Set ℂ) 0 ≠ 0 := by + simp [divisorCanonicalProduct_zero] + have : analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 = 0 := + (hcprodA.analyticOrderAt_eq_zero).2 hcprod0 + have hcast : + (analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 : ℕ∞) = + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 := + Nat.cast_analyticOrderNatAt + (f := divisorCanonicalProduct m f (Set.univ : Set ℂ)) (z₀ := (0 : ℂ)) hcprod_not_top + have : + (analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 : ℕ∞) = + 0 := by + simp [hcast, this] + exact_mod_cast this + +theorem analyticOrderNatAt_hadamardDenom_eq + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) (z : ℂ) : + analyticOrderNatAt (hadamardDenom m f) z = analyticOrderNatAt f z := by + by_cases hz0 : z = 0 + · subst hz0 + have hpowA : AnalyticAt ℂ (fun z : ℂ => z ^ analyticOrderNatAt f 0) 0 := by + simpa using! (analyticAt_id.pow (analyticOrderNatAt f 0)) + have hpow_not_top : + analyticOrderAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) 0 ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero + (hf := (differentiable_id.pow (analyticOrderNatAt f 0))) + ⟨1, by simp⟩ 0 + have hcprodA : AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 := by + exact analyticAt_divisorCanonicalProduct_univ m f h_sum 0 + have hcprod0 : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 = 0 := + analyticOrderNatAt_divisorCanonicalProduct_zero (m := m) (f := f) h_sum + have hid0 : analyticOrderNatAt (fun z : ℂ => z) 0 = 1 := by + have hid_entire : Differentiable ℂ (fun z : ℂ => z) := differentiable_id + have hdiv : + (MeromorphicOn.divisor (fun z : ℂ => z) (Set.univ : Set ℂ)) 0 = + (analyticOrderNatAt (fun z : ℂ => z) 0 : ℤ) := by + simpa using + (divisor_univ_eq_analyticOrderNatAt_int + (f := fun z : ℂ => z) hid_entire 0) + have hdiv1 : (MeromorphicOn.divisor (fun z : ℂ => z) (Set.univ : Set ℂ)) 0 = 1 := by + simpa using + (MeromorphicOn.divisor_sub_const_self (z₀ := (0 : ℂ)) + (U := (Set.univ : Set ℂ)) (by simp)) + have : (analyticOrderNatAt (fun z : ℂ => z) 0 : ℤ) = 1 := by + simpa [hdiv] using hdiv1 + exact_mod_cast this + have hpow0 : + analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) 0 = + analyticOrderNatAt f 0 := by + have hidA : AnalyticAt ℂ (fun z : ℂ => z) 0 := by + simpa [id] using! (analyticAt_id : AnalyticAt ℂ (id : ℂ → ℂ) 0) + simpa [hid0] using! (analyticOrderNatAt_pow (hf := hidA) (n := analyticOrderNatAt f 0)) + have hmul : + analyticOrderNatAt (hadamardDenom m f) 0 = + analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) 0 + + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 := by + have hcprod_not_top' : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero + (hf := differentiable_divisorCanonicalProduct_univ m f h_sum) + ⟨0, by simp [divisorCanonicalProduct_zero]⟩ 0 + simpa [hadamardDenom] using! + analyticOrderNatAt_mul (hf := hpowA) (hg := hcprodA) + (hf' := hpow_not_top) (hg' := hcprod_not_top') + simp [hmul, hpow0, hcprod0] + · have hpowA : AnalyticAt ℂ (fun z : ℂ => z ^ analyticOrderNatAt f 0) z := by + simpa using! (analyticAt_id.pow (analyticOrderNatAt f 0)) + have hpow_not_top : + analyticOrderAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero + (hf := (differentiable_id.pow (analyticOrderNatAt f 0))) + ⟨1, by simp⟩ z + have hpow0 : analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z = 0 := by + have hz' : (fun z : ℂ => z ^ analyticOrderNatAt f 0) z ≠ 0 := by + simp [hz0] + have : analyticOrderAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z = 0 := + ((hpowA).analyticOrderAt_eq_zero).2 hz' + have hcast : (analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z : ℕ∞) = + analyticOrderAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z := + Nat.cast_analyticOrderNatAt + (f := fun z : ℂ => z ^ analyticOrderNatAt f 0) (z₀ := z) hpow_not_top + have : (analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z : ℕ∞) = 0 := by + simp [hcast, this] + exact_mod_cast this + have hcprod_eq : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z = + analyticOrderNatAt f z := + analyticOrderNatAt_divisorCanonicalProduct_eq_analyticOrderNatAt + (m := m) (hf := hf) (h_sum := h_sum) (z₀ := z) hz0 + have hcprodA : AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := by + exact analyticAt_divisorCanonicalProduct_univ m f h_sum z + have hcprod_not_top : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero + (hf := differentiable_divisorCanonicalProduct_univ m f h_sum) + ⟨0, by simp [divisorCanonicalProduct_zero]⟩ z + have hmul : + analyticOrderNatAt (hadamardDenom m f) z = + analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z + + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := by + simpa [hadamardDenom] using! + analyticOrderNatAt_mul (hf := hpowA) (hg := hcprodA) + (hf' := hpow_not_top) (hg' := hcprod_not_top) + simp [hmul, hpow0, hcprod_eq] + +theorem divisor_hadamardDenom_eq + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + MeromorphicOn.divisor (hadamardDenom m f) (Set.univ : Set ℂ) = + MeromorphicOn.divisor f (Set.univ : Set ℂ) := by + ext z + have hden_entire : Differentiable ℂ (hadamardDenom m f) := + differentiable_hadamardDenom (m := m) f h_sum + have hf_entire : Differentiable ℂ f := hf + have hden : + (MeromorphicOn.divisor (hadamardDenom m f) (Set.univ : Set ℂ)) z = + (analyticOrderNatAt (hadamardDenom m f) z : ℤ) := by + simpa using (divisor_univ_eq_analyticOrderNatAt_int (f := hadamardDenom m f) hden_entire z) + have hfz : + (MeromorphicOn.divisor f (Set.univ : Set ℂ)) z = + (analyticOrderNatAt f z : ℤ) := by + simpa using (divisor_univ_eq_analyticOrderNatAt_int (f := f) hf_entire z) + simp [hden, hfz, analyticOrderNatAt_hadamardDenom_eq (m := m) (hf := hf) (h_sum := h_sum) z] + +theorem divisor_hadamardQuotient_eq_zero + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + MeromorphicOn.divisor (fun z : ℂ => f z / hadamardDenom m f z) (Set.univ : Set ℂ) = 0 := by + have hf_mero : MeromorphicOn f (Set.univ : Set ℂ) := by + intro z hz + exact (hf.analyticAt z).meromorphicAt + have hden_entire : Differentiable ℂ (hadamardDenom m f) := + differentiable_hadamardDenom (m := m) f h_sum + have hden_mero : MeromorphicOn (hadamardDenom m f) (Set.univ : Set ℂ) := by + intro z hz + exact (hden_entire.analyticAt z).meromorphicAt + rcases hnot with ⟨z1, hz1⟩ + have hden1 : hadamardDenom m f z1 ≠ 0 := + hadamardDenom_ne_zero_at (m := m) (f := f) hf ⟨z1, hz1⟩ h_sum hz1 + have hf_order_ne_top : ∀ z ∈ (Set.univ : Set ℂ), meromorphicOrderAt f z ≠ ⊤ := by + intro z hzU + have hz1_ne_top : meromorphicOrderAt f z1 ≠ ⊤ := by + have hfAt : MeromorphicAt f z1 := hf_mero z1 (by simp) + have hcont : ContinuousAt f z1 := (hf.differentiableAt).continuousAt + have hne_nhds : ∀ᶠ w in 𝓝 z1, f w ≠ 0 := + (hcont.ne_iff_eventually_ne continuousAt_const).1 hz1 + have hne_nhdsNE : ∀ᶠ w in 𝓝[≠] z1, f w ≠ 0 := + eventually_nhdsWithin_of_eventually_nhds hne_nhds + exact (meromorphicOrderAt_ne_top_iff_eventually_ne_zero (hf := hfAt)).2 hne_nhdsNE + exact MeromorphicOn.meromorphicOrderAt_ne_top_of_isPreconnected (hf := hf_mero) + (x := z1) (hU := isPreconnected_univ) (h₁x := by simp) (hy := by simp) hz1_ne_top + have hden_order_ne_top : + ∀ z ∈ (Set.univ : Set ℂ), meromorphicOrderAt (hadamardDenom m f) z ≠ ⊤ := by + intro z hzU + have hz1_ne_top : meromorphicOrderAt (hadamardDenom m f) z1 ≠ ⊤ := by + have hdenAt : MeromorphicAt (hadamardDenom m f) z1 := hden_mero z1 (by simp) + have hcont : ContinuousAt (hadamardDenom m f) z1 := + (hden_entire.differentiableAt).continuousAt + have hne_nhds : ∀ᶠ w in 𝓝 z1, hadamardDenom m f w ≠ 0 := + (hcont.ne_iff_eventually_ne continuousAt_const).1 hden1 + have hne_nhdsNE : ∀ᶠ w in 𝓝[≠] z1, hadamardDenom m f w ≠ 0 := + eventually_nhdsWithin_of_eventually_nhds hne_nhds + exact (meromorphicOrderAt_ne_top_iff_eventually_ne_zero (hf := hdenAt)).2 hne_nhdsNE + exact MeromorphicOn.meromorphicOrderAt_ne_top_of_isPreconnected (hf := hden_mero) + (x := z1) (hU := isPreconnected_univ) (h₁x := by simp) (hy := by simp) hz1_ne_top + have hinv_order_ne_top : + ∀ z ∈ (Set.univ : Set ℂ), + meromorphicOrderAt (fun z : ℂ => (hadamardDenom m f z)⁻¹) z ≠ ⊤ := by + intro z hzU + have hinv_mero : + MeromorphicOn (fun z : ℂ => (hadamardDenom m f z)⁻¹) (Set.univ : Set ℂ) := + hden_mero.inv + have hz1_ne_top : + meromorphicOrderAt (fun z : ℂ => (hadamardDenom m f z)⁻¹) z1 ≠ ⊤ := by + have hinvAt : MeromorphicAt (fun z : ℂ => (hadamardDenom m f z)⁻¹) z1 := + hinv_mero z1 (by simp) + have hcont_denom : ContinuousAt (hadamardDenom m f) z1 := + (hden_entire.differentiableAt).continuousAt + have hcont : ContinuousAt (fun z : ℂ => (hadamardDenom m f z)⁻¹) z1 := + hcont_denom.inv₀ hden1 + have hinv1 : (fun z : ℂ => (hadamardDenom m f z)⁻¹) z1 ≠ 0 := by + simpa using inv_ne_zero hden1 + have hne_nhds : + ∀ᶠ w in 𝓝 z1, (fun z : ℂ => (hadamardDenom m f z)⁻¹) w ≠ 0 := + (hcont.ne_iff_eventually_ne continuousAt_const).1 hinv1 + have hne_nhdsNE : + ∀ᶠ w in 𝓝[≠] z1, (fun z : ℂ => (hadamardDenom m f z)⁻¹) w ≠ 0 := + eventually_nhdsWithin_of_eventually_nhds hne_nhds + exact (meromorphicOrderAt_ne_top_iff_eventually_ne_zero (hf := hinvAt)).2 hne_nhdsNE + exact MeromorphicOn.meromorphicOrderAt_ne_top_of_isPreconnected (hf := hinv_mero) + (x := z1) (hU := isPreconnected_univ) (h₁x := by simp) (hy := by simp) hz1_ne_top + have hdiv_denom : MeromorphicOn.divisor (hadamardDenom m f) (Set.univ : Set ℂ) = + MeromorphicOn.divisor f (Set.univ : Set ℂ) := + divisor_hadamardDenom_eq (m := m) (hf := hf) (h_sum := h_sum) + calc + MeromorphicOn.divisor (fun z : ℂ => f z / hadamardDenom m f z) (Set.univ : Set ℂ) + = MeromorphicOn.divisor + (fun z : ℂ => f z * (hadamardDenom m f z)⁻¹) (Set.univ : Set ℂ) := by + simp [div_eq_mul_inv] + _ = MeromorphicOn.divisor f (Set.univ : Set ℂ) + + MeromorphicOn.divisor (fun z : ℂ => (hadamardDenom m f z)⁻¹) (Set.univ : Set ℂ) := by + simpa using (MeromorphicOn.divisor_fun_mul (U := (Set.univ : Set ℂ)) + (f₁ := f) (f₂ := fun z => (hadamardDenom m f z)⁻¹) hf_mero (hden_mero.inv) + hf_order_ne_top hinv_order_ne_top) + _ = MeromorphicOn.divisor f (Set.univ : Set ℂ) - + MeromorphicOn.divisor (hadamardDenom m f) (Set.univ : Set ℂ) := by + simp [sub_eq_add_neg] + _ = 0 := by + simp [hdiv_denom] + +theorem exists_entire_nonzero_hadamardQuotient + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + ∃ H : ℂ → ℂ, Differentiable ℂ H ∧ (∀ z, H z ≠ 0) ∧ ∀ z : ℂ, f z = + H z * z ^ (analyticOrderNatAt f 0) * divisorCanonicalProduct m f (Set.univ : Set ℂ) z := by + let denom : ℂ → ℂ := hadamardDenom m f + let q : ℂ → ℂ := fun z => f z / denom z + have hden_entire : Differentiable ℂ denom := + differentiable_hadamardDenom (m := m) f h_sum + have hq_mero : MeromorphicOn q (Set.univ : Set ℂ) := by + intro z hzU + have hf_m : MeromorphicAt f z := (hf.analyticAt z).meromorphicAt + have hden_m : MeromorphicAt denom z := (hden_entire.analyticAt z).meromorphicAt + simpa [q, denom, div_eq_mul_inv] using! (hf_m.mul hden_m.inv) + let H : ℂ → ℂ := toMeromorphicNFOn q (Set.univ : Set ℂ) + have hNF : MeromorphicNFOn H (Set.univ : Set ℂ) := + meromorphicNFOn_toMeromorphicNFOn q (Set.univ : Set ℂ) + have hdivH : MeromorphicOn.divisor H (Set.univ : Set ℂ) = 0 := by + have hdivq : MeromorphicOn.divisor q (Set.univ : Set ℂ) = 0 := + divisor_hadamardQuotient_eq_zero (m := m) (f := f) (hf := hf) + (hnot := hnot) (h_sum := h_sum) + simpa [H, hdivq] using + (MeromorphicOn.divisor_of_toMeromorphicNFOn + (f := q) (U := (Set.univ : Set ℂ)) hq_mero) + have hA : AnalyticOnNhd ℂ H (Set.univ : Set ℂ) := by + have : + (0 : Function.locallyFinsuppWithin (Set.univ : Set ℂ) ℤ) ≤ + MeromorphicOn.divisor H (Set.univ : Set ℂ) := by + simp [hdivH] + exact (MeromorphicNFOn.divisor_nonneg_iff_analyticOnNhd (h₁f := hNF)).1 (by simp [hdivH]) + have hH_entire : Differentiable ℂ H := by + intro z + exact (hA z (by simp)).differentiableAt + rcases hnot with ⟨z1, hz1⟩ + have hden1 : denom z1 ≠ 0 := + hadamardDenom_ne_zero_at (m := m) (f := f) hf ⟨z1, hz1⟩ h_sum hz1 + have hqA1 : AnalyticAt ℂ q z1 := by + have hdenA1 : AnalyticAt ℂ denom z1 := hden_entire.analyticAt z1 + exact (hf.analyticAt z1).div hdenA1 hden1 + have hqNF1 : MeromorphicNFAt q z1 := hqA1.meromorphicNFAt + have htoEq : toMeromorphicNFAt q z1 = q := (toMeromorphicNFAt_eq_self (f := q) (x := z1)).2 hqNF1 + have hH1 : H z1 = q z1 := by + have hx : z1 ∈ (Set.univ : Set ℂ) := by simp + have : toMeromorphicNFOn q (Set.univ : Set ℂ) z1 = toMeromorphicNFAt q z1 z1 := + (toMeromorphicNFOn_eq_toMeromorphicNFAt (f := q) (U := (Set.univ : Set ℂ)) hq_mero hx) + simpa [H, htoEq] using this + have hH1_ne : H z1 ≠ 0 := by + have : q z1 ≠ 0 := div_ne_zero hz1 hden1 + simpa [hH1] using this + have hH_not_top : ∀ z : ℂ, analyticOrderAt H z ≠ ⊤ := by + exact analyticOrderAt_ne_top_of_exists_ne_zero (hf := hH_entire) ⟨z1, hH1_ne⟩ + have hH_orderNat_zero : ∀ z : ℂ, analyticOrderNatAt H z = 0 := by + intro z + have hzdiv : + (MeromorphicOn.divisor H (Set.univ : Set ℂ)) z = (analyticOrderNatAt H z : ℤ) := by + simpa using (divisor_univ_eq_analyticOrderNatAt_int (f := H) hH_entire z) + have : (MeromorphicOn.divisor H (Set.univ : Set ℂ)) z = 0 := by + simp [hdivH] + have : (analyticOrderNatAt H z : ℤ) = 0 := by simpa [hzdiv] using this + exact_mod_cast this + have hH_ne : ∀ z : ℂ, H z ≠ 0 := by + intro z + have hcast : (analyticOrderNatAt H z : ℕ∞) = analyticOrderAt H z := + Nat.cast_analyticOrderNatAt (f := H) (z₀ := z) (hH_not_top z) + have : analyticOrderAt H z = 0 := by + have : (analyticOrderNatAt H z : ℕ∞) = 0 := by exact_mod_cast (hH_orderNat_zero z) + simpa [hcast] using this + exact ((hA z (by simp)).analyticOrderAt_eq_zero).1 this + have hfA : AnalyticOnNhd ℂ f (Set.univ : Set ℂ) := fun z hzU => hf.analyticAt z + have hdenA : AnalyticOnNhd ℂ denom (Set.univ : Set ℂ) := fun z hzU => hden_entire.analyticAt z + have hprodA : AnalyticOnNhd ℂ (fun z => H z * denom z) (Set.univ : Set ℂ) := + (hA.mul hdenA) + have hlocal : f =ᶠ[𝓝 z1] fun z => H z * denom z := by + have hden_ne : ∀ᶠ z in 𝓝 z1, denom z ≠ 0 := + (hden_entire.differentiableAt.continuousAt.ne_iff_eventually_ne continuousAt_const).1 hden1 + have hH_eq_q : H =ᶠ[𝓝 z1] q := by + have hx : z1 ∈ (Set.univ : Set ℂ) := by simp + have hloc : + toMeromorphicNFOn q (Set.univ : Set ℂ) =ᶠ[𝓝 z1] toMeromorphicNFAt q z1 := by + simpa [H] using (toMeromorphicNFOn_eq_toMeromorphicNFAt_on_nhds (f := q) + (U := (Set.univ : Set ℂ)) hq_mero hx) + simpa [H, htoEq] using hloc + filter_upwards [hden_ne, hH_eq_q] with z hzden hHz + have hcancel : q z * denom z = f z := by + dsimp [q] + field_simp [hzden] + calc + f z = q z * denom z := hcancel.symm + _ = H z * denom z := by simp [hHz] + have hglob : f = fun z => H z * denom z := + AnalyticOnNhd.eq_of_eventuallyEq (hf := hfA) (hg := hprodA) hlocal + refine ⟨H, hH_entire, hH_ne, ?_⟩ + intro z + have hglobz : f z = H z * denom z := congrArg (fun g => g z) hglob + simpa [denom, hadamardDenom, mul_assoc, mul_left_comm, mul_comm] using hglobz + +end Complex.Hadamard +end HadamardSourceScope16 + +section HadamardSourceScope17 + +open Filter _root_.Function _root_.MeromorphicOn _root_.Erdos970.MeromorphicOn Metric + _root_.Real _root_.Erdos970.Real Set + +namespace Function.locallyFinsuppWithin + +open _root_.Function.locallyFinsuppWithin + +variable {E : Type*} [NormedAddCommGroup E] + +lemma norm_le_abs_of_mem_toClosedBall_support {D : locallyFinsupp E ℤ} {r : ℝ} {z : E} + (hz : z ∈ (toClosedBall r D).support) : ‖z‖ ≤ |r| := by + have hz_ball : z ∈ closedBall (0 : E) |r| := (toClosedBall r D).supportWithinDomain hz + simpa [mem_closedBall, dist_zero_right] using hz_ball + +lemma toClosedBall_eval_eq_of_norm_le_abs {D : locallyFinsupp E ℤ} {r : ℝ} {z : E} + (hz : ‖z‖ ≤ |r|) : toClosedBall r D z = D z := by + have hz_ball : z ∈ closedBall (0 : E) |r| := by + simpa [mem_closedBall, dist_zero_right] using hz + simpa using toClosedBall_eval_within (f := D) hz_ball + +lemma mem_toClosedBall_support_of_mem_support_of_norm_le_abs + {D : locallyFinsupp E ℤ} {r : ℝ} {z : E} (hzD : z ∈ D.support) (hzR : ‖z‖ ≤ |r|) : + z ∈ (toClosedBall r D).support := by + rw [Function.mem_support] + rw [toClosedBall_eval_eq_of_norm_le_abs hzR] + rwa [Function.mem_support] at hzD + +lemma mem_support_of_mem_toClosedBall_support {D : locallyFinsupp E ℤ} {r : ℝ} {z : E} + (hz : z ∈ (toClosedBall r D).support) : z ∈ D.support := by + have hnorm : ‖z‖ ≤ |r| := norm_le_abs_of_mem_toClosedBall_support hz + rw [Function.mem_support] at hz ⊢ + rw [toClosedBall_eval_eq_of_norm_le_abs hnorm] at hz + exact hz + +noncomputable def massClosedBall₀ {E : Type*} [NormedAddCommGroup E] [ProperSpace E] + (D : locallyFinsupp E ℤ) (R : ℝ) : ℝ := by + classical + exact + (((finiteSupport (toClosedBall R D) (isCompact_closedBall (0 : E) |R|)).toFinset).filter + (fun z => z ≠ (0 : E))).sum fun z => (D z : ℝ) + +end Function.locallyFinsuppWithin + +namespace Function.locallyFinsuppWithin + +open _root_.Function.locallyFinsuppWithin + +theorem logCounting_divisor_eq_circleAverage_sub_const_of_differentiable + {R : ℝ} {f : ℂ → ℂ} (hf : Differentiable ℂ f) (hR : R ≠ 0) : + logCounting (divisor f ⊤) R = + circleAverage (log ‖f ·‖) 0 R - log ‖meromorphicTrailingCoeffAt f 0‖ := by + have hmero : Meromorphic f := fun z => (hf.analyticAt z).meromorphicAt + simpa [top_eq_univ] using + logCounting_divisor_eq_circleAverage_sub_const (f := f) hmero hR + +end Function.locallyFinsuppWithin +end HadamardSourceScope17 + +section HadamardSourceScope18 + +namespace Real + +open _root_.Real + +theorem log_one_add_exp_le_add_log_two {x : ℝ} (hx : 0 ≤ x) : + log (1 + exp x) ≤ x + log 2 := by + have hexp_one : (1 : ℝ) ≤ exp x := by + simpa using (one_le_exp_iff.2 hx) + have hadd : 1 + exp x ≤ 2 * exp x := by linarith + have hlog : log (1 + exp x) ≤ log (2 * exp x) := + log_le_log (by positivity) hadd + calc + log (1 + exp x) ≤ log (2 * exp x) := hlog + _ = log 2 + x := by simp [log_mul, add_comm] + _ = x + log 2 := by ring + +theorem log_one_add_le_add_log_two_of_le_exp {x y : ℝ} (hy : 0 ≤ y) (hx : 0 ≤ x) + (hxy : y ≤ exp x) : + log (1 + y) ≤ x + log 2 := by + have hpos : 0 < (1 : ℝ) + y := by linarith + have hle : (1 : ℝ) + y ≤ 1 + exp x := by linarith + exact (log_le_log hpos hle).trans (log_one_add_exp_le_add_log_two hx) + +theorem le_exp_of_log_one_add_le {x y : ℝ} (hy : 0 ≤ y) (hxy : log (1 + y) ≤ x) : + y ≤ exp x := by + have hpos : 0 < (1 : ℝ) + y := by linarith + have hone : 1 + y ≤ exp x := (log_le_iff_le_exp hpos).1 hxy + linarith + +theorem neg_posLog_inv_le_log (x : ℝ) : -log⁺ x⁻¹ ≤ log x := by + linarith [posLog_sub_posLog_inv (x := x), posLog_nonneg (x := x)] + +end Real +end HadamardSourceScope18 + +section HadamardSourceScope20 + +namespace Real + +open _root_.Real + +variable {α E : Type*} [SeminormedAddCommGroup E] + +theorem log_norm_le_log_one_add_norm (w : E) : + Real.log ‖w‖ ≤ Real.log (1 + ‖w‖) := by + by_cases h0 : ‖w‖ = 0 + · simp [h0] + · have hpos : 0 < ‖w‖ := lt_of_le_of_ne (norm_nonneg w) (Ne.symm h0) + exact Real.log_le_log hpos (by linarith [norm_nonneg w]) + +variable {F : Type*} [NormedAddCommGroup F] + +theorem log_nonneg_mul_inv_norm_of_norm_le {z : F} {r : ℝ} (hz : ‖z‖ ≤ r) : + 0 ≤ Real.log (r * ‖z‖⁻¹) := by + by_cases hz0 : z = 0 + · simp [hz0] + · have hzpos : 0 < ‖z‖ := norm_pos_iff.2 hz0 + have : (1 : ℝ) ≤ r * ‖z‖⁻¹ := by + have : (1 : ℝ) ≤ r / ‖z‖ := (one_le_div hzpos).2 hz + simpa [div_eq_mul_inv] using this + exact Real.log_nonneg this + +theorem log_two_le_log_two_mul_mul_inv_norm_of_norm_le {z : F} {R : ℝ} (hz0 : z ≠ 0) + (hz : ‖z‖ ≤ R) : + Real.log 2 ≤ Real.log ((2 * R) * ‖z‖⁻¹) := by + have hzpos : 0 < ‖z‖ := norm_pos_iff.2 hz0 + have hRdiv : (1 : ℝ) ≤ R / ‖z‖ := (one_le_div hzpos).2 hz + have hle2 : (2 : ℝ) ≤ (2 * R) * ‖z‖⁻¹ := by + have : (2 : ℝ) ≤ 2 * (R / ‖z‖) := by nlinarith + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using this + exact Real.log_le_log (by norm_num) hle2 + +theorem norm_le_exp_mul_rpow_of_exponent_le + {f : α → E} {r : α → ℝ} {C ρ τ : ℝ} (hC : 0 ≤ C) (hr : ∀ x, 1 ≤ r x) (hρτ : ρ ≤ τ) + (hbound : ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ ρ)) : ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ τ) := by + intro x + refine (hbound x).trans (Real.exp_le_exp.2 ?_) + exact mul_le_mul_of_nonneg_left (Real.rpow_le_rpow_of_exponent_le (hr x) hρτ) hC + +theorem norm_le_exp_mul_rpow_of_log_growth + {f : α → E} {r : α → ℝ} {C ρ τ : ℝ} (hC : 0 ≤ C) (hr : ∀ x, 1 ≤ r x) (hρτ : ρ ≤ τ) + (hlog : ∀ x, Real.log (1 + ‖f x‖) ≤ C * (r x) ^ ρ) : ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ τ) := by + intro x + have hpow : (r x) ^ ρ ≤ (r x) ^ τ := + Real.rpow_le_rpow_of_exponent_le (hr x) hρτ + have hlogτ : Real.log (1 + ‖f x‖) ≤ C * (r x) ^ τ := + (hlog x).trans (mul_le_mul_of_nonneg_left hpow hC) + exact Real.le_exp_of_log_one_add_le (norm_nonneg (f x)) hlogτ + +theorem log_growth_of_norm_le_exp_mul_rpow + {f : α → E} {r : α → ℝ} {C τ : ℝ} (hC : 0 < C) (hτ : 0 ≤ τ) + (hr : ∀ x, 1 ≤ r x) (hbound : ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ τ)) : + ∃ C' > 0, ∀ x, Real.log (1 + ‖f x‖) ≤ C' * (r x) ^ τ := by + refine ⟨C + Real.log 2, by + have hlog2 : 0 ≤ Real.log 2 := Real.log_nonneg (by norm_num) + linarith, ?_⟩ + intro x + have hX : (1 : ℝ) ≤ (r x) ^ τ := Real.one_le_rpow (hr x) hτ + have hB : 0 ≤ C * (r x) ^ τ := + mul_nonneg hC.le (Real.rpow_nonneg (le_trans zero_le_one (hr x)) _) + have hlog : + Real.log (1 + ‖f x‖) ≤ C * (r x) ^ τ + Real.log 2 := + Real.log_one_add_le_add_log_two_of_le_exp (norm_nonneg _) hB (hbound x) + have hlog2_nonneg : 0 ≤ Real.log 2 := Real.log_nonneg (by norm_num) + nlinarith [hlog, hX, hlog2_nonneg] + +theorem exists_norm_le_exp_mul_pow_of_rpow_bound + {f : α → E} {r : α → ℝ} {τ : ℝ} {n : ℕ} (hr : ∀ x, 1 ≤ r x) (hτn : τ < (n : ℝ)) + (hbound : ∃ C > 0, ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ τ)) : + ∃ C > 0, ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ n) := by + rcases hbound with ⟨C, hCpos, hC⟩ + have hweak : + ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ (n : ℝ)) := + norm_le_exp_mul_rpow_of_exponent_le + (f := f) (r := r) hCpos.le hr (le_of_lt hτn) hC + refine ⟨C, hCpos, ?_⟩ + intro x + have hpow : (r x) ^ (n : ℝ) = (r x) ^ n := Real.rpow_natCast (r x) n + simpa [hpow] using hweak x + +theorem one_add_le_three_mul_one_add_of_le_two_mul_max {x r : ℝ} (hx : 0 ≤ x) + (hr : r ≤ 2 * max x 1) : 1 + r ≤ 3 * (1 + x) := by + have hmax : max x 1 ≤ 1 + x := max_le_iff.2 ⟨by linarith, by linarith⟩ + nlinarith + +theorem exp_mul_rpow_le_exp_mul_rpow_of_le_mul + {A B x y τ : ℝ} (hA : 0 ≤ A) (hB : 0 ≤ B) (hx : 0 ≤ x) (hy : 0 ≤ y) + (hτ : 0 ≤ τ) (hxy : x ≤ B * y) : Real.exp (A * x ^ τ) ≤ Real.exp ((A * B ^ τ) * y ^ τ) := by + refine Real.exp_le_exp.2 ?_ + have hpow : x ^ τ ≤ (B * y) ^ τ := Real.rpow_le_rpow hx hxy hτ + have hsplit : (B * y) ^ τ = B ^ τ * y ^ τ := by + simpa using (Real.mul_rpow (x := B) (y := y) (z := τ) hB hy) + simpa [mul_assoc] using mul_le_mul_of_nonneg_left (hpow.trans_eq hsplit) hA + +theorem exists_between_self_and_floor_add_one_same_floor {ρ : ℝ} (hρ : 0 ≤ ρ) : + ∃ τ : ℝ, ρ < τ ∧ τ < (Nat.floor ρ + 1 : ℝ) ∧ 0 ≤ τ ∧ Nat.floor τ = Nat.floor ρ := by + set m : ℕ := Nat.floor ρ + set τ : ℝ := (ρ + (m + 1 : ℝ)) / 2 + have hm : ρ < (m + 1 : ℝ) := by simpa [m] using Nat.lt_floor_add_one (a := ρ) + have hτ : ρ < τ := by dsimp [τ]; linarith + have hτ_lt : τ < (m + 1 : ℝ) := by dsimp [τ]; linarith + have hτ_nonneg : 0 ≤ τ := le_trans hρ (le_of_lt hτ) + have hfloorτ : Nat.floor τ = m := by + have hm_le_τ : (m : ℝ) ≤ τ := le_trans (Nat.floor_le hρ) (le_of_lt hτ) + have hτ_lt_m1 : τ < (m : ℝ) + 1 := by simpa [add_assoc, add_comm, add_left_comm] using hτ_lt + exact (Nat.floor_eq_iff hτ_nonneg).2 ⟨hm_le_τ, hτ_lt_m1⟩ + exact ⟨τ, hτ, by simpa [m] using hτ_lt, hτ_nonneg, by simpa [m] using hfloorτ⟩ + +open Metric _root_.Complex _root_.Erdos970.Complex + +theorem log_norm_le_of_log_one_add_growth_on_sphere {f : ℂ → ℂ} {C ρ R : ℝ} + (hC : ∀ z : ℂ, _root_.Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) {z : ℂ} + (hz : z ∈ sphere (0 : ℂ) |R|) : _root_.Real.log ‖f z‖ ≤ C * (1 + |R|) ^ ρ := by + have hz_norm : ‖z‖ = |R| := by + simpa [mem_sphere, dist_zero_right] using hz + simpa [hz_norm] using le_trans (log_norm_le_log_one_add_norm (f z)) (hC z) + +end Real +end HadamardSourceScope20 + +section HadamardSourceScope21 + +open Filter _root_.Function _root_.Erdos970.Function _root_.MeromorphicOn + _root_.Erdos970.MeromorphicOn Metric _root_.Real _root_.Erdos970.Real Set + +namespace Function.locallyFinsuppWithin + +open _root_.Function.locallyFinsuppWithin + +theorem logCounting_divisor_le_of_log_growth {f : ℂ → ℂ} {ρ C : ℝ} (hf : Differentiable ℂ f) + (hC : ∀ z : ℂ, log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) {R : ℝ} (hR0 : 0 < R) : + logCounting (divisor f (Set.univ : Set ℂ)) R + ≤ C * (1 + |R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + have hR : R ≠ 0 := ne_of_gt hR0 + have hEq := + logCounting_divisor_eq_circleAverage_sub_const_of_differentiable (f := f) hf hR + have hf_sphere : MeromorphicOn f (sphere (0 : ℂ) |R|) := by + intro z hz + exact (hf.analyticAt z).meromorphicAt + have hInt : CircleIntegrable (fun z : ℂ => log ‖f z‖) 0 R := + MeromorphicOn.circleIntegrable_log_norm hf_sphere + have hbound_circle : ∀ z ∈ sphere (0 : ℂ) |R|, + log ‖f z‖ ≤ C * (1 + |R|) ^ ρ := by + intro z hz + exact log_norm_le_of_log_one_add_growth_on_sphere hC hz + have hCircleAvg_le : + circleAverage (fun z : ℂ => log ‖f z‖) 0 R ≤ C * (1 + |R|) ^ ρ := + circleAverage_mono_on_of_le_circle (c := (0 : ℂ)) (R := R) + (f := fun z => log ‖f z‖) hInt hbound_circle + calc + logCounting (divisor f (Set.univ : Set ℂ)) R + = circleAverage (fun z : ℂ => log ‖f z‖) 0 R + - log ‖meromorphicTrailingCoeffAt f 0‖ := by + simpa [top_eq_univ] using hEq + _ ≤ circleAverage (fun z : ℂ => log ‖f z‖) 0 R + + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + have : + -log ‖meromorphicTrailingCoeffAt f 0‖ + ≤ |log ‖meromorphicTrailingCoeffAt f 0‖| := + neg_le_abs (log ‖meromorphicTrailingCoeffAt f 0‖) + linarith + _ ≤ C * (1 + |R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + nlinarith [hCircleAvg_le] + +variable {E : Type*} [NormedAddCommGroup E] [ProperSpace E] + +theorem log_two_mul_massClosedBall₀_le_logCounting {D : locallyFinsupp E ℤ} (hDnonneg : 0 ≤ D) + {R : ℝ} (hR : 1 ≤ R) : + (log 2) * massClosedBall₀ D R ≤ logCounting D (2 * R) := by + classical + have hR0 : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hR + set r : ℝ := 2 * R + have hrpos : 0 < r := by dsimp [r]; nlinarith + let Dr := toClosedBall r D + have hDr_fin : Set.Finite Dr.support := Dr.finiteSupport (isCompact_closedBall (0 : E) |r|) + let F : Finset E := hDr_fin.toFinset + let SR : Finset E := + (finiteSupport (toClosedBall R D) (isCompact_closedBall (0 : E) |R|)).toFinset + let S : Finset E := SR.filter fun z => z ≠ (0 : E) + have hS_sub : S ⊆ F := by + intro z hzS + have hz_mem_SR : z ∈ SR := (Finset.mem_filter.1 hzS).1 + have hzR : z ∈ (toClosedBall R D).support := by + exact (finiteSupport (toClosedBall R D) (isCompact_closedBall (0 : E) |R|)).mem_toFinset.1 + hz_mem_SR + have hz_norm_le_R : ‖z‖ ≤ R := by + have := norm_le_abs_of_mem_toClosedBall_support hzR + simpa [abs_of_pos hR0] using this + have hz_norm_le_r : ‖z‖ ≤ |r| := by + have : ‖z‖ ≤ r := le_trans hz_norm_le_R (by dsimp [r]; nlinarith) + simpa [abs_of_pos hrpos] using this + have hzD : z ∈ D.support := mem_support_of_mem_toClosedBall_support hzR + have : z ∈ Dr.support := by + simpa [Dr] using + mem_toClosedBall_support_of_mem_support_of_norm_le_abs (D := D) (r := r) hzD hz_norm_le_r + exact hDr_fin.mem_toFinset.2 this + have hlogCounting : + logCounting D r + = (F.sum fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) + (D 0 : ℝ) * log r := by + have hsupp : Function.support (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) ⊆ F := by + intro z hz + have : Dr z ≠ 0 := by + by_contra h0 + simp [Function.mem_support, h0] at hz + have : z ∈ Dr.support := by simpa [Function.mem_support] using this + exact hDr_fin.mem_toFinset.2 this + simp [logCounting, Dr, r, + finsum_eq_sum_of_support_subset (f := fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) (s := F) hsupp] + have hsum_le : + (log 2) * (S.sum fun z => (D z : ℝ)) + ≤ F.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) := by + have hterm_nonneg : ∀ z ∈ F, 0 ≤ (Dr z : ℝ) * log (r * ‖z‖⁻¹) := by + intro z hzF + have hz_sup : z ∈ Dr.support := hDr_fin.mem_toFinset.1 hzF + have hDz : 0 ≤ Dr z := by + have hDz' : 0 ≤ D z := hDnonneg z + have hDrz : Dr z = D z := + toClosedBall_eval_eq_of_norm_le_abs (norm_le_abs_of_mem_toClosedBall_support hz_sup) + simpa [hDrz] using hDz' + have hlog : 0 ≤ log (r * ‖z‖⁻¹) := by + have hzle : ‖z‖ ≤ r := by + have hnorm := norm_le_abs_of_mem_toClosedBall_support hz_sup + simpa [abs_of_pos hrpos] using hnorm + exact log_nonneg_mul_inv_norm_of_norm_le hzle + exact mul_nonneg (by exact_mod_cast hDz) hlog + have hsumSF : + S.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) + ≤ F.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) := + Finset.sum_le_sum_of_subset_of_nonneg hS_sub (by + intro z hzF _; exact hterm_nonneg z hzF) + have hterm_ge : ∀ z ∈ S, (log 2) * (D z : ℝ) ≤ (Dr z : ℝ) * log (r * ‖z‖⁻¹) := by + intro z hzS + have hz0 : z ≠ (0 : E) := (Finset.mem_filter.1 hzS).2 + have hz_norm_le_R : ‖z‖ ≤ R := by + have hz_mem_SR : z ∈ SR := (Finset.mem_filter.1 hzS).1 + have hzRsup : z ∈ (toClosedBall R D).support := by + exact (finiteSupport (toClosedBall R D) (isCompact_closedBall (0 : E) |R|)).mem_toFinset.1 + hz_mem_SR + have hnorm := norm_le_abs_of_mem_toClosedBall_support hzRsup + simpa [abs_of_pos hR0] using hnorm + have hlog_le : log 2 ≤ log (r * ‖z‖⁻¹) := by + simpa [r] using log_two_le_log_two_mul_mul_inv_norm_of_norm_le hz0 hz_norm_le_R + have hDz_nonneg : 0 ≤ D z := hDnonneg z + have hz_in_ballr : z ∈ closedBall (0 : E) |r| := by + have : ‖z‖ ≤ r := le_trans hz_norm_le_R (by dsimp [r]; nlinarith) + simpa [mem_closedBall, dist_zero_right, abs_of_pos hrpos] using this + have hDrz : Dr z = D z := by + have hz_norm_le : ‖z‖ ≤ |r| := by + simpa [mem_closedBall, dist_zero_right] using hz_in_ballr + simpa [Dr] using toClosedBall_eval_eq_of_norm_le_abs (D := D) (r := r) (z := z) hz_norm_le + have : (log 2) * (D z : ℝ) ≤ (log (r * ‖z‖⁻¹)) * (D z : ℝ) := + mul_le_mul_of_nonneg_right hlog_le (by exact_mod_cast hDz_nonneg) + simpa [hDrz, mul_assoc, mul_left_comm, mul_comm] using this + calc + (log 2) * (S.sum fun z => (D z : ℝ)) + = S.sum (fun z => (log 2) * (D z : ℝ)) := by simp [Finset.mul_sum] + _ ≤ S.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) := + Finset.sum_le_sum fun z hz => hterm_ge z hz + _ ≤ F.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) := hsumSF + have hcenter_nonneg : 0 ≤ (D 0 : ℝ) * log r := by + have hD0 : 0 ≤ D 0 := hDnonneg 0 + have hlogr : 0 ≤ log r := log_nonneg (by nlinarith [hR]) + exact mul_nonneg (by exact_mod_cast hD0) hlogr + have : (log 2) * (S.sum fun z => (D z : ℝ)) ≤ logCounting D r := by + rw [hlogCounting] + nlinarith [hsum_le, hcenter_nonneg] + simpa [massClosedBall₀, r, S, SR] using this + +theorem massClosedBall₀_divisor_le_of_log_growth {f : ℂ → ℂ} {ρ C : ℝ} + (hf : Differentiable ℂ f) + (hC : ∀ z : ℂ, log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) {R : ℝ} (hR : 1 ≤ R) : + massClosedBall₀ (divisor f (Set.univ : Set ℂ)) R + ≤ (C * (1 + |2 * R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖|) / log 2 := by + have hR0 : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hR + have hlog2pos : 0 < log 2 := log_pos (by norm_num : (1 : ℝ) < 2) + have hlow : + (log 2) * massClosedBall₀ (divisor f (Set.univ : Set ℂ)) R + ≤ logCounting (divisor f (Set.univ : Set ℂ)) (2 * R) := + log_two_mul_massClosedBall₀_le_logCounting + (D := divisor f (Set.univ : Set ℂ)) + (MeromorphicOn.AnalyticOnNhd.divisor_nonneg + (hf.differentiableOn.analyticOnNhd isOpen_univ)) hR + have hupp : + logCounting (divisor f (Set.univ : Set ℂ)) (2 * R) + ≤ C * (1 + |2 * R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + have h2R0 : 0 < 2 * R := by nlinarith [hR0] + simpa using logCounting_divisor_le_of_log_growth (f := f) (ρ := ρ) (C := C) hf hC + (R := 2 * R) h2R0 + have hmul : + (log 2) * massClosedBall₀ (divisor f (Set.univ : Set ℂ)) R + ≤ C * (1 + |2 * R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := + hlow.trans hupp + have hmul' : + massClosedBall₀ (divisor f (Set.univ : Set ℂ)) R * log 2 + ≤ C * (1 + |2 * R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + simpa [mul_assoc, mul_left_comm, mul_comm] using hmul + exact (le_div_iff₀ hlog2pos).2 hmul' + +end Function.locallyFinsuppWithin +end HadamardSourceScope21 + +section HadamardSourceScope22 + +open Set + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] [CompleteSpace E] + +theorem Differentiable.divisor_nonneg {f : ℂ → E} (hf : Differentiable ℂ f) : + 0 ≤ MeromorphicOn.divisor f (univ : Set ℂ) := + MeromorphicOn.AnalyticOnNhd.divisor_nonneg (hf.differentiableOn.analyticOnNhd isOpen_univ) +end HadamardSourceScope22 + +section HadamardSourceScope23 + +noncomputable section + +open scoped BigOperators +open Filter + +namespace Real + +open _root_.Real + +lemma two_pow_floor_logb_le {x : ℝ} (hx : 1 ≤ x) : + (2 : ℝ) ^ (⌊Real.logb 2 x⌋₊ : ℝ) ≤ x := by + have hx0 : 0 < x := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hx + have hlog_nonneg : 0 ≤ Real.logb 2 x := + Real.logb_nonneg (b := (2 : ℝ)) (by norm_num : (1 : ℝ) < 2) hx + have hfloor_le : (⌊Real.logb 2 x⌋₊ : ℝ) ≤ Real.logb 2 x := by + simpa using (Nat.floor_le hlog_nonneg) + exact (Real.le_logb_iff_rpow_le (b := (2 : ℝ)) + (x := (⌊Real.logb 2 x⌋₊ : ℝ)) (y := x) + (by norm_num : (1 : ℝ) < 2) hx0).1 hfloor_le + +lemma lt_two_pow_floor_logb_add_one {x : ℝ} (hx : 1 ≤ x) : + x < (2 : ℝ) ^ ((⌊Real.logb 2 x⌋₊ : ℝ) + 1) := by + have hx0 : 0 < x := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hx + have hlt : Real.logb 2 x < (⌊Real.logb 2 x⌋₊ : ℝ) + 1 := by + simpa using (Nat.lt_floor_add_one (Real.logb 2 x)) + exact (Real.logb_lt_iff_lt_rpow (b := (2 : ℝ)) (x := x) + (y := (⌊Real.logb 2 x⌋₊ : ℝ) + 1) + (by norm_num : (1 : ℝ) < 2) hx0).1 hlt + +lemma dyadicShell_lower_bound {r0 x : ℝ} {k : ℕ} (hr0 : 0 < r0) (hx : r0 ≤ x) + (hk : ⌊Real.logb 2 (x / r0)⌋₊ = k) : + r0 * (2 : ℝ) ^ (k : ℝ) ≤ x := by + have hr0ne : r0 ≠ 0 := ne_of_gt hr0 + have hx1 : (1 : ℝ) ≤ x / r0 := by + have : r0 / r0 ≤ x / r0 := div_le_div_of_nonneg_right hx hr0.le + simpa [hr0ne] using this + have hle : (2 : ℝ) ^ (k : ℝ) ≤ x / r0 := by + have := Real.two_pow_floor_logb_le (x := x / r0) hx1 + simpa [hk] using this + have := mul_le_mul_of_nonneg_left hle hr0.le + have hxEq : r0 * (x / r0) = x := by + field_simp [hr0ne] + simpa [mul_assoc, hxEq] using this + +lemma dyadicShell_upper_bound {r0 x : ℝ} {k : ℕ} (hr0 : 0 < r0) (hx : r0 ≤ x) + (hk : ⌊Real.logb 2 (x / r0)⌋₊ = k) : + x ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1) := by + have hr0ne : r0 ≠ 0 := ne_of_gt hr0 + have hx1 : (1 : ℝ) ≤ x / r0 := by + have : r0 / r0 ≤ x / r0 := div_le_div_of_nonneg_right hx hr0.le + simpa [hr0ne] using this + have hlt : x / r0 < (2 : ℝ) ^ ((k : ℝ) + 1) := by + have := Real.lt_two_pow_floor_logb_add_one (x := x / r0) hx1 + simpa [hk] using this + have := mul_lt_mul_of_pos_left hlt hr0 + have hxEq : r0 * (x / r0) = x := by + field_simp [hr0ne] + exact le_of_lt (by simpa [mul_assoc, hxEq] using this) + +lemma exists_nat_le_two_pow (A : ℝ) : + ∃ k0 : ℕ, ∀ n ≥ k0, A ≤ (2 : ℝ) ^ n := by + have htend : Tendsto (fun n : ℕ => (2 : ℝ) ^ n) atTop atTop := + tendsto_pow_atTop_atTop_of_one_lt (r := (2 : ℝ)) (by norm_num : (1 : ℝ) < 2) + exact eventually_atTop.1 ((tendsto_atTop.1 htend) A) + +lemma one_le_dyadicRadius_succ_of_inv_le_two_pow + {r0 : ℝ} {k0 kk : ℕ} (hr0 : 0 < r0) + (hk0 : ∀ n ≥ k0, (1 / r0 : ℝ) ≤ (2 : ℝ) ^ n) (hkk : k0 ≤ kk + 1) : + (1 : ℝ) ≤ r0 * (2 : ℝ) ^ ((kk : ℝ) + 1) := by + have hr0ne : r0 ≠ 0 := ne_of_gt hr0 + have hpow_nat : (1 / r0 : ℝ) ≤ (2 : ℝ) ^ (kk + 1) := hk0 (kk + 1) hkk + have hpow_rpow : (1 / r0 : ℝ) ≤ (2 : ℝ) ^ ((kk : ℝ) + 1) := by + have hcast : (2 : ℝ) ^ ((kk : ℝ) + 1) = (2 : ℝ) ^ (kk + 1) := by + calc + (2 : ℝ) ^ ((kk : ℝ) + 1) = (2 : ℝ) ^ ((kk + 1 : ℕ) : ℝ) := by + simp [Nat.cast_add, Nat.cast_one] + _ = (2 : ℝ) ^ (kk + 1) := by + simpa using (Real.rpow_natCast (2 : ℝ) (kk + 1)) + simpa [hcast] using hpow_nat + have : (r0 * (1 / r0) : ℝ) ≤ r0 * (2 : ℝ) ^ ((kk : ℝ) + 1) := + mul_le_mul_of_nonneg_left hpow_rpow hr0.le + simpa [one_div, hr0ne, mul_assoc] using this + +lemma one_add_abs_two_mul_dyadicRadius_rpow_le {r0 ρ : ℝ} (k : ℕ) + (hr0 : 0 < r0) (hρ : 0 ≤ ρ) : + (1 + |2 * (r0 * (2 : ℝ) ^ ((k : ℝ) + 1))|) ^ ρ + ≤ (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ ρ) ^ k := by + let Rk : ℝ := r0 * (2 : ℝ) ^ ((k : ℝ) + 1) + have hRk' : |2 * Rk| = 4 * r0 * (2 : ℝ) ^ (k : ℝ) := by + have hnonneg : 0 ≤ (2 : ℝ) * Rk := by + have : 0 ≤ Rk := by + dsimp [Rk] + exact mul_nonneg hr0.le (le_of_lt (Real.rpow_pos_of_pos (by norm_num) _)) + nlinarith + have hmul : (2 : ℝ) * Rk = 4 * r0 * (2 : ℝ) ^ (k : ℝ) := by + dsimp [Rk] + calc + (2 : ℝ) * (r0 * (2 : ℝ) ^ ((k : ℝ) + 1)) + = (2 * r0) * (2 : ℝ) ^ ((k : ℝ) + 1) := by ring + _ = (2 * r0) * ((2 : ℝ) ^ (k : ℝ) * (2 : ℝ) ^ (1 : ℝ)) := by + simp [Real.rpow_add, mul_assoc] + _ = (2 * r0) * ((2 : ℝ) ^ (k : ℝ) * 2) := by simp [Real.rpow_one] + _ = 4 * r0 * (2 : ℝ) ^ (k : ℝ) := by ring + calc + |2 * Rk| = 2 * Rk := abs_of_nonneg hnonneg + _ = 4 * r0 * (2 : ℝ) ^ (k : ℝ) := hmul + have hbase : + (1 + |2 * Rk|) ≤ (1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ) := by + have h1 : (1 : ℝ) ≤ (2 : ℝ) ^ (k : ℝ) := by + have : (1 : ℝ) ≤ (2 : ℝ) ^ (k : ℕ) := by + simpa using (one_le_pow₀ (by norm_num : (1 : ℝ) ≤ (2 : ℝ))) + simpa [Real.rpow_natCast] using this + have habs : + 1 + |2 * Rk| ≤ (2 : ℝ) ^ (k : ℝ) + (4 * r0) * (2 : ℝ) ^ (k : ℝ) := by + rw [hRk'] + simpa [add_assoc, add_left_comm, add_comm, mul_assoc, mul_left_comm, mul_comm] using + (add_le_add_right h1 ((4 * r0) * (2 : ℝ) ^ (k : ℝ))) + have hfac : + (2 : ℝ) ^ (k : ℝ) + (4 * r0) * (2 : ℝ) ^ (k : ℝ) + = (1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ) := by + ring + exact habs.trans (le_of_eq hfac) + have hRnonneg : 0 ≤ (1 + |2 * Rk|) := by linarith [abs_nonneg (2 * Rk)] + have : + (1 + |2 * Rk|) ^ ρ ≤ ((1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ)) ^ ρ := + Real.rpow_le_rpow hRnonneg hbase hρ + have hsplit : + ((1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ)) ^ ρ + = (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ (k : ℝ)) ^ ρ := by + have h1 : 0 ≤ (1 + 4 * r0) := by nlinarith [hr0.le] + have h2 : 0 ≤ (2 : ℝ) ^ (k : ℝ) := + le_of_lt (Real.rpow_pos_of_pos (by norm_num) _) + simpa using (Real.mul_rpow h1 h2 (z := ρ)) + have hpow : ((2 : ℝ) ^ (k : ℝ)) ^ ρ = ((2 : ℝ) ^ ρ) ^ k := by + have h2nonneg : (0 : ℝ) ≤ 2 := by norm_num + calc + ((2 : ℝ) ^ (k : ℝ)) ^ ρ = (2 : ℝ) ^ ((k : ℝ) * ρ) := by + simp [Real.rpow_mul] + _ = ((2 : ℝ) ^ ρ) ^ (k : ℝ) := by + simpa [mul_comm] using + (Real.rpow_mul (x := (2 : ℝ)) (y := ρ) (z := (k : ℝ)) h2nonneg) + _ = ((2 : ℝ) ^ ρ) ^ k := by + simp [Real.rpow_natCast] + calc + (1 + |2 * (r0 * (2 : ℝ) ^ ((k : ℝ) + 1))|) ^ ρ + = (1 + |2 * Rk|) ^ ρ := by rfl + _ ≤ ((1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ)) ^ ρ := this + _ = (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ (k : ℝ)) ^ ρ := hsplit + _ = (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ ρ) ^ k := by + simpa [mul_assoc] using congrArg (fun t => (1 + 4 * r0) ^ ρ * t) hpow + +lemma tsum_inv_rpow_le_card_mul_of_lower_bound {α : Type*} [Fintype α] {a : α → ℝ} + {R τ : ℝ} (hR : 0 < R) (hτ : 0 < τ) (ha_nonneg : ∀ x, 0 ≤ a x) + (ha_lower : ∀ x, R ≤ a x) : + (∑' x : α, (a x)⁻¹ ^ τ) ≤ (Fintype.card α : ℝ) * (R⁻¹ ^ τ) := by + have hsum_le : + (∑ x : α, (a x)⁻¹ ^ τ) ≤ ∑ _x : α, R⁻¹ ^ τ := by + refine Finset.sum_le_sum ?_ + intro x _hx + have hinv : (a x)⁻¹ ≤ R⁻¹ := by + simpa using (inv_anti₀ hR (ha_lower x)) + exact Real.rpow_le_rpow (inv_nonneg.2 (ha_nonneg x)) hinv hτ.le + simpa [tsum_fintype, Finset.sum_const, nsmul_eq_mul, mul_comm] using hsum_le + +lemma inv_dyadicRadius_rpow_eq (r0 τ : ℝ) (k : ℕ) (hr0 : 0 ≤ r0) : + (r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ = + (r0⁻¹ : ℝ) ^ τ * ((2 : ℝ) ^ (-τ)) ^ k := by + have h2k_nonneg : 0 ≤ (2 : ℝ) ^ (k : ℝ) := + le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) _) + calc + (r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ = + (r0 * (2 : ℝ) ^ (k : ℝ)) ^ (-τ) := by + simpa using (Real.rpow_neg_eq_inv_rpow (r0 * (2 : ℝ) ^ (k : ℝ)) τ).symm + _ = r0 ^ (-τ) * (((2 : ℝ) ^ (k : ℝ)) ^ (-τ)) := by + simpa using (Real.mul_rpow hr0 h2k_nonneg (z := -τ)) + _ = (r0⁻¹ : ℝ) ^ τ * ((2 : ℝ) ^ (-τ)) ^ k := by + have hr0' : r0 ^ (-τ) = (r0⁻¹ : ℝ) ^ τ := by + simp [Real.rpow_neg_eq_inv_rpow] + have h2' : ((2 : ℝ) ^ (k : ℝ)) ^ (-τ) = ((2 : ℝ) ^ (-τ)) ^ k := by + have h2nonneg : (0 : ℝ) ≤ (2 : ℝ) := by norm_num + calc + ((2 : ℝ) ^ (k : ℝ)) ^ (-τ) = (2 : ℝ) ^ ((k : ℝ) * (-τ)) := by + exact (Real.rpow_mul (x := (2 : ℝ)) (y := (k : ℝ)) (z := -τ) + h2nonneg).symm + _ = (2 : ℝ) ^ ((-τ) * (k : ℝ)) := by ring_nf + _ = ((2 : ℝ) ^ (-τ)) ^ (k : ℝ) := by + exact Real.rpow_mul (x := (2 : ℝ)) (y := -τ) (z := (k : ℝ)) h2nonneg + _ = ((2 : ℝ) ^ (-τ)) ^ k := by + simp [Real.rpow_natCast] + calc + r0 ^ (-τ) * (((2 : ℝ) ^ (k : ℝ)) ^ (-τ)) + = (r0⁻¹ : ℝ) ^ τ * (((2 : ℝ) ^ (k : ℝ)) ^ (-τ)) := by + rw [hr0'] + _ = (r0⁻¹ : ℝ) ^ τ * ((2 : ℝ) ^ (-τ)) ^ k := by + rw [h2'] + +lemma two_rpow_sub_eq_mul_neg (ρ τ : ℝ) : + (2 : ℝ) ^ (ρ - τ) = (2 : ℝ) ^ ρ * (2 : ℝ) ^ (-τ) := by + have h2pos : (0 : ℝ) < (2 : ℝ) := by norm_num + calc + (2 : ℝ) ^ (ρ - τ) = (2 : ℝ) ^ (ρ + (-τ)) := by ring_nf + _ = (2 : ℝ) ^ ρ * (2 : ℝ) ^ (-τ) := by + simp [Real.rpow_add h2pos] + +lemma two_rpow_sub_pow_eq_mul_pow (ρ τ : ℝ) (k : ℕ) : + ((2 : ℝ) ^ (ρ - τ)) ^ k = + ((2 : ℝ) ^ ρ) ^ k * (((2 : ℝ) ^ (-τ)) ^ k) := by + simp [two_rpow_sub_eq_mul_neg, mul_pow] + +lemma dyadic_growth_inv_term_eq (C L M r0 ρ τ : ℝ) (k : ℕ) (hr0 : 0 ≤ r0) : + ((C / L) * (M * ((2 : ℝ) ^ ρ) ^ k)) * + ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + = (((C / L) * M) * (r0⁻¹ : ℝ) ^ τ) * ((2 : ℝ) ^ (ρ - τ)) ^ k := by + have hrk_inv : + (r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ = + (r0⁻¹ : ℝ) ^ τ * (((2 : ℝ) ^ (-τ)) ^ k) := + inv_dyadicRadius_rpow_eq r0 τ k hr0 + rw [hrk_inv, two_rpow_sub_pow_eq_mul_pow] + ac_rfl + +lemma dyadic_trailing_inv_term_le (C L r0 τ : ℝ) (k : ℕ) (hr0 : 0 ≤ r0) : + (C / L) * ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + ≤ (((C / L) + 1) * (r0⁻¹ : ℝ) ^ τ) * ((2 : ℝ) ^ (-τ)) ^ k := by + rw [inv_dyadicRadius_rpow_eq r0 τ k hr0] + have hcoeff : C / L ≤ C / L + 1 := by linarith + have hr0Inv_nonneg : 0 ≤ (r0⁻¹ : ℝ) ^ τ := + Real.rpow_nonneg (inv_nonneg.2 hr0) _ + have hmul : + (C / L) * ((r0⁻¹ : ℝ) ^ τ) + ≤ ((C / L) + 1) * ((r0⁻¹ : ℝ) ^ τ) := + mul_le_mul_of_nonneg_right hcoeff hr0Inv_nonneg + have hqpow_nonneg : 0 ≤ ((2 : ℝ) ^ (-τ)) ^ k := + pow_nonneg (le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) _)) _ + have := mul_le_mul_of_nonneg_right hmul hqpow_nonneg + simpa [mul_assoc, mul_left_comm, mul_comm] using this + +lemma dyadic_growth_mass_mul_inv_le_geometric {C L M X T Ctrail r0 ρ τ : ℝ} {k : ℕ} + (hL : 0 < L) (hC : 0 ≤ C) (hr0 : 0 ≤ r0) + (hX : X ≤ M * ((2 : ℝ) ^ ρ) ^ k) + (hT : T ≤ ((C * X + Ctrail) / L) * ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ)) : + T ≤ (((C / L) * M) * (r0⁻¹ : ℝ) ^ τ) * ((2 : ℝ) ^ (ρ - τ)) ^ k + + (((Ctrail / L) + 1) * (r0⁻¹ : ℝ) ^ τ) * ((2 : ℝ) ^ (-τ)) ^ k := by + have hmul : C * X ≤ C * (M * ((2 : ℝ) ^ ρ) ^ k) := + mul_le_mul_of_nonneg_left hX hC + have hnum : C * X + Ctrail ≤ C * (M * ((2 : ℝ) ^ ρ) ^ k) + Ctrail := + add_le_add hmul le_rfl + have hdiv : + (C * X + Ctrail) / L ≤ (C * (M * ((2 : ℝ) ^ ρ) ^ k) + Ctrail) / L := + div_le_div_of_nonneg_right hnum hL.le + have h2k_nonneg : 0 ≤ (2 : ℝ) ^ (k : ℝ) := + le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) (k : ℝ)) + have hrk_nonneg : 0 ≤ r0 * (2 : ℝ) ^ (k : ℝ) := + mul_nonneg hr0 h2k_nonneg + have hfactor_nonneg : 0 ≤ ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) := + Real.rpow_nonneg (inv_nonneg.2 hrk_nonneg) τ + have hmul' := + mul_le_mul_of_nonneg_right hdiv hfactor_nonneg + have hdecomp : + ((C * (M * ((2 : ℝ) ^ ρ) ^ k) + Ctrail) / L) * + ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + = + ((C / L) * (M * ((2 : ℝ) ^ ρ) ^ k)) * + ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + + ((Ctrail / L) * ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ)) := by + let Y : ℝ := (r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ + have : + ((C * (M * ((2 : ℝ) ^ ρ) ^ k) + Ctrail) / L) * Y + = ((C / L) * (M * ((2 : ℝ) ^ ρ) ^ k)) * Y + + ((Ctrail / L) * Y) := by + ring + simpa [Y] + have hpre : + T ≤ ((C / L) * (M * ((2 : ℝ) ^ ρ) ^ k)) * + ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + + ((Ctrail / L) * ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ)) := + hT.trans (hmul'.trans_eq hdecomp) + have hA := le_of_eq (dyadic_growth_inv_term_eq C L M r0 ρ τ k hr0) + have hB := dyadic_trailing_inv_term_le Ctrail L r0 τ k hr0 + exact hpre.trans (by + simpa [mul_assoc, mul_left_comm, mul_comm] using add_le_add hA hB) + +lemma two_geometric_shift_add (A B q qσ : ℝ) (k k0 : ℕ) : + A * q ^ (k + k0) + B * qσ ^ (k + k0) + = (A * q ^ k0) * q ^ k + (B * qσ ^ k0) * qσ ^ k := by + rw [pow_add, pow_add] + ac_rfl + +end Real +end +end HadamardSourceScope23 + +section HadamardSourceScope24 + +noncomputable section + +open Filter Topology Set _root_.Complex _root_.Erdos970.Complex +open scoped BigOperators Topology + +namespace Complex.Hadamard + +open _root_.Complex + +open scoped _root_.Real + +noncomputable def divisorMassClosedBall₀ (f : ℂ → ℂ) (R : ℝ) : ℝ := + Function.locallyFinsuppWithin.massClosedBall₀ (MeromorphicOn.divisor f (Set.univ : Set ℂ)) R + +lemma divisorMassClosedBall₀_le_of_growth {f : ℂ → ℂ} {ρ C : ℝ} + (hf : Differentiable ℂ f) + (hC : ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) + {R : ℝ} (hR : 1 ≤ R) : + divisorMassClosedBall₀ f R + ≤ (C * (1 + |2 * R|) ^ ρ + |Real.log ‖meromorphicTrailingCoeffAt f 0‖|) / + Real.log 2 := by + simpa [divisorMassClosedBall₀] using + (Function.locallyFinsuppWithin.massClosedBall₀_divisor_le_of_log_growth + (f := f) (ρ := ρ) (C := C) hf hC hR) + +lemma exists_r0_le_norm_divisorZeroIndex₀Val {f : ℂ → ℂ} + (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) : + ∃ r0 : ℝ, 0 < r0 ∧ + ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), r0 ≤ ‖divisorZeroIndex₀Val p‖ := by + classical + set U : Set ℂ := (Set.univ : Set ℂ) + set D : Function.locallyFinsuppWithin U ℤ := MeromorphicOn.divisor f U + have hDnonneg : 0 ≤ D := by + simpa [D, U] using (Differentiable.divisor_nonneg (f := f) hf) + have hzero : ∀ p : divisorZeroIndex₀ f U, f (divisorZeroIndex₀Val p) = 0 := by + intro p + set z : ℂ := divisorZeroIndex₀Val p + have hneTop : meromorphicOrderAt f z ≠ ⊤ := by + have hzAnal : AnalyticAt ℂ f z := hf.analyticAt z + have hzA : analyticOrderAt f z ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (f := f) (hf := hf) hnot (z := z) + intro htop + have hm : meromorphicOrderAt f z = (analyticOrderAt f z).map (↑) := + hzAnal.meromorphicOrderAt_eq (𝕜 := ℂ) + cases h : analyticOrderAt f z with + | top => + exact hzA (by simp [h]) + | coe n => + have : (analyticOrderAt f z).map (↑) ≠ (⊤ : WithTop ℤ) := by + simp [h] + exact this (by simpa [hm] using htop) + have hmon : MeromorphicOn f U := by + intro w hw; exact (hf.analyticAt w).meromorphicAt + have hdiv : MeromorphicOn.divisor f U z = (meromorphicOrderAt f z).untop₀ := by + simpa [U] using (MeromorphicOn.divisor_apply (f := f) (U := U) (z := z) hmon (by aesop)) + have hDz : MeromorphicOn.divisor f U z ≠ 0 := by + have hzsup : z ∈ (MeromorphicOn.divisor f U).support := by + simp [z] + simpa [Function.mem_support] using hzsup + have hposZ : (0 : ℤ) < (meromorphicOrderAt f z).untop₀ := by + have hge0 : 0 ≤ (meromorphicOrderAt f z).untop₀ := by + have : 0 ≤ MeromorphicOn.divisor f U z := by + simpa [D, U, z] using hDnonneg z + simpa [hdiv] using this + have hne0 : (meromorphicOrderAt f z).untop₀ ≠ 0 := by + simpa [hdiv] using hDz + exact lt_of_le_of_ne hge0 (by simpa [eq_comm] using hne0) + have hpos : (0 : WithTop ℤ) < meromorphicOrderAt f z := by + have : (0 : WithTop ℤ) < ((meromorphicOrderAt f z).untop₀ : WithTop ℤ) := + WithTop.coe_lt_coe.2 hposZ + simpa [WithTop.coe_untop₀_of_ne_top hneTop] using this + have htend0 : Tendsto f (𝓝[≠] z) (𝓝 (0 : ℂ)) := + tendsto_zero_of_meromorphicOrderAt_pos (f := f) (x := z) hpos + have hcontz : ContinuousAt f z := (hf z).continuousAt + have htendz : Tendsto f (𝓝[≠] z) (𝓝 (f z)) := + (hcontz.tendsto.mono_left (nhdsWithin_le_nhds : 𝓝[≠] z ≤ 𝓝 z)) + exact tendsto_nhds_unique htendz htend0 + by_cases h0 : f 0 = 0 + · have hD0 : D 0 ≠ 0 := by + have hmero0 : MeromorphicAt f (0 : ℂ) := (hf.analyticAt 0).meromorphicAt + have hneTop0 : meromorphicOrderAt f (0 : ℂ) ≠ ⊤ := by + have hA0 : analyticOrderAt f (0 : ℂ) ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (f := f) (hf := hf) hnot (z := 0) + intro htop + have hm : meromorphicOrderAt f (0 : ℂ) = (analyticOrderAt f (0 : ℂ)).map (↑) := + (hf.analyticAt 0).meromorphicOrderAt_eq (𝕜 := ℂ) + cases h : analyticOrderAt f (0 : ℂ) with + | top => exact (hA0 h).elim + | coe n => + have : (analyticOrderAt f (0 : ℂ)).map (↑) ≠ (⊤ : WithTop ℤ) := by + simp [h] + exact this (by simpa [hm] using htop) + have htend0 : Tendsto f (𝓝[≠] (0 : ℂ)) (𝓝 (0 : ℂ)) := by + have hcont0 : ContinuousAt f (0 : ℂ) := (hf 0).continuousAt + have : Tendsto f (𝓝 (0 : ℂ)) (𝓝 (0 : ℂ)) := by simpa [h0] using hcont0.tendsto + exact this.mono_left (nhdsWithin_le_nhds : 𝓝[≠] (0 : ℂ) ≤ 𝓝 (0 : ℂ)) + have hpos0 : (0 : WithTop ℤ) < meromorphicOrderAt f (0 : ℂ) := + (tendsto_zero_iff_meromorphicOrderAt_pos hmero0).1 htend0 + have hpos0' : (0 : ℤ) < (meromorphicOrderAt f (0 : ℂ)).untop₀ := by + have : (0 : WithTop ℤ) < ((meromorphicOrderAt f (0 : ℂ)).untop₀ : WithTop ℤ) := by + simpa [WithTop.coe_untop₀_of_ne_top hneTop0] using hpos0 + simpa using (WithTop.coe_lt_coe.1 this) + have hdiv0 : D 0 = (meromorphicOrderAt f (0 : ℂ)).untop₀ := by + have hmon : MeromorphicOn f U := by + intro w hw; exact (hf.analyticAt w).meromorphicAt + simpa [D, U] using + (MeromorphicOn.divisor_apply (f := f) (U := U) (z := (0 : ℂ)) + hmon (by aesop)) + exact by + have : (meromorphicOrderAt f (0 : ℂ)).untop₀ ≠ 0 := ne_of_gt hpos0' + simpa [hdiv0] using this + have hmem0 : (0 : ℂ) ∈ D.support := by + simp [Function.mem_support, hD0] + have hdisc : IsDiscrete D.support := by + simpa [D] using (D.discreteSupport) + rcases Metric.exists_ball_inter_eq_singleton_of_mem_discrete hdisc hmem0 with ⟨r0, hr0pos, hr0⟩ + refine ⟨r0, hr0pos, ?_⟩ + intro p + have hp : divisorZeroIndex₀Val p ∈ D.support := by + simp [D, divisorZeroIndex₀Val_mem_divisor_support (f := f) (U := U) p] + have hnotBall : divisorZeroIndex₀Val p ∉ Metric.ball (0 : ℂ) r0 := by + intro hball + have : divisorZeroIndex₀Val p ∈ Metric.ball (0 : ℂ) r0 ∩ D.support := ⟨hball, hp⟩ + have : divisorZeroIndex₀Val p ∈ ({(0 : ℂ)} : Set ℂ) := by simp [hr0] at this + have : divisorZeroIndex₀Val p = 0 := by simp [Set.mem_singleton_iff] at this + exact (divisorZeroIndex₀Val_ne_zero p) this + have : r0 ≤ ‖divisorZeroIndex₀Val p‖ := by + have : ¬ ‖divisorZeroIndex₀Val p‖ < r0 := by + intro hlt + exact hnotBall (by simpa [Metric.mem_ball, dist_zero_right] using hlt) + exact le_of_not_gt this + exact this + · have hcont0 : ContinuousAt f (0 : ℂ) := (hf 0).continuousAt + have hne : ∀ᶠ z in 𝓝 (0 : ℂ), f z ≠ 0 := hcont0.eventually_ne h0 + rcases Metric.mem_nhds_iff.1 hne with ⟨r0, hr0pos, hr0⟩ + refine ⟨r0, hr0pos, ?_⟩ + intro p + have : ¬ ‖divisorZeroIndex₀Val p‖ < r0 := by + intro hlt + have hzball : divisorZeroIndex₀Val p ∈ Metric.ball (0 : ℂ) r0 := by + simpa [Metric.mem_ball, dist_zero_right] using hlt + have : f (divisorZeroIndex₀Val p) ≠ 0 := hr0 hzball + exact this (hzero p) + exact le_of_not_gt this + +open scoped BigOperators + +lemma card_ball_le_divisorMassClosedBall₀ + {f : ℂ → ℂ} (hf : Differentiable ℂ f) {R : ℝ} (hR : 0 < R) : + (Nat.card {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) // ‖divisorZeroIndex₀Val p‖ ≤ R} : ℝ) + ≤ divisorMassClosedBall₀ f R := by + set U : Set ℂ := (Set.univ : Set ℂ) + set D : Function.locallyFinsuppWithin U ℤ := MeromorphicOn.divisor f U + have : + Fintype {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} := by + have : Finite {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} := by + have : Metric.closedBall (0 : ℂ) R ⊆ U := by simp [U] + simpa using (finite_divisorZeroIndex₀_subtype_norm_le (f := f) (U := U) (B := R) this) + exact Fintype.ofFinite _ + have hDnonneg : 0 ≤ D := by + simpa [D, U] using (Differentiable.divisor_nonneg (f := f) hf) + let SR : Finset ℂ := + (Function.locallyFinsuppWithin.finiteSupport (Function.locallyFinsuppWithin.toClosedBall R D) + (isCompact_closedBall (0 : ℂ) |R|)).toFinset + let S : Finset ℂ := SR.filter fun z : ℂ => z ≠ 0 + let T : Type := + Σ z : S, Fin (Int.toNat (D z.1)) + let φ : + {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} → T := fun p => + let z0 : ℂ := divisorZeroIndex₀Val p.1 + have hz0_memSR : z0 ∈ SR := by + have hz0_norm : ‖z0‖ ≤ |R| := by + have : ‖z0‖ ≤ R := p.2 + simpa [abs_of_pos hR] using this + have hz0_support : z0 ∈ (Function.locallyFinsuppWithin.toClosedBall R D).support := by + have hz0_suppD : z0 ∈ D.support := by + simp [z0, D] + exact Function.locallyFinsuppWithin.mem_toClosedBall_support_of_mem_support_of_norm_le_abs + hz0_suppD hz0_norm + exact (Set.Finite.mem_toFinset + (Function.locallyFinsuppWithin.finiteSupport + (Function.locallyFinsuppWithin.toClosedBall R D) + (isCompact_closedBall (0 : ℂ) |R|))).2 hz0_support + have hz0_ne0 : z0 ≠ 0 := divisorZeroIndex₀Val_ne_zero p.1 + have hz0_memS : z0 ∈ S := Finset.mem_filter.2 ⟨hz0_memSR, hz0_ne0⟩ + ⟨⟨z0, hz0_memS⟩, by + simpa [z0, divisorZeroIndex₀Val, D] using p.1.1.2⟩ + have hφ_inj : Function.Injective φ := by + intro p q hpq + have hσ := (Sigma.mk.inj_iff).1 hpq + have hzS : (φ p).1 = (φ q).1 := hσ.1 + have hz : divisorZeroIndex₀Val p.1 = divisorZeroIndex₀Val q.1 := by + simpa [φ] using congrArg Subtype.val hzS + apply Subtype.ext + apply Subtype.ext + apply Sigma.ext + · exact hz + · simpa [φ] using hσ.2 + have hcard_le : + Fintype.card {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} ≤ Fintype.card T := + Fintype.card_le_of_injective φ hφ_inj + have hT_card : + (Fintype.card T : ℝ) = + (S.sum fun z : ℂ => (Int.toNat (D z) : ℝ)) := by + have hNat : + Fintype.card T = ∑ z : S, Int.toNat (D z.1) := by + have h1 : + Fintype.card T = ∑ z : S, Fintype.card (Fin (Int.toNat (D z.1))) := by + change Fintype.card (Sigma (fun z : S => Fin (Int.toNat (D z.1)))) + = ∑ z : S, Fintype.card (Fin (Int.toNat (D z.1))) + exact (Fintype.card_sigma (ι := S) (α := fun z : S => Fin (Int.toNat (D z.1)))) + simpa using h1 + have hR : + (Fintype.card T : ℝ) = ∑ z : S, (Int.toNat (D z.1) : ℝ) := by + exact_mod_cast hNat + have hR' : + (Fintype.card T : ℝ) = S.attach.sum (fun z : S => (Int.toNat (D z.1) : ℝ)) := by + simpa [Finset.univ_eq_attach] using hR + calc + (Fintype.card T : ℝ) = S.attach.sum (fun z : S => (Int.toNat (D z.1) : ℝ)) := hR' + _ = S.sum (fun z : ℂ => (Int.toNat (D z) : ℝ)) := by + simpa using (Finset.sum_attach (s := S) (f := fun z : ℂ => (Int.toNat (D z) : ℝ))) + have htoNat_le : ∀ z ∈ S, (Int.toNat (D z) : ℝ) ≤ (D z : ℝ) := by + intro z hz + have hDz_nonneg : 0 ≤ D z := by simpa [D] using hDnonneg z + have hEqZ : ((Int.toNat (D z) : ℕ) : ℤ) = D z := by + simpa using (Int.toNat_of_nonneg hDz_nonneg) + have hEqR : (Int.toNat (D z) : ℝ) = (D z : ℝ) := by + exact_mod_cast hEqZ + exact le_of_eq hEqR + calc + (Nat.card {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} : ℝ) + = (Fintype.card {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} : ℝ) := by + simp [Nat.card_eq_fintype_card] + _ ≤ (Fintype.card T : ℝ) := by exact_mod_cast hcard_le + _ = S.sum (fun z : ℂ => (Int.toNat (D z) : ℝ)) := hT_card + _ ≤ S.sum (fun z : ℂ => (D z : ℝ)) := by + refine Finset.sum_le_sum ?_ + intro z hz + exact htoNat_le z hz + _ = divisorMassClosedBall₀ f R := by + rfl + +lemma card_subtype_le_divisorMassClosedBall₀_of_norm_le + {f : ℂ → ℂ} (hf : Differentiable ℂ f) + {s : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))} [Fintype s] + {R : ℝ} (hR : 0 < R) (hs : ∀ p : s, ‖divisorZeroIndex₀Val p.1‖ ≤ R) : + (Fintype.card s : ℝ) ≤ divisorMassClosedBall₀ f R := by + let Aball : Type := + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) // ‖divisorZeroIndex₀Val p‖ ≤ R} + have : Fintype Aball := by + have : Finite Aball := by + have : Metric.closedBall (0 : ℂ) R ⊆ (Set.univ : Set ℂ) := by simp + simpa [Aball] using + (finite_divisorZeroIndex₀_subtype_norm_le (f := f) (U := (Set.univ : Set ℂ)) + (B := R) this) + exact Fintype.ofFinite _ + have hinj : Function.Injective (fun p : s => (⟨p.1, hs p⟩ : Aball)) := by + intro p q hpq + apply Subtype.ext + exact congrArg (fun x : Aball => x.1) hpq + have hcard_le : Fintype.card s ≤ Fintype.card Aball := + Fintype.card_le_of_injective _ hinj + have hAball : (Nat.card Aball : ℝ) ≤ divisorMassClosedBall₀ f R := by + simpa [Aball] using card_ball_le_divisorMassClosedBall₀ (f := f) hf hR + calc + (Fintype.card s : ℝ) ≤ (Fintype.card Aball : ℝ) := by exact_mod_cast hcard_le + _ = (Nat.card Aball : ℝ) := by simp [Nat.card_eq_fintype_card] + _ ≤ divisorMassClosedBall₀ f R := hAball + +lemma divisorZeroIndex₀_dyadicShell_upper_bound + {f : ℂ → ℂ} {r0 : ℝ} + (hr0pos : 0 < r0) + (hr0 : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), r0 ≤ ‖divisorZeroIndex₀Val p‖) + {k : ℕ} {p : divisorZeroIndex₀ f (Set.univ : Set ℂ)} + (hp : ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ = k) : + ‖divisorZeroIndex₀Val p‖ ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1) := by + exact Real.dyadicShell_upper_bound (r0 := r0) (x := ‖divisorZeroIndex₀Val p‖) + hr0pos (hr0 p) hp + +lemma divisorZeroIndex₀_dyadicShell_lower_bound + {f : ℂ → ℂ} {r0 : ℝ} + (hr0pos : 0 < r0) + (hr0 : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), r0 ≤ ‖divisorZeroIndex₀Val p‖) + {k : ℕ} {p : divisorZeroIndex₀ f (Set.univ : Set ℂ)} + (hp : ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ = k) : + r0 * (2 : ℝ) ^ (k : ℝ) ≤ ‖divisorZeroIndex₀Val p‖ := by + exact Real.dyadicShell_lower_bound (r0 := r0) (x := ‖divisorZeroIndex₀Val p‖) + hr0pos (hr0 p) hp + +lemma finite_divisorZeroIndex₀_dyadicShell + {f : ℂ → ℂ} {r0 : ℝ} + (hr0pos : 0 < r0) + (hr0 : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), r0 ≤ ‖divisorZeroIndex₀Val p‖) + (k : ℕ) : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ = k} : Set _).Finite := by + have hsub : + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ = k} ⊆ + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ‖divisorZeroIndex₀Val p‖ ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1)} := by + intro p hp + exact divisorZeroIndex₀_dyadicShell_upper_bound hr0pos hr0 hp + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ‖divisorZeroIndex₀Val p‖ ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1)} : Set _).Finite := by + have : + Metric.closedBall (0 : ℂ) (r0 * (2 : ℝ) ^ ((k : ℝ) + 1)) ⊆ + (Set.univ : Set ℂ) := by + simp + simpa using + (divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) + (B := r0 * (2 : ℝ) ^ ((k : ℝ) + 1)) this) + exact hfin.subset hsub + +lemma tsum_divisorZeroIndex₀_dyadicShell_inv_rpow_le_geometric_of_growth + {f : ℂ → ℂ} {ρ τ r0 Cgrow : ℝ} + (hρ : 0 ≤ ρ) (hτpos : 0 < τ) (hf : Differentiable ℂ f) + (hCgrow_pos : 0 < Cgrow) + (hCgrow : ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ Cgrow * (1 + ‖z‖) ^ ρ) + (hr0pos : 0 < r0) + (hr0 : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + r0 ≤ ‖divisorZeroIndex₀Val p‖) + (k : ℕ) (hk_ge_one : 1 ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1)) : + let kfun : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℕ := + fun p => ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ + let S : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := {p | kfun p = k} + let Ctrail : ℝ := |Real.log ‖meromorphicTrailingCoeffAt f 0‖| + let A : ℝ := ((Cgrow / Real.log 2) * (1 + 4 * r0) ^ ρ) * (r0⁻¹) ^ τ + let B : ℝ := ((Ctrail / Real.log 2) + 1) * (r0⁻¹) ^ τ + let q : ℝ := (2 : ℝ) ^ (ρ - τ) + let qσ : ℝ := (2 : ℝ) ^ (-τ) + (∑' p : S, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) ≤ A * q ^ k + B * qσ ^ k := by + classical + intro kfun S Ctrail A B q qσ + let rk : ℝ := r0 * (2 : ℝ) ^ (k : ℝ) + let Rk : ℝ := r0 * (2 : ℝ) ^ ((k : ℝ) + 1) + have hrk_pos : 0 < rk := mul_pos hr0pos (Real.rpow_pos_of_pos (by norm_num) _) + have hrk0 : 0 ≤ rk := le_of_lt hrk_pos + have : Finite S := by + simpa [S, kfun] using (finite_divisorZeroIndex₀_dyadicShell + (f := f) hr0pos hr0 k).to_subtype + have : Fintype S := Fintype.ofFinite S + have hk_upper : ∀ p : S, ‖divisorZeroIndex₀Val p.1‖ ≤ Rk := by + intro p + have hk' : kfun p.1 = k := p.2 + simpa [Rk, kfun] using + divisorZeroIndex₀_dyadicShell_upper_bound (f := f) hr0pos hr0 hk' + have hk_lower : ∀ p : S, rk ≤ ‖divisorZeroIndex₀Val p.1‖ := by + intro p + have hk' : kfun p.1 = k := p.2 + simpa [rk, kfun] using + divisorZeroIndex₀_dyadicShell_lower_bound (f := f) hr0pos hr0 hk' + have htsum_le : + (∑' p : S, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) + ≤ (Fintype.card S : ℝ) * (rk⁻¹ ^ τ) := by + exact Real.tsum_inv_rpow_le_card_mul_of_lower_bound + (a := fun p : S => ‖divisorZeroIndex₀Val p.1‖) + hrk_pos hτpos (fun _ => norm_nonneg _) hk_lower + have hmass_le_growth : + divisorMassClosedBall₀ f Rk + ≤ (Cgrow * (1 + |2 * Rk|) ^ ρ + Ctrail) / (Real.log 2) := by + simpa [Ctrail, Rk] using + (divisorMassClosedBall₀_le_of_growth (f := f) (ρ := ρ) (C := Cgrow) hf hCgrow + (R := Rk) hk_ge_one) + have hcard_le_mass : + (Fintype.card S : ℝ) ≤ divisorMassClosedBall₀ f Rk := by + have hRk_pos : 0 < Rk := lt_of_lt_of_le (by norm_num) hk_ge_one + exact card_subtype_le_divisorMassClosedBall₀_of_norm_le (f := f) hf hRk_pos hk_upper + have htsum' : + (∑' p : S, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) + ≤ ((Cgrow * (1 + |2 * Rk|) ^ ρ + Ctrail) / (Real.log 2)) * (rk⁻¹ ^ τ) := by + have hcard_le_growth : + (Fintype.card S : ℝ) ≤ + (Cgrow * (1 + |2 * Rk|) ^ ρ + Ctrail) / (Real.log 2) := + le_trans hcard_le_mass hmass_le_growth + exact le_trans htsum_le <| + mul_le_mul_of_nonneg_right hcard_le_growth (Real.rpow_nonneg (inv_nonneg.2 hrk0) τ) + have hpow_bound : + (1 + |2 * Rk|) ^ ρ ≤ (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ ρ) ^ k := by + simpa [Rk] using + Real.one_add_abs_two_mul_dyadicRadius_rpow_le (r0 := r0) (ρ := ρ) k hr0pos hρ + have hlog2pos : 0 < Real.log 2 := Real.log_pos (by norm_num : (1 : ℝ) < 2) + simpa [A, B, q, qσ, rk, Ctrail, mul_assoc, mul_left_comm, mul_comm] using + Real.dyadic_growth_mass_mul_inv_le_geometric + (C := Cgrow) (L := Real.log 2) (M := (1 + 4 * r0) ^ ρ) + (X := (1 + |2 * Rk|) ^ ρ) + (T := ∑' p : S, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) + (Ctrail := Ctrail) (r0 := r0) (ρ := ρ) (τ := τ) (k := k) + hlog2pos hCgrow_pos.le hr0pos.le hpow_bound + (by simpa [rk] using htsum') + +theorem summable_norm_inv_rpow_divisorZeroIndex₀_of_growth {f : ℂ → ℂ} {ρ τ : ℝ} + (hρ : 0 ≤ ρ) (hτ : ρ < τ) (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + (hgrowth : ∃ C > 0, ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := by + rcases hgrowth with ⟨Cgrow, hCgrow_pos, hCgrow⟩ + have hτpos : 0 < τ := lt_of_le_of_lt hρ hτ + rcases exists_r0_le_norm_divisorZeroIndex₀Val (f := f) hf hnot with ⟨r0, hr0pos, hr0⟩ + have hr0ne : (r0 : ℝ) ≠ 0 := ne_of_gt hr0pos + let kfun : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℕ := + fun p => ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ + let S : ℕ → Set (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + fun k => {p | kfun p = k} + have hS : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ∃! k : ℕ, p ∈ S k := by + intro p + refine ⟨kfun p, ?_, ?_⟩ + · simp [S] + · intro k hk + simpa [S] using hk.symm + have hnonneg : 0 ≤ fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + intro p + exact Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _ + have hSk_summable : ∀ k : ℕ, Summable fun p : S k => ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ := by + intro k + have : Finite (S k) := by + simpa [S, kfun] using (finite_divisorZeroIndex₀_dyadicShell + (f := f) hr0pos hr0 k).to_subtype + exact Summable.of_finite + have hshell_summable : + Summable fun k : ℕ => ∑' p : S k, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ := by + let q : ℝ := (2 : ℝ) ^ (ρ - τ) + let qσ : ℝ := (2 : ℝ) ^ (-τ) + have hq_nonneg : 0 ≤ q := le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) _) + have hq_lt_one : q < 1 := + Real.rpow_lt_one_of_one_lt_of_neg (x := (2 : ℝ)) (by norm_num : (1 : ℝ) < 2) + (sub_neg.2 hτ) + have hqσ_nonneg : 0 ≤ qσ := le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) _) + have hqσ_lt_one : qσ < 1 := + Real.rpow_lt_one_of_one_lt_of_neg (x := (2 : ℝ)) (by norm_num : (1 : ℝ) < 2) + (by simpa using (neg_neg_of_pos hτpos)) + have hgeom_q : Summable (fun k : ℕ => q ^ k) := + summable_geometric_of_lt_one hq_nonneg hq_lt_one + have hgeom_qσ : Summable (fun k : ℕ => qσ ^ k) := + summable_geometric_of_lt_one hqσ_nonneg hqσ_lt_one + let Ctrail : ℝ := |Real.log ‖meromorphicTrailingCoeffAt f 0‖| + let A : ℝ := ((Cgrow / Real.log 2) * (1 + 4 * r0) ^ ρ) * (r0⁻¹) ^ τ + let B : ℝ := ((Ctrail / Real.log 2) + 1) * (r0⁻¹) ^ τ + rcases Real.exists_nat_le_two_pow (1 / r0) with ⟨k0, hk0⟩ + let A0 : ℝ := A * q ^ k0 + let B0 : ℝ := B * qσ ^ k0 + have hmajor : Summable (fun k : ℕ => A0 * q ^ k + B0 * qσ ^ k) := + (hgeom_q.mul_left A0).add (hgeom_qσ.mul_left B0) + have hshell_summable_shift : + Summable fun k : ℕ => ∑' p : S (k + k0), ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ := by + refine hmajor.of_nonneg_of_le + (fun k => by + have : ∀ p : S (k + k0), 0 ≤ ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ := by + intro p; exact Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _ + exact tsum_nonneg this) + (fun k => by + let kk : ℕ := k + k0 + let Rk : ℝ := r0 * (2 : ℝ) ^ ((kk : ℝ) + 1) + have hRk_ge_one : (1 : ℝ) ≤ Rk := by + have hkk : k0 ≤ kk + 1 := by + simp [kk, Nat.add_assoc, Nat.add_comm] + simpa [Rk] using + Real.one_le_dyadicRadius_succ_of_inv_le_two_pow hr0pos hk0 hkk + have hmain : + (∑' p : S kk, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) ≤ A * q ^ kk + B * qσ ^ kk := by + simpa [S, kfun, Ctrail, A, B, q, qσ] using + tsum_divisorZeroIndex₀_dyadicShell_inv_rpow_le_geometric_of_growth + (f := f) (ρ := ρ) (τ := τ) hρ hτpos hf hCgrow_pos hCgrow hr0pos hr0 kk hRk_ge_one + have : A * q ^ kk + B * qσ ^ kk = A0 * q ^ k + B0 * qσ ^ k := by + simpa [A0, B0, kk] using Real.two_geometric_shift_add A B q qσ k k0 + simpa [kk] using (hmain.trans_eq this) + ) + exact (summable_nat_add_iff k0).1 hshell_summable_shift + have hpart := + (summable_partition (f := fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) hnonneg (s := S) hS) + exact (hpart.2 ⟨hSk_summable, hshell_summable⟩) + +theorem summable_norm_inv_pow_divisorZeroIndex₀_of_growth {f : ℂ → ℂ} {ρ : ℝ} + (hρ : 0 ≤ ρ) (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + (hgrowth : ∃ C > 0, ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (Nat.floor ρ + 1)) := by + have hτ : ρ < (Nat.floor ρ + 1 : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one] using (Nat.lt_floor_add_one (a := ρ)) + have hs := + summable_norm_inv_rpow_divisorZeroIndex₀_of_growth (f := f) (ρ := ρ) + (τ := (Nat.floor ρ + 1 : ℝ)) hρ hτ hf hnot hgrowth + exact hs.congr fun p => by + have hcast : ((Nat.floor ρ : ℝ) + 1) = ((Nat.floor ρ + 1 : ℕ) : ℝ) := by + norm_num + rw [hcast, Real.rpow_natCast] + +end Complex.Hadamard +end +end HadamardSourceScope24 + +section HadamardSourceScope25 + +namespace Complex + +open _root_.Complex + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℂ F] + +theorem norm_le_of_mem_ball_of_forall_sphere_norm_le {f : ℂ → F} {r C : ℝ} {z : ℂ} + (hd : Differentiable ℂ f) (hrpos : 0 < r) + (hz : z ∈ Metric.ball (0 : ℂ) r) (hsphere : ∀ u : ℂ, ‖u‖ = r → ‖f u‖ ≤ C) : + ‖f z‖ ≤ C := by + let U : Set ℂ := Metric.ball (0 : ℂ) r + have hfront : ∀ u ∈ frontier U, ‖f u‖ ≤ C := by + intro u hu + have hur : ‖u‖ = r := by + have hfront' : frontier (Metric.ball (0 : ℂ) r) = Metric.sphere (0 : ℂ) r := by + simpa using (frontier_ball (x := (0 : ℂ)) (r := r) (ne_of_gt hrpos)) + have : u ∈ Metric.sphere (0 : ℂ) r := by simpa [U, hfront'] using hu + simpa [Metric.mem_sphere, dist_zero_right] using this + exact hsphere u hur + exact norm_le_of_forall_mem_frontier_norm_le (f := f) (U := U) Metric.isBounded_ball + hd.diffContOnCl hfront (subset_closure hz) + +end Complex +end HadamardSourceScope25 + +section HadamardSourceScope26 + +namespace Complex + +open _root_.Complex +namespace CartanBound + +open _root_.Real _root_.Erdos970.Real MeasureTheory intervalIntegral +open scoped Topology ENNReal + +private lemma neg_log_le_sqrt_two_div {x : ℝ} (hx : 0 < x) (hxle : x ≤ 1) : + -Real.log x ≤ Real.sqrt (2 / x) := by + have hx0 : 0 ≤ x := le_of_lt hx + have ht : 0 ≤ -Real.log x := by + have : Real.log x ≤ 0 := Real.log_nonpos hx0 hxle + linarith + have hsq_div_two_le_exp : ∀ {t : ℝ}, 0 ≤ t → t ^ 2 / 2 ≤ Real.exp t := by + intro t ht + let g : ℝ → ℝ := fun u => Real.exp u - u ^ 2 / 2 + have hg_cont : ContinuousOn g (Set.Ici (0 : ℝ)) := by + have : Continuous g := by fun_prop + simpa using this.continuousOn + have hg_diff : DifferentiableOn ℝ g (interior (Set.Ici (0 : ℝ))) := by + intro u hu + have : DifferentiableAt ℝ g u := by fun_prop + exact this.differentiableWithinAt + have hg'_nonneg : ∀ u ∈ interior (Set.Ici (0 : ℝ)), 0 ≤ deriv g u := by + intro u hu + have hu0 : 0 < u := by simpa [interior_Ici] using hu + have hderiv : deriv g u = Real.exp u - u := by + have hExp : HasDerivAt Real.exp (Real.exp u) u := Real.hasDerivAt_exp u + have hpow2 : HasDerivAt (fun z : ℝ => z ^ 2) (2 * u) u := by + simpa using! ((hasDerivAt_id u).pow 2) + have hpow2_div : HasDerivAt (fun z : ℝ => z ^ 2 / 2) u u := by + simpa using (hpow2.div_const (2 : ℝ)) + have hG : HasDerivAt g (Real.exp u - u) u := by + simpa [g] using! hExp.sub hpow2_div + exact hG.deriv + have hu_le : u ≤ Real.exp u := by + have h1 : u + 1 ≤ Real.exp u := Real.add_one_le_exp u + exact (le_trans (le_add_of_nonneg_right (by norm_num)) h1) + have : 0 ≤ Real.exp u - u := sub_nonneg.2 hu_le + simpa [hderiv] using this + have hg_mono : MonotoneOn g (Set.Ici (0 : ℝ)) := + monotoneOn_of_deriv_nonneg (D := Set.Ici (0 : ℝ)) (hD := convex_Ici 0) + hg_cont hg_diff hg'_nonneg + have hg0 : g 0 = 1 := by simp [g] + have hle : g 0 ≤ g t := hg_mono (by simp) (by simpa [Set.mem_Ici] using ht) ht + have : (1 : ℝ) ≤ Real.exp t - t ^ 2 / 2 := by simpa [g, hg0] using hle + linarith + have hmain : (-Real.log x) ^ 2 / 2 ≤ Real.exp (-Real.log x) := hsq_div_two_le_exp ht + have hexp : Real.exp (-Real.log x) = x⁻¹ := by simp [Real.exp_neg, Real.exp_log hx] + have hsq2 : (-Real.log x) ^ 2 ≤ 2 * Real.exp (-Real.log x) := by nlinarith [hmain] + have hsq' : (-Real.log x) ^ 2 ≤ 2 / x := by simpa [hexp, div_eq_mul_inv, mul_assoc] using hsq2 + have hy : 0 ≤ 2 / x := div_nonneg (by norm_num) (le_of_lt hx) + exact (Real.le_sqrt ht hy).2 hsq' + +lemma posLog_log_one_div_abs_one_sub_le_sqrt {t : ℝ} : + Real.posLog (1 / |1 - t|) ≤ Real.sqrt (2 / |1 - t|) := by + by_cases ht : |1 - t| ≤ 1 + · by_cases h0 : |1 - t| = 0 + · have : t = 1 := by + have : 1 - t = 0 := by simpa [abs_eq_zero] using h0 + linarith + subst this + simp + · have hpos : 0 < |1 - t| := lt_of_le_of_ne (abs_nonneg _) (Ne.symm h0) + have hle : -Real.log |1 - t| ≤ Real.sqrt (2 / |1 - t|) := + neg_log_le_sqrt_two_div (x := |1 - t|) hpos ht + have hlog : Real.log (1 / |1 - t|) = -Real.log |1 - t| := by simp [Real.log_inv] + have hnonneg : 0 ≤ Real.log (1 / |1 - t|) := by + exact Real.log_nonneg ((one_le_div hpos).2 ht) + have hmax : Real.posLog (1 / |1 - t|) = Real.log (1 / |1 - t|) := + max_eq_right hnonneg + calc + Real.posLog (1 / |1 - t|) = Real.log (1 / |1 - t|) := hmax + _ = -Real.log |1 - t| := hlog + _ ≤ Real.sqrt (2 / |1 - t|) := hle + · have hlt : 1 < |1 - t| := lt_of_not_ge ht + have hle0 : Real.log (1 / |1 - t|) ≤ 0 := by + have hpos : 0 < |1 - t| := lt_trans (by norm_num) hlt + have : (1 / |1 - t| : ℝ) ≤ 1 := (div_le_one hpos).2 (le_of_lt hlt) + exact le_trans (Real.log_le_log (by positivity) this) (by simp) + have hmax : Real.posLog (1 / |1 - t|) = 0 := max_eq_left hle0 + have hrhs : 0 ≤ Real.sqrt (2 / |1 - t|) := by + exact Real.sqrt_nonneg _ + rw [hmax] + exact hrhs + +noncomputable def φ (t : ℝ) : ℝ := + log⁺ (1 / |1 - t|) + +lemma measurable_phi : Measurable φ := by + unfold φ + simpa [Real.posLog_def, Real.posLog] using + (by fun_prop : Measurable fun t : ℝ => max 0 (Real.log (1 / |1 - t|))) + +lemma phi_le_log_two_of_le_half {t : ℝ} (ht : t ≤ (1 / 2 : ℝ)) : φ t ≤ Real.log 2 := by + have hnonneg : 0 ≤ (1 - t : ℝ) := by linarith + have hden : (1 / 2 : ℝ) ≤ |1 - t| := by + have : (1 / 2 : ℝ) ≤ (1 - t : ℝ) := by linarith + simpa [abs_of_nonneg hnonneg] using this + have hfrac : (1 / |1 - t| : ℝ) ≤ 2 := by + have hhalfpos : (0 : ℝ) < (1 / 2 : ℝ) := by norm_num + have := one_div_le_one_div_of_le hhalfpos hden + simpa [one_div, div_eq_mul_inv] using this + have hposLog : log⁺ (1 / |1 - t|) ≤ log⁺ (2 : ℝ) := + Real.posLog_le_posLog ((by trans (0 : ℝ); norm_num; positivity)) hfrac + have habs : (1 : ℝ) ≤ |(2 : ℝ)| := by + simp + have hposLog2 : (log⁺ (2 : ℝ)) = Real.log 2 := by + simpa using (Real.posLog_eq_log habs) + simpa [φ, hposLog2] using hposLog + +lemma phi_eq_zero_of_one_le_abs_one_sub {t : ℝ} (ht : (1 : ℝ) ≤ |1 - t|) : φ t = 0 := by + have hpos : 0 < |1 - t| := lt_of_lt_of_le (by norm_num) ht + have hfrac : (1 / |1 - t| : ℝ) ≤ 1 := (div_le_one hpos).2 ht + have habs : |(1 / |1 - t| : ℝ)| ≤ 1 := by + have hnonneg : 0 ≤ (1 / |1 - t| : ℝ) := by positivity + simpa [abs_of_nonneg hnonneg] using hfrac + have : log⁺ (1 / |1 - t|) = 0 := (Real.posLog_eq_zero_iff _).2 habs + simpa [φ] using this + +lemma φ_nonneg (t : ℝ) : 0 ≤ φ t := by + simpa [φ] using (Real.posLog_nonneg (x := (1 / |1 - t|))) + +lemma φ_le_sqrt (t : ℝ) : φ t ≤ Real.sqrt (2 / |1 - t|) := by + simpa [φ, Real.posLog] using + posLog_log_one_div_abs_one_sub_le_sqrt (t := t) + +lemma ae_restrict_norm_phi_le_of_forall_mem {A B : ℝ} (hAB : A ≤ B) {g : ℝ → ℝ} + (hg : ∀ t, 0 ≤ g t) (h : ∀ t ∈ Set.Icc A B, φ t ≤ g t) : + (fun t : ℝ => ‖φ t‖) ≤ᶠ[ae (volume.restrict (Set.uIoc A B))] fun t => ‖g t‖ := by + refine + MeasureTheory.ae_restrict_of_forall_mem (μ := (volume : MeasureTheory.Measure ℝ)) + (s := Set.uIoc A B) + (by simpa using (measurableSet_uIoc : MeasurableSet (Set.uIoc A B))) ?_ + intro t ht + have htIoc : t ∈ Set.Ioc A B := by + simpa [Set.uIoc_of_le hAB] using ht + have htIcc : t ∈ Set.Icc A B := ⟨le_of_lt htIoc.1, htIoc.2⟩ + have hle : φ t ≤ g t := h t htIcc + have hφ0 : 0 ≤ φ t := φ_nonneg t + have hg0 : 0 ≤ g t := hg t + simpa [Real.norm_eq_abs, abs_of_nonneg hφ0, abs_of_nonneg hg0] using hle + +lemma log_norm_one_sub_div_ge_neg_phi {u a : ℂ} {r : ℝ} + (hur : ‖u‖ = r) (ha : a ≠ 0) (hr : r ≠ ‖a‖) : + Real.log ‖(1 : ℂ) - u / a‖ ≥ -φ (r / ‖a‖) := by + have ha_norm : 0 < ‖a‖ := norm_pos_iff.2 ha + have hnorm_eq : ‖(1 : ℂ) - u / a‖ = ‖a - u‖ / ‖a‖ := by + have : (1 : ℂ) - u / a = (a - u) / a := by + field_simp [ha] + calc + ‖(1 : ℂ) - u / a‖ = ‖(a - u) / a‖ := by simp [this] + _ = ‖a - u‖ / ‖a‖ := by simp + have hrev : |‖a‖ - ‖u‖| ≤ ‖a - u‖ := by + simpa using (abs_norm_sub_norm_le a u) + have hdiv : |‖a‖ - ‖u‖| / ‖a‖ ≤ ‖a - u‖ / ‖a‖ := + div_le_div_of_nonneg_right hrev (le_of_lt ha_norm) + have habs : |1 - (r / ‖a‖)| = |‖a‖ - ‖u‖| / ‖a‖ := by + have hu : ‖u‖ = r := hur + have ha0 : (‖a‖ : ℝ) ≠ 0 := ha_norm.ne' + have h1 : (1 : ℝ) - (r / ‖a‖) = (‖a‖ - r) / ‖a‖ := by + field_simp [ha0] + calc + |1 - (r / ‖a‖)| = |(‖a‖ - r) / ‖a‖| := by simp [h1] + _ = |‖a‖ - r| / ‖a‖ := by simp [abs_div, abs_of_pos ha_norm] + _ = |‖a‖ - ‖u‖| / ‖a‖ := by simp [hu] + have hnorm_ge : |1 - (r / ‖a‖)| ≤ ‖(1 : ℂ) - u / a‖ := by + have : |1 - (r / ‖a‖)| ≤ ‖a - u‖ / ‖a‖ := by + rw [habs] + exact hdiv + rwa [hnorm_eq] + have hx0 : 0 < |1 - (r / ‖a‖)| := by + have : (1 - (r / ‖a‖) : ℝ) ≠ 0 := by + intro h0 + have : r = ‖a‖ := by + have : r / ‖a‖ = (1 : ℝ) := by linarith + simpa using (div_eq_iff ha_norm.ne').1 this + exact hr this + have : |1 - (r / ‖a‖)| ≠ 0 := by + simpa [abs_eq_zero] using this + exact lt_of_le_of_ne (abs_nonneg _) (Ne.symm this) + have hlogx : + Real.log |1 - (r / ‖a‖)| ≥ -φ (r / ‖a‖) := by + have := Real.neg_posLog_inv_le_log (x := |1 - (r / ‖a‖)|) + simpa [φ, one_div, inv_inv, abs_sub_comm, sub_eq_add_neg] using this + have hlog_mono : + Real.log |1 - (r / ‖a‖)| ≤ Real.log ‖(1 : ℂ) - u / a‖ := + Real.log_le_log (by positivity) hnorm_ge + linarith [hlog_mono, hlogx] + +noncomputable def K : ℝ := + ∫ (t : ℝ) in (1 / 4 : ℝ)..(4 : ℝ), Real.sqrt (2 / |1 - t|) ∂volume + +lemma K_nonneg : 0 ≤ K := by + have hle : (1 / 4 : ℝ) ≤ (4 : ℝ) := by norm_num + have hnn : ∀ t ∈ Set.Icc (1 / 4 : ℝ) (4 : ℝ), 0 ≤ Real.sqrt (2 / |1 - t|) := by + intro _t _ht + exact Real.sqrt_nonneg _ + simpa [K] using (intervalIntegral.integral_nonneg + (μ := (volume : MeasureTheory.Measure ℝ)) hle hnn) + +noncomputable def Cφ : ℝ := + Real.log 2 + 4 * K + 1 + +lemma Cφ_pos : 0 < Cφ := by + have hlog : 0 < Real.log 2 := by + simpa using Real.log_pos (by norm_num : (1 : ℝ) < 2) + have hK : 0 ≤ K := K_nonneg + have : 0 < Real.log 2 + 4 * K := by nlinarith + have : 0 < Real.log 2 + 4 * K + 1 := by linarith + simpa [Cφ] using this + +lemma intervalIntegrable_sqrt_two_div_abs_one_sub_Icc : + IntervalIntegrable + (fun t : ℝ => Real.sqrt (2 / |1 - t|)) + volume (1 / 4 : ℝ) (4 : ℝ) := by + let f : ℝ → ℝ := fun u => Real.sqrt (2 / |u|) + have hf0 : IntervalIntegrable f volume (0 : ℝ) (3 : ℝ) := by + have hpow : + IntervalIntegrable (fun u : ℝ => u ^ (- (2⁻¹ : ℝ))) volume (0 : ℝ) (3 : ℝ) := by + simpa using + (intervalIntegral.intervalIntegrable_rpow' (a := (0 : ℝ)) (b := (3 : ℝ)) + (r := (- (2⁻¹ : ℝ))) (by linarith : (-1 : ℝ) < - (2⁻¹ : ℝ))) + have hpow2 : + IntervalIntegrable (fun u : ℝ => Real.sqrt 2 * u ^ (- (2⁻¹ : ℝ))) volume (0 : ℝ) (3 : ℝ) := + hpow.const_mul (Real.sqrt 2) + have hEq : + Set.EqOn f (fun u : ℝ => Real.sqrt 2 * u ^ (- (2⁻¹ : ℝ))) (Set.uIoc (0 : ℝ) (3 : ℝ)) := by + intro u hu + have hu' : u ∈ Set.Ioc (0 : ℝ) (3 : ℝ) := by + simpa [Set.uIoc_of_le (show (0 : ℝ) ≤ 3 by norm_num)] using hu + have hu0 : 0 < u := hu'.1 + have hu0' : 0 ≤ u := le_of_lt hu0 + have habs : |u| = u := abs_of_nonneg hu0' + have : f u = Real.sqrt (2 / u) := by simp [f, habs] + calc + f u = Real.sqrt (2 / u) := this + _ = Real.sqrt 2 / Real.sqrt u := by simp + _ = Real.sqrt 2 * (Real.sqrt u)⁻¹ := by simp [div_eq_mul_inv] + _ = Real.sqrt 2 * (u ^ (2⁻¹ : ℝ))⁻¹ := by simp [Real.sqrt_eq_rpow] + _ = Real.sqrt 2 * u ^ (- (2⁻¹ : ℝ)) := by + have h : (u ^ (2⁻¹ : ℝ))⁻¹ = u ^ (- (2⁻¹ : ℝ)) := by + simpa using (Real.rpow_neg hu0' (2⁻¹ : ℝ)).symm + simp [h] + exact + (IntervalIntegrable.congr (a := (0 : ℝ)) (b := (3 : ℝ)) + (μ := (volume : MeasureTheory.Measure ℝ)) + (f := fun u : ℝ => Real.sqrt 2 * u ^ (- (2⁻¹ : ℝ))) (g := f) hEq.symm) + hpow2 + have hf0' : IntervalIntegrable f volume (0 : ℝ) (3 / 4 : ℝ) := + hf0.mono_set (by + intro u hu + have hsub : Set.uIcc (0 : ℝ) (3 / 4 : ℝ) ⊆ Set.uIcc (0 : ℝ) (3 : ℝ) := by + refine Set.uIcc_subset_uIcc ?_ ?_ + · simp + · have h0 : (0 : ℝ) ≤ (3 / 4 : ℝ) := by nlinarith + have h1 : (3 / 4 : ℝ) ≤ (3 : ℝ) := by nlinarith + exact (Set.mem_uIcc).2 (Or.inl ⟨h0, h1⟩) + exact hsub hu) + have hleft : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) volume (1 / 4 : ℝ) (1 : ℝ) := by + have htmp : + IntervalIntegrable (fun t : ℝ => f (1 - t)) volume (1 : ℝ) ((1 : ℝ) - (3 / 4 : ℝ)) := by + simpa using (hf0'.comp_sub_left (c := (1 : ℝ))) + have htmp' : + IntervalIntegrable (fun t : ℝ => f (1 - t)) volume ((1 : ℝ) - (3 / 4 : ℝ)) (1 : ℝ) := + htmp.symm + have hsub : ((1 : ℝ) - (3 / 4 : ℝ)) = (1 / 4 : ℝ) := by norm_num + have htmp'' : IntervalIntegrable (fun t : ℝ => f (1 - t)) volume (1 / 4 : ℝ) (1 : ℝ) := by + simpa [hsub] using htmp' + simpa [f] using htmp'' + have hright : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) volume (1 : ℝ) (4 : ℝ) := by + have htmp : + IntervalIntegrable (fun t : ℝ => f (t - 1)) volume (1 : ℝ) ((3 : ℝ) + (1 : ℝ)) := by + simpa using (hf0.comp_sub_right (c := (1 : ℝ))) + have hsub : ((3 : ℝ) + (1 : ℝ)) = (4 : ℝ) := by norm_num + have htmp' : IntervalIntegrable (fun t : ℝ => f (t - 1)) volume (1 : ℝ) (4 : ℝ) := by + simpa [hsub] using htmp + have hcongr : + Set.EqOn (fun t : ℝ => f (t - 1)) (fun t : ℝ => Real.sqrt (2 / |1 - t|)) + (Set.uIoc (1 : ℝ) (4 : ℝ)) := by + intro t _ht + simp [f, abs_sub_comm] + exact + (IntervalIntegrable.congr (a := (1 : ℝ)) (b := (4 : ℝ)) + (μ := (volume : MeasureTheory.Measure ℝ)) + (f := fun t : ℝ => f (t - 1)) (g := fun t : ℝ => Real.sqrt (2 / |1 - t|)) hcongr) + htmp' + exact hleft.trans hright + +lemma phi_le_log_two_on_dyadic_of_le_quarter {A t : ℝ} (hA : A ≤ (1 / 4 : ℝ)) + (ht : t ∈ Set.Icc A (2 * A)) : + φ t ≤ Real.log 2 := by + have ht_le : t ≤ (1 / 2 : ℝ) := by + exact ht.2.trans (by nlinarith [hA]) + exact phi_le_log_two_of_le_half ht_le + +lemma phi_eq_zero_of_two_le {t : ℝ} (ht : (2 : ℝ) ≤ t) : φ t = 0 := by + have hden : (1 : ℝ) ≤ |1 - t| := by + have : (1 : ℝ) ≤ t - 1 := by linarith + have : (1 : ℝ) ≤ |t - 1| := by + simpa [abs_of_nonneg (by linarith : 0 ≤ t - 1)] using this + simpa [abs_sub_comm] using this + exact phi_eq_zero_of_one_le_abs_one_sub hden + +lemma intervalIntegrable_phi_dyadic_small {A : ℝ} (hA0 : 0 ≤ A) + (hA : A ≤ (1 / 4 : ℝ)) : + IntervalIntegrable φ volume A (2 * A) := by + have hA_le : A ≤ 2 * A := by nlinarith + have hconst : IntervalIntegrable (fun _ : ℝ => (Real.log 2 : ℝ)) volume A (2 * A) := + intervalIntegrable_const + have hmeas : + AEStronglyMeasurable (fun t : ℝ => φ t) (volume.restrict (Set.uIoc A (2 * A))) := + (measurable_phi.aestronglyMeasurable : _) + have hdom : + (fun t : ℝ => ‖φ t‖) ≤ᶠ[ae (volume.restrict (Set.uIoc A (2 * A)))] + fun _ => ‖(Real.log 2 : ℝ)‖ := by + refine ae_restrict_norm_phi_le_of_forall_mem (A := A) (B := 2 * A) hA_le + (g := fun _ => (Real.log 2 : ℝ)) (hg := fun _ => ?_) ?_ + · simpa using (Real.log_nonneg (by norm_num : (1 : ℝ) ≤ 2)) + · intro t ht + exact phi_le_log_two_on_dyadic_of_le_quarter hA ht + exact IntervalIntegrable.mono_fun hconst hmeas hdom + +lemma intervalIntegrable_phi_dyadic_large {A : ℝ} (hA : (2 : ℝ) ≤ A) : + IntervalIntegrable φ volume A (2 * A) := by + have hA_le : A ≤ 2 * A := by nlinarith + have hEq : Set.EqOn (fun t : ℝ => φ t) (fun _ => (0 : ℝ)) (Set.uIoc A (2 * A)) := by + intro t ht + have htIoc : t ∈ Set.Ioc A (2 * A) := by + simpa [Set.uIoc_of_le hA_le] using ht + exact phi_eq_zero_of_two_le (le_trans hA (le_of_lt htIoc.1)) + have hz : IntervalIntegrable (fun _ : ℝ => (0 : ℝ)) volume A (2 * A) := + intervalIntegrable_const + exact (IntervalIntegrable.congr (a := A) (b := (2 * A)) + (μ := (volume : MeasureTheory.Measure ℝ)) + (f := fun _ => (0 : ℝ)) (g := fun t => φ t) (by + intro t ht + simpa using (hEq (x := t) ht).symm)) hz + +lemma intervalIntegrable_sqrt_two_div_abs_one_sub_dyadic_middle {A : ℝ} + (hA_lower : (1 / 4 : ℝ) ≤ A) (hA_upper : A ≤ (2 : ℝ)) : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) volume A (2 * A) := by + have hsqrt_big : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) + (volume : MeasureTheory.Measure ℝ) (1 / 4 : ℝ) (4 : ℝ) := + intervalIntegrable_sqrt_two_div_abs_one_sub_Icc + refine hsqrt_big.mono_set ?_ + refine Set.uIcc_subset_uIcc ?_ ?_ + · exact (Set.mem_uIcc).2 (Or.inl ⟨hA_lower, by nlinarith [hA_upper]⟩) + · exact (Set.mem_uIcc).2 (Or.inl ⟨by nlinarith [hA_lower], by nlinarith [hA_upper]⟩) + +lemma intervalIntegrable_phi_dyadic_middle {A : ℝ} + (hA_lower : (1 / 4 : ℝ) ≤ A) (hA_upper : A ≤ (2 : ℝ)) : + IntervalIntegrable φ volume A (2 * A) := by + have hA_le : A ≤ 2 * A := by nlinarith [hA_lower] + have hsqrt : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) volume A (2 * A) := + intervalIntegrable_sqrt_two_div_abs_one_sub_dyadic_middle hA_lower hA_upper + have hmeas : + AEStronglyMeasurable (fun t : ℝ => φ t) (volume.restrict (Set.uIoc A (2 * A))) := + (measurable_phi.aestronglyMeasurable : _) + have hdom : + (fun t : ℝ => ‖φ t‖) ≤ᶠ[ae (volume.restrict (Set.uIoc A (2 * A)))] + fun t => ‖Real.sqrt (2 / |1 - t|)‖ := by + refine ae_restrict_norm_phi_le_of_forall_mem (A := A) (B := 2 * A) hA_le + (g := fun t => Real.sqrt (2 / |1 - t|)) (hg := fun _ => Real.sqrt_nonneg _) ?_ + intro t _ht + exact φ_le_sqrt t + exact IntervalIntegrable.mono_fun hsqrt hmeas hdom + +lemma intervalIntegrable_phi_dyadic {A : ℝ} (hA : 0 ≤ A) : + IntervalIntegrable φ volume A (2 * A) := by + by_cases hA0 : A = 0 + · subst hA0 + simp + cases le_total A (1 / 4 : ℝ) with + | inl hsmall => + exact intervalIntegrable_phi_dyadic_small hA hsmall + | inr hge_quarter => + cases le_total (2 : ℝ) A with + | inl hbig => + exact intervalIntegrable_phi_dyadic_large hbig + | inr hA_le_two => + exact intervalIntegrable_phi_dyadic_middle hge_quarter hA_le_two + +lemma intervalIntegrable_phi_div {a R : ℝ} (ha : 0 < a) (hR : 0 ≤ R) : + IntervalIntegrable (fun r : ℝ => φ (r / a)) volume R (2 * R) := by + have ha0 : a ≠ 0 := ne_of_gt ha + have hRa_nonneg : 0 ≤ R / a := by + exact div_nonneg hR (le_of_lt ha) + have hφ : IntervalIntegrable φ volume (R / a) (2 * (R / a)) := + intervalIntegrable_phi_dyadic (A := (R / a)) hRa_nonneg + have := (hφ.comp_mul_right (c := (a⁻¹ : ℝ))) + have hupper : a * (R * (a⁻¹ * 2)) = (2 * R) := by + field_simp [ha0] + simpa [div_eq_mul_inv, ha0, hupper, mul_assoc, mul_left_comm, mul_comm] using this + +lemma log_two_le_Cφ : Real.log 2 ≤ Cφ := by + dsimp [Cφ] + have hK : 0 ≤ K := K_nonneg + linarith [hK] + +lemma four_mul_K_add_one_le_Cφ : (4 * K + 1 : ℝ) ≤ Cφ := by + dsimp [Cφ] + have hlog_nonneg : 0 ≤ Real.log 2 := Real.log_nonneg (by norm_num) + linarith [hlog_nonneg] + +lemma integral_phi_le_Cφ_mul_small {A : ℝ} (hA0 : 0 ≤ A) (hA : A ≤ (1 / 4 : ℝ)) : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) ≤ Cφ * A := by + have hA_le : A ≤ 2 * A := by nlinarith + have hφ_int : IntervalIntegrable φ volume A (2 * A) := + intervalIntegrable_phi_dyadic_small hA0 hA + have hconst : IntervalIntegrable (fun _ : ℝ => (Real.log 2 : ℝ)) volume A (2 * A) := + intervalIntegrable_const + have hle_int : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) + ≤ ∫ (t : ℝ) in A..(2 * A), (Real.log 2 : ℝ) ∂volume := by + refine intervalIntegral.integral_mono_on (μ := (volume : MeasureTheory.Measure ℝ)) + hA_le hφ_int hconst ?_ + intro t ht + exact phi_le_log_two_on_dyadic_of_le_quarter hA ht + have hRHS : + (∫ (t : ℝ) in A..(2 * A), (Real.log 2 : ℝ) ∂volume) = A * Real.log 2 := by + simp [intervalIntegral.integral_const, sub_eq_add_neg, add_assoc, two_mul] + have hcoef : A * Real.log 2 ≤ Cφ * A := by + have := mul_le_mul_of_nonneg_left log_two_le_Cφ hA0 + simpa [mul_assoc, mul_left_comm, mul_comm] using this + exact le_trans (by simpa [hRHS] using hle_int) hcoef + +lemma integral_phi_le_Cφ_mul_large {A : ℝ} (hA : (2 : ℝ) ≤ A) : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) ≤ Cφ * A := by + have hA_le : A ≤ 2 * A := by nlinarith + have hφ0 : Set.EqOn (fun t : ℝ => φ t) (fun _ => (0 : ℝ)) (Set.uIcc A (2 * A)) := by + intro t ht + have ht' : t ∈ Set.Icc A (2 * A) := by + simpa [Set.uIcc_of_le hA_le] using ht + exact phi_eq_zero_of_two_le (le_trans hA ht'.1) + have hzero : (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) = 0 := by + simpa using intervalIntegral.integral_congr (μ := (volume : MeasureTheory.Measure ℝ)) hφ0 + have hnonneg : (0 : ℝ) ≤ Cφ * A := mul_nonneg (le_of_lt Cφ_pos) (by linarith) + simpa [hzero] using hnonneg + +lemma integral_sqrt_two_div_abs_one_sub_le_K_dyadic_middle {A : ℝ} + (hA_lower : (1 / 4 : ℝ) ≤ A) (hA_upper : A ≤ (2 : ℝ)) : + (∫ (t : ℝ) in A..(2 * A), Real.sqrt (2 / |1 - t|) ∂volume) ≤ K := by + let s (t : ℝ) : ℝ := Real.sqrt (2 / |1 - t|) + have hA_le : A ≤ 2 * A := by nlinarith [hA_lower] + have hA_upper' : (2 * A : ℝ) ≤ 4 := by nlinarith [hA_upper] + have hsqrt_big : IntervalIntegrable s volume (1 / 4 : ℝ) (4 : ℝ) := by + simpa [s] using intervalIntegrable_sqrt_two_div_abs_one_sub_Icc + have hle_K : + (∫ (t : ℝ) in A..(2 * A), s t ∂volume) + ≤ ∫ (t : ℝ) in (1 / 4 : ℝ)..(4 : ℝ), s t ∂volume := by + refine intervalIntegral.integral_mono_interval (μ := (volume : MeasureTheory.Measure ℝ)) + (c := (1 / 4 : ℝ)) (d := (4 : ℝ)) (a := A) (b := (2 * A)) + hA_lower hA_le hA_upper' ?_ hsqrt_big + exact Filter.Eventually.of_forall (fun _t => Real.sqrt_nonneg _) + simpa [K, s] using hle_K + +lemma K_le_four_mul_K_add_one_mul_of_quarter_le {A : ℝ} (hA : (1 / 4 : ℝ) ≤ A) : + K ≤ (4 * K + 1) * A := by + have hcoef : 1 ≤ 4 * A := by nlinarith [hA] + have hK : 0 ≤ K := K_nonneg + nlinarith [hK, hcoef] + +lemma integral_phi_le_Cφ_mul_middle {A : ℝ} + (hA_lower : (1 / 4 : ℝ) ≤ A) (hA_upper : A ≤ (2 : ℝ)) : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) ≤ Cφ * A := by + let s (t : ℝ) : ℝ := Real.sqrt (2 / |1 - t|) + have hA_le : A ≤ 2 * A := by nlinarith [hA_lower] + have hφ_int : IntervalIntegrable φ volume A (2 * A) := + intervalIntegrable_phi_dyadic_middle hA_lower hA_upper + have hsqrt : IntervalIntegrable s volume A (2 * A) := by + simpa [s] using + intervalIntegrable_sqrt_two_div_abs_one_sub_dyadic_middle hA_lower hA_upper + have hle_int : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) + ≤ ∫ (t : ℝ) in A..(2 * A), s t ∂volume := by + refine intervalIntegral.integral_mono_on + (μ := (volume : MeasureTheory.Measure ℝ)) hA_le hφ_int hsqrt ?_ + intro t _ht + exact φ_le_sqrt t + have hsqrt_le : (∫ (t : ℝ) in A..(2 * A), s t ∂volume) ≤ (4 * K + 1) * A := by + have hK : (∫ (t : ℝ) in A..(2 * A), s t ∂volume) ≤ K := by + simpa [s] using integral_sqrt_two_div_abs_one_sub_le_K_dyadic_middle hA_lower hA_upper + exact le_trans hK (K_le_four_mul_K_add_one_mul_of_quarter_le hA_lower) + have hcoef : (4 * K + 1 : ℝ) * A ≤ Cφ * A := + mul_le_mul_of_nonneg_right four_mul_K_add_one_le_Cφ (by nlinarith [hA_lower]) + exact le_trans hle_int (le_trans hsqrt_le hcoef) + +lemma integral_phi_le_Cφ_mul {A : ℝ} (hA : 0 ≤ A) : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) ≤ Cφ * A := by + by_cases hA0 : A = 0 + · subst hA0 + simp [Cφ, φ, K] + cases le_total A (1 / 4 : ℝ) with + | inl hsmall => + exact integral_phi_le_Cφ_mul_small hA hsmall + | inr hge_quarter => + cases le_total (2 : ℝ) A with + | inl hbig => + exact integral_phi_le_Cφ_mul_large hbig + | inr hA_le_two => + exact integral_phi_le_Cφ_mul_middle hge_quarter hA_le_two + +open scoped BigOperators + +lemma volume_Ioc_two_mul_ne_zero {R : ℝ} (hR : 0 < R) : + (volume : MeasureTheory.Measure ℝ) (Set.Ioc R (2 * R)) ≠ 0 := by + have hpos : (0 : ℝ) < 2 * R - R := by nlinarith [hR] + simp [Real.volume_Ioc, ENNReal.ofReal_eq_zero, not_le_of_gt hpos] + +lemma volume_Ioc_two_mul_diff_finset_ne_zero (bad : Finset ℝ) {R : ℝ} (hR : 0 < R) : + (volume : MeasureTheory.Measure ℝ) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) ≠ 0 := by + have hbad_meas : (volume : MeasureTheory.Measure ℝ) (bad : Set ℝ) = 0 := by + simpa using (bad.measure_zero (μ := (volume : MeasureTheory.Measure ℝ))) + have hdiff : + (volume : MeasureTheory.Measure ℝ) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) + = (volume : MeasureTheory.Measure ℝ) (Set.Ioc R (2 * R)) := by + simpa [Set.sdiff_eq, Set.inter_assoc, Set.inter_left_comm, Set.inter_comm] using + (MeasureTheory.measure_sdiff_null (s := Set.Ioc R (2 * R)) (t := (bad : Set ℝ)) + hbad_meas) + simpa [hdiff] using volume_Ioc_two_mul_ne_zero hR + +lemma restrict_volume_Ioc_two_mul_diff_finset_ne_zero (bad : Finset ℝ) {R : ℝ} (hR : 0 < R) : + (volume.restrict (Set.Ioc R (2 * R))) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) ≠ 0 := by + have hsubset : Set.Ioc R (2 * R) \ (bad : Set ℝ) ⊆ Set.Ioc R (2 * R) := by + intro r hr + exact hr.1 + have hinter : + (Set.Ioc R (2 * R) \ (bad : Set ℝ)) ∩ Set.Ioc R (2 * R) + = (Set.Ioc R (2 * R) \ (bad : Set ℝ)) := by + exact Set.inter_eq_left.mpr hsubset + simpa [MeasureTheory.Measure.restrict_apply, measurableSet_Ioc, hinter] using + volume_Ioc_two_mul_diff_finset_ne_zero bad hR + +lemma integral_phi_div_le_Cφ_mul {a R : ℝ} (ha : 0 < a) (hR : 0 ≤ R) : + (∫ (r : ℝ) in R..(2 * R), φ (r / a) ∂volume) ≤ Cφ * R := by + have ha0 : a ≠ 0 := ne_of_gt ha + have hrew : + (∫ (r : ℝ) in R..(2 * R), φ (r / a) ∂volume) + = a * (∫ (t : ℝ) in (R / a)..(2 * R / a), φ t ∂volume) := by + simp [smul_eq_mul, mul_left_comm, mul_comm, div_eq_mul_inv, ha0] + rw [hrew] + have hA : 0 ≤ R / a := by + exact div_nonneg hR ha.le + have hle : (∫ (t : ℝ) in (R / a)..(2 * (R / a)), φ t ∂volume) ≤ Cφ * (R / a) := + integral_phi_le_Cφ_mul (A := R / a) hA + have hEq : (2 * R / a) = 2 * (R / a) := by ring + have hle' : + (∫ (t : ℝ) in (R / a)..(2 * R / a), φ t ∂volume) ≤ Cφ * (R / a) := by + simpa [hEq] using hle + have ha_nonneg : 0 ≤ a := ha.le + have := mul_le_mul_of_nonneg_left hle' ha_nonneg + have hRHS : a * (Cφ * (R / a)) = Cφ * R := by + field_simp [ha0] + simpa [hRHS, mul_assoc, mul_left_comm, mul_comm] using this + +lemma intervalIntegrable_sum_mul_phi_div + {ι : Type} (s : Finset ι) (w : ι → ℝ) (a : ι → ℝ) + (ha : ∀ i ∈ s, 0 < a i) {R : ℝ} (hR : 0 ≤ R) : + IntervalIntegrable (∑ i ∈ s, fun r : ℝ => w i * φ (r / a i)) + volume R (2 * R) := by + refine IntervalIntegrable.sum (μ := volume) (a := R) (b := 2 * R) + (s := s) (f := fun i : ι => fun r : ℝ => w i * φ (r / a i)) ?_ + intro i hi + have hφi : IntervalIntegrable (fun r : ℝ => φ (r / a i)) volume R (2 * R) := + intervalIntegrable_phi_div (a := a i) (R := R) (ha i hi) hR + simpa [mul_assoc] using hφi.const_mul (w i) + +lemma integral_sum_mul_phi_div_le_Cφ_mul_sum + {ι : Type} (s : Finset ι) (w : ι → ℝ) (a : ι → ℝ) + (hw : ∀ i ∈ s, 0 ≤ w i) (ha : ∀ i ∈ s, 0 < a i) {R : ℝ} (hR : 0 ≤ R) : + (∫ r in R..(2 * R), (∑ i ∈ s, fun r : ℝ => w i * φ (r / a i)) r ∂volume) + ≤ Cφ * (∑ i ∈ s, w i) * R := by + have hint : ∀ i ∈ s, IntervalIntegrable (fun r : ℝ => w i * φ (r / a i)) + volume R (2 * R) := by + intro i hi + have hφi : IntervalIntegrable (fun r : ℝ => φ (r / a i)) volume R (2 * R) := + intervalIntegrable_phi_div (a := a i) (R := R) (ha i hi) hR + simpa [mul_assoc] using hφi.const_mul (w i) + have hsum_int : + (∫ r in R..(2 * R), (∑ i ∈ s, fun r : ℝ => w i * φ (r / a i)) r ∂volume) + = ∑ i ∈ s, ∫ r in R..(2 * R), (fun r : ℝ => w i * φ (r / a i)) r + ∂volume := by + simpa using + (intervalIntegral.integral_finsetSum (μ := volume) (a := R) (b := 2 * R) + (s := s) (f := fun i : ι => fun r : ℝ => w i * φ (r / a i)) hint) + rw [hsum_int] + have hsum_le : + (∑ i ∈ s, ∫ r in R..(2 * R), (fun r : ℝ => w i * φ (r / a i)) r ∂volume) + ≤ ∑ i ∈ s, w i * (Cφ * R) := by + refine Finset.sum_le_sum ?_ + intro i hi + have hphi : + (∫ r in R..(2 * R), φ (r / a i) ∂volume) ≤ Cφ * R := + integral_phi_div_le_Cφ_mul (a := a i) (R := R) (ha i hi) hR + have := mul_le_mul_of_nonneg_left hphi (hw i hi) + simpa [mul_assoc, mul_left_comm, mul_comm] using this + refine le_trans hsum_le ?_ + have : (∑ i ∈ s, w i * (Cφ * R)) = Cφ * (∑ i ∈ s, w i) * R := by + calc + (∑ i ∈ s, w i * (Cφ * R)) = (∑ i ∈ s, w i) * (Cφ * R) := by + simp [Finset.sum_mul] + _ = Cφ * (∑ i ∈ s, w i) * R := by + ac_rfl + exact le_of_eq this + +lemma exists_radius_Ioc_sum_mul_phi_div_le_Cφ_mul_sum_avoid + {ι : Type} (s : Finset ι) (w : ι → ℝ) (a : ι → ℝ) + (hw : ∀ i ∈ s, 0 ≤ w i) (ha : ∀ i ∈ s, 0 < a i) + (bad : Finset ℝ) {R : ℝ} (hR : 0 < R) : + ∃ r ∈ Set.Ioc R (2 * R), r ∉ bad ∧ + (∑ i ∈ s, w i * φ (r / a i)) ≤ Cφ * (∑ i ∈ s, w i) := by + by_contra hbad + have hforall : + ∀ r ∈ Set.Ioc R (2 * R), r ∉ bad → + Cφ * (∑ i ∈ s, w i) < (∑ i ∈ s, w i * φ (r / a i)) := by + intro r hr hrbad + have : ¬(∑ i ∈ s, w i * φ (r / a i)) ≤ Cφ * (∑ i ∈ s, w i) := by + intro hle + exact hbad ⟨r, hr, hrbad, hle⟩ + exact lt_of_not_ge this + let g : ℝ → ℝ := ∑ i ∈ s, fun r : ℝ => w i * φ (r / a i) + have hg_int : IntervalIntegrable g volume R (2 * R) := by + simpa [g] using intervalIntegrable_sum_mul_phi_div s w a ha hR.le + have hconst_int : + IntervalIntegrable (fun _r : ℝ => Cφ * (∑ i ∈ s, w i)) volume R (2 * R) := + intervalIntegrable_const + have hlt_meas : + (volume.restrict (Set.Ioc R (2 * R))) + {r | Cφ * (∑ i ∈ s, w i) < g r} ≠ 0 := by + have hall : Set.Ioc R (2 * R) \ (bad : Set ℝ) ⊆ {r | Cφ * (∑ i ∈ s, w i) < g r} := by + intro r hr + have hrIoc : r ∈ Set.Ioc R (2 * R) := hr.1 + have hrbad : r ∉ bad := by simpa using hr.2 + simpa [g] using hforall r hrIoc hrbad + have hle : + (volume.restrict (Set.Ioc R (2 * R))) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) + ≤ (volume.restrict (Set.Ioc R (2 * R))) {r | Cφ * (∑ i ∈ s, w i) < g r} := + MeasureTheory.measure_mono hall + have hpos' : + (volume.restrict (Set.Ioc R (2 * R))) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) ≠ 0 := by + exact restrict_volume_Ioc_two_mul_diff_finset_ne_zero bad hR + intro hzero + have : (volume.restrict (Set.Ioc R (2 * R))) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) = 0 := + le_antisymm (le_trans hle (le_of_eq hzero)) (by positivity) + exact hpos' this + have hlt_int : + (∫ r in R..(2 * R), (Cφ * (∑ i ∈ s, w i)) ∂volume) + < ∫ r in R..(2 * R), g r ∂volume := by + have hab : R ≤ 2 * R := by nlinarith [hR.le] + refine intervalIntegral.integral_lt_integral_of_ae_le_of_measure_setOfPred_lt_ne_zero (μ := volume) + (a := R) (b := 2 * R) (f := fun _ => (Cφ * (∑ i ∈ s, w i))) (g := g) + hab hconst_int hg_int ?_ hlt_meas + have hmem : ∀ᵐ r ∂ (volume.restrict (Set.Ioc R (2 * R))), r ∈ Set.Ioc R (2 * R) := + MeasureTheory.ae_restrict_mem (by simp) + have hnotBad : + ∀ᵐ r ∂ (volume.restrict (Set.Ioc R (2 * R))), r ∉ (bad : Set ℝ) := by + simpa using + (bad.finite_toSet.countable.ae_notMem (μ := (volume.restrict (Set.Ioc R (2 * R))))) + filter_upwards [hmem, hnotBad] with r hrIoc hrNotBad + have hrNotBad' : r ∉ bad := by simpa using hrNotBad + exact le_of_lt (by simpa [g] using hforall r hrIoc hrNotBad') + have hconst_eval : + (∫ r in R..(2 * R), (Cφ * (∑ i ∈ s, w i)) ∂volume) = Cφ * (∑ i ∈ s, w i) * R := by + simp [intervalIntegral.integral_const, sub_eq_add_neg, mul_comm] + ring + have hg_le : + (∫ r in R..(2 * R), g r ∂volume) ≤ Cφ * (∑ i ∈ s, w i) * R := by + simpa [g] using integral_sum_mul_phi_div_le_Cφ_mul_sum s w a hw ha hR.le + have : ¬(Cφ * (∑ i ∈ s, w i) * R < Cφ * (∑ i ∈ s, w i) * R) := lt_irrefl _ + have hcontra : Cφ * (∑ i ∈ s, w i) * R < Cφ * (∑ i ∈ s, w i) * R := by + have := hlt_int + simpa [hconst_eval] using (this.trans_le hg_le) + exact this hcontra + +end CartanBound +end Complex +end HadamardSourceScope26 + +section HadamardSourceScope27 + +noncomputable section + +namespace Complex.Hadamard + +open _root_.Complex + +open _root_.Complex _root_.Erdos970.Complex _root_.Real _root_.Erdos970.Real + +lemma max_one_norm_div_pow_le_one_add_rpow + {m : ℕ} {τ r : ℝ} {u a : ℂ} + (hur : ‖u‖ = r) + (hmτ : (m : ℝ) ≤ τ) : + max 1 (‖u / a‖ ^ m) ≤ 1 + (r / ‖a‖) ^ τ := by + by_cases hx : ‖u / a‖ ≤ 1 + · have hpowm_le1 : ‖u / a‖ ^ m ≤ 1 := pow_le_one₀ (norm_nonneg (u / a)) hx + have hr0 : 0 ≤ r := by simpa [hur] using (norm_nonneg u) + have hbase : 0 ≤ r / ‖a‖ := div_nonneg hr0 (norm_nonneg a) + have hnonneg : 0 ≤ (r / ‖a‖) ^ τ := Real.rpow_nonneg hbase τ + have hle1 : (1 : ℝ) ≤ 1 + (r / ‖a‖) ^ τ := le_add_of_nonneg_right hnonneg + have hle2 : ‖u / a‖ ^ m ≤ 1 + (r / ‖a‖) ^ τ := hpowm_le1.trans hle1 + exact (max_le_iff).2 ⟨hle1, hle2⟩ + · have hx1 : 1 < ‖u / a‖ := lt_of_not_ge hx + have hpow : + (‖u / a‖ : ℝ) ^ (m : ℝ) ≤ (‖u / a‖ : ℝ) ^ τ := + Real.rpow_le_rpow_of_exponent_le (le_of_lt hx1) hmτ + have hpow' : ‖u / a‖ ^ m ≤ (‖u / a‖ : ℝ) ^ τ := by + simpa [Real.rpow_natCast] using hpow + have hmax_add : max 1 (‖u / a‖ ^ m) ≤ 1 + ‖u / a‖ ^ m := by + refine max_le (le_add_of_nonneg_right (by positivity)) (le_add_of_nonneg_left (by positivity)) + have : max 1 (‖u / a‖ ^ m) ≤ 1 + (‖u / a‖ : ℝ) ^ τ := + hmax_add.trans (by nlinarith [hpow']) + simpa [norm_div, hur] using this + +lemma norm_inv_weierstrassFactor_le_exp_near + {m : ℕ} {τ r : ℝ} {u a : ℂ} + (hur : ‖u‖ = r) (ha : a ≠ 0) (hr : r ≠ ‖a‖) + (hmτ : (m : ℝ) ≤ τ) : + ‖(weierstrassFactor m (u / a))⁻¹‖ + ≤ Real.exp (CartanBound.φ (r / ‖a‖) + (m : ℝ) * (1 + (r / ‖a‖) ^ τ)) := by + have hlog_one : + Real.log ‖(1 : ℂ) - u / a‖ ≥ -CartanBound.φ (r / ‖a‖) := + CartanBound.log_norm_one_sub_div_ge_neg_phi (hur := hur) (ha := ha) (hr := hr) + have hbase := + log_norm_weierstrassFactor_ge_log_norm_one_sub_sub (m := m) (z := (u / a)) + have hlogE : + Real.log ‖weierstrassFactor m (u / a)‖ + ≥ -CartanBound.φ (r / ‖a‖) - (m : ℝ) * max 1 (‖u / a‖ ^ m) := by + have hpls := + norm_partialLogSum_le_nat_mul_max_one_norm_pow m (u / a) + linarith [hbase, hlog_one, hpls] + have hmax : + max 1 (‖u / a‖ ^ m) ≤ 1 + (r / ‖a‖) ^ τ := + max_one_norm_div_pow_le_one_add_rpow (m := m) (τ := τ) (r := r) (u := u) (a := a) hur hmτ + have hneglog : + -Real.log ‖weierstrassFactor m (u / a)‖ + ≤ CartanBound.φ (r / ‖a‖) + (m : ℝ) * (1 + (r / ‖a‖) ^ τ) := by + have : -Real.log ‖weierstrassFactor m (u / a)‖ + ≤ CartanBound.φ (r / ‖a‖) + (m : ℝ) * max 1 (‖u / a‖ ^ m) := by + linarith [hlogE] + have hm0 : 0 ≤ (m : ℝ) := by exact_mod_cast (Nat.zero_le m) + exact this.trans (by nlinarith [mul_le_mul_of_nonneg_left hmax hm0]) + have hpos : 0 < ‖weierstrassFactor m (u / a)‖ := by + have : weierstrassFactor m (u / a) ≠ 0 := by + intro h0 + have : u / a = (1 : ℂ) := (weierstrassFactor_eq_zero_iff m (u / a)).1 h0 + have : u = a := (div_eq_one_iff_eq ha).1 this + have : r = ‖a‖ := by simpa [this] using hur.symm + exact (hr this).elim + exact norm_pos_iff.2 this + have hEq : + ‖(weierstrassFactor m (u / a))⁻¹‖ = + Real.exp (-Real.log ‖weierstrassFactor m (u / a)‖) := by + simp [norm_inv, Real.exp_neg, Real.exp_log hpos] + have := Real.exp_le_exp.2 hneglog + simpa [hEq] using this + +lemma norm_inv_weierstrassFactor_le_exp_far + {m : ℕ} {τ r : ℝ} {u a : ℂ} + (hur : ‖u‖ = r) (ha : a ≠ 0) + (hz : ‖u / a‖ ≤ (1 / 2 : ℝ)) (hτ_le : τ ≤ (m + 1 : ℝ)) : + ‖(weierstrassFactor m (u / a))⁻¹‖ ≤ Real.exp ((2 : ℝ) * (r / ‖a‖) ^ τ) := by + by_cases hu : u = 0 + · subst hu + have hr0 : r = 0 := by simpa [hur] using (norm_zero : ‖(0 : ℂ)‖ = 0) + subst hr0 + have h0 : 0 ≤ ((0 : ℝ) / ‖a‖) ^ τ := by + exact Real.rpow_nonneg (by positivity : (0 : ℝ) ≤ 0 / ‖a‖) τ + have h0' : 0 ≤ (2 : ℝ) * ((0 : ℝ) / ‖a‖) ^ τ := mul_nonneg (by norm_num) h0 + have hexp : (1 : ℝ) ≤ Real.exp ((2 : ℝ) * ((0 : ℝ) / ‖a‖) ^ τ) := + (Real.one_le_exp_iff).2 h0' + simpa using hexp + have hlogE := + log_norm_weierstrassFactor_ge_neg_two_pow (m := m) (z := (u / a)) hz + have hneglog : -Real.log ‖weierstrassFactor m (u / a)‖ ≤ (2 : ℝ) * (r / ‖a‖) ^ τ := by + have h1 : -Real.log ‖weierstrassFactor m (u / a)‖ ≤ (2 : ℝ) * ‖u / a‖ ^ (m + 1) := by + linarith [hlogE] + set x : ℝ := ‖u / a‖ + have hx1 : x ≤ 1 := le_trans (by simpa [x] using hz) (by norm_num) + have hxpos : 0 < x := by + simpa [x] using (norm_pos_iff.2 (div_ne_zero hu ha)) + have hτ_le' : τ ≤ ((m + 1 : ℕ) : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one] using hτ_le + have hpow_rpow : x ^ ((m + 1 : ℕ) : ℝ) ≤ x ^ τ := + Real.rpow_le_rpow_of_exponent_ge hxpos hx1 hτ_le' + have hpow : x ^ (m + 1) ≤ x ^ τ := by + simpa [← Real.rpow_natCast] using hpow_rpow + have h2x : (2 : ℝ) * x ^ (m + 1) ≤ (2 : ℝ) * x ^ τ := + mul_le_mul_of_nonneg_left hpow (by positivity) + have h2 : (2 : ℝ) * ‖u / a‖ ^ (m + 1) ≤ (2 : ℝ) * (‖u / a‖ : ℝ) ^ τ := by + simpa [x] using h2x + have h3 : (‖u‖ / ‖a‖) ^ τ = (r / ‖a‖) ^ τ := by + simp [hur] + exact (h1.trans h2).trans_eq (by simp [h3]) + have hpos : 0 < ‖weierstrassFactor m (u / a)‖ := by + have : weierstrassFactor m (u / a) ≠ 0 := by + intro h0 + have : u / a = (1 : ℂ) := (weierstrassFactor_eq_zero_iff m (u / a)).1 h0 + have : u = a := (div_eq_one_iff_eq ha).1 this + have : (‖u / a‖ : ℝ) = 1 := by simpa [this] using (by simp [ha]) + linarith [hz, this] + exact norm_pos_iff.2 this + have hEq : + ‖(weierstrassFactor m (u / a))⁻¹‖ = + Real.exp (-Real.log ‖weierstrassFactor m (u / a)‖) := by + simp [norm_inv, Real.exp_neg, Real.exp_log hpos] + have := Real.exp_le_exp.2 hneglog + simpa [hEq] using this + +end Complex.Hadamard +end +end HadamardSourceScope27 + +section HadamardSourceScope28 + +noncomputable section + +namespace Complex.Hadamard + +open _root_.Complex + +open scoped BigOperators +open Filter Finset _root_.Real _root_.Erdos970.Real Topology + +section CartanFiniteSum + +variable {α : Type*} + +private lemma summable_ite_mem_finset [DecidableEq α] (s : Finset α) (u : α → ℝ) : + Summable (fun a => if a ∈ s then u a else 0) := + summable_of_ne_finset_zero (s := s) fun a ha => by simp [ite_eq_right ha] + +private lemma tsum_ite_mem_finset [DecidableEq α] (s : Finset α) (u : α → ℝ) : + (∑' a, if a ∈ s then u a else 0) = ∑ a ∈ s, u a := by + classical + simpa [Finset.sum_ite] using + (hasSum_sum_of_ne_finset_zero (s := s) (f := fun a => if a ∈ s then u a else 0) + fun a ha => by simp [ite_eq_right ha]).tsum_eq + +private lemma tsum_add_four (u₁ u₂ u₃ u₄ : α → ℝ) + (h₁ : Summable u₁) (h₂ : Summable u₂) (h₃ : Summable u₃) (h₄ : Summable u₄) : + tsum (fun a => ((u₁ a + u₂ a) + u₃ a) + u₄ a) + = tsum u₁ + tsum u₂ + tsum u₃ + tsum u₄ := by + calc + tsum (fun a => ((u₁ a + u₂ a) + u₃ a) + u₄ a) + = tsum (fun a => (u₁ a + u₂ a) + (u₃ a + u₄ a)) := by + simp [add_comm, add_left_comm] + _ = tsum (fun a => u₁ a + u₂ a) + tsum (fun a => u₃ a + u₄ a) := + Summable.tsum_add (h₁.add h₂) (h₃.add h₄) + _ = tsum u₁ + tsum u₂ + tsum u₃ + tsum u₄ := by + rw [Summable.tsum_add h₁ h₂, Summable.tsum_add h₃ h₄] + ring + +end CartanFiniteSum + +noncomputable def cartanProductConstant (m : ℕ) (τ Sτ : ℝ) : ℝ := + ((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 3) * (Sτ + 1) + +lemma cartanProductConstant_nonneg {m : ℕ} {τ Sτ : ℝ} (hSτ : 0 ≤ Sτ) : + 0 ≤ cartanProductConstant m τ Sτ := by + have hS : 0 ≤ Sτ + 1 := by linarith + have hA : 0 ≤ (CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 3 := by + have hCφ : 0 ≤ CartanBound.Cφ := le_of_lt CartanBound.Cφ_pos + have hm0 : 0 ≤ (m : ℝ) := by exact_mod_cast (Nat.zero_le m) + have h4τ : 0 ≤ (4 : ℝ) ^ τ := by positivity + nlinarith [hCφ, hm0, h4τ] + simpa [cartanProductConstant] using mul_nonneg hA hS + +lemma rpow_div_norm_divisorZeroIndex₀_eq + {f : ℂ → ℂ} {r τ : ℝ} (hr : 0 ≤ r) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) : + (r / ‖divisorZeroIndex₀Val p‖) ^ τ = + (r ^ τ) * ((‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) := by + have hp : 0 ≤ (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) := by positivity + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using + (Real.mul_rpow (x := r) (y := (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ)) (z := τ) hr hp) + +lemma tsum_rpow_div_norm_divisorZeroIndex₀_eq + {f : ℂ → ℂ} {r τ : ℝ} (hr : 0 ≤ r) : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + = (r ^ τ) * ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + calc + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + = ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ := by + refine tsum_congr ?_ + intro p + exact rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr p + _ = (r ^ τ) * ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + simp [tsum_mul_left] + +lemma tsum_two_mul_rpow_div_norm_divisorZeroIndex₀_le + {f : ℂ → ℂ} {r τ : ℝ} (hr : 0 ≤ r) (hτ_nonneg : 0 ≤ τ) : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (2 : ℝ) * (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + ≤ (2 : ℝ) * ((∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) + 1) * (1 + r) ^ τ := by + set Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + have htsum : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (2 : ℝ) * (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + = (2 : ℝ) * (r ^ τ) * Sτ := by + calc + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (2 : ℝ) * (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + = (2 : ℝ) * ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (r / ‖divisorZeroIndex₀Val p‖) ^ τ := by + simp [tsum_mul_left] + _ = (2 : ℝ) * ((r ^ τ) * Sτ) := by + rw [tsum_rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr] + _ = (2 : ℝ) * (r ^ τ) * Sτ := by ring + have hSτ_nonneg : 0 ≤ Sτ := + tsum_nonneg (fun _ => Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _) + have h1r : r ^ τ ≤ (1 + r) ^ τ := + Real.rpow_le_rpow (by positivity) (by linarith) hτ_nonneg + have hS : Sτ ≤ Sτ + 1 := by linarith + have hle : (r ^ τ) * Sτ ≤ (1 + r) ^ τ * (Sτ + 1) := + mul_le_mul h1r hS (by linarith) (by positivity) + rw [htsum] + have : (2 : ℝ) * (r ^ τ) * Sτ ≤ (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ := by + nlinarith [hle] + simpa [Sτ, mul_assoc, mul_left_comm, mul_comm] using this + +lemma sum_rpow_div_norm_divisorZeroIndex₀_le + {f : ℂ → ℂ} {r τ : ℝ} (small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hr : 0 ≤ r) (hτ_nonneg : 0 ≤ τ) + (hsumτ : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) : + (∑ p ∈ small, (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + ≤ ((∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) + 1) * (1 + r) ^ τ := by + set Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + have hsum_inv : + (∑ p ∈ small, (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) ≤ Sτ := by + have hnn : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + 0 ≤ (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ := by + intro p + positivity + simpa [Sτ] using + (Summable.sum_le_tsum (s := small) + (f := fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) + (fun p _ => hnn p) hsumτ) + have hsum_eq : + ∑ p ∈ small, (r / ‖divisorZeroIndex₀Val p‖) ^ τ = + (r ^ τ) * ∑ p ∈ small, (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ := by + simp [rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr, Finset.mul_sum] + have h1r : r ^ τ ≤ (1 + r) ^ τ := + Real.rpow_le_rpow (by positivity) (by linarith) hτ_nonneg + have hS : (∑ p ∈ small, (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) ≤ Sτ + 1 := by + linarith [hsum_inv] + have hle : + (r ^ τ) * (∑ p ∈ small, (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) + ≤ (1 + r) ^ τ * (Sτ + 1) := + mul_le_mul h1r hS (by positivity) (by positivity) + simpa [Sτ, hsum_eq, mul_assoc, mul_left_comm, mul_comm] using hle + +lemma add_four_le_add_two_mul_of_le {x₁ x₂ x₃ x₄ A B C : ℝ} + (h₁ : x₁ ≤ A) (h₂ : x₂ ≤ B) (h₃ : x₃ ≤ B) (h₄ : x₄ ≤ C) : + x₁ + x₂ + x₃ + x₄ ≤ A + 2 * B + C := by + nlinarith + +lemma cartan_majorant_four_term_bound + {xφ x0 xm xt Cφ m q Y T : ℝ} + (hφ : xφ ≤ Cφ * q * Y * T) + (h0 : x0 ≤ m * q * Y * T) + (hm : xm ≤ m * q * Y * T) + (ht : xt ≤ (2 : ℝ) * Y * T) : + xφ + x0 + xm + xt ≤ (Cφ + (2 : ℝ) * m) * q * Y * T + (2 : ℝ) * Y * T := by + have h := + add_four_le_add_two_mul_of_le hφ h0 hm ht + have hring : + Cφ * (q * (Y * T)) + 2 * (m * (q * (Y * T))) + 2 * (Y * T) + = (Cφ + (2 : ℝ) * m) * (q * (Y * T)) + (2 : ℝ) * (Y * T) := by + ring + simpa [mul_assoc, hring] using h + +lemma cartan_majorant_add_two_factor (A Y T : ℝ) : + A * Y * T + (2 : ℝ) * Y * T = ((A + 2) * Y) * T := by + ring + +lemma cartan_majorant_pad_two_to_three {A S T : ℝ} (hS : 0 ≤ S + 1) (hT : 0 ≤ T) : + ((A + 2) * (S + 1)) * T ≤ ((A + 3) * (S + 1)) * T := by + have h : (A + 2) * (S + 1) ≤ (A + 3) * (S + 1) := by + nlinarith + exact mul_le_mul_of_nonneg_right h hT + +lemma cartan_majorant_nonneg + {f : ℂ → ℂ} {m : ℕ} {τ r : ℝ} (hr : 0 ≤ r) + (small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) : + letI : DecidableEq (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := Classical.decEq _ + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + ∀ p, 0 ≤ b p := by + classical + dsimp + intro p + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun q => ‖divisorZeroIndex₀Val q‖ + have hap : ap p = ‖divisorZeroIndex₀Val p‖ := rfl + by_cases hp : p ∈ small + · have hφ : 0 ≤ CartanBound.φ (r / ap p) := CartanBound.φ_nonneg (t := r / ap p) + have hm0 : 0 ≤ (m : ℝ) := by exact_mod_cast (Nat.zero_le m) + have h1 : 0 ≤ (1 + (r / ap p) ^ τ) := by positivity + have : 0 ≤ CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) := by + nlinarith [hφ, hm0, h1] + simpa [hap, hp, ap] using this + · have hbase : 0 ≤ r / ap p := div_nonneg hr (by positivity) + have hpow : 0 ≤ (r / ap p) ^ τ := Real.rpow_nonneg hbase τ + have : 0 ≤ (2 : ℝ) * (r / ap p) ^ τ := mul_nonneg (by norm_num) hpow + simpa [hap, hp, ap] using this + +lemma cartan_majorant_summable + {f : ℂ → ℂ} {m : ℕ} {τ r : ℝ} (hr : 0 ≤ r) + (small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsumτ : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) : + letI : DecidableEq (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := Classical.decEq _ + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + Summable b := by + classical + dsimp + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun q => ‖divisorZeroIndex₀Val q‖ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + have hb : Summable b := by + let b₁ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else 0 + let b₂ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => if p ∈ small then 0 else (2 : ℝ) * (r / ap p) ^ τ + have hb_decomp : b = fun p => b₁ p + b₂ p := by + funext p + by_cases hp : p ∈ small <;> simp [b, b₁, b₂, hp] + have hb₁ : Summable b₁ := by + simpa [b₁] using + summable_ite_mem_finset small + (fun p => CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ)) + have hb₂ : Summable b₂ := by + have hconst : + Summable (fun p => + (2 : ℝ) * (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) := + hsumτ.mul_left ((2 : ℝ) * (r ^ τ)) + refine Summable.of_nonneg_of_le + (fun p => by + by_cases hp : p ∈ small + · simp [b₂, hp] + · have : 0 ≤ (2 : ℝ) * (r / ap p) ^ τ := by positivity + simpa [b₂, hp] using this) + (fun p => ?_) hconst + by_cases hp : p ∈ small + · have : 0 ≤ (2 : ℝ) * (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := by positivity + simpa [b₂, hp] using this + · have hrpow : (r / ap p) ^ τ = (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := by + simpa [ap] using rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr p + simp [b₂, hp, hrpow, mul_assoc, mul_left_comm, mul_comm] + simpa [hb_decomp] using hb₁.add hb₂ + refine hb.congr ?_ + intro p + by_cases hp : p ∈ small <;> simp [b, ap, hp] + +lemma cartan_card_small_le + {f : ℂ → ℂ} {τ R : ℝ} (hRpos : 0 < R) (hτ_nonneg : 0 ≤ τ) + (small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsmall : ∀ p ∈ small, ‖divisorZeroIndex₀Val p‖ ≤ 4 * R) + (hsumτ : + Summable + (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) : + (small.card : ℝ) + ≤ (4 * R) ^ τ + * ((∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) + 1) := by + classical + set Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + have hsum_le : (∑ p ∈ small, ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) ≤ Sτ := by + have hnn : + ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + 0 ≤ ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + intro p + exact Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _ + simpa [Sτ] using + (Summable.sum_le_tsum (s := small) + (f := fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) + (fun p _ => hnn p) hsumτ) + have hgeom_sum : + (small.card : ℝ) ≤ ∑ p ∈ small, (4 * R) ^ τ * ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + have hcard_eq : (small.card : ℝ) = ∑ p ∈ small, (1 : ℝ) := by simp + rw [hcard_eq] + refine Finset.sum_le_sum (fun p hp => ?_) + have hp_le : ‖divisorZeroIndex₀Val p‖ ≤ 4 * R := hsmall p hp + have hap : 0 < ‖divisorZeroIndex₀Val p‖ := + norm_pos_iff.2 (divisorZeroIndex₀Val_ne_zero p) + have hbase : (1 : ℝ) ≤ (4 * R) / ‖divisorZeroIndex₀Val p‖ := by + exact (le_div_iff₀ hap).2 (by simpa [mul_one] using hp_le) + have : (1 : ℝ) ≤ ((4 * R) / ‖divisorZeroIndex₀Val p‖) ^ τ := + Real.one_le_rpow hbase hτ_nonneg + have hdiv : + ((4 * R) / ‖divisorZeroIndex₀Val p‖) ^ τ = + (4 * R) ^ τ * (‖divisorZeroIndex₀Val p‖)⁻¹ ^ τ := by + have h4 : 0 ≤ (4 * R : ℝ) := by nlinarith [le_of_lt hRpos] + have ha : 0 ≤ (‖divisorZeroIndex₀Val p‖ : ℝ)⁻¹ := by positivity + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using + (Real.mul_rpow (x := (4 * R : ℝ)) + (y := (‖divisorZeroIndex₀Val p‖ : ℝ)⁻¹) (z := τ) h4 ha) + have : (1 : ℝ) ≤ (4 * R) ^ τ * ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + simpa [hdiv] using this + exact this + have hgeom : + (small.card : ℝ) ≤ (4 * R) ^ τ * (∑ p ∈ small, ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := by + simpa [Finset.mul_sum] using hgeom_sum + have hsmall_le : (small.card : ℝ) ≤ (4 * R) ^ τ * Sτ := by + exact hgeom.trans (mul_le_mul_of_nonneg_left hsum_le (by positivity)) + have hS_le : (4 * R) ^ τ * Sτ ≤ (4 * R) ^ τ * (Sτ + 1) := by + refine mul_le_mul_of_nonneg_left ?_ (by positivity) + linarith + have : (small.card : ℝ) ≤ (4 * R) ^ τ * (Sτ + 1) := hsmall_le.trans hS_le + simpa [Sτ, add_comm, add_left_comm, add_assoc, mul_assoc] using this + +lemma cartan_rpow_mul_le + {τ R r : ℝ} (hRpos : 0 < R) (hrpos : 0 < r) (hR_le_r : R ≤ r) (hτ_nonneg : 0 ≤ τ) : + (4 * R) ^ τ ≤ (4 : ℝ) ^ τ * (1 + r) ^ τ := by + have hR_le_1r : R ≤ 1 + r := by linarith [hR_le_r, le_of_lt hrpos] + have hbase0 : 0 ≤ (4 * R : ℝ) := by nlinarith [le_of_lt hRpos] + have : (4 * R) ^ τ ≤ (4 * (1 + r)) ^ τ := by + refine Real.rpow_le_rpow hbase0 ?_ hτ_nonneg + nlinarith [hR_le_1r] + have hmul : (4 * (1 + r)) ^ τ = (4 : ℝ) ^ τ * (1 + r) ^ τ := by + have h4 : 0 ≤ (4 : ℝ) := by norm_num + have h1 : 0 ≤ (1 + r : ℝ) := by positivity + simpa [mul_assoc] using + (Real.mul_rpow (x := (4 : ℝ)) (y := (1 + r : ℝ)) (z := τ) h4 h1) + simpa [hmul] using this + +open Classical in +theorem cartan_sum_majorant_le + {f : ℂ → ℂ} {m : ℕ} {τ R r : ℝ} + (hRpos : 0 < R) + (hrpos : 0 < r) + (hR_le_r : R ≤ r) + (hτ_nonneg : 0 ≤ τ) + (smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsmall_fin : smallSet.Finite) + (hsmallSet : + smallSet = {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ 4 * R}) + (hsumτ : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) + (hr_phi : + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + (∑ p ∈ small, CartanBound.φ (r / a p)) ≤ CartanBound.Cφ * (small.card : ℝ)) : + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + letI : DecidableEq (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := Classical.decEq _ + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + let Sτ : ℝ := ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + let Cprod : ℝ := cartanProductConstant m τ Sτ + ∀ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)), + (∑ p ∈ s, b p) ≤ Cprod * (1 + r) ^ τ := by + classical + intro small ap b Sτ Cprod s + have hr : 0 ≤ r := le_of_lt hrpos + have hSτ_nonneg : 0 ≤ Sτ := + tsum_nonneg (fun _ => Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _) + have hsmall_mem : ∀ p, p ∈ small ↔ p ∈ smallSet := by + intro p + simp [small, hsmall_fin.mem_toFinset] + have hphi_sum : + (∑ p ∈ small, CartanBound.φ (r / ap p)) ≤ CartanBound.Cφ * (small.card : ℝ) := by + simpa [small, ap] using hr_phi + have hb_nonneg : ∀ p, 0 ≤ b p := by + simpa [ap, b] using (cartan_majorant_nonneg (f := f) (m := m) (τ := τ) (r := r) hr small) + have hb_summable : Summable b := by + simpa [ap, b] using + (cartan_majorant_summable (f := f) (m := m) (τ := τ) (r := r) hr small hsumτ) + have hsmall_norm : ∀ p ∈ small, ‖divisorZeroIndex₀Val p‖ ≤ 4 * R := by + intro p hp + have : p ∈ smallSet := (hsmall_mem p).1 hp + simpa [hsmallSet] using this + have hcard_le : (small.card : ℝ) ≤ (4 * R) ^ τ * (Sτ + 1) := by + simpa [Sτ, mul_assoc, add_assoc, add_left_comm, add_comm] using + (cartan_card_small_le (f := f) (τ := τ) (R := R) hRpos hτ_nonneg small hsmall_norm hsumτ) + have hpowR : (4 * R) ^ τ ≤ (4 : ℝ) ^ τ * (1 + r) ^ τ := + cartan_rpow_mul_le (τ := τ) (R := R) (r := r) hRpos hrpos hR_le_r hτ_nonneg + have hcard_le' : (small.card : ℝ) ≤ (4 : ℝ) ^ τ * (1 + r) ^ τ * (Sτ + 1) := by + have : (4 * R) ^ τ * (Sτ + 1) ≤ (4 : ℝ) ^ τ * (1 + r) ^ τ * (Sτ + 1) := by + exact mul_le_mul_of_nonneg_right hpowR (by linarith [hSτ_nonneg]) + exact le_trans hcard_le this + have hb_tsum_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b p) ≤ Cprod * (1 + r) ^ τ := by + let bφ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => if p ∈ small then CartanBound.φ (r / ap p) else 0 + let b0 : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => if p ∈ small then (m : ℝ) else 0 + let bmτ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => if p ∈ small then (m : ℝ) * (r / ap p) ^ τ else 0 + let bt : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (2 : ℝ) * (r / ap p) ^ τ + have hb_pointwise : ∀ p, b p ≤ bφ p + b0 p + bmτ p + bt p := by + intro p + by_cases hp : p ∈ small + · have hbase : 0 ≤ r / ap p := div_nonneg hr (by positivity) + have hx : 0 ≤ (r / ap p) ^ τ := Real.rpow_nonneg hbase τ + have hpos : 0 ≤ (2 : ℝ) * (r / ap p) ^ τ := mul_nonneg (by norm_num) hx + simp [b, bφ, b0, bmτ, bt, hp] + nlinarith + · simp [b, bφ, b0, bmτ, bt, hp] + have hmaj_summ : Summable (fun p => bφ p + b0 p + bmτ p + bt p) := by + have hbφ_summ : Summable bφ := by + simpa [bφ] using summable_ite_mem_finset small (fun p => CartanBound.φ (r / ap p)) + have hb0_summ : Summable b0 := by + simpa [b0] using summable_ite_mem_finset small (fun _ => (m : ℝ)) + have hbmτ_summ : Summable bmτ := by + simpa [bmτ] using summable_ite_mem_finset small (fun p => (m : ℝ) * (r / ap p) ^ τ) + have hbt_summ : Summable bt := by + have hconst : Summable (fun p => + (2 : ℝ) * (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) := + hsumτ.mul_left ((2 : ℝ) * (r ^ τ)) + refine hconst.congr ?_ + intro p + simp [bt, ap, rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr p, + mul_assoc, mul_left_comm, mul_comm] + have h' : Summable (fun p => bφ p + b0 p + (bmτ p + bt p)) := + (hbφ_summ.add hb0_summ).add (hbmτ_summ.add hbt_summ) + simpa [add_assoc] using h' + have htsum_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b p) + ≤ ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (bφ p + b0 p + bmτ p + bt p) := + (hasSum_le hb_pointwise hb_summable.hasSum hmaj_summ.hasSum) + have htsum_bφ : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bφ p) + = ∑ p ∈ small, CartanBound.φ (r / ap p) := by + classical + simpa [bφ] using tsum_ite_mem_finset small (fun p => CartanBound.φ (r / ap p)) + have htsum_b0 : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) + = (m : ℝ) * (small.card : ℝ) := by + classical + have : (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) = ∑ p ∈ small, (m : ℝ) := by + simpa [b0] using tsum_ite_mem_finset small (fun _ => (m : ℝ)) + simp [this, Finset.sum_const, nsmul_eq_mul, mul_comm] + have htsum_bmτ : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) + = (m : ℝ) * ∑ p ∈ small, (r / ap p) ^ τ := by + classical + have : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) + = ∑ p ∈ small, (m : ℝ) * (r / ap p) ^ τ := by + simpa [bmτ] using tsum_ite_mem_finset small (fun p => (m : ℝ) * (r / ap p) ^ τ) + simp [this, Finset.mul_sum] + have htsum_bt : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bt p) + ≤ (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ := by + simpa [bt, ap, Sτ] using + tsum_two_mul_rpow_div_norm_divisorZeroIndex₀_le (f := f) (τ := τ) hr hτ_nonneg + have hsum_small_rpow_le : + (∑ p ∈ small, (r / ap p) ^ τ) ≤ (Sτ + 1) * (1 + r) ^ τ := by + simpa [ap, Sτ] using + sum_rpow_div_norm_divisorZeroIndex₀_le (f := f) (τ := τ) small hr hτ_nonneg hsumτ + have hm0 : 0 ≤ (m : ℝ) := by exact_mod_cast (Nat.zero_le m) + have hCφ : 0 ≤ CartanBound.Cφ := le_of_lt CartanBound.Cφ_pos + have hS : 0 ≤ Sτ + 1 := by linarith [hSτ_nonneg] + have htsum_majorant : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (bφ p + b0 p + bmτ p + bt p)) + ≤ (((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 2) * (Sτ + 1)) + * (1 + r) ^ τ := by + have hφ_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bφ p) + ≤ CartanBound.Cφ * (small.card : ℝ) := by + simpa [htsum_bφ] using hphi_sum + have hb0_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) + ≤ (m : ℝ) * (small.card : ℝ) := by + simp [htsum_b0] + have hbmτ_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) ≤ + (m : ℝ) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + have h0 : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) + ≤ (m : ℝ) * ((Sτ + 1) * (1 + r) ^ τ) := by + have hmul := mul_le_mul_of_nonneg_left hsum_small_rpow_le hm0 + + simpa [htsum_bmτ, mul_assoc, mul_left_comm, mul_comm] using hmul + have h1 : (1 : ℝ) ≤ (4 : ℝ) ^ τ := + Real.one_le_rpow (by norm_num) hτ_nonneg + have hscale : + (m : ℝ) * ((Sτ + 1) * (1 + r) ^ τ) + ≤ (m : ℝ) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + have hnonneg : 0 ≤ (m : ℝ) * ((Sτ + 1) * (1 + r) ^ τ) := by + have : 0 ≤ (Sτ + 1) * (1 + r) ^ τ := by positivity + exact mul_nonneg hm0 this + simpa [mul_assoc, mul_left_comm, mul_comm] using (mul_le_mul_of_nonneg_right h1 hnonneg) + exact h0.trans hscale + have hbt_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bt p) + ≤ (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ := by + simpa [mul_assoc, mul_left_comm, mul_comm] using htsum_bt + have hsplit : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (bφ p + b0 p + bmτ p + bt p)) + = (∑' p, bφ p) + (∑' p, b0 p) + (∑' p, bmτ p) + (∑' p, bt p) := by + classical + have hbφ_summ : Summable bφ := by + simpa [bφ] using summable_ite_mem_finset small (fun p => CartanBound.φ (r / ap p)) + have hb0_summ : Summable b0 := by + simpa [b0] using summable_ite_mem_finset small (fun _ => (m : ℝ)) + have hbmτ_summ : Summable bmτ := by + simpa [bmτ] using summable_ite_mem_finset small (fun p => (m : ℝ) * (r / ap p) ^ τ) + have hbt_summ : Summable bt := by + have hconst : + Summable + (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + (2 : ℝ) * (r ^ τ) * ((‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ)) := + hsumτ.mul_left ((2 : ℝ) * (r ^ τ)) + refine hconst.congr ?_ + intro p + simp [bt, ap, rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr p, + mul_assoc, mul_left_comm, mul_comm] + exact tsum_add_four bφ b0 bmτ bt hbφ_summ hb0_summ hbmτ_summ hbt_summ + have hcard_le'' : + (small.card : ℝ) ≤ (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + simpa [mul_assoc, mul_left_comm, mul_comm] using hcard_le' + have hφ_le' : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bφ p) ≤ + CartanBound.Cφ * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + have : CartanBound.Cφ * (small.card : ℝ) ≤ + CartanBound.Cφ * ((4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ) := + mul_le_mul_of_nonneg_left hcard_le'' hCφ + exact hφ_le.trans (by simpa [mul_assoc, mul_left_comm, mul_comm] using this) + have hb0_le' : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) ≤ + (m : ℝ) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + have : (m : ℝ) * (small.card : ℝ) ≤ (m : ℝ) * ((4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ) := + mul_le_mul_of_nonneg_left hcard_le'' hm0 + exact hb0_le.trans (by simpa [mul_assoc, mul_left_comm, mul_comm] using this) + have htsum_majorant' : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (bφ p + b0 p + bmτ p + bt p)) + ≤ (CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ + + (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ := by + rw [hsplit] + set Y : ℝ := Sτ + 1 with hY + set T : ℝ := (1 + r) ^ τ with hT + have hφ_leY : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bφ p) + ≤ CartanBound.Cφ * (4 : ℝ) ^ τ * Y * T := by + simpa [hY, hT, mul_assoc] using hφ_le' + have hb0_leY : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) + ≤ (m : ℝ) * (4 : ℝ) ^ τ * Y * T := by + simpa [hY, hT, mul_assoc] using hb0_le' + have hbmτ_leY : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) + ≤ (m : ℝ) * (4 : ℝ) ^ τ * Y * T := by + simpa [hY, hT, mul_assoc] using hbmτ_le + have hbt_leY : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bt p) ≤ (2 : ℝ) * Y * T := by + simpa [hY, hT, mul_assoc] using hbt_le + have hmain := + cartan_majorant_four_term_bound + (q := (4 : ℝ) ^ τ) hφ_leY hb0_leY hbmτ_leY hbt_leY + simpa [Y, T, add_assoc] using hmain + have hring : + (CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ + + (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ + = (((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 2) * (Sτ + 1)) * (1 + r) ^ τ := by + exact cartan_majorant_add_two_factor + ((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ) (Sτ + 1) ((1 + r) ^ τ) + rw [← hring] + exact htsum_majorant' + have hCprod' : + (((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 2) * (Sτ + 1)) * (1 + r) ^ τ + ≤ Cprod * (1 + r) ^ τ := by + simpa [Cprod, cartanProductConstant, mul_assoc, mul_left_comm, mul_comm] using + cartan_majorant_pad_two_to_three + (A := (CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ) + (S := Sτ) (T := (1 + r) ^ τ) hS (by positivity) + exact (le_trans (le_trans htsum_le htsum_majorant) hCprod') + have hsum_fin_le : + (∑ p ∈ s, b p) ≤ (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b p) := by + simpa using + (Summable.sum_le_tsum (s := s) (f := b) (fun p _ => hb_nonneg p) hb_summable) + exact hsum_fin_le.trans hb_tsum_le + +end Complex.Hadamard +end +end HadamardSourceScope28 + +section HadamardSourceScope29 + +noncomputable section + +open scoped BigOperators +open Filter Finset _root_.Real _root_.Erdos970.Real Topology + +lemma Finset.prod_le_exp_sum {α : Type} (s : Finset α) (a : α → ℝ) (b : α → ℝ) + (ha : ∀ x ∈ s, 0 ≤ a x) (hab : ∀ x ∈ s, a x ≤ Real.exp (b x)) : + (∏ x ∈ s, a x) ≤ Real.exp (∑ x ∈ s, b x) := by + calc + (∏ x ∈ s, a x) ≤ ∏ x ∈ s, Real.exp (b x) := Finset.prod_le_prod₀ ha hab + _ = Real.exp (∑ x ∈ s, b x) := by + simpa using (Real.exp_sum (s := s) (f := b)).symm + +lemma hasProd_le_of_prod_le_exp {α : Type} {f : α → ℝ} {a : ℝ} + (hf : HasProd f a (SummationFilter.unconditional α)) + {B : ℝ} (hB : ∀ s : Finset α, (∏ x ∈ s, f x) ≤ Real.exp B) : + a ≤ Real.exp B := + hasProd_le_of_prod_le (L := (SummationFilter.unconditional α)) hf hB + +lemma hasProd_inv_unconditional {α : Type} {fac : α → ℂ} {F : ℂ} + (hfac : HasProd fac F (SummationFilter.unconditional α)) (hF : F ≠ 0) : + HasProd (fun x => (fac x)⁻¹) (F⁻¹) (SummationFilter.unconditional α) := by + change + Tendsto (fun s : Finset α => ∏ x ∈ s, (fac x)⁻¹) + (SummationFilter.unconditional α).filter (𝓝 (F⁻¹)) + have hprod : + Tendsto (fun s : Finset α => ∏ x ∈ s, fac x) + (SummationFilter.unconditional α).filter (𝓝 F) := by + simpa [HasProd] using hfac + have hinv : + Tendsto (fun s : Finset α => (∏ x ∈ s, fac x)⁻¹) + (SummationFilter.unconditional α).filter (𝓝 (F⁻¹)) := + hprod.inv₀ hF + refine hinv.congr' (Filter.Eventually.of_forall ?_) + intro s + simp [Finset.prod_inv_distrib] + +lemma hasProd_norm_inv_unconditional {α : Type} {fac : α → ℂ} {F : ℂ} + (hfac : HasProd fac F (SummationFilter.unconditional α)) (hF : F ≠ 0) : + HasProd (fun x => ‖(fac x)⁻¹‖) ‖F⁻¹‖ (SummationFilter.unconditional α) := by + change + Tendsto (fun s : Finset α => ∏ x ∈ s, ‖(fac x)⁻¹‖) + (SummationFilter.unconditional α).filter (𝓝 ‖F⁻¹‖) + have hnorm := (hasProd_inv_unconditional hfac hF).norm + refine hnorm.congr' (Filter.Eventually.of_forall ?_) + intro s + simp [norm_inv, Finset.prod_inv_distrib] + +lemma hasProd_norm_inv_le_exp_of_pointwise_le_exp {α : Type} {fac : α → ℂ} {F : ℂ} + (hfac : HasProd fac F (SummationFilter.unconditional α)) + (b : α → ℝ) (B : ℝ) + (hterm : ∀ x, ‖(fac x)⁻¹‖ ≤ Real.exp (b x)) + (hsum : ∀ s : Finset α, (∑ x ∈ s, b x) ≤ B) : + ‖F⁻¹‖ ≤ Real.exp B := by + by_cases hF : F = 0 + · subst hF + simpa using exp_nonneg B + have hnorm : + HasProd (fun x => ‖(fac x)⁻¹‖) ‖F⁻¹‖ (SummationFilter.unconditional α) := + hasProd_norm_inv_unconditional hfac hF + have hprod : ∀ s : Finset α, (∏ x ∈ s, ‖(fac x)⁻¹‖) ≤ Real.exp B := by + intro s + have h0 : ∀ x ∈ s, 0 ≤ ‖(fac x)⁻¹‖ := by intro _ _; positivity + have h1 : (∏ x ∈ s, ‖(fac x)⁻¹‖) ≤ Real.exp (∑ x ∈ s, b x) := by + refine Finset.prod_le_exp_sum s (a := fun x => ‖(fac x)⁻¹‖) (b := b) h0 ?_ + intro x hx + simpa using hterm x + have h2 : Real.exp (∑ x ∈ s, b x) ≤ Real.exp B := + Real.exp_le_exp.2 (hsum s) + exact h1.trans h2 + exact hasProd_le_of_prod_le_exp hnorm hprod +end +end HadamardSourceScope29 + +section HadamardSourceScope30 + +open Metric + +namespace Complex + +open _root_.Complex + +theorem borelCaratheodory_zero_closedBall {f : ℂ → ℂ} {M r R : ℝ} + (hf : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) R)) + (hr : 0 < r) (hlt : r < R) (hM : 0 < M) (hf0 : f 0 = 0) + (hf_re : ∀ w, ‖w‖ ≤ R → (f w).re ≤ M) {z : ℂ} (hz : ‖z‖ ≤ r) : + ‖f z‖ ≤ 2 * M * r / (R - r) := by + have hR : 0 < R := lt_trans hr hlt + have hz_ball : z ∈ Metric.ball (0 : ℂ) R := by + rw [Metric.mem_ball, dist_zero_right] + exact hz.trans_lt hlt + have hf_diff : DifferentiableOn ℂ f (Metric.ball (0 : ℂ) R) := by + intro w hw + have hw' : w ∈ Metric.closedBall (0 : ℂ) R := ball_subset_closedBall hw + exact (hf w hw').differentiableAt.differentiableWithinAt + have hf_map : Set.MapsTo f (Metric.ball (0 : ℂ) R) {w | w.re ≤ M} := by + intro w hw + simp only [Set.mem_ofPred_eq] + have hw' : ‖w‖ < R := by simpa [Metric.mem_ball, dist_zero_right] using hw + exact hf_re w hw'.le + have hbc := + borelCaratheodory_zero hM hf_diff hf_map hR hz_ball hf0 + have hzR : ‖z‖ < R := by + rw [Metric.mem_ball, dist_zero_right] at hz_ball + exact hz_ball + have hmono : ‖z‖ / (R - ‖z‖) ≤ r / (R - r) := by + have hrden : 0 < R - r := sub_pos.mpr hlt + have hden : 0 < R - ‖z‖ := sub_pos.mpr hzR + rw [div_le_div_iff₀ hden hrden] + nlinarith [hz, norm_nonneg z] + have hM' : 0 ≤ 2 * M := mul_nonneg (by norm_num) (le_of_lt hM) + calc ‖f z‖ + ≤ 2 * M * ‖z‖ / (R - ‖z‖) := hbc + _ ≤ 2 * M * (r / (R - r)) := by + simpa [mul_div_assoc] using mul_le_mul_of_nonneg_left hmono hM' + _ = 2 * M * r / (R - r) := by ring + +end Complex +end HadamardSourceScope30 + +section HadamardSourceScope31 + +noncomputable section + +namespace Complex + +open _root_.Complex +namespace Hadamard + +open _root_.Complex _root_.Erdos970.Complex _root_.Real _root_.Erdos970.Real + BigOperators _root_.Finset Set Filter Topology Metric + +open scoped Topology + +theorem zero_free_polynomial_growth_is_exp_poly {H : ℂ → ℂ} {n : ℕ} + (hH : Differentiable ℂ H) + (h_nonzero : ∀ z, H z ≠ 0) + (h_bound : ∃ C > 0, ∀ z, ‖H z‖ ≤ Real.exp (C * (1 + ‖z‖) ^ n)) : + ∃ P : Polynomial ℂ, P.natDegree ≤ n ∧ ∀ z, H z = Complex.exp (Polynomial.eval z P) := by + classical + rcases h_bound with ⟨C, hCpos, hC⟩ + let L : ℂ → ℂ := fun z => deriv H z / H z + have hderivH : Differentiable ℂ (deriv H) := by + intro z + exact ((hH.analyticAt z).deriv).differentiableAt + have hL : Differentiable ℂ L := by + simpa [L] using! (hderivH.div hH h_nonzero) + let h : ℂ → ℂ := fun z => Complex.wedgeIntegral (0 : ℂ) z L + have hh_deriv : ∀ z, HasDerivAt h (L z) z := by + intro z + let r : ℝ := ‖z‖ + 1 + have hrpos : 0 < r := by + dsimp [r]; linarith [norm_nonneg z] + have hz_ball : z ∈ Metric.ball (0 : ℂ) r := by + have : dist z (0 : ℂ) < r := by simp [r, dist_zero_right] + simpa [Metric.mem_ball] using this + have hconserv : Complex.IsConservativeOn L (Metric.ball (0 : ℂ) r) := + (hL.differentiableOn).isConservativeOn + have hcont : ContinuousOn L (Metric.ball (0 : ℂ) r) := + hL.continuous.continuousOn + simpa [h, r] using hconserv.hasDerivAt_wedgeIntegral (f_cont := hcont) (hz := hz_ball) + have hh : Differentiable ℂ h := fun z => (hh_deriv z).differentiableAt + have hderiv_h : ∀ z, deriv h z = L z := fun z => (hh_deriv z).deriv + let k : ℂ → ℂ := fun z => h z + Complex.log (H 0) + have hk : Differentiable ℂ k := hh.add_const (Complex.log (H 0)) + have hk_exp : ∀ z, H z = Complex.exp (k z) := by + let F : ℂ → ℂ := fun z => Complex.exp (k z) / H z + have hF_deriv : ∀ z, deriv F z = 0 := by + intro z + have hH_has : HasDerivAt H (deriv H z) z := (hH z).hasDerivAt + have hk_has : HasDerivAt k (L z) z := by + have hh_has : HasDerivAt h (L z) z := hh_deriv z + simpa [k, L] using hh_has.add_const (Complex.log (H 0)) + have hExp : HasDerivAt (fun w => Complex.exp (k w)) (Complex.exp (k z) * L z) z := + (HasDerivAt.cexp hk_has) + have hDiv := (HasDerivAt.div hExp hH_has (h_nonzero z)) + have : + deriv F z = + ((Complex.exp (k z) * L z) * H z - Complex.exp (k z) * deriv H z) / (H z) ^ 2 := by + simpa [F] using! hDiv.deriv + rw [this] + have hnum : + (Complex.exp (k z) * L z) * H z - Complex.exp (k z) * deriv H z = 0 := by + dsimp [L] + field_simp [h_nonzero z] + ring + simp [hnum] + have hF_diff : Differentiable ℂ F := (hk.cexp).div hH h_nonzero + have hF_const : ∀ z, F z = F 0 := by + intro z + exact is_const_of_deriv_eq_zero hF_diff hF_deriv z 0 + have hF0 : F 0 = 1 := by + have hh0 : h 0 = 0 := by simp [h, Complex.wedgeIntegral] + have hk0 : k 0 = Complex.log (H 0) := by simp [k, hh0] + have hH0 : H 0 ≠ 0 := h_nonzero 0 + simp [F, hk0, Complex.exp_log hH0, hH0] + intro z + have : F z = 1 := by simpa [hF0] using (hF_const z) + have hHz : H z ≠ 0 := h_nonzero z + have : Complex.exp (k z) / H z = 1 := by simpa [F] using this + have : Complex.exp (k z) = H z := by + field_simp [hHz] at this + simpa using this + exact this.symm + have hk_re_bound : ∀ z, (k z).re ≤ C * (1 + ‖z‖) ^ n := by + intro z + have hHz : H z ≠ 0 := h_nonzero z + have hpos : 0 < ‖H z‖ := norm_pos_iff.mpr hHz + have hlog_le : Real.log ‖H z‖ ≤ C * (1 + ‖z‖) ^ n := by + have := Real.log_le_log hpos (hC z) + simpa [Real.log_exp] using this + have hlog_eq : Real.log ‖H z‖ = (k z).re := by + have : ‖H z‖ = Real.exp (k z).re := by + simpa [hk_exp z] using (Complex.norm_exp (k z)) + calc + Real.log ‖H z‖ = Real.log (Real.exp (k z).re) := by simp [this] + _ = (k z).re := by simp + simpa [hlog_eq] using hlog_le + have hk_iteratedDeriv_eq_zero : ∀ m : ℕ, n < m → iteratedDeriv m k 0 = 0 := by + intro m hm + have hm' : 0 < (m - n : ℕ) := Nat.sub_pos_of_lt hm + have hmne : m - n ≠ 0 := (Nat.pos_iff_ne_zero.1 hm') + let f : ℂ → ℂ := fun z => k z - k 0 + have hf : Differentiable ℂ f := hk.sub_const (k 0) + have hf0 : f 0 = 0 := by simp [f] + have hf_re_bound : ∀ R : ℝ, 0 < R → + ∀ z, ‖z‖ ≤ R → (f z).re ≤ C * (1 + R) ^ n + ‖k 0‖ := by + intro R hRpos z hzR + have hkz : (k z).re ≤ C * (1 + ‖z‖) ^ n := hk_re_bound z + have hkz' : (k z).re ≤ C * (1 + R) ^ n := by + have h1 : (1 + ‖z‖ : ℝ) ≤ 1 + R := by linarith + have hpow : (1 + ‖z‖ : ℝ) ^ n ≤ (1 + R) ^ n := + pow_le_pow_left₀ (by linarith [norm_nonneg z]) h1 n + exact hkz.trans (mul_le_mul_of_nonneg_left hpow (le_of_lt hCpos)) + have hRe0 : -(k 0).re ≤ ‖k 0‖ := by + have habs : |(k 0).re| ≤ ‖k 0‖ := Complex.abs_re_le_norm (k 0) + have hneg : -(k 0).re ≤ |(k 0).re| := by simpa using (neg_le_abs (k 0).re) + exact hneg.trans habs + have : (f z).re ≤ C * (1 + R) ^ n + ‖k 0‖ := by + have : (f z).re = (k z).re - (k 0).re := by simp [f, sub_eq_add_neg] + nlinarith [this, hkz', hRe0] + exact this + have hf_bound_on_ball : ∀ R : ℝ, 0 < R → + ∀ z, ‖z‖ ≤ R / 2 → ‖f z‖ ≤ 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + intro R hRpos z hz + have hR2pos : 0 < R / 2 := by nlinarith + have hlt : R / 2 < R := by nlinarith + have hMpos : 0 < (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + have : 0 ≤ C * (1 + R) ^ n := by + refine mul_nonneg (le_of_lt hCpos) ?_ + exact pow_nonneg (by linarith) _ + nlinarith [this, norm_nonneg (k 0)] + have hf_anal : AnalyticOnNhd ℂ f (Metric.closedBall 0 R) := by + intro w _hw + exact (hf.analyticAt w) + have hf_re : ∀ w, ‖w‖ ≤ R → (f w).re ≤ (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + intro w hw + have := hf_re_bound R hRpos w hw + linarith + have hf_bc := + borelCaratheodory_zero_closedBall (f := f) (r := R / 2) (R := R) + (M := (C * (1 + R) ^ n + ‖k 0‖ + 1)) + hf_anal hR2pos hlt hMpos hf0 hf_re (z := z) hz + have hconst : + 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1) * (R / 2) / (R - R / 2) + = 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + field_simp [hRpos.ne'] ; ring + simpa [hconst] using hf_bc + have hCauchy : ∀ R : ℝ, 0 < R → + ‖iteratedDeriv m f 0‖ ≤ + (m.factorial : ℝ) * (2 * (C * (1 + R) ^ n + ‖k 0‖ + 1)) / (R / 2) ^ m := by + intro R hRpos + have hR2pos : 0 < R / 2 := by nlinarith + have hf_diffCont : DiffContOnCl ℂ f (Metric.ball (0 : ℂ) (R / 2)) := hf.diffContOnCl + have hbound_sphere : + ∀ z ∈ Metric.sphere (0 : ℂ) (R / 2), + ‖f z‖ ≤ 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + intro z hz + have hz' : ‖z‖ ≤ R / 2 := by + simpa [Metric.mem_sphere, dist_zero_right] using (le_of_eq hz) + exact hf_bound_on_ball R hRpos z hz' + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using + (Complex.norm_iteratedDeriv_le_of_forall_mem_sphere_norm_le (n := m) (c := (0 : ℂ)) + (R := R / 2) (C := 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1)) + (hR := hR2pos) hf_diffCont hbound_sphere) + have hf_iter_eq : iteratedDeriv m f 0 = 0 := by + by_contra hne + have ha : 0 < ‖iteratedDeriv m f 0‖ := norm_pos_iff.2 hne + let RHS : ℝ → ℝ := fun R => + (m.factorial : ℝ) * (2 * (C * (1 + R) ^ n + ‖k 0‖ + 1)) / (R / 2) ^ m + have hle_RHS : ∀ R : ℝ, 0 < R → ‖iteratedDeriv m f 0‖ ≤ RHS R := by + intro R hRpos + simpa [RHS] using hCauchy R hRpos + have hRHS_tendsto : Tendsto RHS atTop (𝓝 0) := by + let K : ℝ := ‖k 0‖ + 1 + have hmpos : 0 < m := lt_of_le_of_lt (Nat.zero_le n) hm + have hm0 : m ≠ 0 := ne_of_gt hmpos + have hratio : Tendsto (fun R : ℝ => R ^ n / (R / 2) ^ m) atTop (𝓝 0) := by + have hident : + (fun R : ℝ => R ^ n / (R / 2) ^ m) = fun R : ℝ => (2 : ℝ) ^ m * (R ^ n / R ^ m) := by + funext R + simp [div_eq_mul_inv, mul_pow, mul_assoc, mul_comm] + have hmain : Tendsto (fun R : ℝ => R ^ n / R ^ m) atTop (𝓝 0) := by + have hp : m - n ≠ 0 := (Nat.pos_iff_ne_zero.1 (Nat.sub_pos_of_lt hm)) + have hmain' : Tendsto (fun R : ℝ => (R ^ (m - n))⁻¹) atTop (𝓝 0) := by + simpa using (tendsto_pow_neg_atTop (𝕜 := ℝ) (n := m - n) hp) + have hEq : (fun R : ℝ => (R ^ (m - n))⁻¹) =ᶠ[atTop] fun R : ℝ => R ^ n / R ^ m := by + have hEq' : (fun R : ℝ => R ^ n / R ^ m) =ᶠ[atTop] fun R : ℝ => (R ^ (m - n))⁻¹ := by + filter_upwards [eventually_ne_atTop (0 : ℝ)] with R hR + have hle : n ≤ m := le_of_lt hm + have hm_eq : n + (m - n) = m := Nat.add_sub_of_le hle + have hn0 : R ^ n ≠ 0 := pow_ne_zero n hR + calc + R ^ n / R ^ m = R ^ n / R ^ (n + (m - n)) := by simp [hm_eq] + _ = R ^ n * ((R ^ (m - n))⁻¹ * (R ^ n)⁻¹) := by + simp [pow_add, div_eq_mul_inv, mul_comm] + _ = (R ^ (m - n))⁻¹ := by + ring_nf + simp [hn0] + exact hEq'.symm + exact Filter.Tendsto.congr' hEq hmain' + have : Tendsto (fun R : ℝ => (2 : ℝ) ^ m * (R ^ n / R ^ m)) atTop (𝓝 ((2 : ℝ) ^ m * 0)) := + tendsto_const_nhds.mul hmain + simpa [hident] using this + have hinv : Tendsto (fun R : ℝ => ((R / 2) ^ m)⁻¹) atTop (𝓝 0) := by + have hdiv : Tendsto (fun R : ℝ => R / 2) atTop atTop := + (tendsto_id.atTop_div_const (r := (2 : ℝ)) (by norm_num : (0 : ℝ) < 2)) + have hpow : Tendsto (fun R : ℝ => (R / 2) ^ m) atTop atTop := + (Filter.tendsto_pow_atTop (α := ℝ) (n := m) hm0).comp hdiv + simpa using! hpow.inv_tendsto_atTop + have hdiv : Tendsto (fun R : ℝ => (1 + R) / R) atTop (𝓝 (1 : ℝ)) := by + have hinv' : Tendsto (fun R : ℝ => (R : ℝ)⁻¹) atTop (𝓝 (0 : ℝ)) := tendsto_inv_atTop_zero + have hadd : Tendsto (fun R : ℝ => (1 : ℝ) + (R : ℝ)⁻¹) atTop (𝓝 (1 : ℝ)) := by + simpa using (tendsto_const_nhds.add hinv') + have hEq : (fun R : ℝ => (1 + R) / R) =ᶠ[atTop] fun R : ℝ => (1 : ℝ) + (R : ℝ)⁻¹ := by + filter_upwards [eventually_ne_atTop (0 : ℝ)] with R hR + field_simp [hR]; ring + exact Filter.Tendsto.congr' hEq.symm hadd + have hdiv_pow : Tendsto (fun R : ℝ => ((1 + R) / R) ^ n) atTop (𝓝 (1 : ℝ)) := by + simpa using (hdiv.pow n) + have hone_add_ratio : + Tendsto (fun R : ℝ => (1 + R) ^ n / (R / 2) ^ m) atTop (𝓝 (0 : ℝ)) := by + have hEq : + (fun R : ℝ => (1 + R) ^ n / (R / 2) ^ m) + =ᶠ[atTop] fun R : ℝ => ((1 + R) / R) ^ n * (R ^ n / (R / 2) ^ m) := by + filter_upwards [eventually_ne_atTop (0 : ℝ)] with R hR + have hRpow : (R ^ n : ℝ) ≠ 0 := pow_ne_zero n hR + have hident : + ((1 + R) / R) ^ n * (R ^ n / (R / 2) ^ m) = (1 + R) ^ n / (R / 2) ^ m := by + calc + ((1 + R) / R) ^ n * (R ^ n / (R / 2) ^ m) + = ((1 + R) ^ n / R ^ n) * (R ^ n / (R / 2) ^ m) := by + simp [div_pow] + _ = ((1 + R) ^ n * R ^ n) / (R ^ n * (R / 2) ^ m) := by + simp [div_mul_div_comm, mul_comm] + _ = ((1 + R) ^ n * R ^ n) / ((R / 2) ^ m * R ^ n) := by + simp [mul_comm] + _ = (1 + R) ^ n / (R / 2) ^ m := by + simpa [mul_assoc, mul_comm, mul_left_comm] using + (mul_div_mul_right (a := (1 + R) ^ n) (b := (R / 2) ^ m) hRpow) + exact hident.symm + have hmul : + Tendsto + (fun R : ℝ => ((1 + R) / R) ^ n * (R ^ n / (R / 2) ^ m)) + atTop (𝓝 (0 : ℝ)) := by + simpa [mul_zero] using (hdiv_pow.mul hratio) + exact Filter.Tendsto.congr' hEq.symm hmul + have h1 : Tendsto (fun R : ℝ => C * ((1 + R) ^ n / (R / 2) ^ m)) atTop (𝓝 0) := by + simpa using (tendsto_const_nhds.mul hone_add_ratio) + have h2 : Tendsto (fun R : ℝ => K * ((R / 2) ^ m)⁻¹) atTop (𝓝 0) := by + simpa using (tendsto_const_nhds.mul hinv) + have hsum : + Tendsto + (fun R : ℝ => C * ((1 + R) ^ n / (R / 2) ^ m) + K * ((R / 2) ^ m)⁻¹) + atTop (𝓝 0) := by + simpa using (h1.add h2) + have hrew : + (fun R : ℝ => (C * (1 + R) ^ n + K) / (R / 2) ^ m) + = fun R : ℝ => C * ((1 + R) ^ n / (R / 2) ^ m) + K * ((R / 2) ^ m)⁻¹ := by + funext R + simp [div_eq_mul_inv, mul_add, mul_assoc, mul_comm] + have hbase : Tendsto (fun R : ℝ => (C * (1 + R) ^ n + K) / (R / 2) ^ m) atTop (𝓝 0) := by + simpa [hrew] using hsum + have hconst : + Tendsto (fun _ : ℝ => (m.factorial : ℝ) * (2 : ℝ)) atTop + (𝓝 ((m.factorial : ℝ) * (2 : ℝ))) := tendsto_const_nhds + have hmul : Tendsto (fun R : ℝ => ((m.factorial : ℝ) * (2 : ℝ)) * + ((C * (1 + R) ^ n + K) / (R / 2) ^ m)) atTop (𝓝 0) := by + simpa [mul_assoc, mul_left_comm, mul_comm] using (hconst.mul hbase) + have hRHS_rw : RHS = fun R : ℝ => ((m.factorial : ℝ) * (2 : ℝ)) * + ((C * (1 + R) ^ n + K) / (R / 2) ^ m) := by + funext R + dsimp [RHS, K] + ring_nf + simpa [hRHS_rw] using hmul + have hsmall : ∀ᶠ R in atTop, RHS R < ‖iteratedDeriv m f 0‖ / 2 := + (tendsto_order.1 hRHS_tendsto).2 _ (half_pos ha) + have hle_eventually : ∀ᶠ R in atTop, ‖iteratedDeriv m f 0‖ ≤ RHS R := by + filter_upwards [eventually_gt_atTop (0 : ℝ)] with R hRpos + exact hle_RHS R hRpos + rcases (hle_eventually.and hsmall).exists with ⟨R, hle, hlt⟩ + have : ‖iteratedDeriv m f 0‖ < ‖iteratedDeriv m f 0‖ := + (lt_of_le_of_lt hle hlt).trans (half_lt_self ha) + exact lt_irrefl _ this + have hmpos : 0 < m := lt_of_le_of_lt (Nat.zero_le n) hm + have hm0 : m ≠ 0 := ne_of_gt hmpos + have hkcd : ContDiffAt ℂ (↑m) k (0 : ℂ) := (hk.analyticAt 0).contDiffAt + have hccd : ContDiffAt ℂ (↑m) (fun _ : ℂ => k 0) (0 : ℂ) := contDiffAt_const + have hsub : + iteratedDeriv m f 0 = + iteratedDeriv m k 0 - iteratedDeriv m (fun _ : ℂ => k 0) 0 := by + simpa [f] using! (iteratedDeriv_sub (n := m) (x := (0 : ℂ)) hkcd hccd) + have hconst0 : iteratedDeriv m (fun _ : ℂ => k 0) 0 = 0 := by + simp [iteratedDeriv_const, hm0] + have hf_eq : iteratedDeriv m f 0 = iteratedDeriv m k 0 := by + simp [hsub, hconst0] + simpa [hf_eq] using hf_iter_eq + let P : Polynomial ℂ := + ∑ m ∈ Finset.range (n + 1), Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0) + have hPdeg : P.natDegree ≤ n := by + have hnat : + P.natDegree ≤ + Finset.fold max 0 + (fun m : ℕ => + (Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0)).natDegree) + (Finset.range (n + 1)) := by + simpa [P, Function.comp] using + (Polynomial.natDegree_sum_le (s := Finset.range (n + 1)) + (f := fun m : ℕ => + Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0))) + have hfold : + Finset.fold max 0 + (fun m : ℕ => + (Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0)).natDegree) + (Finset.range (n + 1)) ≤ n := by + refine (Finset.fold_max_le (f := fun m : ℕ => + (Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0)).natDegree) + (b := 0) (s := Finset.range (n + 1)) (c := n)).2 ?_ + refine ⟨Nat.zero_le n, ?_⟩ + intro m hm + have hmon : + (Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0)).natDegree ≤ m := + Polynomial.natDegree_monomial_le _ + have hm_le : m ≤ n := Nat.le_of_lt_succ (Finset.mem_range.1 hm) + exact hmon.trans hm_le + exact hnat.trans hfold + have hk_poly : ∀ z, k z = Polynomial.eval z P := by + intro z + have htaylor := Complex.taylorSeries_eq_of_entire' (c := (0 : ℂ)) (z := z) hk + have htail : ∀ m : ℕ, m ∉ Finset.range (n + 1) → + ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * (z - 0) ^ m) = 0 := by + intro m hm' + have hmgt : n < m := by + have : n + 1 ≤ m := Nat.le_of_not_lt (by simpa [Finset.mem_range] using hm') + exact Nat.lt_of_lt_of_le (Nat.lt_succ_self n) this + have hz : iteratedDeriv m k 0 = 0 := hk_iteratedDeriv_eq_zero m hmgt + simp [hz] + have htsum : + (∑' m : ℕ, (m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * (z - 0) ^ m) + = ∑ m ∈ Finset.range (n + 1), (m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * z ^ m := by + simpa [sub_zero] using (tsum_eq_sum (s := Finset.range (n + 1)) htail) + have hfinite : + k z = ∑ m ∈ Finset.range (n + 1), (m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * z ^ m := by + calc + k z = ∑' m : ℕ, (m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * (z - 0) ^ m := by + simpa using htaylor.symm + _ = _ := htsum + have hEval : + Polynomial.eval z P = + ∑ m ∈ Finset.range (n + 1), z ^ m * ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0) := by + classical + change Polynomial.eval₂ (RingHom.id ℂ) z P = _ + let φ : Polynomial ℂ →+* ℂ := Polynomial.eval₂RingHom (RingHom.id ℂ) z + change φ P = _ + simp [P, φ, Polynomial.eval₂_monomial, mul_comm] + have hfinite' : + k z = ∑ m ∈ Finset.range (n + 1), z ^ m * ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0) := by + simpa [mul_comm, mul_left_comm, mul_assoc] using hfinite + simpa [hEval] using hfinite' + refine ⟨P, hPdeg, ?_⟩ + intro z + have : H z = Complex.exp (k z) := by simp [hk_exp z] + simp [this, hk_poly z] + +end Hadamard +end Complex +end +end HadamardSourceScope31 + +section HadamardSourceScope32 + +noncomputable section + +namespace Complex + +open _root_.Complex +namespace Hadamard + +open _root_.Complex _root_.Erdos970.Complex _root_.Real _root_.Erdos970.Real + BigOperators _root_.Finset Set Filter Topology Metric + +open scoped Topology + +open Polynomial + +private lemma exists_pow_eq_complex {n : ℕ} (hn : 0 < n) (w : ℂ) : ∃ z : ℂ, z ^ n = w := by + classical + by_cases hw : w = 0 + · subst hw + refine ⟨0, ?_⟩ + have hn0 : n ≠ 0 := Nat.ne_of_gt hn + simp [hn0] + · refine ⟨Complex.exp (Complex.log w / n), ?_⟩ + have hn0 : (n : ℂ) ≠ 0 := by + exact_mod_cast (Nat.ne_of_gt hn) + calc + (Complex.exp (Complex.log w / n)) ^ n + = Complex.exp ((n : ℂ) * (Complex.log w / n)) := by + simpa using (Complex.exp_nat_mul (Complex.log w / n) n).symm + _ = Complex.exp (Complex.log w) := by + have : (n : ℂ) * (Complex.log w / n) = Complex.log w := by + field_simp [hn0] + simp [this] + _ = w := by simpa using (Complex.exp_log hw) + +private lemma mul_conj_div_norm (a : ℂ) (ha : a ≠ 0) : + a * ((starRingEnd ℂ) a / (‖a‖ : ℂ)) = (‖a‖ : ℂ) := by + have hnorm_pos : 0 < ‖a‖ := norm_pos_iff.mpr ha + have hnorm_ne : (‖a‖ : ℂ) ≠ 0 := by + exact_mod_cast (ne_of_gt hnorm_pos) + have hmul : a * (starRingEnd ℂ) a = (Complex.normSq a : ℂ) := + Complex.mul_conj a + have hcast : (Complex.normSq a : ℂ) = ((‖a‖ ^ 2 : ℝ) : ℂ) := by + exact_mod_cast (Complex.normSq_eq_norm_sq a) + have hdiv : ((‖a‖ ^ 2 : ℝ) : ℂ) / (‖a‖ : ℂ) = (‖a‖ : ℂ) := by + have : ((‖a‖ ^ 2 : ℝ) : ℂ) = (‖a‖ : ℂ) * (‖a‖ : ℂ) := by + simp [pow_two] + calc + ((‖a‖ ^ 2 : ℝ) : ℂ) / (‖a‖ : ℂ) + = ((‖a‖ : ℂ) * (‖a‖ : ℂ)) / (‖a‖ : ℂ) := by simp [this] + _ = (‖a‖ : ℂ) := by + field_simp [hnorm_ne] + calc + a * ((starRingEnd ℂ) a / (‖a‖ : ℂ)) + = (a * (starRingEnd ℂ) a) / (‖a‖ : ℂ) := by + simp [div_eq_mul_inv, mul_assoc] + _ = (Complex.normSq a : ℂ) / (‖a‖ : ℂ) := by simp [hmul] + _ = ((‖a‖ ^ 2 : ℝ) : ℂ) / (‖a‖ : ℂ) := by simp [hcast] + _ = (‖a‖ : ℂ) := hdiv + +private lemma exists_z_norm_eq_re_eval_ge + (P : Polynomial ℂ) (hn : 0 < P.natDegree) : + ∃ R0 : ℝ, 0 < R0 ∧ + ∀ R : ℝ, R0 ≤ R → + ∃ z : ℂ, ‖z‖ = R ∧ + (‖P.leadingCoeff‖ / 2) * R ^ P.natDegree ≤ (P.eval z).re := by + classical + set n : ℕ := P.natDegree + have hn0 : 0 < n := hn + have hP0 : P ≠ 0 := by + intro h0 + simp [n, h0] at hn0 + have hLC : P.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr hP0 + set a : ℂ := P.leadingCoeff + have ha : a ≠ 0 := hLC + have hnorm_a_pos : 0 < ‖a‖ := norm_pos_iff.mpr ha + set wtarget : ℂ := (starRingEnd ℂ) a / (‖a‖ : ℂ) + have hwtarget_norm : ‖wtarget‖ = (1 : ℝ) := by + calc + ‖wtarget‖ = ‖(starRingEnd ℂ) a‖ / ‖(‖a‖ : ℂ)‖ := by + simp [wtarget] + _ = ‖a‖ / ‖a‖ := by simp + _ = (1 : ℝ) := by + field_simp [hnorm_a_pos.ne'] + rcases exists_pow_eq_complex (n := n) hn0 (w := wtarget) with ⟨w, hw⟩ + have hw_norm : ‖w‖ = (1 : ℝ) := by + have hpow : (‖w‖ : ℝ) ^ n = 1 := by + have := congrArg (fun z : ℂ => ‖z‖) hw + simpa [norm_pow, hwtarget_norm] using this + have hn0' : n ≠ 0 := Nat.ne_of_gt hn0 + exact (pow_eq_one_iff_of_nonneg (norm_nonneg w) hn0').1 hpow + set S : ℝ := ∑ i ∈ Finset.range n, ‖P.coeff i‖ + set R0 : ℝ := max 1 (2 * S / ‖a‖) + refine ⟨R0, ?_, ?_⟩ + · have : (0 : ℝ) < (1 : ℝ) := by norm_num + exact lt_of_lt_of_le this (le_max_left _ _) + · intro R hR + have hR_ge1 : (1 : ℝ) ≤ R := by + exact le_trans (le_max_left _ _) hR + have hR_nonneg : 0 ≤ R := le_trans (by norm_num) hR_ge1 + set z : ℂ := (R : ℂ) * w + have hz_norm : ‖z‖ = R := by + have : ‖z‖ = |R| * ‖w‖ := by + simp [z] + simp [this, hw_norm, abs_of_nonneg hR_nonneg] + have h_eval : P.eval z = + (∑ i ∈ Finset.range n, P.coeff i * z ^ i) + P.coeff n * z ^ n := by + have hsum : P.eval z = ∑ i ∈ Finset.range (n + 1), P.coeff i * z ^ i := by + have : P.natDegree + 1 = n + 1 := by simp [n] + simpa [this] using (Polynomial.eval_eq_sum_range (p := P) z) + have hsplit : + (∑ i ∈ Finset.range (n + 1), P.coeff i * z ^ i) + = (∑ i ∈ Finset.range n, P.coeff i * z ^ i) + P.coeff n * z ^ n := by + simpa using (Finset.sum_range_succ (f := fun i => P.coeff i * z ^ i) n) + exact hsum.trans hsplit + have h_lower_norm : + ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ ≤ S * R ^ (n - 1) := by + have h1 : + ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ + ≤ ∑ i ∈ Finset.range n, ‖P.coeff i * z ^ i‖ := by + simpa using (norm_sum_le (Finset.range n) (fun i => P.coeff i * z ^ i)) + have hterm : ∀ i ∈ Finset.range n, ‖P.coeff i * z ^ i‖ ≤ ‖P.coeff i‖ * R ^ (n - 1) := by + intro i hi + have hi_lt : i < n := Finset.mem_range.mp hi + have hi_le : i ≤ n - 1 := Nat.le_pred_of_lt hi_lt + have hzpow : ‖z‖ ^ i ≤ R ^ (n - 1) := by + have hmono : ‖z‖ ^ i ≤ ‖z‖ ^ (n - 1) := + pow_le_pow_right₀ (by simpa [hz_norm] using hR_ge1) hi_le + simpa [hz_norm] using hmono + calc + ‖P.coeff i * z ^ i‖ = ‖P.coeff i‖ * ‖z‖ ^ i := by + simp [norm_pow] + _ ≤ ‖P.coeff i‖ * R ^ (n - 1) := by + exact mul_le_mul_of_nonneg_left hzpow (norm_nonneg _) + have h2 : + ∑ i ∈ Finset.range n, ‖P.coeff i * z ^ i‖ + ≤ ∑ i ∈ Finset.range n, ‖P.coeff i‖ * R ^ (n - 1) := by + exact Finset.sum_le_sum (fun i hi => hterm i hi) + have h3 : + (∑ i ∈ Finset.range n, ‖P.coeff i‖ * R ^ (n - 1)) + = (∑ i ∈ Finset.range n, ‖P.coeff i‖) * R ^ (n - 1) := by + simp [Finset.sum_mul] + have hsum_le : (∑ i ∈ Finset.range n, ‖P.coeff i‖) ≤ S := by + simp [S] + calc + ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ + ≤ ∑ i ∈ Finset.range n, ‖P.coeff i * z ^ i‖ := h1 + _ ≤ ∑ i ∈ Finset.range n, ‖P.coeff i‖ * R ^ (n - 1) := h2 + _ = (∑ i ∈ Finset.range n, ‖P.coeff i‖) * R ^ (n - 1) := h3 + _ ≤ S * R ^ (n - 1) := by + exact mul_le_mul_of_nonneg_right hsum_le (pow_nonneg hR_nonneg _) + have h_lead_re : (P.coeff n * z ^ n).re = ‖a‖ * R ^ n := by + have hw_pow : w ^ n = wtarget := hw + have ha_mul : a * w ^ n = (‖a‖ : ℂ) := by + have : a * w ^ n = a * wtarget := by simp [hw_pow] + simpa [wtarget, a] using (this.trans (mul_conj_div_norm a ha)) + have hz_pow : z ^ n = ((R : ℂ) ^ n) * (w ^ n) := by + simp [z, mul_pow, mul_comm] + have hcoeffn : P.coeff n = a := by simp [a, n, Polynomial.coeff_natDegree] + have hreR : ∀ m : ℕ, (((R : ℂ) ^ m).re) = R ^ m := by + intro m + induction m with + | zero => simp + | succ m ih => + simp [pow_succ, ih, mul_re] + calc + (P.coeff n * z ^ n).re + = (a * z ^ n).re := by simp [hcoeffn] + _ = (a * (((R : ℂ) ^ n) * (w ^ n))).re := by simp [hz_pow] + _ = (((R : ℂ) ^ n) * (a * (w ^ n))).re := by + ring_nf + _ = (((R : ℂ) ^ n) * (‖a‖ : ℂ)).re := by simp [ha_mul] + _ = (((R : ℂ) ^ n).re) * ‖a‖ := by + simp [mul_re] + _ = (R ^ n) * ‖a‖ := by simp [hreR n] + _ = ‖a‖ * R ^ n := by ring + refine ⟨z, hz_norm, ?_⟩ + have hre_lower : (∑ i ∈ Finset.range n, P.coeff i * z ^ i).re + ≥ -‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ := by + have habs : |(∑ i ∈ Finset.range n, P.coeff i * z ^ i).re| + ≤ ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ := + Complex.abs_re_le_norm _ + have := neg_le_of_abs_le habs + simpa using this + have hre_main : + (P.eval z).re ≥ (P.coeff n * z ^ n).re - ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ := by + have : (P.eval z).re = + (∑ i ∈ Finset.range n, P.coeff i * z ^ i).re + (P.coeff n * z ^ n).re := by + simp [h_eval, add_comm] + linarith [this, hre_lower] + have hR_ge_R0 : R0 ≤ R := hR + have hR_ge : 2 * S / ‖a‖ ≤ R := le_trans (le_max_right _ _) hR_ge_R0 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hR_ge1 + have hR_nonneg' : 0 ≤ R := le_of_lt hRpos + have hn_ge1 : 1 ≤ n := Nat.succ_le_of_lt hn0 + have hlower_le : S * R ^ (n - 1) ≤ (‖a‖ / 2) * R ^ n := by + have ha_pos : 0 < ‖a‖ := hnorm_a_pos + have hS_le : S ≤ (‖a‖ / 2) * R := by + have : 2 * S ≤ ‖a‖ * R := by + have := (mul_le_mul_of_nonneg_left hR_ge (by linarith [ha_pos.le] : (0 : ℝ) ≤ ‖a‖)) + have hne : (‖a‖ : ℝ) ≠ 0 := ne_of_gt ha_pos + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm, hne] using this + have : S ≤ (‖a‖ * R) / 2 := by linarith + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using this + have : S * R ^ (n - 1) ≤ (‖a‖ / 2) * R * R ^ (n - 1) := by + have hpow_nonneg : 0 ≤ R ^ (n - 1) := pow_nonneg hR_nonneg' _ + exact mul_le_mul_of_nonneg_right hS_le hpow_nonneg + have hRR : R * R ^ (n - 1) = R ^ n := by + have : n = (n - 1) + 1 := by + exact (Nat.sub_add_cancel hn_ge1).symm + rw [this, pow_succ] + ring_nf; grind + simpa [mul_assoc, hRR] using this + have hfinal_re : + (‖a‖ / 2) * R ^ n ≤ (P.eval z).re := by + have hlower' : ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ ≤ (‖a‖ / 2) * R ^ n := by + exact h_lower_norm.trans hlower_le + have hlead : (P.coeff n * z ^ n).re = ‖a‖ * R ^ n := by simpa [a] using h_lead_re + have hre_main' : + (‖a‖ * R ^ n) - ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ ≤ (P.eval z).re := by + simpa [hlead] using hre_main + have hsub : + (‖a‖ * R ^ n) - (‖a‖ / 2) * R ^ n ≤ + (‖a‖ * R ^ n) - ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ := + sub_le_sub_left hlower' (‖a‖ * R ^ n) + have hsim : (‖a‖ * R ^ n) - (‖a‖ / 2) * R ^ n = (‖a‖ / 2) * R ^ n := by ring + have : (‖a‖ * R ^ n) - (‖a‖ / 2) * R ^ n ≤ (P.eval z).re := + hsub.trans hre_main' + simpa [hsim] using this + simpa [a, n] using hfinal_re + +theorem natDegree_le_floor_of_growth_exp_eval + {ρ : ℝ} (hρ : 0 ≤ ρ) (P : Polynomial ℂ) + (hgrowth : + ∃ C > 0, ∀ z : ℂ, + Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) ≤ C * (1 + ‖z‖) ^ ρ) : + P.natDegree ≤ Nat.floor ρ := by + classical + by_cases hdeg : P.natDegree = 0 + · simp [hdeg] + · have hnpos : 0 < P.natDegree := Nat.pos_of_ne_zero hdeg + rcases exists_z_norm_eq_re_eval_ge (P := P) hnpos with ⟨R0, hR0pos, hray⟩ + rcases hgrowth with ⟨C, hCpos, hC⟩ + have hLCpos : 0 < ‖P.leadingCoeff‖ := by + have hP0 : P ≠ 0 := by + intro h0 + simp [h0] at hdeg + have : P.leadingCoeff ≠ 0 := (Polynomial.leadingCoeff_ne_zero).2 hP0 + exact norm_pos_iff.2 this + let c : ℝ := ‖P.leadingCoeff‖ / 2 + have hcpos : 0 < c := by + have : (0 : ℝ) < (2 : ℝ) := by norm_num + exact (div_pos hLCpos this) + have hn_le_real : (P.natDegree : ℝ) ≤ ρ := by + by_contra hnlt + have hnlt' : ρ < (P.natDegree : ℝ) := lt_of_not_ge hnlt + let δ : ℝ := (P.natDegree : ℝ) - ρ + have hδ : 0 < δ := sub_pos.2 hnlt' + let K0 : ℝ := (C * (2 : ℝ) ^ ρ) / c + have hK0 : ∃ R1, ∀ R ≥ R1, K0 + 1 ≤ R ^ δ := by + have h : ∀ᶠ R in (atTop : Filter ℝ), K0 + 1 ≤ R ^ δ := + (tendsto_atTop.mp (tendsto_rpow_atTop hδ)) (K0 + 1) + rcases (eventually_atTop.1 h) with ⟨R1, hR1⟩ + exact ⟨R1, hR1⟩ + rcases hK0 with ⟨R1, hR1⟩ + set R : ℝ := max (max R0 1) R1 + have hR_ge_R0 : R0 ≤ R := le_trans (le_max_left _ _) (le_max_left _ _) + have hR_ge1 : (1 : ℝ) ≤ R := le_trans (le_max_right _ _) (le_max_left _ _) + have hR_ge_R1 : R1 ≤ R := le_max_right _ _ + have hR_pos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hR_ge1 + have hRδ : K0 + 1 ≤ R ^ δ := hR1 R hR_ge_R1 + rcases hray R hR_ge_R0 with ⟨z, hz_norm, hz_re⟩ + have hlog_lower : + (P.eval z).re ≤ Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) := by + have hpos : 0 < ‖Complex.exp (Polynomial.eval z P)‖ := by + simp + have hle : + ‖Complex.exp (Polynomial.eval z P)‖ ≤ + 1 + ‖Complex.exp (Polynomial.eval z P)‖ := by + linarith [norm_nonneg (Complex.exp (Polynomial.eval z P))] + have hlog_le : Real.log ‖Complex.exp (Polynomial.eval z P)‖ + ≤ Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) := + Real.log_le_log hpos hle + have hlog_eq : Real.log ‖Complex.exp (Polynomial.eval z P)‖ = (P.eval z).re := by + simp [Complex.norm_exp] + simpa [hlog_eq] using hlog_le + have hlog_upper : + Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) ≤ C * (1 + ‖z‖) ^ ρ := + hC z + have hmain : c * R ^ (P.natDegree : ℝ) ≤ C * (1 + R) ^ ρ := by + have hz_re' : c * R ^ P.natDegree ≤ (P.eval z).re := by + simpa [c] using hz_re + have hz_re'' : c * R ^ (P.natDegree : ℝ) ≤ (P.eval z).re := by + simpa [Real.rpow_natCast, c] using hz_re' + have : c * R ^ (P.natDegree : ℝ) ≤ Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) := + hz_re''.trans hlog_lower + have : c * R ^ (P.natDegree : ℝ) ≤ C * (1 + ‖z‖) ^ ρ := + this.trans hlog_upper + simpa [hz_norm] using this + have h1R_le : (1 + R : ℝ) ≤ R * 2 := by linarith + have hpow1 : (1 + R : ℝ) ^ ρ ≤ (R * 2) ^ ρ := + Real.rpow_le_rpow (by linarith [hR_pos.le]) h1R_le hρ + have hR2 : (R * 2) ^ ρ = R ^ ρ * (2 : ℝ) ^ ρ := by + have hRnonneg : 0 ≤ R := le_of_lt hR_pos + have h2nonneg : 0 ≤ (2 : ℝ) := by norm_num + simpa [mul_assoc] using (Real.mul_rpow hRnonneg h2nonneg (z := ρ)) + have hmain' : c * R ^ (P.natDegree : ℝ) ≤ C * (R ^ ρ * (2 : ℝ) ^ ρ) := by + have := le_trans hmain (mul_le_mul_of_nonneg_left hpow1 (le_of_lt hCpos)) + simpa [hR2, mul_assoc, mul_left_comm, mul_comm] using this + have hRρ_pos : 0 < R ^ ρ := Real.rpow_pos_of_pos hR_pos _ + have hRρ_ne : (R ^ ρ : ℝ) ≠ 0 := ne_of_gt hRρ_pos + have hdiv : + (c * R ^ (P.natDegree : ℝ)) / (R ^ ρ) ≤ C * (2 : ℝ) ^ ρ := by + have h := + div_le_div_of_nonneg_right hmain' (le_of_lt hRρ_pos) + have hRhs : (C * (R ^ ρ * (2 : ℝ) ^ ρ)) / (R ^ ρ) = C * (2 : ℝ) ^ ρ := by + field_simp [hRρ_ne] + simpa [hRhs, mul_assoc, mul_left_comm, mul_comm] using h + have hRsub : R ^ δ = R ^ (P.natDegree : ℝ) / R ^ ρ := by + simpa [δ] using (Real.rpow_sub hR_pos (P.natDegree : ℝ) ρ) + have hRδ_le : c * (R ^ δ) ≤ C * (2 : ℝ) ^ ρ := by + have hLhs : c * (R ^ δ) = (c * R ^ (P.natDegree : ℝ)) / (R ^ ρ) := by + simp [hRsub, div_eq_mul_inv, mul_left_comm, mul_comm] + simpa [hLhs] using hdiv + have hRδ_le' : R ^ δ ≤ K0 := by + have : R ^ δ ≤ (C * (2 : ℝ) ^ ρ) / c := by + refine (le_div_iff₀ hcpos).2 ?_ + simpa [mul_assoc, mul_left_comm, mul_comm] using hRδ_le + simpa [K0] using this + have : K0 + 1 ≤ K0 := le_trans hRδ (le_trans hRδ_le' (le_rfl)) + exact (not_lt_of_ge this) (lt_add_of_pos_right _ (by norm_num : (0 : ℝ) < 1)) + exact (Nat.le_floor_iff hρ).2 hn_le_real + +theorem natDegree_le_floor_of_exp_eval_norm_bound {τ : ℝ} (hτ : 0 ≤ τ) (P : Polynomial ℂ) + (hbound : + ∃ C > 0, ∀ z : ℂ, + ‖Complex.exp (Polynomial.eval z P)‖ ≤ Real.exp (C * (1 + ‖z‖) ^ τ)) : + P.natDegree ≤ Nat.floor τ := by + rcases hbound with ⟨C, hCpos, hC⟩ + have hlog_growth : + ∃ C > 0, ∀ z : ℂ, + Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) ≤ C * (1 + ‖z‖) ^ τ := + Real.log_growth_of_norm_le_exp_mul_rpow + (f := fun z : ℂ => Complex.exp (Polynomial.eval z P)) + (r := fun z : ℂ => 1 + ‖z‖) hCpos hτ + (fun z => by linarith [norm_nonneg z]) hC + exact natDegree_le_floor_of_growth_exp_eval (ρ := τ) hτ P hlog_growth + +end Hadamard +end Complex +end +end HadamardSourceScope32 + +section HadamardSourceScope33 + +noncomputable section + +open Set Filter Asymptotics +open scoped Topology BigOperators + +namespace Complex.Hadamard + +open _root_.Complex + +lemma no_zero_on_sphere_of_norm_image_avoid + {f : ℂ → ℂ} (hentire : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + {B r : ℝ} (hrpos : 0 < r) (hr_le_B : r ≤ B) + (smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (hsmall_fin : smallSet.Finite) + (hsmallSet : + smallSet = {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ B}) + (hr_not_bad : + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + r ∉ small.image a) : + ∀ u : ℂ, ‖u‖ = r → f u ≠ 0 := by + classical + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let bad : Finset ℝ := small.image a + have hr_not_bad' : r ∉ bad := by + simpa [bad, small, a] using hr_not_bad + have hr_not : + ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖ ≤ B → r ≠ ‖divisorZeroIndex₀Val p‖ := by + intro p hpB hEq + have hp_small : p ∈ small := by + have hp_mem : p ∈ smallSet := by + simpa [hsmallSet] using hpB + simpa [small] using (hsmall_fin.mem_toFinset.2 hp_mem) + have : r ∈ bad := Finset.mem_image.2 ⟨p, hp_small, by simpa [a] using hEq.symm⟩ + exact (hr_not_bad' this).elim + exact no_zero_on_sphere_of_forall_val_norm_ne (f := f) hentire hnot + (B := B) (r := r) hrpos hr_le_B hr_not + +theorem norm_inv_hadamardDenominator_le_exp_on_cartan_circle + {f : ℂ → ℂ} {ρ τ : ℝ} {m : ℕ} + (hmρ : (m : ℝ) ≤ ρ) (hτ : ρ < τ) (hτ_lt : τ < (m + 1 : ℝ)) + (hτ_nonneg : 0 ≤ τ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (hsumτ : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) : + let Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + let Cprod : ℝ := cartanProductConstant m τ Sτ + ∀ {R r : ℝ}, 0 < R → 1 ≤ R → R ≤ r → r ≤ 2 * R → + ∀ (smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsmall_fin : smallSet.Finite), + smallSet = + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ‖divisorZeroIndex₀Val p‖ ≤ 4 * R} → + (let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => ‖divisorZeroIndex₀Val p‖ + r ∉ small.image a) → + (let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => ‖divisorZeroIndex₀Val p‖ + (∑ p ∈ small, (1 : ℝ) * CartanBound.φ (r / a p)) ≤ + CartanBound.Cφ * (small.card : ℝ)) → + ∀ u : ℂ, ‖u‖ = r → + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + ≤ Real.exp (Cprod * (1 + r) ^ τ) := by + classical + intro Sτ Cprod R r hRpos hRle hR_le_r hr_le_2R smallSet hsmall_fin + hsmallSet hr_not_bad hr_phi u hur + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let bad : Finset ℝ := small.image a + have hr_not_bad' : r ∉ bad := by + simpa [bad, small, a] using hr_not_bad + have hr1 : (1 : ℝ) ≤ r := le_trans hRle hR_le_r + have hpow_inv_le1 : ‖(u ^ analyticOrderNatAt f 0)⁻¹‖ ≤ 1 := + Complex.norm_inv_pow_le_one_of_one_le_norm u (analyticOrderNatAt f 0) (by simpa [hur] using hr1) + let fac : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ := + fun p => weierstrassFactor m (u / divisorZeroIndex₀Val p) + have hloc : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (w : ℂ) => + weierstrassFactor m (w / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + (Set.univ : Set ℂ) := + hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + have hprod : + HasProd fac (divisorCanonicalProduct m f (Set.univ : Set ℂ) u) := + hloc.hasProd (by simp : u ∈ (Set.univ : Set ℂ)) + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + have : DecidablePred (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => p ∈ small) := + Classical.decPred _ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if hp : p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + have hterm : ∀ p, ‖(fac p)⁻¹‖ ≤ Real.exp (b p) := by + intro p + by_cases hp : p ∈ small + · have hval_ne : r ≠ ap p := by + intro hEq + have : r ∈ bad := by + refine Finset.mem_image.2 ⟨p, hp, ?_⟩ + simp [ap, a, hEq] + exact (hr_not_bad' this).elim + have hval0 : divisorZeroIndex₀Val p ≠ 0 := divisorZeroIndex₀Val_ne_zero p + have hmτ : (m : ℝ) ≤ τ := le_trans hmρ (le_of_lt hτ) + have hnear : + ‖(weierstrassFactor m (u / divisorZeroIndex₀Val p))⁻¹‖ + ≤ Real.exp (CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ)) := by + simpa [ap] using + (norm_inv_weierstrassFactor_le_exp_near (m := m) (τ := τ) (r := r) + (u := u) (a := divisorZeroIndex₀Val p) + (hur := hur) (ha := hval0) (hr := by simpa [ap] using hval_ne) hmτ) + simpa [fac, b, hp] using hnear + · have hlarge : (4 * R : ℝ) < ap p := by + have : ¬ap p ≤ 4 * R := by + intro hle + have : p ∈ small := by + have hp_mem : p ∈ smallSet := by + simpa [hsmallSet, ap] using hle + simpa [small] using (hsmall_fin.mem_toFinset.2 hp_mem) + exact hp this + exact lt_of_not_ge this + have hz' : ‖u / divisorZeroIndex₀Val p‖ ≤ (1 / 2 : ℝ) := + norm_div_le_half_of_norm_le_of_two_mul_lt (z := u) (a := divisorZeroIndex₀Val p) + (R := 2 * R) (by nlinarith [hRpos]) (by rw [hur]; exact hr_le_2R) + (by nlinarith [hlarge]) + have hτ_le : τ ≤ (m + 1 : ℝ) := le_of_lt hτ_lt + have hfar : + ‖(weierstrassFactor m (u / divisorZeroIndex₀Val p))⁻¹‖ ≤ + Real.exp ((2 : ℝ) * (r / ap p) ^ τ) := by + simpa [ap] using + (norm_inv_weierstrassFactor_le_exp_far (m := m) (τ := τ) (r := r) + (u := u) (a := divisorZeroIndex₀Val p) + (hur := hur) (ha := divisorZeroIndex₀Val_ne_zero p) (hz := hz') hτ_le) + simpa [fac, b, hp] using hfar + have hb_le : + ∀ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)), + (∑ p ∈ s, b p) ≤ Cprod * (1 + r) ^ τ := by + intro s + simpa [small, ap, b, Sτ, Cprod, a, hsmallSet] using + (Complex.Hadamard.cartan_sum_majorant_le (f := f) (m := m) (τ := τ) (R := R) (r := r) + (hRpos := hRpos) (hrpos := lt_of_lt_of_le hRpos hR_le_r) + (hR_le_r := hR_le_r) (hτ_nonneg := hτ_nonneg) + (smallSet := smallSet) (hsmall_fin := hsmall_fin) (hsmallSet := hsmallSet) + (hsumτ := hsumτ) + (hr_phi := by + simpa [small, a, one_mul] using hr_phi) + s) + have hcprod_inv : + ‖(divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ ≤ + Real.exp (Cprod * (1 + r) ^ τ) := by + refine hasProd_norm_inv_le_exp_of_pointwise_le_exp + (α := divisorZeroIndex₀ f (Set.univ : Set ℂ)) (fac := fac) + (F := divisorCanonicalProduct m f (Set.univ : Set ℂ) u) + hprod (b := b) (B := Cprod * (1 + r) ^ τ) ?_ ?_ + · exact hterm + · intro s + exact hb_le s + have hmul : + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + = + ‖(u ^ analyticOrderNatAt f 0)⁻¹‖ * + ‖(divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ := by + simp [mul_inv_rev, mul_comm] + rw [hmul] + have : + ‖(u ^ analyticOrderNatAt f 0)⁻¹‖ * + ‖(divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + ≤ 1 * Real.exp (Cprod * (1 + r) ^ τ) := + mul_le_mul hpow_inv_le1 hcprod_inv (by positivity) (by positivity) + simpa using this + +theorem hadamardQuotient_norm_le_exp_on_cartan_circle + {f H : ℂ → ℂ} {ρ τ : ℝ} {m : ℕ} {Cf : ℝ} + (hmρ : (m : ℝ) ≤ ρ) (hτ : ρ < τ) (hτ_lt : τ < (m + 1 : ℝ)) + (hτ_nonneg : 0 ≤ τ) (hentire : Differentiable ℂ f) + (hnot : ∃ z : ℂ, f z ≠ 0) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (hsumτ : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) + (hf_boundτ : ∀ z : ℂ, ‖f z‖ ≤ Real.exp (Cf * (1 + ‖z‖) ^ τ)) + (hfactor : ∀ z : ℂ, + f z = + H z * z ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) z) : + let Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + let Cprod : ℝ := cartanProductConstant m τ Sτ + ∀ {R r : ℝ}, 0 < R → 1 ≤ R → R ≤ r → r ≤ 2 * R → 0 < r → + ∀ (smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsmall_fin : smallSet.Finite), + smallSet = + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ‖divisorZeroIndex₀Val p‖ ≤ 4 * R} → + (let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => ‖divisorZeroIndex₀Val p‖ + r ∉ small.image a) → + (let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => ‖divisorZeroIndex₀Val p‖ + (∑ p ∈ small, (1 : ℝ) * CartanBound.φ (r / a p)) ≤ + CartanBound.Cφ * (small.card : ℝ)) → + ∀ u : ℂ, ‖u‖ = r → ‖H u‖ ≤ Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) := by + classical + intro Sτ Cprod R r hRpos hRle hR_le_r hr_le_2R hrpos smallSet hsmall_fin + hsmallSet hr_not_bad hr_phi u hur + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let bad : Finset ℝ := small.image a + have hr_not_bad' : r ∉ bad := by + simpa [bad, small, a] using hr_not_bad + have hden_eq : + f u = + H u * (u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u) := by + simpa [mul_assoc, mul_left_comm, mul_comm] using (hfactor u) + have hfu_ne : f u ≠ 0 := by + have hr_le_4R : r ≤ 4 * R := by nlinarith [hr_le_2R, hRpos] + exact no_zero_on_sphere_of_norm_image_avoid (f := f) hentire hnot + (B := 4 * R) (r := r) hrpos hr_le_4R smallSet hsmall_fin hsmallSet + (by simpa [small, a] using hr_not_bad) u hur + have hden_ne : + (u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u) ≠ 0 := by + intro hden0 + have : f u = 0 := by simpa [hden0] using hden_eq + exact hfu_ne this + have hHu : + H u = + f u / (u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u) := by + exact eq_div_of_mul_eq hden_ne (Eq.symm hden_eq) + have hf_u : ‖f u‖ ≤ Real.exp (Cf * (1 + r) ^ τ) := by + simpa [hur] using hf_boundτ u + have hden_inv : + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + ≤ Real.exp (Cprod * (1 + r) ^ τ) := by + simpa [Sτ, Cprod] using + (norm_inv_hadamardDenominator_le_exp_on_cartan_circle + (f := f) (ρ := ρ) (τ := τ) (m := m) + hmρ hτ hτ_lt hτ_nonneg h_sum hsumτ + (R := R) (r := r) hRpos hRle hR_le_r hr_le_2R + smallSet hsmall_fin hsmallSet + (by simpa [small, a] using hr_not_bad) + (by simpa [small, a, one_mul] using hr_phi) + u hur) + have : + ‖H u‖ ≤ + ‖f u‖ * + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ := by + have : + ‖H u‖ = + ‖f u / + (u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)‖ := by + simp [hHu] + simp [div_eq_mul_inv, norm_inv, this] + have hmul : + ‖f u‖ * + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + ≤ Real.exp (Cf * (1 + r) ^ τ) * Real.exp (Cprod * (1 + r) ^ τ) := + mul_le_mul hf_u hden_inv (by positivity) (by positivity) + have hexp : + Real.exp (Cf * (1 + r) ^ τ) * Real.exp (Cprod * (1 + r) ^ τ) + = Real.exp ((Cf + Cprod) * (1 + r) ^ τ) := by + simp [Real.exp_add, add_mul, add_comm] + have : ‖H u‖ ≤ Real.exp ((Cf + Cprod) * (1 + r) ^ τ) := + (this.trans hmul).trans_eq hexp + have hslack : + Real.exp ((Cf + Cprod) * (1 + r) ^ τ) ≤ + Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) := by + refine Real.exp_le_exp.2 ?_ + have hnn : 0 ≤ (1 + r) ^ τ := by positivity + nlinarith + exact this.trans hslack + +theorem hadamardQuotient_norm_le_exp_rpow_of_growth {f H : ℂ → ℂ} {ρ τ : ℝ} {m : ℕ} + (hρ : 0 ≤ ρ) (hmρ : (m : ℝ) ≤ ρ) (hτ : ρ < τ) (hτ_lt : τ < (m + 1 : ℝ)) + (hτ_nonneg : 0 ≤ τ) (hentire : Differentiable ℂ f) (hH_entire : Differentiable ℂ H) + (hnot : ∃ z : ℂ, f z ≠ 0) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (hgrowth : ∃ C > 0, ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) + (hfactor : ∀ z : ℂ, + f z = + H z * z ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) z) : + ∃ C > 0, ∀ z : ℂ, ‖H z‖ ≤ Real.exp (C * (1 + ‖z‖) ^ τ) := by + rcases hgrowth with ⟨Cf, hCfpos, hCf⟩ + have hsumτ : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := + summable_norm_inv_rpow_divisorZeroIndex₀_of_growth (f := f) (ρ := ρ) (τ := τ) + hρ hτ hentire hnot ⟨Cf, hCfpos, hCf⟩ + let Sτ : ℝ := ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + have hSτ_nonneg : 0 ≤ Sτ := tsum_nonneg fun _ => + Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _ + let Cprod : ℝ := cartanProductConstant m τ Sτ + have hCprod_nonneg : 0 ≤ Cprod := by + simpa [Cprod] using cartanProductConstant_nonneg (m := m) (τ := τ) hSτ_nonneg + have hf_boundτ : ∀ z : ℂ, ‖f z‖ ≤ Real.exp (Cf * (1 + ‖z‖) ^ τ) := + Real.norm_le_exp_mul_rpow_of_log_growth + (f := f) (r := fun z : ℂ => 1 + ‖z‖) (C := Cf) (ρ := ρ) (τ := τ) + hCfpos.le (fun z => by linarith [norm_nonneg z]) (le_of_lt hτ) hCf + refine ⟨(Cf + Cprod + 10) * (3 : ℝ) ^ τ, by + have h3τ : 0 < (3 : ℝ) ^ τ := by positivity + nlinarith [hCfpos, hCprod_nonneg, h3τ], ?_⟩ + intro z + let R : ℝ := max ‖z‖ 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num) (le_max_right _ _) + have hRle : (1 : ℝ) ≤ R := le_max_right _ _ + let smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + {p | ‖divisorZeroIndex₀Val p‖ ≤ 4 * R} + have hsmall_fin : smallSet.Finite := by + have : Metric.closedBall (0 : ℂ) (4 * R) ⊆ (Set.univ : Set ℂ) := by simp + simpa [smallSet] using + (divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) + (B := 4 * R) this) + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + have ha_pos : ∀ p ∈ small, 0 < a p := by + intro p hp + exact norm_pos_iff.2 (divisorZeroIndex₀Val_ne_zero p) + let bad : Finset ℝ := small.image a + rcases CartanBound.exists_radius_Ioc_sum_mul_phi_div_le_Cφ_mul_sum_avoid + (s := small) (w := fun _ => (1 : ℝ)) (a := a) + (hw := by intro _ _; norm_num) (ha := ha_pos) (bad := bad) (R := R) hRpos with + ⟨r, hr_mem, hr_not_bad, hr_phi⟩ + have hR_le_r : R ≤ r := le_of_lt hr_mem.1 + have hr_le_2R : r ≤ 2 * R := hr_mem.2 + have hrpos : 0 < r := lt_of_lt_of_le hRpos hR_le_r + have hcircle : + ∀ u : ℂ, ‖u‖ = r → ‖H u‖ ≤ Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) := by + simpa [Sτ, Cprod] using + (hadamardQuotient_norm_le_exp_on_cartan_circle + (f := f) (H := H) (ρ := ρ) (τ := τ) (m := m) (Cf := Cf) + hmρ hτ hτ_lt hτ_nonneg hentire hnot h_sum hsumτ hf_boundτ hfactor + (R := R) (r := r) hRpos hRle hR_le_r hr_le_2R hrpos + smallSet hsmall_fin (by rfl) + (by simpa [small, a, bad] using hr_not_bad) + (by simpa [small, a, one_mul, Finset.sum_const, nsmul_eq_mul] using hr_phi)) + have hz_ball : z ∈ Metric.ball (0 : ℂ) r := by + rw [Metric.mem_ball, dist_zero_right] + exact lt_of_le_of_lt (le_max_left _ _) hr_mem.1 + have hball : + ‖H z‖ ≤ Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) := by + exact Complex.norm_le_of_mem_ball_of_forall_sphere_norm_le hH_entire hrpos hz_ball hcircle + have hr_le_3 : 1 + r ≤ 3 * (1 + ‖z‖) := by + exact Real.one_add_le_three_mul_one_add_of_le_two_mul_max (norm_nonneg z) + (by simpa [R] using hr_le_2R) + have hmain : + Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) + ≤ Real.exp (((Cf + Cprod + 10) * (3 : ℝ) ^ τ) * (1 + ‖z‖) ^ τ) := by + have hnn : 0 ≤ (Cf + Cprod + 10) := by nlinarith [le_of_lt hCfpos, hCprod_nonneg] + exact Real.exp_mul_rpow_le_exp_mul_rpow_of_le_mul hnn (by norm_num) + (by linarith [le_of_lt hrpos]) (by positivity) hτ_nonneg hr_le_3 + simpa [mul_assoc] using hball.trans hmain + +theorem hadamard_factorization_of_growth {f : ℂ → ℂ} {ρ : ℝ} (hρ : 0 ≤ ρ) + (hentire : Differentiable ℂ f) + (hnot : ∃ z : ℂ, f z ≠ 0) + (hgrowth : ∃ C > 0, ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) : + ∃ (P : Polynomial ℂ), + P.degree ≤ Nat.floor ρ ∧ + ∀ z : ℂ, + f z = + Complex.exp (Polynomial.eval z P) * + z ^ (analyticOrderNatAt f 0) * + divisorCanonicalProduct (Nat.floor ρ) f (Set.univ : Set ℂ) z := by + set m : ℕ := Nat.floor ρ + have h_sum : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + simpa [m] using + (summable_norm_inv_pow_divisorZeroIndex₀_of_growth (f := f) (ρ := ρ) + hρ hentire hnot hgrowth) + rcases exists_entire_nonzero_hadamardQuotient (m := m) (f := f) hentire hnot h_sum with + ⟨H, hH_entire, hH_ne, hfactor⟩ + rcases Real.exists_between_self_and_floor_add_one_same_floor hρ with + ⟨τ, hτ, hτ_lt, hτ_nonneg, hfloorτ'⟩ + have hfloorτ : Nat.floor τ = m := by + simpa [m] using hfloorτ' + have hτ_lt_m : τ < (m + 1 : ℝ) := by + simpa [m] using hτ_lt + have hτ_lt_nat : τ < ((m + 1 : ℕ) : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one] using hτ_lt_m + have hmρ : (m : ℝ) ≤ ρ := by + have := Nat.floor_le hρ + simpa [m] using this + have hH_bound_rpow : + ∃ C > 0, ∀ z : ℂ, ‖H z‖ ≤ Real.exp (C * (1 + ‖z‖) ^ τ) := + hadamardQuotient_norm_le_exp_rpow_of_growth (f := f) (H := H) (ρ := ρ) (τ := τ) + (m := m) hρ hmρ hτ hτ_lt hτ_nonneg hentire hH_entire hnot h_sum hgrowth hfactor + have hH_growth_nat : + ∃ C > 0, ∀ z : ℂ, ‖H z‖ ≤ Real.exp (C * (1 + ‖z‖) ^ (m + 1)) := by + exact Real.exists_norm_le_exp_mul_pow_of_rpow_bound + (f := H) (r := fun z : ℂ => 1 + ‖z‖) + (fun z => by linarith [norm_nonneg z]) hτ_lt_nat hH_bound_rpow + rcases zero_free_polynomial_growth_is_exp_poly (H := H) (n := m + 1) + hH_entire hH_ne hH_growth_nat with + ⟨P, hPn, hHP⟩ + have hPnat : P.natDegree ≤ m := by + have hbound : + ∃ C > 0, ∀ z : ℂ, + ‖Complex.exp (Polynomial.eval z P)‖ ≤ Real.exp (C * (1 + ‖z‖) ^ τ) := by + rcases hH_bound_rpow with ⟨C, hCpos, hC⟩ + exact ⟨C, hCpos, fun z => by simpa [hHP z] using (hC z)⟩ + have := natDegree_le_floor_of_exp_eval_norm_bound hτ_nonneg P hbound + simpa [hfloorτ] using this + refine ⟨P, ?_, ?_⟩ + · have : P.degree ≤ m := Polynomial.degree_le_of_natDegree_le hPnat + simpa [m] using this + · intro z + have hH' : H z = Complex.exp (Polynomial.eval z P) := by simpa using (hHP z) + simpa [hH', mul_assoc, mul_left_comm, mul_comm, m] using (hfactor z) + +end Complex.Hadamard +end +end HadamardSourceScope33 + +end HadamardAssemblyScope + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Mathlib/Algebra/Notation/Support.lean b/PrimeNumberTheoremAnd/Erdos970/Mathlib/Algebra/Notation/Support.lean new file mode 100644 index 0000000..39dd03b --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Mathlib/Algebra/Notation/Support.lean @@ -0,0 +1,17 @@ +import Mathlib.Algebra.Notation.Support + +namespace Erdos970 + +namespace Function + +variable {α : Type*} [Zero α] + +theorem support_id : _root_.Function.support (id : α → α) = {0}ᶜ := by + ext; simp + +theorem support_id' {α : Type*} [Zero α] : _root_.Function.support (fun x : α ↦ x) = {0}ᶜ := + support_id + +end Function + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Mathlib/Analysis/Asymptotics/Asymptotics.lean b/PrimeNumberTheoremAnd/Erdos970/Mathlib/Analysis/Asymptotics/Asymptotics.lean new file mode 100644 index 0000000..1ef2299 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Mathlib/Analysis/Asymptotics/Asymptotics.lean @@ -0,0 +1,42 @@ +import Mathlib.Analysis.Asymptotics.Lemmas +import Mathlib.Topology.Order.Compact + +namespace Erdos970 + +open Filter Topology + +namespace Asymptotics + +variable {α : Type*} {β : Type*} {E : Type*} {F : Type*} {G : Type*} {E' : Type*} + {F' : Type*} {G' : Type*} {E'' : Type*} {F'' : Type*} {G'' : Type*} {R : Type*} + {R' : Type*} {𝕜 : Type*} {𝕜' : Type*} + +variable [Norm E] [Norm F] [Norm G] + +variable [SeminormedAddCommGroup E'] [SeminormedAddCommGroup F'] [SeminormedAddCommGroup G'] + [NormedAddCommGroup E''] [NormedAddCommGroup F''] [NormedAddCommGroup G''] [SeminormedRing R] + [SeminormedRing R'] + +theorem isLittleO_const_id_cocompact [ProperSpace F''] + (c : E'') : (fun _x : F'' => c) =o[cocompact F''] id := + _root_.Asymptotics.isLittleO_const_left.2 <| Or.inr tendsto_norm_cocompact_atTop + +theorem isLittleO_const_id_atTop2 [LinearOrder F''] [NoMaxOrder F''] [ClosedIciTopology F''] + [ProperSpace F''] (c : E'') : (fun _x : F'' => c) =o[atTop] id := + (isLittleO_const_id_cocompact c).mono atTop_le_cocompact + +theorem isLittleO_const_id_atBot2 [LinearOrder F''] [NoMinOrder F''] [ClosedIicTopology F''] + [ProperSpace F''] (c : E'') : (fun _x : F'' => c) =o[atBot] id := + (isLittleO_const_id_cocompact c).mono atBot_le_cocompact + +theorem _root_.Erdos970.Filter.Eventually.natCast {f : ℝ → Prop} (hf : ∀ᶠ x in atTop, f x) : + ∀ᶠ n : ℕ in atTop, f n := + tendsto_natCast_atTop_atTop.eventually hf + +theorem IsBigO.natCast {f g : ℝ → E} (h : f =O[atTop] g) : + (fun n : ℕ => f n) =O[atTop] fun n : ℕ => g n := + h.comp_tendsto tendsto_natCast_atTop_atTop + +end Asymptotics + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean b/PrimeNumberTheoremAnd/Erdos970/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean new file mode 100644 index 0000000..b8b7136 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Mathlib/Analysis/SpecialFunctions/Log/Basic.lean @@ -0,0 +1,20 @@ +import Mathlib.Algebra.Order.Floor.Defs +import Mathlib.Algebra.Order.Floor.Ring +import Mathlib.Algebra.Order.Floor.Semiring +import Mathlib.Analysis.SpecialFunctions.Log.Basic +import Mathlib.Analysis.SpecialFunctions.Pow.Continuity + +namespace Erdos970 + +open Filter Real + +theorem Real.tendsto_pow_log_div_pow_atTop (a : ℝ) (b : ℝ) (ha : 0 < a) : + Filter.Tendsto (fun x ↦ log x ^ b / x^a) Filter.atTop (nhds 0) := by + apply Asymptotics.isLittleO_iff_tendsto' _|>.mp <| isLittleO_log_rpow_rpow_atTop _ ha + filter_upwards [eventually_gt_atTop 0] with x hx + intro h + rw [rpow_eq_zero hx.le ha.ne.symm] at h + exfalso + linarith + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/MellinCalculus.lean b/PrimeNumberTheoremAnd/Erdos970/MellinCalculus.lean new file mode 100644 index 0000000..12adb34 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/MellinCalculus.lean @@ -0,0 +1,1024 @@ +import Batteries.Tactic.Lemma +import Mathlib.Algebra.GroupWithZero.Units.Basic +import Mathlib.Analysis.MellinTransform +import Mathlib.MeasureTheory.Integral.IntegrableOn +import Mathlib.Tactic.Bound +import Mathlib.Tactic.GCongr +import PrimeNumberTheoremAnd.Erdos970.Auxiliary + +namespace Erdos970 + +open scoped ContDiff + + +open _root_.Complex _root_.Topology _root_.Filter _root_.Real _root_.MeasureTheory + _root_.Set _root_.Function + +theorem 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 + +open Erdos970.Complex Erdos970.MeasureTheory + +variable {𝕂 : Type*} [RCLike 𝕂] + +lemma 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 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 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 + +lemma 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 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 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 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 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 Function.support_ofReal {f : ℝ → ℝ} : + (fun x ↦ ((f x) : ℂ)).support = f.support := by + apply Function.support_comp_eq (g := ofReal); simp + +lemma 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 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 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 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 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 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 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 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] + +open Erdos970.Filter + +lemma deriv.ofReal_comp' {f : ℝ → ℝ} : + deriv (fun x : ℝ ↦ (f x : ℂ)) = (fun x ↦ ((deriv f) x : ℂ)) := + funext fun _ ↦ deriv.ofReal_comp + +lemma deriv.comp_ofReal' {e : ℂ → ℂ} (hf : Differentiable ℂ e) : + deriv (fun x : ℝ ↦ e x) = fun (x : ℝ) ↦ deriv e x := + funext fun _ ↦ deriv.comp_ofReal (hf.differentiableAt) + +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 + +local notation (name := mellintransform) "𝓜" => mellin + +noncomputable def MellinConvolution (f g : ℝ → 𝕂) (x : ℝ) : 𝕂 := + ∫ y in Ioi 0, f y * g (x / y) / y + +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 + + +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] + +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⟩ + +noncomputable def DeltaSpike (ν : ℝ → ℝ) (ε : ℝ) : ℝ → ℝ := + fun x ↦ ν (x ^ (1 / ε)) / ε + +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ν + + +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 + +lemma MellinOfDeltaSpikeAt1 (ν : ℝ → ℝ) {ε : ℝ} (εpos : ε > 0) : + 𝓜 (fun x ↦ (DeltaSpike ν ε x : ℂ)) 1 = 𝓜 (fun x ↦ (ν x : ℂ)) ε := by + convert MellinOfDeltaSpike ν εpos 1; simp [mul_one] + +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 [Erdos970.Function.support_ofReal (f := ν)] + · 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 [Erdos970.Function.support_ofReal (f := ν)] + 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] + +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 + +noncomputable def Smooth1 (ν : ℝ → ℝ) (ε : ℝ) : ℝ → ℝ := + MellinConvolution (fun x ↦ if 0 < x ∧ x ≤ 1 then 1 else 0) (DeltaSpike ν ε) + +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)] + +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 + +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 + +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 + +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 + +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 + +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 + +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 + 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 + change Integrable (fun x : ℝ × ℝ => f x.2 * (x.1 : ℂ) ^ (s - 1)) + (volume.restrict (Tx ×ˢ Ty)) + have : volume.restrict (Tx ×ˢ Ty) = (volume.restrict Tx).prod (volume.restrict Ty) := by + rw [Measure.prod_restrict, MeasureTheory.Measure.volume_eq_prod] + conv => rw [this]; 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 + +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 + +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ε + +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 Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/MertensClassical.lean b/PrimeNumberTheoremAnd/Erdos970/MertensClassical.lean new file mode 100644 index 0000000..8f3e823 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/MertensClassical.lean @@ -0,0 +1,1982 @@ +import Mathlib.Algebra.Order.Field.GeomSum +import Mathlib.Analysis.SumIntegralComparisons +import Mathlib.NumberTheory.Chebyshev +import Mathlib.NumberTheory.Harmonic.EulerMascheroni +import Mathlib.NumberTheory.LSeries.PrimesInAP +import Mathlib.NumberTheory.LSeries.RiemannZeta +import Mathlib.NumberTheory.Harmonic.GammaDeriv +import Mathlib.Analysis.Asymptotics.Lemmas +import Mathlib.Analysis.SpecialFunctions.Complex.Analytic +import Mathlib.Analysis.SpecialFunctions.Integrability.LogMeromorphic +import Mathlib.NumberTheory.EulerProduct.DirichletLSeries +import Mathlib.NumberTheory.EulerProduct.ExpLog +import Mathlib.Analysis.SpecialFunctions.Complex.LogBounds +import Mathlib.Analysis.SpecialFunctions.Log.Summable +import Mathlib.Algebra.Group.Submonoid.BigOperators +import PrimeNumberTheoremAnd.Erdos970.EulerMaclaurin + +namespace Erdos970 + +theorem Filter.EventuallyEq.iff_eventually {α : Type _} {β : Type _} {l : Filter α} {f g : α → β} : f =ᶠ[l] g ↔ ∀ᶠ (x : α) in l, f x = g x := by rfl + +namespace Real + +open _root_.Real _root_.Filter _root_.Asymptotics + +theorem inv_log_eq_o_one : (fun x ↦ 1 / log x) =o[atTop] (fun _ ↦ (1:ℝ)) := by + rw [isLittleO_one_iff] + convert tendsto_log_atTop.inv_tendsto_atTop using 1 + ext; simp + +theorem one_eq_o_log_log : (fun _ ↦ (1:ℝ)) =o[atTop] (fun x ↦ log (log x)) := by + simp only [isLittleO_one_left_iff, norm_eq_abs] + exact tendsto_abs_atTop_atTop.comp (tendsto_log_atTop.comp tendsto_log_atTop) + +end Real + +section Issue1584 +open _root_.MeasureTheory _root_.Set _root_.Filter _root_.Topology + +private lemma integrableOn_log_mul_exp_neg : + IntegrableOn (fun v : ℝ => Real.log v * Real.exp (-v)) (Ioi 0) := by + rw [← Set.Ioc_union_Ioi_eq_Ioi (zero_le_one' ℝ), integrableOn_union] + constructor + · + have hlog : IntegrableOn (fun v : ℝ => Real.log v) (Ioc 0 1) volume := by + have := (intervalIntegral.intervalIntegrable_log' (a := 0) (b := 1)) + rwa [intervalIntegrable_iff_integrableOn_Ioc_of_le (zero_le_one' ℝ)] at this + apply Integrable.mono' hlog.norm + · apply (Measurable.aestronglyMeasurable ?_) + exact (Real.measurable_log.mul (Real.measurable_exp.comp measurable_neg)) + · filter_upwards [self_mem_ae_restrict measurableSet_Ioc] with v hv + rw [norm_mul, Real.norm_eq_abs, Real.norm_eq_abs] + have h1 : |Real.exp (-v)| = Real.exp (-v) := abs_of_pos (Real.exp_pos _) + have h2 : Real.exp (-v) ≤ 1 := Real.exp_le_one_iff.mpr (by linarith [hv.1]) + rw [h1] + nlinarith [abs_nonneg (Real.log v), Real.exp_pos (-v)] + · + have hexp : IntegrableOn (fun v : ℝ => (2 : ℝ) * Real.exp ((-1/2) * v)) (Ioi 1) volume := by + exact (integrableOn_exp_mul_Ioi (by norm_num : (-1/2 : ℝ) < 0) 1).const_mul 2 + apply Integrable.mono' hexp + · apply (Measurable.aestronglyMeasurable ?_) + exact (Real.measurable_log.mul (Real.measurable_exp.comp measurable_neg)) + · filter_upwards [self_mem_ae_restrict measurableSet_Ioi] with v hv + have hv1 : (1 : ℝ) ≤ v := le_of_lt hv + have hvpos : (0 : ℝ) < v := by linarith + rw [norm_mul, Real.norm_eq_abs, Real.norm_eq_abs] + have hlogabs : |Real.log v| = Real.log v := + abs_of_nonneg (Real.log_nonneg hv1) + have hexpabs : |Real.exp (-v)| = Real.exp (-v) := abs_of_pos (Real.exp_pos _) + rw [hlogabs, hexpabs] + + have hlogv : Real.log v ≤ v := (Real.log_le_sub_one_of_pos hvpos).trans (by linarith) + + have hvexp : v ≤ 2 * Real.exp (v/2) := by + have := Real.add_one_le_exp (v/2) + nlinarith [Real.exp_pos (v/2)] + + have hstep : Real.log v * Real.exp (-v) ≤ 2 * Real.exp (v/2) * Real.exp (-v) := by + apply mul_le_mul_of_nonneg_right (hlogv.trans hvexp) (le_of_lt (Real.exp_pos _)) + have heq : 2 * Real.exp (v/2) * Real.exp (-v) = 2 * Real.exp ((-1/2) * v) := by + rw [mul_assoc, ← Real.exp_add] + ring_nf + rw [heq] at hstep + exact hstep + +private lemma integral_log_mul_exp_neg_eq_deriv_Gamma : + ∫ t in Ioi (0:ℝ), Real.log t * Real.exp (-t) = deriv Real.Gamma 1 := by + set I : ℝ := ∫ t in Ioi (0:ℝ), Real.log t * Real.exp (-t) with hI + + have h1 := Complex.hasDerivAt_GammaIntegral (s := (1 : ℂ)) (by norm_num) + + have hval : (∫ t : ℝ in Ioi 0, (↑t : ℂ) ^ ((1 : ℂ) - 1) * (↑(Real.log t) * ↑(Real.exp (-t)))) + = (I : ℂ) := by + have key : ∀ t : ℝ, (↑t : ℂ) ^ ((1 : ℂ) - 1) * (↑(Real.log t) * ↑(Real.exp (-t))) + = ((Real.log t * Real.exp (-t) : ℝ) : ℂ) := by + intro t + rw [sub_self, Complex.cpow_zero, one_mul, Complex.ofReal_mul] + simp_rw [key] + rw [integral_complex_ofReal, hI] + rw [hval] at h1 + + have h2 : HasDerivAt Complex.Gamma (I : ℂ) 1 := by + apply h1.congr_of_eventuallyEq + filter_upwards [(isOpen_lt continuous_const Complex.continuous_re).mem_nhds + (show (0:ℝ) < (1:ℂ).re by norm_num)] with z hz + exact Complex.Gamma_eq_integral hz + + have h3 := h2.real_of_complex + have h4 : HasDerivAt Real.Gamma I 1 := by + have hcongr : (fun x : ℝ => (Complex.Gamma ↑x).re) = Real.Gamma := by + funext x + rw [Complex.Gamma_ofReal, Complex.ofReal_re] + rw [hcongr, Complex.ofReal_re] at h3 + exact h3 + rw [← h4.deriv] + +private theorem mul_integ_log_log_eq_aux (s : ℝ) (hs : 1 < s) : + (s - 1) * ∫ x in Ioi (1:ℝ), Real.log (Real.log x) * x ^ (-s) = + - Real.log (s - 1) + deriv Real.Gamma 1 := by + have hs0 : 0 < s - 1 := by linarith + set f : ℝ → ℝ := fun x => (s - 1) * Real.log x with hf_def + set f' : ℝ → ℝ := fun x => (s - 1) / x with hf'_def + set g : ℝ → ℝ := fun u => (Real.log u - Real.log (s - 1)) * Real.exp (-u) with hg_def + + have hf1 : f 1 = 0 := by simp [hf_def] + + have hf_cont : ContinuousOn f (Ici 1) := by + apply ContinuousOn.mul continuousOn_const + apply Real.continuousOn_log.mono + intro x hx + simp only [mem_Ici] at hx + simp only [Set.mem_compl_iff, Set.mem_singleton_iff] + linarith + + have hft : Tendsto f atTop atTop := by + apply Filter.Tendsto.const_mul_atTop hs0 + exact Real.tendsto_log_atTop + + have hff' : ∀ x ∈ Ioi (1:ℝ), HasDerivWithinAt f (f' x) (Ioi x) x := by + intro x hx + simp only [mem_Ioi] at hx + have hxne : x ≠ 0 := by linarith + have := (Real.hasDerivAt_log hxne).const_mul (s - 1) + have h2 : HasDerivAt f ((s - 1) * x⁻¹) x := this + have : (s - 1) * x⁻¹ = f' x := by rw [hf'_def]; field_simp + rw [this] at h2 + exact h2.hasDerivWithinAt + + have hmono : StrictMonoOn f (Ici 1) := by + intro a ha b hb hab + simp only [mem_Ici] at ha hb + apply mul_lt_mul_of_pos_left _ hs0 + exact Real.log_lt_log (by linarith) hab + have himg_Ioi : f '' Ioi 1 = Ioi 0 := by + ext y + simp only [Set.mem_image, mem_Ioi] + constructor + · rintro ⟨x, hx, rfl⟩ + have : 0 < Real.log x := Real.log_pos hx + positivity + · intro hy + refine ⟨Real.exp (y / (s - 1)), ?_, ?_⟩ + · exact Real.one_lt_exp_iff.mpr (div_pos hy hs0) + · rw [hf_def] + simp only [Real.log_exp] + field_simp + have himg_Ici : f '' Ici 1 = Ici 0 := by + ext y + simp only [Set.mem_image, mem_Ici] + constructor + · rintro ⟨x, hx, rfl⟩ + have : 0 ≤ Real.log x := Real.log_nonneg hx + rw [hf_def]; positivity + · intro hy + refine ⟨Real.exp (y / (s - 1)), ?_, ?_⟩ + · exact Real.one_le_exp_iff.mpr (div_nonneg hy hs0.le) + · rw [hf_def] + simp only [Real.log_exp] + field_simp + + have hg_cont : ContinuousOn g (f '' Ioi 1) := by + rw [himg_Ioi] + apply ContinuousOn.mul + · apply ContinuousOn.sub _ continuousOn_const + apply Real.continuousOn_log.mono + intro u hu + simp only [mem_Ioi] at hu + simp only [Set.mem_compl_iff, Set.mem_singleton_iff] + linarith + · exact (Real.continuous_exp.comp continuous_neg).continuousOn + + have hg1 : IntegrableOn g (f '' Ici 1) := by + rw [himg_Ici, integrableOn_Ici_iff_integrableOn_Ioi] + have e1 : IntegrableOn (fun u => Real.log u * Real.exp (-u)) (Ioi 0) := + integrableOn_log_mul_exp_neg + have e2 : IntegrableOn (fun u => Real.log (s - 1) * Real.exp (-u)) (Ioi 0) := + (integrableOn_exp_neg_Ioi 0).const_mul _ + have : g = fun u => Real.log u * Real.exp (-u) - Real.log (s - 1) * Real.exp (-u) := by + funext u; rw [hg_def]; ring + rw [this] + exact e1.sub e2 + + have hg2 : IntegrableOn (fun x => (g ∘ f) x * f' x) (Ici 1) := by + + have hff'_Ici : ∀ x ∈ Ici (1:ℝ), HasDerivWithinAt f (f' x) (Ici 1) x := by + intro x hx + simp only [mem_Ici] at hx + have hxne : x ≠ 0 := by linarith + have hd : HasDerivAt f ((s - 1) * x⁻¹) x := (Real.hasDerivAt_log hxne).const_mul (s - 1) + have heq : (s - 1) * x⁻¹ = f' x := by rw [hf'_def]; field_simp + rw [heq] at hd + exact hd.hasDerivWithinAt + + have hinj : InjOn f (Ici 1) := hmono.injOn + + have hiff := integrableOn_image_iff_integrableOn_abs_deriv_smul + (s := Ici (1:ℝ)) (f := f) (f' := f') measurableSet_Ici hff'_Ici hinj g + rw [hiff] at hg1 + + apply hg1.congr + filter_upwards [self_mem_ae_restrict measurableSet_Ici] with x hx + simp only [mem_Ici] at hx + have hxpos : (0:ℝ) < x := by linarith + have hf'pos : 0 < f' x := by rw [hf'_def]; positivity + simp only [smul_eq_mul, Function.comp, abs_of_pos hf'pos] + ring + + have hcov := integral_comp_mul_deriv_Ioi hf_cont hft hff' hg_cont hg1 hg2 + rw [hf1] at hcov + + have hrhs : ∫ u in Ioi (0:ℝ), g u = deriv Real.Gamma 1 - Real.log (s - 1) := by + have e1 : IntegrableOn (fun u => Real.log u * Real.exp (-u)) (Ioi 0) := + integrableOn_log_mul_exp_neg + have e2 : IntegrableOn (fun u => Real.log (s - 1) * Real.exp (-u)) (Ioi 0) := + (integrableOn_exp_neg_Ioi 0).const_mul _ + have hsplit : (fun u => g u) + = fun u => Real.log u * Real.exp (-u) - Real.log (s - 1) * Real.exp (-u) := by + funext u; rw [hg_def]; ring + rw [show (∫ u in Ioi (0:ℝ), g u) + = ∫ u in Ioi (0:ℝ), (Real.log u * Real.exp (-u) - Real.log (s - 1) * Real.exp (-u)) + from by rw [hsplit]] + rw [integral_sub e1 e2, integral_log_mul_exp_neg_eq_deriv_Gamma] + rw [integral_const_mul, integral_exp_neg_Ioi_zero, mul_one] + + have hlhs : ∫ x in Ioi (1:ℝ), (g ∘ f) x * f' x + = (s - 1) * ∫ x in Ioi (1:ℝ), Real.log (Real.log x) * x ^ (-s) := by + have hpt : ∀ x ∈ Ioi (1:ℝ), (g ∘ f) x * f' x + = (s - 1) * (Real.log (Real.log x) * x ^ (-s)) := by + intro x hx + simp only [mem_Ioi] at hx + have hxpos : (0:ℝ) < x := by linarith + have hlogpos : 0 < Real.log x := Real.log_pos hx + have hlogne : Real.log x ≠ 0 := ne_of_gt hlogpos + have hs1ne : s - 1 ≠ 0 := ne_of_gt hs0 + simp only [Function.comp, hf_def, hg_def, hf'_def] + + rw [Real.log_mul hs1ne hlogne] + + have hexp : Real.exp (-((s - 1) * Real.log x)) = x ^ (-(s - 1)) := by + rw [Real.rpow_def_of_pos hxpos] + ring_nf + rw [hexp] + + have hx1 : x ^ (-(s - 1)) * ((s - 1) / x) = (s - 1) * x ^ (-s) := by + rw [div_eq_mul_inv, ← Real.rpow_neg_one x] + rw [show x ^ (-(s - 1)) * ((s - 1) * x ^ (-1 : ℝ)) + = (s - 1) * (x ^ (-(s - 1)) * x ^ (-1 : ℝ)) by ring] + rw [← Real.rpow_add hxpos] + ring_nf + rw [show (Real.log (s - 1) + Real.log (Real.log x) - Real.log (s - 1)) + = Real.log (Real.log x) by ring] + linear_combination Real.log (Real.log x) * hx1 + rw [setIntegral_congr_fun measurableSet_Ioi hpt, integral_const_mul] + rw [hlhs, hrhs] at hcov + rw [hcov] + ring + +end Issue1584 + +namespace Mertens + +open _root_.Real Erdos970.Real _root_.Finset _root_.Filter _root_.Asymptotics _root_.Topology +open ArithmeticFunction hiding log + +lemma sum_Ioc_one_eq_sum_Ioc_zero {f : ℕ → ℝ} {x : ℕ} (hx : 1 ≤ x) (hf : f 1 = 0) : + ∑ n ∈ Ioc 1 x, f n = ∑ n ∈ Ioc 0 x, f n := by + rw [(by rfl : Ioc 0 x = Icc 1 x), ← add_sum_Ioc_eq_sum_Icc hx] + simpa + +theorem sum_log_eq {x : ℝ} (hx : 1 ≤ x) : + ∑ n ∈ Ioc 0 ⌊ x ⌋₊, log n = + x * log x - (x - ⌊x⌋₊ - 1 / 2) * log x - x + 1 + ∫ t in 1..x, (t - ⌊t⌋₊ - 1 / 2) / t := by + rw [← sum_Ioc_one_eq_sum_Ioc_zero (Nat.le_floor (by grind)) (by simp)] + have : 1 = ⌊(1 : ℝ)⌋₊ := by simp + nth_rw 1 [this] + rw [sum_eq_integral_add_integral_deriv (by norm_num) hx (fun _ _ ↦ (by fun_prop (disch := grind)))] + · simp only [log_one, B1, Nat.floor_one, Nat.cast_one, sub_self, zero_sub, + RCLike.ofReal_real_eq_id, id_eq, mul_neg, zero_mul, neg_zero, integral_log, mul_zero, sub_zero, + deriv_log'] + ring_nf + congr + ext + ring + · simp only [deriv_log', Set.uIcc_of_le hx] + fun_prop (disch := grind) + +theorem sum_log_le {x : ℝ} (hx : 1 ≤ x) : + ∑ n ∈ Ioc 0 ⌊ x ⌋₊, log n ≤ x * log x := by + calc + _ ≤ ∑ n ∈ Ioc 0 ⌊ x ⌋₊, log x := by + refine sum_le_sum fun n hn ↦ ?_ + simp only [mem_Ioc] at hn + exact log_le_log (by exact_mod_cast hn.1) (Nat.le_floor_iff (by linarith)|>.mp hn.2) + _ = ⌊x⌋₊ * log x := by simp + _ ≤ _ := by + gcongr + · exact log_nonneg hx + · exact Nat.floor_le (by linarith) + +lemma integral_log_le {a b : ℝ} (ha : 1 ≤ a) (hab : a ≤ b) : + ∫ t in a..b, log t ≤ log b * (b - a) := by + apply le_of_abs_le + have : ∀ t ∈ Set.uIoc a b, ‖log t‖ ≤ log b := by + intro t ht + rw [Set.uIoc_of_le hab, Set.mem_Ioc] at ht + rw [norm_of_nonneg <| log_nonneg (by linarith)] + gcongr <;> linarith + grw [← norm_eq_abs, intervalIntegral.norm_integral_le_of_norm_le_const this, + abs_of_nonneg (by linarith)] + +theorem sum_log_ge {x : ℝ} (hx : 1 ≤ x) : + ∑ n ∈ Ioc 0 ⌊ x ⌋₊, log n ≥ x * log x - 2 * x := by + have one_le_floor : 1 ≤ ⌊x⌋₊ := by simpa + calc + _ = ∑ n ∈ Icc 1 ⌊ x ⌋₊, log n := by rfl + _ = ∑ n ∈ Ico (1 + 1) (⌊ x ⌋₊ + 1), log n := by + rw [← add_sum_Ioc_eq_sum_Icc one_le_floor] + simp + rfl + _ = ∑ n ∈ Ico 1 ⌊ x ⌋₊, log ((n + 1 : ℕ)) := by + rw [← Finset.sum_Ico_add'] + _ ≥ ∫ t in 1..⌊x⌋₊, log t := by + convert MonotoneOn.integral_le_sum_Ico one_le_floor ?_|>.ge + · norm_cast + · exact StrictMonoOn.monotoneOn (strictMonoOn_log.mono fun y hy ↦ (by simp_all; linarith)) + _ = (∫ t in 1..x, log t) - ∫ t in ⌊x⌋₊..x, log t := by + nth_rw 3 [intervalIntegral.integral_symm] + rw [sub_neg_eq_add, intervalIntegral.integral_add_adjacent_intervals] <;> exact intervalIntegral.intervalIntegrable_log' + _ ≥ (∫ t in 1..x, log t) - log x := by + gcongr + grw [integral_log_le (by simpa) (Nat.floor_le (by linarith))] + nth_rw 2 [← mul_one (log x)] + gcongr + · exact log_nonneg hx + · linarith [Nat.lt_floor_add_one x] + _ ≥ x * log x - x - log x := by simp only [integral_log, log_one, mul_zero, sub_zero, ge_iff_le, + tsub_le_iff_right, sub_add_cancel, le_add_iff_nonneg_right, zero_le_one] + _ ≥ _ := by linarith [log_le_self (by linarith : 0 ≤ x)] + +theorem sum_log_eq_log_factorial (x : ℝ) : + ∑ n ∈ Ioc 0 ⌊ x ⌋₊, log n = log (Nat.floor x).factorial := by + rw [←prod_Ico_id_eq_factorial, ←log_prod, prod_natCast] + · congr + intro x hx + simp at hx ⊢; grind + +theorem sum_log_eq_sum_mangoldt {x : ℝ} : + ∑ n ∈ Ioc 0 ⌊x⌋₊, log n = ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d * ⌊x / d⌋₊ := by + have : ∀ n : ℕ, log n = (Λ * zeta) n := by simp [vonMangoldt_mul_zeta] + simp_rw [this, sum_Ioc_mul_zeta_eq_sum, ← Nat.floor_div_natCast] + +noncomputable abbrev E₁Λ (x : ℝ) : ℝ := ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / d - log x + +theorem sum_mangoldt_div_eq (x : ℝ) : ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / d = log x + E₁Λ x := by + grind + +theorem E₁Λ.ge {x : ℝ} (hx : 1 ≤ x) : + E₁Λ x ≥ -2 := by + unfold E₁Λ + suffices x * ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d / d ≥ x * (log x - 2) by + linarith [le_of_mul_le_mul_left this (by linarith)] + calc + _ = ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d * (x / d) := by + rw [Finset.mul_sum] + ring_nf + _ ≥ ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d * ⌊x / d⌋₊ := by + gcongr + exact Nat.floor_le <| div_nonneg (by linarith) (by linarith) + _ ≥ x * log x - 2 * x := + sum_log_eq_sum_mangoldt ▸ sum_log_ge hx + _ = _ := by ring + +theorem E₁Λ.le {x : ℝ} (hx : 1 ≤ x) : + E₁Λ x ≤ log 4 + 4 := by + unfold E₁Λ + suffices x * ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d / d ≤ x * (log x + log 4 + 4) by + linarith [le_of_mul_le_mul_left this (by linarith)] + calc + _ = ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d * (x / d) := by + rw [Finset.mul_sum] + ring_nf + _ ≤ ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d * (⌊x / d⌋₊ + 1) := by + gcongr + exact Nat.lt_floor_add_one _|>.le + _ = (∑ d ∈ Ioc 0 ⌊x⌋₊, log d) + ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d := by + simp_rw [mul_add, mul_one] + rw [Finset.sum_add_distrib, sum_log_eq_sum_mangoldt] + _ ≤ x * log x + (log 4 + 4) * x := by + gcongr + · exact sum_log_le hx + · exact Chebyshev.psi_le_const_mul_self (by linarith) + _ = _ := by ring + +theorem sum_mangoldt_div_eq_log {x : ℝ} (hx : 1 ≤ x) : + |∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / d - log x| ≤ log 4 + 4 := by + grind [E₁Λ.le hx, E₁Λ.ge hx, log_nonneg] + +theorem E₁Λ.bounded' : ∃ c > 0, ∀ x ≥ 1, |E₁Λ x| ≤ c := by + exact ⟨log 4 + 4, (by positivity), fun x hx ↦ sum_mangoldt_div_eq_log hx⟩ + +theorem E₁Λ.bounded : E₁Λ =O[atTop] (fun _ ↦ (1:ℝ)) := by + simp only [isBigO_iff, norm_eq_abs, norm_one, mul_one, + eventually_atTop] + exact ⟨log 4 + 4, 1, fun _ hx ↦ sum_mangoldt_div_eq_log hx⟩ + +theorem one_eq_o_log : (fun _ ↦ (1:ℝ)) =o[atTop] (fun x ↦ log x) := by + simp only [isLittleO_one_left_iff, norm_eq_abs] + exact tendsto_abs_atTop_atTop.comp tendsto_log_atTop + +theorem sum_mangoldt_div_eq_log' : + (fun x ↦ ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / d) ~[atTop] (fun x ↦ log x) := by + apply IsLittleO.isEquivalent (IsBigO.trans_isLittleO _ one_eq_o_log) + convert! E₁Λ.bounded using 1 + +noncomputable abbrev E₁p (x : ℝ) : ℝ := ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (log p) / p - log x + +theorem sum_log_prime_div_eq (x : ℝ) : ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (log p) / p = log x + E₁p x := by + grind + +theorem E₁p.le_E₁Λ (x : ℝ) : + E₁p x ≤ E₁Λ x := by + unfold E₁p E₁Λ; rw [sum_filter] + gcongr with p _ + split_ifs with hp + · simp [vonMangoldt_apply_prime hp] + have : 0 ≤ Λ p := vonMangoldt_nonneg + positivity + +theorem E₁p.le {x : ℝ} (hx : 1 ≤ x) : + E₁p x ≤ log 4 + 4 := by + linarith [E₁Λ.le hx, E₁p.le_E₁Λ x] + +noncomputable abbrev E₁ : ℝ := ∑' p : ℕ, if p.Prime then (log p) / (p*(p-1)) else 0 + +lemma E₁.summand_nonneg (p : ℕ) : 0 ≤ if p.Prime then (log p) / (p*(p-1)) else 0 := by + split_ifs with h + · refine div_nonneg (log_natCast_nonneg _) (mul_nonneg (Nat.cast_nonneg _) ?_) + suffices 1 ≤ (p : ℝ) by linarith + exact_mod_cast h.one_le + · rfl + +theorem E₁.summable : Summable (fun p : ℕ ↦ if p.Prime then (log p) / (p*(p-1)) else 0) := by + refine (Real.summable_one_div_nat_rpow.mpr (by norm_num: 1 < (3 : ℝ) / 2)|>.const_div + 4).of_nonneg_of_le E₁.summand_nonneg fun n ↦ ?_ + split_ifs with h + · grw [Real.log_le_rpow_div (Nat.cast_nonneg _) (by norm_num : 0 < (1 : ℝ) / 2)] + · have denom : (n : ℝ) * ((n : ℝ) - 1) ≥ n ^ 2/ 2 := by + rw [sq, mul_div_assoc] + gcongr + suffices (n : ℝ) ≥ 2 by linarith + exact_mod_cast h.two_le + grw [denom] + · apply le_of_eq + rw [← Real.rpow_natCast] + field_simp + rw [mul_div_assoc, ← Real.rpow_sub (mod_cast h.pos)] + norm_num + rw [Real.rpow_neg (Nat.cast_nonneg _)] + field + · exact div_pos (pow_pos (mod_cast h.pos) _) (by norm_num) + · apply mul_nonneg (Nat.cast_nonneg _) + suffices 1 ≤ (n : ℝ) by linarith + exact_mod_cast h.one_le + · positivity + +private lemma antitoneOn_log_div_sq : + AntitoneOn (fun t ↦ log (t + 2) / (t + 2) ^ 2) (Set.Ici 0) := by + apply antitoneOn_of_deriv_nonpos (convex_Ici 0) + · refine fun t ht ↦ ContinuousAt.continuousWithinAt ?_ + simp at ht + have : (t + 2) ≠ 0 := by simp; linarith + fun_prop (disch := grind) + · refine fun t ht ↦ DifferentiableAt.differentiableWithinAt ?_ + simp at ht + have : (t + 2) ^ 2 ≠ 0 := by simp; grind + fun_prop (disch := grind) + · intro t ht + simp at ht + rw [deriv_fun_div (by fun_prop (disch := grind)) (by fun_prop) (by simp; grind), deriv_comp_add_const, deriv_log] + simp + field_simp + simp only [mul_zero, tsub_le_iff_right, zero_add] + rw [← log_rpow (by linarith), ← log_exp 1, rpow_ofNat] + gcongr + nlinarith [exp_one_lt_three] + +private lemma log_div_sq_nonneg : + ∀ t ∈ Set.Ioi 0, 0 ≤ log (t + 2) / (t + 2) ^ 2 := by + exact fun t ht ↦ div_nonneg (log_nonneg (by simp_all; linarith)) (by positivity) + +private lemma log_div_sq_is_deriv : + ∀ x ∈ Set.Ici 0, HasDerivAt (fun t ↦ (-log (t + 2) - 1) / (t + 2)) (log (x + 2) / (x + 2) ^ 2) x := by + intro t ht + simp at ht + apply HasDerivAt.comp_add_const (f := (fun t ↦ (-log t - 1)/ t)) t 2 + convert! HasDerivAt.fun_div (c' := -1 / (t + 2)) (d' := (1 : ℝ)) _ _ _ using 1 + · field + · apply HasDerivAt.sub_const + convert! (hasDerivAt_log (by linarith : t + 2 ≠ 0)).neg using 1 + ring_nf + · exact hasDerivAt_id _ + · linarith + +private lemma tendsto_antideriv_log_div_sq : + Tendsto (fun t ↦ (-log (t + 2) - 1) / (t + 2)) atTop (nhds 0) := by + have : Tendsto (fun (t : ℝ) ↦ t + 2) atTop atTop := by exact tendsto_atTop_add_const_right atTop 2 tendsto_id + apply Tendsto.comp (g := (fun t ↦ (-log t - 1) / t)) _ this + convert! Tendsto.sub (f := (fun t ↦ -log t / t)) (a := 0) _ tendsto_inv_atTop_zero using 1 + · ring_nf + · ring_nf + · convert! (Real.tendsto_pow_log_div_mul_add_atTop 1 0 1 (by linarith)).neg using 1 + · ext; ring + · simp + +private lemma integrableOn_log_div_sq : + MeasureTheory.IntegrableOn (fun t ↦ log (t + 2) / (t + 2) ^ 2) (Set.Ioi 0) := by + exact MeasureTheory.integrableOn_Ioi_deriv_of_nonneg' log_div_sq_is_deriv log_div_sq_nonneg tendsto_antideriv_log_div_sq + +private lemma integral_log_div_sq : + ∫ t in Set.Ioi 0, log (t + 2) / (t + 2) ^ 2 = (log 2 + 1) / 2 := by + rw [MeasureTheory.integral_Ioi_of_hasDerivAt_of_nonneg' log_div_sq_is_deriv log_div_sq_nonneg tendsto_antideriv_log_div_sq] + ring_nf + +private lemma summable_log_div_sq : + Summable (fun (n : ℕ)↦ log (n + 3) / (n + 3) ^ 2) := by + let g : ℝ → ℝ := (fun n ↦ log (n + 2) / (n + 2) ^ 2) + suffices Summable (fun (n : ℕ) ↦ g n ) by + convert! summable_nat_add_iff 1|>.mpr this using 2 + unfold g + push_cast + ring_nf + exact antitoneOn_log_div_sq.summable_of_integrableOn_Ioi_zero integrableOn_log_div_sq log_div_sq_nonneg + +private lemma sum_log_div_sq_le : + ∑' (n : ℕ), log (n + 3) / (n + 3) ^2 ≤ (log 2 + 1) / 2 := by + let g : ℝ → ℝ := (fun n ↦ log (n + 2) / (n + 2) ^ 2) + calc + _ = ∑' (n : ℕ), g (n + 1 : ℕ):= by + unfold g + congr + push_cast + ring_nf + _ ≤ ∫ x in Set.Ioi 0, g x := by + exact antitoneOn_log_div_sq.tsum_add_one_le_integral integrableOn_log_div_sq log_div_sq_nonneg + _ = _ := by + exact integral_log_div_sq + +theorem E₁.le : E₁ ≤ (5 * log 2 + 3) / 4 := by + unfold E₁ + calc + _ = log 2 / 2 + ∑' (n : ℕ), if (n + 3).Prime then log (n + 3) / ((n + 3) * (n + 2)) else 0 := by + rw [← E₁.summable.sum_add_tsum_nat_add 3, (by rfl : range 3 = {0, 1, 2})] + simp [Nat.prime_two] + ring_nf + _ ≤ log 2 / 2 + ∑' (n : ℕ), (3 / 2) * (log (n + 3) / (n + 3) ^ 2) := by + gcongr with n + · convert! summable_nat_add_iff 3|>.mpr E₁.summable using 4 + · norm_cast + · push_cast; ring + · exact summable_log_div_sq.mul_left _ + · split_ifs with h + · grw [(by linarith : (n + 2 : ℝ) ≥ 2 * (n + 3) / 3)] + · field_simp + rfl + · exact log_nonneg (by grind) + · exact mul_nonneg (by norm_num) (div_nonneg (log_nonneg (by grind)) (by positivity)) + _ = log 2 / 2 + (3 / 2) * ∑' (n : ℕ), log (n + 3) / (n + 3) ^ 2 := by + rw [tsum_mul_left] + _ ≤ _ := by + grw [sum_log_div_sq_le] + ring_nf + rfl + +theorem E₁.nonneg : E₁ ≥ 0 := + tsum_nonneg E₁.summand_nonneg + +theorem E₁Λ.le_E₁p_add_E₁ {x : ℝ} (hx : 1 ≤ x) : + E₁Λ x ≤ E₁p x + E₁ := by + unfold E₁Λ E₁p + suffices ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d / d ≤ ∑ p ∈ Ioc 0 ⌊x⌋₊ with Nat.Prime p, log p / p + E₁ by linarith + simp_rw [vonMangoldt_apply, ite_div, zero_div, ← sum_filter, Chebyshev.sum_PrimePow_eq_sum_sum _ (by linarith)] + calc + _ = ∑ k ∈ Icc 1 ⌊log x / log 2⌋₊, ∑ p ∈ Ioc 0 ⌊x ^ (1 / (k : ℝ))⌋₊ with Nat.Prime p, log p / (p ^ k : ℕ) := by + refine sum_congr rfl fun k hk ↦ sum_congr rfl fun p hp ↦ ?_ + rw [Nat.Prime.pow_minFac (by simp_all) (by simp_all; linarith)] + _ ≤ ∑ k ∈ Icc 1 ⌊log x / log 2⌋₊, ∑ p ∈ Ioc 0 ⌊x⌋₊ with Nat.Prime p, log p / (p ^ k : ℕ) := by + gcongr with k hk + apply rpow_le_self_of_one_le hx + simp only [mem_Icc] at hk + exact div_le_one₀ (by norm_cast; linarith)|>.mpr (mod_cast hk.1) + _ ≤ ∑ k ∈ Icc 1 (max 1 ⌊log x / log 2⌋₊), ∑ p ∈ Ioc 0 ⌊x⌋₊ with Nat.Prime p, log p / (p ^ k : ℕ) := by + apply sum_le_sum_of_subset_of_nonneg + · gcongr + exact le_max_right .. + · exact fun _ _ _ ↦ sum_nonneg fun _ _ ↦ (by positivity) + _ = ∑ p ∈ Ioc 0 ⌊x⌋₊ with Nat.Prime p, (log p / p) + ∑ k ∈ Ioc 1 (max 1 ⌊log x / log 2⌋₊), ∑ p ∈ Ioc 0 ⌊x⌋₊ with Nat.Prime p, log p / (p ^ k : ℕ) := by + rw [← add_sum_Ioc_eq_sum_Icc (le_max_left ..)] + simp + _ ≤ _ := by + gcongr + rw [sum_comm] + conv => lhs; arg 2; ext p; arg 2; ext k; rw [← mul_one_div, Nat.cast_pow, ← one_div_pow] + simp_rw [← mul_sum] + calc + _ ≤ ∑ p ∈ Ioc 0 ⌊x⌋₊ with Nat.Prime p, log p / (p * (p - 1)) := by + gcongr with p hp + simp only [mem_filter, mem_Ioc] at hp + conv => rhs; rw [← mul_one_div] + gcongr + rw [(by rfl : Ioc 1 (max 1 ⌊log x / log 2⌋₊) = Ico 2 (max 1 ⌊log x / log 2⌋₊ + 1))] + grw [geom_sum_Ico_le_of_lt_one (by simp)] + · apply le_of_eq + have : (p : ℝ) ≠ 0 := by exact_mod_cast hp.1.1.ne.symm + field + · simpa using inv_lt_one_of_one_lt₀ (mod_cast hp.2.one_lt) + _ ≤ _ := by + rw [sum_filter] + exact E₁.summable.sum_le_tsum _ fun p hp ↦ E₁.summand_nonneg p + +theorem E₁p.ge {x : ℝ} (hx : 1 ≤ x) : + E₁p x ≥ -2 - E₁ := by + linarith [E₁Λ.le_E₁p_add_E₁ hx, E₁Λ.ge hx] + +theorem sum_log_prime_div_eq_log {x : ℝ} (hx : 1 ≤ x) : + |∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (log p) / p - log x| ≤ log 4 + 4 := by + rw [abs_le'] + refine ⟨ E₁p.le hx, ?_ ⟩ + have : log 2 > 0 := by apply log_pos; norm_num + have : log 4 = 2 * log 2 := by rw [←Real.log_rpow (by norm_num)]; norm_num + grind [E₁p.ge hx, E₁.le] + +theorem E₁p.bounded : ∃ c > 0, ∀ x ≥ 1, |E₁p x| ≤ c := by + exact ⟨log 4 + 4, (by positivity), fun _ hx ↦ sum_log_prime_div_eq_log hx⟩ + +theorem sum_log_prime_div_eq_log' : E₁p =O[atTop] (fun _ ↦ (1:ℝ)) := by + simp only [isBigO_iff, norm_eq_abs, one_mem, CStarRing.norm_of_mem_unitary, mul_one, + eventually_atTop, E₁p] + exact ⟨ log 4 + 4, 1, fun _ ↦ sum_log_prime_div_eq_log ⟩ + +theorem sum_log_prime_div_eq_log'' : (fun x ↦ ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (log p) / p) ~[atTop] (fun x ↦ log x) := by + apply IsLittleO.isEquivalent (IsBigO.trans_isLittleO _ one_eq_o_log) + convert! sum_log_prime_div_eq_log' using 1 + +noncomputable abbrev γ : ℝ := (∫ t in Set.Ioi 2, E₁Λ t / (t * log t^2)) + 1 - log (log 2) + +noncomputable abbrev E₂Λ (x : ℝ) : ℝ := ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d) - log (log x) - γ + +lemma sum_Ioc_one_eq_sum_Icc_zero {f : ℕ → ℝ} {x : ℕ} (hx : 1 ≤ x) (hf1 : f 1 = 0) (hf0 : f 0 = 0) : + ∑ n ∈ Ioc 1 x, f n = ∑ n ∈ Icc 0 x, f n := by + rw [sum_Ioc_one_eq_sum_Ioc_zero hx hf1, ← add_sum_Ioc_eq_sum_Icc (by linarith)] + simpa + +private theorem sum_div_log_eq {x : ℝ} (hx : 2 ≤ x) (f : ℕ → ℝ) : + ∑ n ∈ Ioc 1 ⌊ x ⌋₊, f n / log n = + (∑ n ∈ Ioc 1 ⌊ x ⌋₊, f n) / log x + ∫ t in 2..x, (∑ n ∈ Ioc 1 ⌊ t ⌋₊, f n) / (t * log t^2) := by + let g : ℕ → ℝ := (fun n ↦ if n < 2 then 0 else f n) + trans ∑ n ∈ Icc 0 ⌊ x ⌋₊, (log n)⁻¹ * g n + · rw [← sum_Ioc_one_eq_sum_Icc_zero (Nat.le_floor (by grind)) (by simp) (by simp)] + refine sum_congr rfl fun n hn ↦ ?_ + have : ¬(n ≤ 1) := by simp_all + simp [g, this] + field + rw [sum_mul_eq_sub_integral_mul₁ g (f := (fun n ↦ (log n)⁻¹)) (by simp [g]) (by simp [g])] + · rw [intervalIntegral.integral_of_le hx, mul_comm, ← div_eq_mul_inv, ← sub_neg_eq_add] + simp_rw [deriv_inv_log] + congr 1 + · rw [← sum_Ioc_one_eq_sum_Icc_zero (Nat.le_floor (by grind)) (by simp [g]) (by simp [g])] + congr 1 + refine sum_congr rfl fun n hn ↦ ?_ + simp only [mem_Ioc] at hn + have : ¬(n ≤ 1) := by linarith + simp [g, this] + · rw [← MeasureTheory.integral_neg] + refine MeasureTheory.setIntegral_congr_fun (by measurability) fun t ht ↦ ?_ + simp only [Set.mem_Ioc] at ht + rw [← sum_Ioc_one_eq_sum_Icc_zero (Nat.le_floor (by grind)) (by simp [g]) (by simp [g])] + field_simp + congr 2 + refine sum_congr rfl fun n hn ↦ ?_ + simp only [mem_Ioc] at hn + have : ¬(n ≤ 1) := by linarith + simp [g, this] + · intro t ht + simp only [Set.mem_Icc] at ht + have : log t ≠ 0 := by simp; grind + fun_prop (disch := grind) + · refine ContinuousOn.integrableOn_Icc fun t ht ↦ ContinuousAt.continuousWithinAt ?_ + simp only [Set.mem_Icc] at ht + conv => arg 1; ext x; rw [deriv_inv_log] + have : log t ^2 ≠ 0 := by simp; grind + fun_prop (disch := grind) + +private theorem integrable_const_div_mul_log_sq {x : ℝ} (c : ℝ) (hx : 2 ≤ x) : + MeasureTheory.IntegrableOn (fun x ↦ c / (x * log x ^ 2)) (Set.Ioi x) MeasureTheory.volume := by + conv => arg 1; ext t; rw [← mul_one_div] + apply MeasureTheory.Integrable.const_mul + refine MeasureTheory.integrableOn_Ioi_deriv_of_nonneg' ?_ ?_ tendsto_log_atTop.inv_tendsto_atTop.neg + · intro t ht + simp only [Set.mem_Ici] at ht + have : log t ≠ 0 := by simp; grind + have : DifferentiableAt ℝ (fun t ↦ -(log t)⁻¹) t := by + fun_prop (disch := grind) + convert! this.hasDerivAt using 1 + simp [deriv_inv_log] + field + · intro t ht + simp only [Set.mem_Ioi] at ht + exact one_div_nonneg.mpr <| mul_nonneg (by linarith) (sq_nonneg _) + +attribute [fun_prop] measurable_from_top + +private theorem integrable_E₁Λ_div_mul_log_sq {x : ℝ} (hx : 2 ≤ x) : + MeasureTheory.IntegrableOn (fun x ↦ E₁Λ x / (x * log x ^ 2)) (Set.Ioi x) MeasureTheory.volume := by + obtain ⟨c, hc1, hc2⟩ := E₁Λ.bounded' + apply MeasureTheory.Integrable.mono (integrable_const_div_mul_log_sq c hx) + · exact Measurable.aestronglyMeasurable (by fun_prop) + · filter_upwards [MeasureTheory.ae_restrict_mem (by measurability)] with t ht + simp only [Set.mem_Ioi] at ht + simp only [norm_div, norm_eq_abs, norm_mul, norm_pow, sq_abs, abs_of_pos hc1] + gcongr + exact hc2 t (by linarith) + +private theorem integrable_E₁p_div_mul_log_sq {x : ℝ} (hx : 2 ≤ x) : + MeasureTheory.IntegrableOn (fun x ↦ E₁p x / (x * log x ^ 2)) (Set.Ioi x) MeasureTheory.volume := by + obtain ⟨c, hc1, hc2⟩ := E₁p.bounded + apply MeasureTheory.Integrable.mono (integrable_const_div_mul_log_sq c hx) + · exact Measurable.aestronglyMeasurable (by fun_prop) + · filter_upwards [MeasureTheory.ae_restrict_mem (by measurability)] with t ht + simp only [Set.mem_Ioi] at ht + simp only [norm_div, norm_eq_abs, norm_mul, norm_pow, sq_abs, abs_of_pos hc1] + gcongr + exact hc2 t (by linarith) + +lemma deriv_log_log {x : ℝ} (hx : 1 < x) : + deriv (fun t ↦ log (log t)) x = 1 / (x * log x) := by + rw [deriv.log (differentiableAt_log (by linarith)) (by simp; grind), deriv_log] + field + +lemma integral_one_div_mul_log {x : ℝ} (hx : 2 ≤ x) : + ∫ t in 2..x, 1 / (t * log t) = log (log x) - log (log 2) := by + rw [← intervalIntegral.integral_deriv_eq_sub (f := fun t ↦ log (log t))] + · refine intervalIntegral.integral_congr fun t ht ↦ ?_ + rw [deriv_log_log] + rw [Set.uIcc_of_le hx, Set.mem_Icc] at ht + linarith + · intro t ht + rw [Set.uIcc_of_le hx, Set.mem_Icc] at ht + have : log t ≠ 0 := by simp; grind + fun_prop (disch := grind) + · refine ContinuousOn.intervalIntegrable ?_ + apply ContinuousOn.congr (f := (fun t ↦ 1 / (t * log t))) + · refine fun t ht ↦ ContinuousAt.continuousWithinAt ?_ + rw [Set.uIcc_of_le hx, Set.mem_Icc] at ht + have : log t ≠ 0 := by simp; grind + fun_prop (disch := grind) + · intro t ht + rw [Set.uIcc_of_le hx, Set.mem_Icc] at ht + exact deriv_log_log (by linarith) + +lemma intervalIntegrable_one_div_mul_log {x : ℝ} (hx : 2 ≤ x) : + IntervalIntegrable (fun t ↦ 1 / (t * log t)) MeasureTheory.volume 2 x := by + refine ContinuousOn.intervalIntegrable fun t ht ↦ ContinuousAt.continuousWithinAt ?_ + rw [Set.uIcc_of_le hx, Set.mem_Icc] at ht + have : log t ≠ 0 := by simp; grind + fun_prop (disch := grind) + +theorem E₂Λ.eq {x : ℝ} (hx : 2 ≤ x) : + E₂Λ x = E₁Λ x / log x - ∫ t in Set.Ioi x, E₁Λ t / (t * log t^2) := by + unfold E₂Λ + rw [← sum_Ioc_one_eq_sum_Ioc_zero (Nat.le_floor (by grind)) (by simp)] + conv => lhs; arg 1; arg 1; arg 2; ext n; rw [(by field : Λ n / (n * log n) = (Λ n / n) / log n)] + rw [sum_div_log_eq hx] + rw [sum_Ioc_one_eq_sum_Ioc_zero (Nat.le_floor (by grind)) (by simp), sum_mangoldt_div_eq] + have : ∫ t in 2..x, (∑ n ∈ Ioc 1 ⌊t⌋₊, Λ n / n) / (t * log t ^ 2) = ∫ t in 2..x, (1 / (t * log t) + E₁Λ t / (t * log t ^ 2)) := by + refine intervalIntegral.integral_congr fun t ht ↦ ?_ + rw [Set.uIcc_of_le hx, Set.mem_Icc] at ht + rw [sum_Ioc_one_eq_sum_Ioc_zero (Nat.le_floor (by grind)) (by simp), sum_mangoldt_div_eq] + field + rw [this, intervalIntegral.integral_add] + · rw [integral_one_div_mul_log hx, add_div, div_self (by simp; grind)] + unfold γ + calc + _ = E₁Λ x / log x + (∫ (x : ℝ) in 2..x, E₁Λ x / (x * log x ^ 2)) - + ((∫ (t : ℝ) in Set.Ioi 2, E₁Λ t / (t * log t ^ 2))) := by ring + _ = _ := by + rw [← intervalIntegral.integral_interval_add_Ioi (integrable_E₁Λ_div_mul_log_sq (by rfl)) (integrable_E₁Λ_div_mul_log_sq hx)] + ring + · exact intervalIntegrable_one_div_mul_log hx + · rw [intervalIntegrable_iff, Set.uIoc_of_le hx] + exact integrable_E₁Λ_div_mul_log_sq (x := 2) (by rfl)|>.mono (by grind) (by rfl) + +private theorem integ_div_mul_log_sq {x : ℝ} (c : ℝ) (hx : 2 ≤ x) : + ∫ t in Set.Ioi x, c / (t * log t^2) = c / log x := by + convert! MeasureTheory.integral_Ioi_of_hasDerivAt_of_tendsto' (m := 0) (f := fun x ↦ - c / log x) ?_ + (integrable_const_div_mul_log_sq c hx) ?_ using 1 + · grind + · intro t ht; simp at ht + convert! HasDerivAt.fun_div (hasDerivAt_const _ (-c)) (hasDerivAt_log (by linarith)) ?_ using 1 + · grind + simp; grind + convert! tendsto_log_atTop.inv_tendsto_atTop.const_mul (-c) using 1 + simp + +theorem E₂Λ.abs_le {x : ℝ} (hx : 2 ≤ x) : + |E₂Λ x| ≤ (log 4 + 6) / log x := by + have : 0 < log x := by apply log_pos; linarith + rw [E₂Λ.eq hx, abs_le'] + constructor + · grw [E₁Λ.le (by linarith)] + have : ∫ t in Set.Ioi x, E₁Λ t / (t * log t^2) ≥ - 2 / log x := calc + _ ≥ ∫ t in Set.Ioi x, (-2) / (t * log t^2) := by + apply MeasureTheory.setIntegral_mono_on (integrable_const_div_mul_log_sq (-2) hx) + (integrable_E₁Λ_div_mul_log_sq hx) (by measurability) + intro y hy; simp at hy + have : 1 < y := by linarith + have : 0 < log y := log_pos this + gcongr; exact E₁Λ.ge (by linarith) + _ = _ := integ_div_mul_log_sq (-2) hx + grw [this] + grind + grw [E₁Λ.ge (by linarith)] + have : ∫ t in Set.Ioi x, E₁Λ t / (t * log t^2) ≤ (log 4 + 4) / log x := calc + _ ≤ ∫ t in Set.Ioi x, (log 4 + 4) / (t * log t^2) := by + apply MeasureTheory.setIntegral_mono_on (integrable_E₁Λ_div_mul_log_sq hx) + (integrable_const_div_mul_log_sq (log 4 + 4) hx) (by measurability) + intro y hy; simp at hy + have : 1 < y := by linarith + have : 0 < log y := log_pos this + gcongr; exact E₁Λ.le (by linarith) + _ = _ := integ_div_mul_log_sq (log 4 + 4) hx + grw [this] + grind + +theorem E₂Λ.bound : E₂Λ =O[atTop] (fun x ↦ 1 / log x) := by + simp only [one_div, isBigO_iff, norm_eq_abs, norm_inv, eventually_atTop] + use log 4 + 6, 2 + intro x hx + convert E₂Λ.abs_le hx using 1 + have : 0 < log x := by apply log_pos; linarith + grind [abs_of_pos this] + +theorem E₂Λ.bound' : E₂Λ =o[atTop] (fun _ ↦ (1:ℝ)) := E₂Λ.bound.trans_isLittleO inv_log_eq_o_one + +theorem log_zeta_eq_sum (s : ℝ) (hs : 1 < s) : + log (riemannZeta (s:ℂ)).re = ∑' n, Λ n / (n^s * log n) := by + have hsc : (1 : ℝ) < ((s : ℂ)).re := by simpa using hs + + have hep := riemannZeta_eulerProduct_exp_log (s := (s : ℂ)) hsc + set S : ℂ := ∑' p : Nat.Primes, -Complex.log (1 - (p : ℂ) ^ (-(s : ℂ))) with hS + + have hcpow : ∀ p : Nat.Primes, (p : ℂ) ^ (-(s : ℂ)) = (((p : ℝ) ^ (-s) : ℝ) : ℂ) := by + intro p + rw [Complex.ofReal_cpow (by positivity)] + push_cast; ring_nf + + set z : Nat.Primes → ℝ := fun p => (p : ℝ) ^ (-s) with hz + + have hz_pos : ∀ p : Nat.Primes, 0 < z p := fun p => by + have : (0 : ℝ) < (p : ℝ) := by exact_mod_cast p.prop.pos + positivity + have hz_lt_one : ∀ p : Nat.Primes, z p < 1 := by + intro p + have hp1 : (1 : ℝ) < (p : ℝ) := by exact_mod_cast p.prop.one_lt + change (p : ℝ) ^ (-s) < 1 + rw [Real.rpow_neg (by positivity), inv_lt_one_iff₀] + right + exact (Real.one_lt_rpow_iff_of_pos (by positivity)).mpr (Or.inl ⟨hp1, by linarith⟩) + + have hterm : ∀ p : Nat.Primes, + -Complex.log (1 - (p : ℂ) ^ (-(s : ℂ))) = ((-Real.log (1 - z p) : ℝ) : ℂ) := by + intro p + rw [hcpow p] + have h1z : (0 : ℝ) < 1 - z p := by have := hz_lt_one p; linarith + rw [show (1 : ℂ) - ((z p : ℝ) : ℂ) = (((1 - z p : ℝ)) : ℂ) by push_cast; ring] + rw [← Complex.ofReal_log h1z.le] + push_cast; ring + + set Sr : ℝ := ∑' p : Nat.Primes, -Real.log (1 - z p) with hSr + have hSeq : S = (Sr : ℂ) := by + rw [hS, hSr, Complex.ofReal_tsum] + exact tsum_congr hterm + have hSim : S.im = 0 := by rw [hSeq]; exact Complex.ofReal_im _ + have hSre : S.re = Sr := by rw [hSeq]; exact Complex.ofReal_re _ + + have hlog_zeta : Complex.log (riemannZeta (s : ℂ)) = S := by + rw [← hep, Complex.log_exp (by rw [hSim]; exact neg_lt_zero.mpr Real.pi_pos) + (by rw [hSim]; exact Real.pi_pos.le)] + + have hkey : Real.log (riemannZeta (s : ℂ)).re = Sr := by + have hζim : (riemannZeta (s : ℂ)).im = 0 := riemannZeta_im_eq_zero_of_one_lt hs + have hζeq : riemannZeta (s : ℂ) = ((riemannZeta (s : ℂ)).re : ℂ) := by + apply Complex.ext <;> simp [hζim] + have : Real.log (riemannZeta (s : ℂ)).re + = (Complex.log (riemannZeta (s : ℂ))).re := by + conv_rhs => rw [hζeq] + rw [Complex.log_ofReal_re] + rw [this, hlog_zeta, hSre] + rw [hkey] + + have habs : ∀ p : Nat.Primes, |z p| < 1 := by + intro p + rw [abs_of_pos (hz_pos p)]; exact hz_lt_one p + have htaylor : ∀ p : Nat.Primes, + HasSum (fun n : ℕ => (z p) ^ (n + 1) / (n + 1)) (-Real.log (1 - z p)) := + fun p => hasSum_pow_div_log_of_abs_lt_one (habs p) + have hSr_double : Sr = ∑' (p : Nat.Primes) (n : ℕ), (z p) ^ (n + 1) / (n + 1) := by + rw [hSr] + exact tsum_congr fun p => ((htaylor p).tsum_eq).symm + + have hsummable_z : Summable z := Nat.Primes.summable_rpow.mpr (by linarith) + + have hsummable_prime : Summable (fun p : Nat.Primes => -Real.log (1 - z p)) := by + have := Real.summable_log_one_add_of_summable hsummable_z.neg + convert! this.neg using 1 + + have hg_nonneg : ∀ pk : Nat.Primes × ℕ, 0 ≤ (z pk.1) ^ (pk.2 + 1) / (pk.2 + 1) := by + intro pk; positivity [hz_pos pk.1] + have hsummable_g : Summable (fun pk : Nat.Primes × ℕ => (z pk.1) ^ (pk.2 + 1) / (pk.2 + 1)) := by + rw [summable_prod_of_nonneg hg_nonneg] + refine ⟨fun p => (htaylor p).summable, ?_⟩ + refine hsummable_prime.congr (fun p => ?_) + exact ((htaylor p).tsum_eq).symm + + have hpoint : ∀ (p : Nat.Primes) (n : ℕ), + Λ ((p : ℕ) ^ (n + 1)) / + ((((p : ℕ) ^ (n + 1) : ℕ) : ℝ) ^ s * Real.log (((p : ℕ) ^ (n + 1) : ℕ) : ℝ)) + = (z p) ^ (n + 1) / (n + 1) := by + intro p n + have hp1 : (1 : ℝ) < (p : ℝ) := by exact_mod_cast p.prop.one_lt + have hlogp : 0 < Real.log (p : ℝ) := Real.log_pos hp1 + rw [vonMangoldt_apply_pow (Nat.succ_ne_zero n), vonMangoldt_apply_prime p.prop] + have hcast : (((p : ℕ) ^ (n + 1) : ℕ) : ℝ) = (p : ℝ) ^ (n + 1) := by push_cast; ring + rw [hcast, Real.log_pow] + rw [show (z p) ^ (n + 1) = ((p : ℝ) ^ (n + 1)) ^ (-s) by + rw [hz]; rw [← Real.rpow_natCast ((p : ℝ) ^ (-s)) (n + 1), + ← Real.rpow_natCast ((p : ℝ)) (n + 1), ← Real.rpow_mul (by positivity), + ← Real.rpow_mul (by positivity)]; ring_nf] + rw [Real.rpow_neg (by positivity)] + field_simp + push_cast + ring + + set F : ℕ → ℝ := fun n => Λ n / ((n : ℝ) ^ s * Real.log n) with hF + + have hsupp : Function.support F ⊆ {n : ℕ | IsPrimePow n} := by + intro n hn + rw [Function.mem_support] at hn + simp only [Set.mem_ofPred_eq] + by_contra hpp + apply hn + simp only [hF, vonMangoldt_eq_zero_iff.mpr hpp, zero_div] + + have hprod_eq : (∑' pk : Nat.Primes × ℕ, (z pk.1) ^ (pk.2 + 1) / (pk.2 + 1)) + = ∑' m : {n : ℕ // IsPrimePow n}, F m.val := by + rw [← Equiv.tsum_eq Nat.Primes.prodNatEquiv (fun m : {n : ℕ // IsPrimePow n} => F m.val)] + apply tsum_congr + intro pk + rw [Nat.Primes.coe_prodNatEquiv_apply, hF] + exact (hpoint pk.1 pk.2).symm + + rw [hSr_double, ← hsummable_g.tsum_prod' (fun p => (htaylor p).summable), hprod_eq] + exact tsum_subtype_eq_of_support_subset hsupp + +section +open MeasureTheory Set + +namespace LogZetaInteg + +private noncomputable def c (d : ℕ) : ℝ := Λ d / (d * Real.log d) + +private noncomputable def f (s : ℝ) (d : ℕ) (x : ℝ) : ℝ := + c d * (Set.Ici (d:ℝ)).indicator (fun x => x ^ (-s)) x + +@[simp] private lemma c_zero : c 0 = 0 := by simp [c] +@[simp] private lemma c_one : c 1 = 0 := by simp [c, vonMangoldt_apply_one] + +private lemma c_nonneg (d : ℕ) : 0 ≤ c d := by + unfold c + rcases Nat.eq_zero_or_pos d with hd | hd + · subst hd; simp + · apply div_nonneg vonMangoldt_nonneg + have : (0:ℝ) ≤ (d:ℝ) := Nat.cast_nonneg d + have hlog : 0 ≤ Real.log d := Real.log_natCast_nonneg d + positivity + +private lemma summable_log_rpow_div_rpow (a : ℝ) {s : ℝ} (hs : 1 < s) : + Summable (fun n : ℕ => (Real.log n) ^ a / (n:ℝ) ^ s) := by + have hε : (0:ℝ) < (s - 1) / 2 := by linarith + refine summable_of_isBigO_nat (g := fun n : ℕ => (n:ℝ) ^ ((s - 1) / 2 - s)) ?_ ?_ + · rw [Real.summable_nat_rpow]; linarith + · have ho : (fun x : ℝ => (Real.log x) ^ a) =O[atTop] (fun x : ℝ => x ^ ((s - 1) / 2)) := + (isLittleO_log_rpow_rpow_atTop a hε).isBigO + have hmul : (fun x : ℝ => (Real.log x) ^ a / x ^ s) + =O[atTop] (fun x : ℝ => x ^ ((s - 1) / 2) / x ^ s) := by + simpa only [div_eq_mul_inv] using ho.mul (isBigO_refl (fun x : ℝ => (x ^ s)⁻¹) atTop) + have heq : (fun x : ℝ => x ^ ((s - 1) / 2) / x ^ s) + =ᶠ[atTop] (fun x : ℝ => x ^ ((s - 1) / 2 - s)) := by + filter_upwards [eventually_gt_atTop 0] with x hx + rw [← Real.rpow_sub hx] + exact (hmul.trans_eventuallyEq heq).natCast_atTop + +private lemma summable_vonMangoldt_div_rpow (s : ℝ) (hs : 1 < s) : + Summable (fun n : ℕ => (Λ n : ℝ) / (n:ℝ) ^ s) := by + refine Summable.of_nonneg_of_le (fun n => div_nonneg vonMangoldt_nonneg (by positivity)) ?_ + (summable_log_rpow_div_rpow 1 hs) + intro n + rw [Real.rpow_one] + gcongr + exact vonMangoldt_le_log + +private lemma summable_c_term (s : ℝ) (hs : 1 < s) : + Summable (fun d : ℕ => c d * ((d:ℝ) ^ (1 - s) / (s - 1))) := by + have hs1 : (0:ℝ) < s - 1 := by linarith + have hlog2 : (0:ℝ) < Real.log 2 := Real.log_pos (by norm_num) + + refine Summable.of_nonneg_of_le (fun d => ?_) (fun d => ?_) + ((summable_vonMangoldt_div_rpow s hs).mul_left (1 / (Real.log 2 * (s - 1)))) + · + refine mul_nonneg (c_nonneg d) (div_nonneg ?_ hs1.le) + rcases eq_or_ne (d:ℝ) 0 with hd | hd + · rw [hd, Real.zero_rpow (by linarith : (1 - s) ≠ 0)] + · positivity + · + rcases lt_or_ge d 2 with hd | hd + · have hc : c d = 0 := by interval_cases d <;> simp + rw [hc, zero_mul] + exact mul_nonneg (by positivity) (div_nonneg vonMangoldt_nonneg (by positivity)) + · have hd2 : (2:ℝ) ≤ (d:ℝ) := by exact_mod_cast hd + have hd0 : (0:ℝ) < (d:ℝ) := by linarith + have hlogge : Real.log 2 ≤ Real.log d := Real.log_le_log (by norm_num) hd2 + have hds : (0:ℝ) < (d:ℝ) ^ s := Real.rpow_pos_of_pos hd0 s + have hkey : c d * ((d:ℝ) ^ (1 - s) / (s - 1)) = Λ d / ((d:ℝ) ^ s * Real.log d * (s - 1)) := by + unfold c + rw [show (1 - s : ℝ) = -s + 1 by ring, Real.rpow_add hd0, Real.rpow_one, Real.rpow_neg hd0.le] + field_simp + + have hcb : (d:ℝ) ^ s * Real.log 2 * (s - 1) ≤ (d:ℝ) ^ s * Real.log d * (s - 1) := + mul_le_mul_of_nonneg_right (mul_le_mul_of_nonneg_left hlogge hds.le) hs1.le + rw [hkey, show (1 / (Real.log 2 * (s - 1))) * ((Λ d : ℝ) / (d:ℝ) ^ s) + = Λ d / ((d:ℝ) ^ s * Real.log 2 * (s - 1)) from by field_simp] + exact div_le_div_of_nonneg_left vonMangoldt_nonneg (by positivity) hcb + +theorem log_zeta_eq_integ_aux (s : ℝ) (hs : 1 < s) : + Real.log (riemannZeta (s:ℂ)).re = + (s - 1) * ∫ x in Set.Ioi 1, (Real.log (Real.log x) + γ + E₂Λ x) * x ^ (-s) := by + rw [Mertens.log_zeta_eq_sum s hs] + symm + have hstep1 : ∀ x ∈ Set.Ioi (1:ℝ), + (Real.log (Real.log x) + γ + E₂Λ x) * x ^ (-s) + = (∑ d ∈ Finset.Ioc 0 ⌊x⌋₊, c d) * x ^ (-s) := by + intro x hx + simp only [Mertens.E₂Λ, c] + ring + have hstep2 : ∀ x ∈ Set.Ioi (1:ℝ), + (Real.log (Real.log x) + γ + E₂Λ x) * x ^ (-s) = ∑' d : ℕ, f s d x := by + intro x hx + rw [hstep1 x hx] + simp only [f] + rw [Finset.sum_mul] + have hx0 : (0:ℝ) ≤ x := by have := hx; simp only [Set.mem_Ioi] at this; linarith + rw [tsum_eq_sum (s := Finset.Ioc 0 ⌊x⌋₊) ?_] + · apply Finset.sum_congr rfl + intro d hd + simp only [Finset.mem_Ioc] at hd + have hdx : (d:ℝ) ≤ x := by + rw [← Nat.le_floor_iff hx0]; exact hd.2 + rw [Set.indicator_of_mem (by simpa using hdx)] + · intro d hd + simp only [Finset.mem_Ioc, not_and, not_le] at hd + rcases Nat.eq_zero_or_pos d with hd0 | hd0 + · subst hd0; simp + · have hfloor : ⌊x⌋₊ < d := hd hd0 + have hdx : x < (d:ℝ) := by + rw [← Nat.floor_lt hx0]; exact hfloor + rw [Set.indicator_of_notMem (by simpa using not_le.mpr hdx)] + ring + rw [MeasureTheory.setIntegral_congr_fun measurableSet_Ioi hstep2] + have hperterm : ∀ d : ℕ, ∫ x in Set.Ioi (1:ℝ), f s d x = c d * ((d:ℝ) ^ (1 - s) / (s - 1)) := by + intro d + rcases Nat.eq_zero_or_pos d with hd0 | hd0 + · subst hd0; simp [f] + simp only [f] + rw [MeasureTheory.integral_const_mul, MeasureTheory.setIntegral_indicator measurableSet_Ici] + congr 1 + have hdR : (1:ℝ) ≤ (d:ℝ) := by exact_mod_cast hd0 + have hdR0 : (0:ℝ) < (d:ℝ) := by exact_mod_cast hd0 + set A : Set ℝ := Set.Ioi (1:ℝ) ∩ Set.Ici (d:ℝ) with hA + have hae : A =ᵐ[volume] Set.Ioi (d:ℝ) := by + have h1 : A =ᵐ[volume] (Set.Ici (1:ℝ) ∩ Set.Ici (d:ℝ) : Set ℝ) := + MeasureTheory.ae_eq_set_inter MeasureTheory.Ioi_ae_eq_Ici (ae_eq_refl _) + rw [Set.Ici_inter_Ici, max_eq_right hdR] at h1 + exact h1.trans MeasureTheory.Ioi_ae_eq_Ici.symm + rw [MeasureTheory.setIntegral_congr_set hae] + rw [integral_Ioi_rpow_of_lt (by linarith : (-s:ℝ) < -1) hdR0, + show (-s + 1 : ℝ) = 1 - s by ring] + have hs1 : (1 - s) ≠ 0 := by linarith + have hs2 : (s - 1) ≠ 0 := by linarith + field_simp + ring + have hint : ∀ d : ℕ, MeasureTheory.IntegrableOn (f s d) (Set.Ioi (1:ℝ)) := by + intro d + unfold f + apply MeasureTheory.Integrable.const_mul + rw [show MeasureTheory.Integrable ((Set.Ici (d:ℝ)).indicator fun x => x ^ (-s)) + (volume.restrict (Set.Ioi (1:ℝ))) + ↔ MeasureTheory.IntegrableOn ((Set.Ici (d:ℝ)).indicator fun x => x ^ (-s)) + (Set.Ioi (1:ℝ)) volume from Iff.rfl, + MeasureTheory.integrableOn_indicator_iff measurableSet_Ici] + apply MeasureTheory.IntegrableOn.mono_set + (integrableOn_Ioi_rpow_of_lt (by linarith : (-s:ℝ) < -1) (by norm_num : (0:ℝ) < 1/2)) + intro x hx + simp only [Set.mem_inter_iff, Set.mem_Ici, Set.mem_Ioi] at hx ⊢ + linarith [hx.2] + have hnorm_int : ∀ d : ℕ, + ∫ x in Set.Ioi (1:ℝ), ‖f s d x‖ = c d * ((d:ℝ) ^ (1 - s) / (s - 1)) := by + intro d + rw [← hperterm d] + apply MeasureTheory.setIntegral_congr_fun measurableSet_Ioi + intro x hx + simp only [Set.mem_Ioi] at hx + have hfnn : 0 ≤ f s d x := by + simp only [f] + apply mul_nonneg (c_nonneg d) + by_cases hxd : (d:ℝ) ≤ x + · rw [Set.indicator_of_mem (by simpa using hxd)] + exact le_of_lt (Real.rpow_pos_of_pos (by linarith) _) + · rw [Set.indicator_of_notMem (by simpa using hxd)] + change ‖f s d x‖ = f s d x + rw [Real.norm_eq_abs, abs_of_nonneg hfnn] + have hinterchange : ∫ x in Set.Ioi (1:ℝ), ∑' d : ℕ, f s d x + = ∑' d : ℕ, ∫ x in Set.Ioi (1:ℝ), f s d x := by + refine (MeasureTheory.integral_tsum_of_summable_integral_norm hint ?_).symm + apply (summable_c_term s hs).congr + intro d + exact (hnorm_int d).symm + rw [hinterchange] + simp_rw [hperterm] + rw [← tsum_mul_left] + apply tsum_congr + intro d + rcases Nat.eq_zero_or_pos d with hd0 | hd0 + · subst hd0; simp + · have hdR : (0:ℝ) < (d:ℝ) := by exact_mod_cast hd0 + have hsub : (d:ℝ) ^ (1 - s) = (d:ℝ) ^ (-s) * (d:ℝ) := by + rw [show (1 - s : ℝ) = -s + 1 by ring, Real.rpow_add hdR, Real.rpow_one] + have hs1 : s - 1 ≠ 0 := by linarith + have hneg : (d:ℝ) ^ (-s) = ((d:ℝ) ^ s)⁻¹ := by + rw [Real.rpow_neg (le_of_lt hdR)] + unfold c + rw [hsub, hneg] + field_simp + +end LogZetaInteg +end + +private theorem log_zeta_eq_integ (s : ℝ) (hs : 1 < s) : + log (riemannZeta (s:ℂ)).re = (s - 1) * ∫ x in .Ioi 1, (log (log x) + γ + E₂Λ x) * x^(-s) := + LogZetaInteg.log_zeta_eq_integ_aux s hs + +private theorem mul_integ_log_log_eq (s : ℝ) (hs : 1 < s) : + (s - 1) * ∫ x in .Ioi 1, log (log x) * x^(-s) = - log (s - 1) + deriv Gamma 1 := + mul_integ_log_log_eq_aux s hs + +private theorem mul_integ_gamma_eq (s) (hs : 1 < s) : (s - 1) * ∫ x in .Ioi 1, γ * x^(-s) = γ := by + rw [MeasureTheory.integral_const_mul γ (· ^ (-s)), @integral_Ioi_rpow_of_lt (-s), one_rpow] <;> + grind + +private theorem integrableOn_Ioi_mul_rpow_neg_of_abs_le + {c B a s : ℝ} (hc : 0 < c) (has : a + 1 < s) {f : ℝ → ℝ} (hf : Measurable f) + (hbound : ∀ x ∈ Set.Ioi c, |f x| ≤ B * x ^ a) : + MeasureTheory.IntegrableOn (fun x => f x * x ^ (-s)) (Set.Ioi c) := by + have hg : MeasureTheory.IntegrableOn (fun x => B * x ^ (a - s)) (Set.Ioi c) := + (integrableOn_Ioi_rpow_of_lt (by linarith : a - s < -1) hc).const_mul B + refine MeasureTheory.Integrable.mono' hg + (hf.mul (measurable_id.pow_const (-s))).aestronglyMeasurable ?_ + filter_upwards [MeasureTheory.ae_restrict_mem measurableSet_Ioi] with x hx + have hxpos : (0:ℝ) < x := hc.trans hx + have hxs : (0:ℝ) < x ^ (-s) := Real.rpow_pos_of_pos hxpos _ + rw [norm_mul, norm_eq_abs, norm_eq_abs, abs_of_pos hxs] + calc |f x| * x ^ (-s) ≤ B * x ^ a * x ^ (-s) := + mul_le_mul_of_nonneg_right (hbound x hx) hxs.le + _ = B * x ^ (a - s) := by rw [mul_assoc, ← Real.rpow_add hxpos, sub_eq_add_neg] + +private theorem integrableOn_log_log_mul_rpow (s : ℝ) (hs : 1 < s) : + MeasureTheory.IntegrableOn (fun x => log (log x) * x ^ (-s)) (Set.Ioi 1) := by + rw [← Set.Ioc_union_Ioi_eq_Ioi (by norm_num : (1:ℝ) ≤ 2)] + apply MeasureTheory.IntegrableOn.union + · + have hll : MeasureTheory.IntegrableOn (fun x => log (log x)) (Set.Ioc 1 2) := by + have h : IntervalIntegrable (log ∘ log) MeasureTheory.volume 1 2 := by + apply MeromorphicOn.intervalIntegrable_log + intro x hx + rw [Set.uIcc_of_le (by norm_num : (1:ℝ) ≤ 2)] at hx + exact (analyticAt_log (by linarith [hx.1] : 0 < x)).meromorphicAt + exact (intervalIntegrable_iff_integrableOn_Ioc_of_le (by norm_num)).mp h + have hmul : MeasureTheory.IntegrableOn (fun x => x ^ (-s) * log (log x)) (Set.Ioc 1 2) := by + apply hll.bdd_mul (c := 1) + · fun_prop + · filter_upwards [MeasureTheory.ae_restrict_mem measurableSet_Ioc] with x hx + rw [norm_eq_abs, abs_of_nonneg (Real.rpow_nonneg (by linarith [hx.1] : (0:ℝ) ≤ x) _)] + calc x ^ (-s) ≤ (1:ℝ) ^ (-s) := + Real.rpow_le_rpow_of_nonpos (by norm_num) hx.1.le (by linarith) + _ = 1 := Real.one_rpow _ + simpa [mul_comm] using hmul + · + set ε := (s - 1) / 2 with hε + have hεpos : 0 < ε := by rw [hε]; linarith + refine integrableOn_Ioi_mul_rpow_neg_of_abs_le (a := ε) (B := 1 / ε + |log (log 2)|) + (by norm_num) (by rw [hε]; linarith) (Real.measurable_log.comp Real.measurable_log) ?_ + intro x hx + simp only [Set.mem_Ioi] at hx + have hx1 : (1:ℝ) ≤ x ^ ε := Real.one_le_rpow (by linarith) hεpos.le + have hlogx : 0 < log x := Real.log_pos (by linarith) + have hlog2 : 0 < log 2 := Real.log_pos (by norm_num) + have hmono : log 2 ≤ log x := Real.log_le_log (by norm_num) (by linarith) + have hub : log (log x) ≤ x ^ ε / ε := + calc log (log x) ≤ log x := (Real.log_le_sub_one_of_pos hlogx).trans (by linarith) + _ ≤ x ^ ε / ε := Real.log_le_rpow_div (by linarith) hεpos + have hlb : log (log 2) ≤ log (log x) := Real.log_le_log hlog2 hmono + have hxε : 0 ≤ x ^ ε / ε := by positivity + calc |log (log x)| ≤ x ^ ε / ε + |log (log 2)| := by + rw [abs_le] + exact ⟨by linarith [neg_abs_le (log (log 2))], + by linarith [abs_nonneg (log (log 2))]⟩ + _ ≤ (1 / ε + |log (log 2)|) * x ^ ε := by + have h2 : |log (log 2)| ≤ |log (log 2)| * x ^ ε := le_mul_of_one_le_right (abs_nonneg _) hx1 + have h1 : x ^ ε / ε = 1 / ε * x ^ ε := by ring + rw [add_mul]; linarith + +private theorem integrableOn_γ_mul_rpow (s : ℝ) (hs : 1 < s) : + MeasureTheory.IntegrableOn (fun x => γ * x ^ (-s)) (Set.Ioi 1) := by + exact (integrableOn_Ioi_rpow_of_lt (by linarith : -s < -1) one_pos).const_mul γ + +private theorem integrableOn_E₂Λ_mul_rpow (s : ℝ) (hs : 1 < s) : + MeasureTheory.IntegrableOn (fun x => E₂Λ x * x ^ (-s)) (Set.Ioi 1) := by + rw [← Set.Ioo_union_Ici_eq_Ioi (by norm_num : (1:ℝ) < 2)] + apply MeasureTheory.IntegrableOn.union + · + have hsub : Set.Ioo (1:ℝ) 2 ⊆ Set.Ioi 1 := fun x hx => hx.1 + have h1 := (integrableOn_γ_mul_rpow s hs).mono_set hsub + have h2 := (integrableOn_log_log_mul_rpow s hs).mono_set hsub + have hb : MeasureTheory.IntegrableOn + (fun x => -(log (log x) * x ^ (-s)) - γ * x ^ (-s)) (Set.Ioo 1 2) := + h2.neg.sub h1 + apply hb.congr_fun _ measurableSet_Ioo + intro x hx + simp only [Set.mem_Ioo] at hx + have hfloor : ⌊ x ⌋₊ = 1 := by + rw [Nat.floor_eq_iff (by linarith)] + exact ⟨by push_cast; linarith [hx.1], by push_cast; linarith [hx.2]⟩ + have hsum : (∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / ((d:ℝ) * log d)) = 0 := by rw [hfloor]; norm_num + change -(log (log x) * x ^ (-s)) - γ * x ^ (-s) + = (∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d) - log (log x) - γ) * x ^ (-s) + rw [hsum]; ring + · + rw [integrableOn_Ici_iff_integrableOn_Ioi] + refine integrableOn_Ioi_mul_rpow_neg_of_abs_le (a := 0) (B := (log 4 + 6) / log 2) + (by norm_num) (by linarith) (by fun_prop) ?_ + intro x hx + simp only [Set.mem_Ioi] at hx + have hlog2 : 0 < log 2 := Real.log_pos (by norm_num) + have hc : 0 ≤ log 4 + 6 := by positivity + rw [Real.rpow_zero, mul_one] + have hb2 : (log 4 + 6) / log x ≤ (log 4 + 6) / log 2 := + div_le_div_of_nonneg_left hc hlog2 (Real.log_le_log (by norm_num) (le_of_lt hx)) + exact (E₂Λ.abs_le (le_of_lt hx)).trans hb2 + +private theorem log_zeta_eq (s : ℝ) (hs : 1 < s) : + log (riemannZeta (s:ℂ)).re = - log (s - 1) + deriv Gamma 1 + γ + (s - 1) * ∫ x in Set.Ioi 1, E₂Λ x * x^(-s) := by + + rw [log_zeta_eq_integ s hs] + + have key : (∫ x in Set.Ioi 1, (log (log x) + γ + E₂Λ x) * x ^ (-s)) + = (∫ x in Set.Ioi 1, log (log x) * x ^ (-s)) + + (∫ x in Set.Ioi 1, γ * x ^ (-s)) + + (∫ x in Set.Ioi 1, E₂Λ x * x ^ (-s)) := by + rw [← MeasureTheory.integral_add (integrableOn_log_log_mul_rpow s hs) + (integrableOn_γ_mul_rpow s hs)] + rw [← MeasureTheory.integral_add (f := fun x => log (log x) * x ^ (-s) + γ * x ^ (-s)) + (g := fun x => E₂Λ x * x ^ (-s)) + ((integrableOn_log_log_mul_rpow s hs).add (integrableOn_γ_mul_rpow s hs)) + (integrableOn_E₂Λ_mul_rpow s hs)] + apply MeasureTheory.setIntegral_congr_fun measurableSet_Ioi + intro x _ + ring + + rw [key, mul_add, mul_add, mul_integ_log_log_eq s hs, mul_integ_gamma_eq s hs] + +private lemma zeta_pole_mul_re_tendsto_one : + Filter.Tendsto (fun s : ℝ => (s - 1) * (riemannZeta (s : ℂ)).re) + (nhdsWithin 1 (Set.Ioi 1)) (nhds 1) := by + have hofReal : + Filter.Tendsto (fun s : ℝ => (s : ℂ)) (nhdsWithin 1 (Set.Ioi 1)) + (nhdsWithin (1 : ℂ) ({1} : Set ℂ)ᶜ) := by + refine tendsto_nhdsWithin_of_tendsto_nhds_of_eventually_within _ ?_ ?_ + · exact (Complex.continuous_ofReal.tendsto 1).mono_left nhdsWithin_le_nhds + · filter_upwards [self_mem_nhdsWithin] with s hs + exact Set.mem_compl_singleton_iff.mpr (by + norm_num + exact ne_of_gt (Set.mem_Ioi.mp hs)) + have hcomplex : + Filter.Tendsto (fun s : ℝ => ((s : ℂ) - 1) * riemannZeta (s : ℂ)) + (nhdsWithin 1 (Set.Ioi 1)) (nhds 1) := + riemannZeta_residue_one.comp hofReal + have hreal : + Filter.Tendsto + (fun s : ℝ => (((s : ℂ) - 1) * riemannZeta (s : ℂ)).re) + (nhdsWithin 1 (Set.Ioi 1)) (nhds (1 : ℝ)) := + (Complex.continuous_re.tendsto (1 : ℂ)).comp hcomplex + simpa [Complex.ofReal_sub, Complex.ofReal_mul] using hreal + +private theorem log_zeta_limit : + Filter.Tendsto + (fun s : ℝ => Real.log (riemannZeta (s : ℂ)).re + Real.log (s - 1)) + (nhdsWithin 1 (Set.Ioi 1)) (nhds 0) := by + have hlog : + Filter.Tendsto + (fun s : ℝ => Real.log ((s - 1) * (riemannZeta (s : ℂ)).re)) + (nhdsWithin 1 (Set.Ioi 1)) (nhds (Real.log 1)) := + (Real.continuousAt_log (by norm_num : (1 : ℝ) ≠ 0)).tendsto.comp + zeta_pole_mul_re_tendsto_one + have hEq : + (fun s : ℝ => Real.log (riemannZeta (s : ℂ)).re + Real.log (s - 1)) + =ᶠ[nhdsWithin 1 (Set.Ioi 1)] + fun s : ℝ => Real.log ((s - 1) * (riemannZeta (s : ℂ)).re) := by + filter_upwards [self_mem_nhdsWithin] with s hs + have hspos : 0 < s - 1 := sub_pos.mpr (Set.mem_Ioi.mp hs) + have hzpos : 0 < (riemannZeta (s : ℂ)).re := + riemannZeta_re_pos_of_one_lt (Set.mem_Ioi.mp hs) + rw [Real.log_mul hspos.ne' hzpos.ne'] + ring + simpa using hlog.congr' (hEq.mono fun s hs => hs.symm) + +section +open MeasureTheory Set + +private lemma measurable_E₂Λ : Measurable E₂Λ := by fun_prop + +private lemma E₂Λ_eq_on_Ioo {x : ℝ} (hx : x ∈ Set.Ioo (1 : ℝ) 2) : + E₂Λ x = - log (log x) - γ := by + obtain ⟨h1, h2⟩ := hx + have hf : ⌊x⌋₊ = 1 := by + rw [Nat.floor_eq_iff (by linarith)] + exact ⟨by exact_mod_cast h1.le, by exact_mod_cast h2⟩ + unfold E₂Λ + rw [hf] + simp + +private lemma abs_E₂Λ_le_on_Ioo {x : ℝ} (hx : x ∈ Set.Ioo (1 : ℝ) 2) : + |E₂Λ x| ≤ |log (x - 1)| + log 2 + |γ| := by + obtain ⟨hx1, hx2⟩ := hx + have hloglog : |log (log x)| ≤ |log (x - 1)| + log 2 := by + have hxpos : (0:ℝ) < x := by linarith + have hlogx_pos : 0 < log x := Real.log_pos hx1 + have hxm1 : 0 < x - 1 := by linarith + have hub : log x ≤ x - 1 := by have := Real.log_le_sub_one_of_pos hxpos; linarith + have hlb2 : (x - 1) / 2 ≤ log x := by + have h := Real.log_le_sub_one_of_pos (x := 1 / x) (by positivity) + rw [Real.log_div one_ne_zero (by positivity), Real.log_one] at h + simp only [zero_sub] at h + have h12 : (x - 1) / 2 ≤ 1 - 1 / x := by + rw [← sub_nonneg] + have e : (1 - 1 / x) - (x - 1) / 2 = (3 * x - 2 - x ^ 2) / (2 * x) := by field_simp; ring + rw [e]; exact div_nonneg (by nlinarith [hx1, hx2]) (by positivity) + linarith + have hupper : log (log x) ≤ log (x - 1) := Real.log_le_log hlogx_pos hub + have hlower : log (x - 1) - log 2 ≤ log (log x) := by + have := Real.log_le_log (show (0:ℝ) < (x - 1) / 2 by positivity) hlb2 + rwa [Real.log_div (by linarith) (by norm_num)] at this + have h2 : (0:ℝ) ≤ log 2 := Real.log_nonneg (by norm_num) + rw [abs_le] + exact ⟨by have := neg_abs_le (log (x - 1)); linarith, + by have := le_abs_self (log (x - 1)); linarith⟩ + rw [E₂Λ_eq_on_Ioo ⟨hx1, hx2⟩] + have htri : |(- log (log x) - γ)| ≤ |log (log x)| + |γ| := by + have h := abs_sub (-log (log x)) γ + rwa [abs_neg] at h + linarith + +private lemma abs_E₂Λ_le_const {x : ℝ} (hx : 2 ≤ x) : + |E₂Λ x| ≤ (log 4 + 6) / log 2 := + (E₂Λ.abs_le hx).trans <| div_le_div_of_nonneg_left (by positivity) + (Real.log_pos (by norm_num)) (Real.log_le_log (by norm_num) hx) + +private lemma integrableOn_log_sub_one_bound : + IntegrableOn (fun x => |log (x - 1)| + log 2 + |γ|) (Set.Ioo 1 2) volume := by + have hlog : IntegrableOn (fun x => |log (x - 1)|) (Set.Ioo 1 2) volume := by + have h0 : IntervalIntegrable (fun x => log x) volume 0 1 := + intervalIntegral.intervalIntegrable_log' + have h1 : IntervalIntegrable (fun x => log (x - 1)) volume (0 + 1) (1 + 1) := + h0.comp_sub_right 1 + norm_num at h1 + exact (h1.1.mono_set Set.Ioo_subset_Ioc_self).abs + have hc : IntegrableOn (fun _ : ℝ => log 2 + |γ|) (Set.Ioo (1 : ℝ) 2) volume := + integrableOn_const (measure_Ioo_lt_top).ne (by finiteness) + have hsum : IntegrableOn (fun x => |log (x - 1)| + (log 2 + |γ|)) (Set.Ioo 1 2) volume := + hlog.add hc + exact hsum.congr_fun (fun x _ => by ring) measurableSet_Ioo + +private lemma integrableOn_E₂Λ_Ioo {X : ℝ} (_hX : 2 ≤ X) : + IntegrableOn E₂Λ (Set.Ioo 1 X) volume := by + have hsub : Set.Ioo (1 : ℝ) X ⊆ Set.Ioo 1 2 ∪ Set.Icc 2 X := by + intro x hx; simp only [Set.mem_Ioo, Set.mem_union, Set.mem_Icc] at * + rcases lt_or_ge x 2 with h | h + · exact Or.inl ⟨hx.1, h⟩ + · exact Or.inr ⟨h, hx.2.le⟩ + apply IntegrableOn.mono_set _ hsub + apply IntegrableOn.union + · have hg := integrableOn_log_sub_one_bound + refine Integrable.mono' hg measurable_E₂Λ.aestronglyMeasurable ?_ + filter_upwards [self_mem_ae_restrict measurableSet_Ioo] with x hx + rw [Real.norm_eq_abs]; exact abs_E₂Λ_le_on_Ioo hx + · refine Integrable.mono' (g := fun _ => (log 4 + 6) / log 2) ?_ + measurable_E₂Λ.aestronglyMeasurable ?_ + · exact integrableOn_const (by rw [Real.volume_Icc]; exact ENNReal.ofReal_ne_top) (by finiteness) + · filter_upwards [self_mem_ae_restrict measurableSet_Icc] with x hx + rw [Real.norm_eq_abs]; exact abs_E₂Λ_le_const hx.1 + +private lemma sub_one_mul_integral_E₂Λ_tendsto : + Filter.Tendsto (fun s : ℝ => (s - 1) * ∫ x in Set.Ioi 1, E₂Λ x * x ^ (-s)) + (nhdsWithin 1 (Set.Ioi 1)) (nhds 0) := by + rw [Metric.tendsto_nhdsWithin_nhds] + intro ε hε + + obtain ⟨X₀, hX₀⟩ : ∃ X, ∀ x ≥ X, |E₂Λ x| ≤ ε / 2 := by + have := E₂Λ.bound'.def (by positivity : (0:ℝ) < ε / 2) + simp only [Real.norm_eq_abs, abs_one, mul_one] at this + rw [Filter.eventually_atTop] at this; exact this + set X := max X₀ 2 with hXdef + have hX2 : 2 ≤ X := le_max_right _ _ + have hXge : ∀ x ≥ X, |E₂Λ x| ≤ ε / 2 := fun x hx => hX₀ x (le_trans (le_max_left _ _) hx) + + set B := ∫ x in Set.Ioo 1 X, |E₂Λ x| with hBdef + have hB0 : 0 ≤ B := setIntegral_nonneg measurableSet_Ioo (fun x _ => abs_nonneg _) + refine ⟨min 1 (ε / 2 / (B + 1)), by positivity, ?_⟩ + intro s hs hdist + simp only [Set.mem_Ioi] at hs + rw [Real.dist_eq] at hdist + have hs1 : s - 1 < min 1 (ε / 2 / (B + 1)) := by + rw [abs_of_pos (by linarith)] at hdist; exact hdist + have hsm1 : 0 < s - 1 := by linarith + + have hintAbs : IntegrableOn (fun x => |E₂Λ x| * x ^ (-s)) (Set.Ioi 1) volume := by + have h2 : IntegrableOn (fun x => |E₂Λ x * x ^ (-s)|) (Set.Ioi 1) volume := + (integrableOn_E₂Λ_mul_rpow s hs).abs + refine h2.congr_fun ?_ measurableSet_Ioi + intro x hx; simp only [Set.mem_Ioi] at hx + change |E₂Λ x * x ^ (-s)| = |E₂Λ x| * x ^ (-s) + rw [abs_mul, abs_of_nonneg (Real.rpow_nonneg (by linarith) _)] + have hintAbsIoc : IntegrableOn (fun x => |E₂Λ x| * x ^ (-s)) (Set.Ioc 1 X) volume := + hintAbs.mono_set Set.Ioc_subset_Ioi_self + have hintAbsIoiX : IntegrableOn (fun x => |E₂Λ x| * x ^ (-s)) (Set.Ioi X) volume := + hintAbs.mono_set (Set.Ioi_subset_Ioi (by linarith)) + + have hsplit : ∫ x in Set.Ioi 1, |E₂Λ x| * x ^ (-s) = + (∫ x in Set.Ioc 1 X, |E₂Λ x| * x ^ (-s)) + ∫ x in Set.Ioi X, |E₂Λ x| * x ^ (-s) := by + have hu : Set.Ioi (1:ℝ) = Set.Ioc 1 X ∪ Set.Ioi X := + (Set.Ioc_union_Ioi_eq_Ioi (by linarith)).symm + rw [hu, setIntegral_union (Set.Ioc_disjoint_Ioi le_rfl) measurableSet_Ioi + (hintAbs.mono_set (by rw [hu]; exact Set.subset_union_left)) + (hintAbs.mono_set (by rw [hu]; exact Set.subset_union_right))] + + have hp1 : ∫ x in Set.Ioc 1 X, |E₂Λ x| * x ^ (-s) ≤ B := by + rw [hBdef] + have ha : IntegrableOn (fun x => |E₂Λ x|) (Set.Ioo 1 X) volume := (integrableOn_E₂Λ_Ioo hX2).abs + have habsIoc : IntegrableOn (fun x => |E₂Λ x|) (Set.Ioc 1 X) volume := + ha.congr_set_ae (Ioo_ae_eq_Ioc).symm + rw [← integral_Ioc_eq_integral_Ioo] + apply setIntegral_mono_on hintAbsIoc habsIoc measurableSet_Ioc + intro x hx + have hx1 : (1:ℝ) ≤ x := by have := hx.1; linarith + have hle1 : x ^ (-s) ≤ 1 := Real.rpow_le_one_of_one_le_of_nonpos hx1 (by linarith) + calc |E₂Λ x| * x ^ (-s) ≤ |E₂Λ x| * 1 := by gcongr + _ = |E₂Λ x| := mul_one _ + + have hp2 : ∫ x in Set.Ioi X, |E₂Λ x| * x ^ (-s) ≤ (ε / 2) * (X ^ (1 - s) / (s - 1)) := by + have hrpow_int : IntegrableOn (fun x : ℝ => x ^ (-s)) (Set.Ioi X) volume := + integrableOn_Ioi_rpow_of_lt (by linarith) (by linarith : (0:ℝ) < X) + have hval : ∫ x in Set.Ioi X, x ^ (-s) = X ^ (1 - s) / (s - 1) := by + rw [integral_Ioi_rpow_of_lt (by linarith) (by linarith : (0:ℝ) < X), + show -s + 1 = 1 - s by ring, show (1:ℝ) - s = -(s - 1) by ring] + rw [div_neg, neg_div, neg_neg] + rw [← hval, ← integral_const_mul] + apply setIntegral_mono_on hintAbsIoiX (hrpow_int.const_mul (ε / 2)) measurableSet_Ioi + intro x hx + have hxpos : (0:ℝ) < x := by simp only [Set.mem_Ioi] at hx; linarith + have hnn : 0 ≤ x ^ (-s) := Real.rpow_nonneg hxpos.le _ + have hb : |E₂Λ x| ≤ ε / 2 := hXge x (by simp only [Set.mem_Ioi] at hx; linarith) + gcongr + have hXpow : X ^ (1 - s) ≤ 1 := + Real.rpow_le_one_of_one_le_of_nonpos (by linarith) (by linarith) + + have hbound : (s - 1) * ∫ x in Set.Ioi 1, |E₂Λ x| * x ^ (-s) ≤ (s - 1) * B + ε / 2 := by + rw [hsplit, mul_add] + have ht2 : (s - 1) * ∫ x in Set.Ioi X, |E₂Λ x| * x ^ (-s) ≤ ε / 2 := by + calc (s - 1) * ∫ x in Set.Ioi X, |E₂Λ x| * x ^ (-s) + ≤ (s - 1) * ((ε / 2) * (X ^ (1 - s) / (s - 1))) := + mul_le_mul_of_nonneg_left hp2 hsm1.le + _ = (ε / 2) * X ^ (1 - s) := by + have hne : s - 1 ≠ 0 := by linarith + field_simp + _ ≤ (ε / 2) * 1 := by gcongr + _ = ε / 2 := mul_one _ + have ht1 : (s - 1) * ∫ x in Set.Ioc 1 X, |E₂Λ x| * x ^ (-s) ≤ (s - 1) * B := + mul_le_mul_of_nonneg_left hp1 hsm1.le + linarith + + have habs_le : |(s - 1) * ∫ x in Set.Ioi 1, E₂Λ x * x ^ (-s)| + ≤ (s - 1) * ∫ x in Set.Ioi 1, |E₂Λ x| * x ^ (-s) := by + rw [abs_mul, abs_of_pos hsm1] + gcongr + rw [← Real.norm_eq_abs] + refine (norm_integral_le_integral_norm _).trans_eq ?_ + refine setIntegral_congr_fun measurableSet_Ioi (fun x hx => ?_) + simp only [Set.mem_Ioi] at hx + change ‖E₂Λ x * x ^ (-s)‖ = |E₂Λ x| * x ^ (-s) + rw [Real.norm_eq_abs, abs_mul, abs_of_nonneg (Real.rpow_nonneg (by linarith) _)] + rw [Real.dist_eq, sub_zero] + + have hfin : (s - 1) * B + ε / 2 < ε := by + have hlt : s - 1 < ε / 2 / (B + 1) := lt_of_lt_of_le hs1 (min_le_right _ _) + have hBp : 0 < B + 1 := by linarith + have h1 : (s - 1) * B ≤ (s - 1) * (B + 1) := by nlinarith + have h2 : (s - 1) * (B + 1) < (ε / 2 / (B + 1)) * (B + 1) := mul_lt_mul_of_pos_right hlt hBp + have h3 : (ε / 2 / (B + 1)) * (B + 1) = ε / 2 := by field_simp + linarith + calc |(s - 1) * ∫ x in Set.Ioi 1, E₂Λ x * x ^ (-s)| + ≤ (s - 1) * ∫ x in Set.Ioi 1, |E₂Λ x| * x ^ (-s) := habs_le + _ ≤ (s - 1) * B + ε / 2 := hbound + _ < ε := hfin + +end + +theorem deriv_gamma_add_γ_eq_zero : deriv Gamma 1 + γ = 0 := by + + have key : ∀ s : ℝ, 1 < s → + (Real.log (riemannZeta (s:ℂ)).re + Real.log (s - 1)) + - (s - 1) * ∫ x in Set.Ioi 1, E₂Λ x * x ^ (-s) = deriv Gamma 1 + γ := by + intro s hs + have h := log_zeta_eq s hs + linarith + + have hconst : Filter.Tendsto + (fun s : ℝ => (Real.log (riemannZeta (s:ℂ)).re + Real.log (s - 1)) + - (s - 1) * ∫ x in Set.Ioi 1, E₂Λ x * x ^ (-s)) + (nhdsWithin 1 (Set.Ioi 1)) (nhds (deriv Gamma 1 + γ)) := by + refine Filter.Tendsto.congr' ?_ tendsto_const_nhds + filter_upwards [self_mem_nhdsWithin] with s hs + exact (key s hs).symm + + have hlim := log_zeta_limit.sub sub_one_mul_integral_E₂Λ_tendsto + rw [sub_zero] at hlim + exact tendsto_nhds_unique hconst hlim + +theorem γ.eq_eulerMascheroni : γ = eulerMascheroniConstant := by + linarith [Real.eulerMascheroniConstant_eq_neg_deriv, deriv_gamma_add_γ_eq_zero] + +theorem sum_mangoldt_div_log_eq (x : ℝ) : ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d) = log (log x) + eulerMascheroniConstant + E₂Λ x := by + grind [γ.eq_eulerMascheroni] + +theorem sum_mangoldt_div_log_eq_log_log : ∃ C, ∀ x, 2 ≤ x → + |∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d) - log (log x)| ≤ C := by + use (log 4 + 6)/log 2 + |eulerMascheroniConstant| + intro x hx + rw [sum_mangoldt_div_log_eq] + calc + _ = |E₂Λ x + eulerMascheroniConstant| := by ring_nf + _ ≤ (log 4 + 6)/log x + |eulerMascheroniConstant| := by grw [abs_add_le, E₂Λ.abs_le hx] + _ ≤ _ := by gcongr + +theorem sum_mangoldt_div_log_eq_log_log' : (fun x ↦ ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d) - log (log x)) =O[atTop] (fun _ ↦ (1:ℝ)) := by + simp only [isBigO_iff, norm_eq_abs, one_mem, CStarRing.norm_of_mem_unitary, mul_one, + eventually_atTop] + obtain ⟨ C, _ ⟩ := sum_mangoldt_div_log_eq_log_log + use C, 2 + +theorem sum_mangoldt_div_log_eq_log_log'' : (fun x ↦ ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d)) ~[atTop] (fun x ↦ log (log x)) := by + apply IsLittleO.isEquivalent (IsBigO.trans_isLittleO _ one_eq_o_log_log) + convert! sum_mangoldt_div_log_eq_log_log' using 1 + +noncomputable def M : ℝ := (∫ t in Set.Ioi 2, E₁p t / (t * log t^2)) + 1 - log (log 2) + +theorem M.le : M ≤ (log 4 + 4) / log 2 + 1 - log (log 2) := calc + _ ≤ (∫ t in Set.Ioi 2, (log 4 + 4) / (t * log t^2)) + 1 - log (log 2) := by + unfold M; gcongr with x hx + · exact integrable_E₁p_div_mul_log_sq (by norm_num) + · exact integrable_const_div_mul_log_sq _ (by norm_num) + · measurability + · simp at hx; positivity + simp at hx; exact E₁p.le (by linarith) + _ = _ := by rw [integ_div_mul_log_sq _ (by norm_num)] + +theorem M.ge : M ≥ (-2 - E₁) / log 2 + 1 - log (log 2) := calc + _ ≥ (∫ t in Set.Ioi 2, (-2 - E₁) / (t * log t^2)) + 1 - log (log 2) := by + unfold M; gcongr with x hx + · exact integrable_const_div_mul_log_sq _ (by norm_num) + · exact integrable_E₁p_div_mul_log_sq (by norm_num) + · measurability + · simp at hx; positivity + simp at hx; exact E₁p.ge (by linarith) + _ = _ := by rw [integ_div_mul_log_sq _ (by norm_num)] + +noncomputable abbrev E₂p (x : ℝ) : ℝ := ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (1:ℝ) / p - log (log x) - M + +theorem sum_prime_div_eq (x : ℝ) : ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (1:ℝ) / p = log (log x) + M + E₂p x := by + ring + +theorem E₂p.eq {x : ℝ} (hx : 2 ≤ x) : + E₂p x = E₁p x / log x - ∫ t in Set.Ioi x, E₁p t / (t * log t^2) := by + unfold E₂p + rw [sum_filter, ← sum_Ioc_one_eq_sum_Ioc_zero (Nat.le_floor (by grind)) (by simp [Nat.not_prime_one])] + have (n : ℕ) : (if Nat.Prime n then (1 : ℝ) / n else 0) = (if Nat.Prime n then log n / n else 0) / log n := by + split_ifs with h + · have : log n ≠ 0 := by simp; grind [h.two_le] + field + · simp + simp_rw [this] + rw [sum_div_log_eq hx, sum_Ioc_one_eq_sum_Ioc_zero (Nat.le_floor (by grind)) (by simp), ← sum_filter] + rw [sum_log_prime_div_eq] + have : ∫ t in 2..x, (∑ n ∈ Ioc 1 ⌊t⌋₊, if Nat.Prime n then log ↑n / ↑n else 0) / (t * log t ^ 2) = ∫ t in 2..x, (1 / (t * log t) + E₁p t / (t * log t ^2)) := by + refine intervalIntegral.integral_congr fun t ht ↦ ?_ + rw [Set.uIcc_of_le hx, Set.mem_Icc] at ht + rw [sum_Ioc_one_eq_sum_Ioc_zero (Nat.le_floor (by grind)) (by simp), ← sum_filter, sum_log_prime_div_eq] + field + rw [this, intervalIntegral.integral_add] + · rw [integral_one_div_mul_log hx, add_div, div_self (by simp; grind)] + unfold M + calc + _ = E₁p x / log x + (∫ (x : ℝ) in 2..x, E₁p x / (x * log x ^ 2)) - + ((∫ (t : ℝ) in Set.Ioi 2, E₁p t / (t * log t ^ 2))) := by ring + _ = _ := by + rw [← intervalIntegral.integral_interval_add_Ioi (integrable_E₁p_div_mul_log_sq (by rfl)) (integrable_E₁p_div_mul_log_sq hx)] + ring + · exact intervalIntegrable_one_div_mul_log hx + · rw [intervalIntegrable_iff, Set.uIoc_of_le hx] + exact integrable_E₁p_div_mul_log_sq (x := 2) (by rfl)|>.mono (by grind) (by rfl) + +theorem E₂p.abs_le {x : ℝ} (hx : 2 ≤ x) : + |E₂p x| ≤ (log 4 + 6 + E₁) / log x := by + have : 0 < log x := by apply log_pos; linarith + rw [E₂p.eq hx, abs_le'] + constructor + · grw [E₁p.le (by linarith)] + have : ∫ t in Set.Ioi x, E₁p t / (t * log t^2) ≥ (- 2 - E₁) / log x := calc + _ ≥ ∫ t in Set.Ioi x, (-2 - E₁) / (t * log t^2) := by + apply MeasureTheory.setIntegral_mono_on (integrable_const_div_mul_log_sq (-2 - E₁) hx) + (integrable_E₁p_div_mul_log_sq hx) (by measurability) + intro y hy; simp at hy + have : 1 < y := by linarith + have : 0 < log y := log_pos this + gcongr; exact E₁p.ge (by linarith) + _ = _ := integ_div_mul_log_sq (-2 - E₁) hx + grw [this] + grind + grw [E₁p.ge (by linarith)] + have : ∫ t in Set.Ioi x, E₁p t / (t * log t^2) ≤ (log 4 + 4) / log x := calc + _ ≤ ∫ t in Set.Ioi x, (log 4 + 4) / (t * log t^2) := by + apply MeasureTheory.setIntegral_mono_on (integrable_E₁p_div_mul_log_sq hx) + (integrable_const_div_mul_log_sq (log 4 + 4) hx) (by measurability) + intro y hy; simp at hy + have : 1 < y := by linarith + have : 0 < log y := log_pos this + gcongr; exact E₁p.le (by linarith) + _ = _ := integ_div_mul_log_sq (log 4 + 4) hx + grw [this] + grind + +theorem E₂p.bound : E₂p =O[atTop] (fun x ↦ 1 / log x) := by + simp only [one_div, isBigO_iff, norm_eq_abs, norm_inv, eventually_atTop] + use log 4 + 6 + E₁, 2 + intro x hx + convert E₂p.abs_le hx using 1 + have : 0 < log x := by apply log_pos; linarith + grind [abs_of_pos this] + +theorem E₂p.bound' : E₂p =o[atTop] (fun _ ↦ (1:ℝ)) := E₂p.bound.trans_isLittleO inv_log_eq_o_one + +theorem sum_prime_div_eq_log_log : ∃ C, ∀ x, 2 ≤ x → + |∑ p ∈ Ioc 0 ⌊x⌋₊ with p.Prime, (1:ℝ) / p - log (log x)| ≤ C := by + use |M| + (log 4 + 6 + E₁) / log 2 + intro x hx + rw [sum_prime_div_eq] + calc + _ = |M + E₂p x| := by ring_nf + _ ≤ |M| + (log 4 + 6 + E₁) / log x := by grw [abs_add_le, E₂p.abs_le hx] + _ ≤ _ := by + gcongr + have : 0 < log 4 := by apply log_pos; norm_num + linarith [E₁.nonneg] + +theorem sum_prime_div_eq_log_log' : (fun x ↦ ∑ p ∈ Ioc 0 ⌊x⌋₊ with p.Prime, (1:ℝ) / p - log (log x)) =O[atTop] (fun _ ↦ (1:ℝ)) := by + simp only [isBigO_iff, norm_eq_abs, one_mem, CStarRing.norm_of_mem_unitary, mul_one, + eventually_atTop] + obtain ⟨ C, hC ⟩ := sum_prime_div_eq_log_log + use C, 2 + +theorem sum_prime_div_eq_log_log'' : (fun x ↦ ∑ p ∈ Ioc 0 ⌊x⌋₊ with p.Prime, (1:ℝ) / p) ~[atTop] (fun x ↦ log (log x)) := by + apply IsLittleO.isEquivalent (IsBigO.trans_isLittleO _ one_eq_o_log_log) + convert! sum_prime_div_eq_log_log' using 1 + +lemma HasSum_log_one_sub_one_div_prime {p : ℕ} (hp : p.Prime) : + HasSum (fun n : ℕ ↦ (-1 : ℝ) / (( n + 1) * p ^ (n + 1))) (log (1 - 1 / p)) := by + convert! Real.hasSum_pow_div_log_of_abs_lt_one (x := 1 / p) _|>.neg using 1 + · ext + rw [div_pow, one_pow, div_div] + ring + · ring + · simp only [one_div, abs_inv, Nat.abs_cast] + exact inv_lt_one_of_one_lt₀ (mod_cast hp.one_lt) + +lemma E₂Λ_sub_E₂p_tendsto : + Tendsto (E₂Λ - E₂p) atTop (nhds 0) := by + exact isLittleO_one_iff ℝ|>.mp <| E₂Λ.bound'.sub E₂p.bound' + +noncomputable abbrev M_eq_f (n : ℕ) := + if ¬n.Prime then Λ n /(n * log n) else 0 + +lemma E₂Λ_sub_E₂p_eq (x : ℝ) : + E₂Λ x - E₂p x = ∑ n ∈ Ioc 0 ⌊x⌋₊, M_eq_f n - (γ - M) := by + calc + _ = ∑ n ∈ Ioc 0 ⌊x⌋₊, Λ n / (n * log n) - ∑ p ∈ Ioc 0 ⌊x⌋₊ with p.Prime, (1 : ℝ) / p - (γ - M) := by ring + _ = _ := by + rw [sum_filter, ← sum_sub_distrib] + congr + ext n + split_ifs with hn + · rw [vonMangoldt_apply_prime hn] + have : log n ≠ 0 := by simp; grind [hn.two_le] + field + · ring + +lemma M_eq_f.sum_tendsto : + Tendsto (fun (x : ℝ) ↦ ∑ n ∈ Ioc 0 ⌊x⌋₊, M_eq_f n) atTop (nhds (γ - M)) := by + apply tendsto_sub_nhds_zero_iff.mp + convert E₂Λ_sub_E₂p_tendsto using 1 + ext + rw [← E₂Λ_sub_E₂p_eq] + simp + +lemma M_eq_f.sum_tendsto' : + Tendsto (fun (N : ℕ) ↦ ∑ n ∈ range N, M_eq_f n) atTop (nhds (γ - M)) := by + have : Tendsto (fun (N : ℕ) ↦ (∑ n ∈ Ioc 0 ⌊(N : ℝ)⌋₊, M_eq_f n)) atTop (nhds (γ - M)) := M_eq_f.sum_tendsto.comp tendsto_natCast_atTop_atTop + simp_rw [Nat.floor_natCast] at this + apply (this.comp (tendsto_sub_atTop_nat 1)).congr' + filter_upwards [eventually_ge_atTop 1] with N hn + rw [Nat.range_eq_Icc_zero_sub_one, ← add_sum_Ioc_eq_sum_Icc] <;> grind + +lemma M_eq_f.HasSum : + HasSum M_eq_f (γ - M) := by + refine hasSum_iff_tendsto_nat_of_nonneg (fun n ↦ ?_) _|>.mpr M_eq_f.sum_tendsto' + unfold M_eq_f + split_ifs with hn + · rfl + · exact div_nonneg vonMangoldt_nonneg (by positivity) + +lemma M_eq_f.sum_primes : + ∑' (p : Nat.Primes), M_eq_f p = 0 := by + convert! tsum_zero with p + grind + +lemma tsum_primes_eq_tsum_ite (f : ℕ → ℝ) : + ∑' (n : Nat.Primes), f n = ∑' (n : ℕ), if n.Prime then f n else 0 := by + convert! _root_.tsum_subtype Nat.Prime f using 2 + ext + simp [Set.indicator] + congr + +lemma tsum_M_eq_f_eq_tsum : + -∑' (n : ℕ), M_eq_f n = ∑' p : ℕ, if p.Prime then log (1 - 1 / p) + 1 / p else 0 := by + rw [tsum_eq_tsum_primes_add_tsum_primes_of_support_subset_prime_powers M_eq_f.HasSum.summable + (fun n hn ↦ (by simp_all [vonMangoldt_ne_zero_iff])), M_eq_f.sum_primes, zero_add, + tsum_primes_eq_tsum_ite (fun p ↦ ∑' (k : ℕ), M_eq_f (p ^ (k + 2))), ← tsum_neg] + refine tsum_congr fun n ↦ ?_ + split_ifs with hn + · rw [← HasSum_log_one_sub_one_div_prime hn|>.tsum_eq, HasSum_log_one_sub_one_div_prime hn|>.summable.tsum_eq_zero_add] + simp only [ite_not, Nat.cast_pow, log_pow, Nat.cast_add, Nat.cast_ofNat, CharP.cast_eq_zero, + zero_add, pow_one, one_mul, Nat.cast_one, one_div] + trans -∑' (k : ℕ), (1 : ℝ) / ((k + 2) * n ^ (k + 2)) + · congr + ext k + have : ¬(Nat.Prime (n ^ (k + 2))) := by exact Nat.Prime.not_prime_pow (by grind) + simp only [this, ↓reduceIte, one_div, mul_inv_rev] + rw [vonMangoldt_apply_pow (by grind), vonMangoldt_apply_prime hn] + have : log n ≠ 0 := by simp; grind [hn.two_le] + field + · rw [← tsum_neg] + ring_nf + congr + ext + ring_nf + · ring + +theorem M.eq : M = γ + ∑' p : ℕ, if p.Prime then log (1 - 1 / p) + 1 / p else 0 := by + rw [← tsum_M_eq_f_eq_tsum, M_eq_f.HasSum.tsum_eq] + ring + +noncomputable def E₃ (x : ℝ) : ℝ := ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, log (1 - (1:ℝ) / p) + log (log x) + eulerMascheroniConstant + +theorem prod_one_minus_div_prime_eq {x : ℝ} (hx : 1 < x) : + ∏ p ∈ Ioc 0 ⌊x⌋₊ with p.Prime, (1 - (1 : ℝ) / p) = + exp (-eulerMascheroniConstant) * exp (E₃ x) / log x := by + have hlog : 0 < log x := log_pos hx + have hpos : ∀ {p : ℕ}, p.Prime → (0 : ℝ) < 1 - 1 / p := fun {p} hp ↦ by + have : (2 : ℝ) ≤ p := mod_cast hp.two_le + grind [one_div_le_one_div_of_le two_pos this] + rw [E₃, exp_add, exp_add, exp_sum, exp_log hlog, exp_neg, + prod_congr rfl fun p hp ↦ exp_log (hpos (mem_filter.mp hp).2)] + field_simp + +noncomputable abbrev M_eq_summand (p : ℕ) := if p.Prime then log (1 - 1 / p) + 1 / p else 0 + +lemma M_eq_summand_bound (n : ℕ) : + |M_eq_summand n| ≤ 2 / n ^ 2 := by + unfold M_eq_summand + split_ifs with h + · trans 1 / n ^ 2 / (1 - 1 / n) + · convert abs_log_sub_add_sum_range_le (x := 1 / n) _ 1 using 1 + · rw [add_comm] + simp + · rw [abs_of_nonneg (by simp)] + ring + · simpa using inv_lt_one_of_one_lt₀ (mod_cast h.one_lt) + rw [(by ring : (2 : ℝ) / n ^ 2 = 1 / n ^ 2 / (1 / 2))] + gcongr + suffices (1 : ℝ) / n ≤ 1 / 2 by linarith + gcongr + exact_mod_cast h.two_le + · rw [abs_zero] + positivity + +lemma M_eq_summable : Summable M_eq_summand := by + apply Summable.of_abs + exact Summable.of_nonneg_of_le (by simp) M_eq_summand_bound (Summable.const_div (by simp) _) + +lemma tsum_M_eq_summand_eq : + ∑' (n : ℕ), M_eq_summand n = M - γ := by + rw [M.eq] + grind + +lemma sum_one_div_sq_le {N : ℝ} (hN : 1 ≤ N) : + ∑' (n : ℕ), (1 : ℝ) / (n + N) ^ 2 ≤ 2 / N := by + grw [AntitoneOn.tsum_le_integral (f := (fun t ↦ 1 / (t + N) ^ 2))] + · have hd : ∀ x ∈ Set.Ici 0, HasDerivAt (fun t ↦ -1 / (t + N)) (1 / (x + N) ^ 2) x := by + intro t ht + convert! HasDerivAt.fun_div (d' := (1 : ℝ)) (hasDerivAt_const ..) _ _ using 1 + · ring + · simpa using hasDerivAt_id' t + · simp at ht + linarith + have lim : Tendsto (fun t ↦ -1 / (t + N)) atTop (nhds 0) := by + exact (tendsto_atTop_add_const_right atTop N tendsto_id).const_div_atTop _ + rw [MeasureTheory.integral_Ioi_of_hasDerivAt_of_nonneg' hd (fun _ _ ↦ (by positivity)) lim] + ring_nf + rw [mul_two] + gcongr + field_simp + exact hN + · unfold AntitoneOn + intro a ha b hb h + beta_reduce + simp at ha hb + gcongr + · convert! integrableOn_add_rpow_Ioi_of_lt (by norm_num : (-2 : ℝ) < -1) (by linarith : -N < 0) using 2 + simp + · exact fun _ _ ↦ (by positivity) + +lemma sum_M_eq_summand_le {N : ℕ} (hN : 0 < N) : + |∑ n ∈ range N, M_eq_summand n - (M - γ)| ≤ 4 / N := by + rw [← tsum_M_eq_summand_eq, ← M_eq_summable.sum_add_tsum_nat_add N] + simp only [sub_add_cancel_left, abs_neg] + rw [← norm_eq_abs] + have summable := summable_nat_add_iff N|>.mpr M_eq_summable.norm + apply norm_tsum_le_tsum_norm summable|>.trans + apply Summable.tsum_le_tsum (fun _ ↦ M_eq_summand_bound _) summable _|>.trans + · conv => lhs; arg 1; ext; rw [← mul_one_div] + rw [tsum_mul_left] + push_cast + grw [sum_one_div_sq_le (mod_cast hN)] + ring_nf + rfl + · exact (summable_nat_add_iff N|>.mpr (summable_one_div_nat_pow.mpr one_lt_two))|>.const_div _ + +lemma sum_M_eq_summand_le' {x : ℝ} (hx : 2 ≤ x) : + |∑ n ∈ Ioc 0 ⌊x⌋₊, M_eq_summand n - (M - γ)| ≤ 4 / x := by + have := sum_M_eq_summand_le (by grind : 0 < ⌊x⌋₊ + 1) + rw [Nat.range_eq_Icc_zero_sub_one _ (by grind), ← add_sum_Ioc_eq_sum_Icc (by grind), + (by simp : M_eq_summand 0 = 0), zero_add] at this + simp only [add_tsub_cancel_right, Nat.cast_add, Nat.cast_one] at this + grw [this] + gcongr + exact Nat.lt_floor_add_one _|>.le + +theorem E₃.abs_le : ∃ C, ∀ x, 2 ≤ x → |E₃ x| ≤ C / log x := by + unfold E₃ + refine ⟨4 + (log 4 + 6 + E₁), fun x hx ↦ ?_⟩ + calc + _ = |(∑ n ∈ Ioc 0 ⌊x⌋₊, M_eq_summand n - (M - γ)) - E₂p x| := by + unfold E₂p + have (n : ℕ) : M_eq_summand n = (if n.Prime then log (1 - 1 / n) else 0) + (if n.Prime then (1 : ℝ) / n else 0) := by + unfold M_eq_summand + split_ifs + · rfl + · ring + simp_rw [this] + rw [sum_filter, sum_filter, sum_add_distrib, γ.eq_eulerMascheroni] + ring_nf + _ ≤ _ := by + grw [abs_sub, E₂p.abs_le hx, sum_M_eq_summand_le' hx] + have : 4 / x ≤ 4 / log x := by + gcongr + · exact log_pos (by linarith) + · exact log_le_self (by linarith) + grw [this] + rw [← add_div] + +theorem E₃.bound : E₃ =O[atTop] (fun x ↦ 1 / log x) := by + simp only [isBigO_iff, norm_eq_abs, eventually_atTop] + obtain ⟨ C, hC ⟩ := E₃.abs_le + use C, 2 + convert hC using 3 with x hx + have : 0 < log x := by apply log_pos; linarith + have : 0 < 1 / log x := by positivity + grind [abs_of_pos this] + +theorem E₃.bound' : E₃ =o[atTop] (fun _ ↦ (1:ℝ)) := E₃.bound.trans_isLittleO inv_log_eq_o_one + +theorem E₃.bound'' : (fun x ↦ ∏ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (1 - (1:ℝ) / p)) ~[atTop] (fun x ↦ exp (-eulerMascheroniConstant) / log x) := by + rw [isEquivalent_iff_tendsto_one] + · convert Tendsto.congr' ?_ (Tendsto.rexp ((isLittleO_one_iff ℝ).mp E₃.bound')) using 2 with x + · simp + simp only [Erdos970.Filter.EventuallyEq.iff_eventually, Pi.div_apply, eventually_atTop]; use 2; intro x hx + rw [prod_one_minus_div_prime_eq (by linarith)] + have : 0 < log x := by apply log_pos; linarith + field_simp + simp only [ne_eq, div_eq_zero_iff, exp_ne_zero, log_eq_zero, eventually_atTop]; use 2 + grind + +theorem E₃.bound''' : (fun x ↦ ∏ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (1 - (1:ℝ) / p) - exp (-eulerMascheroniConstant) / log x) =O[atTop] (fun x ↦ 1 / (log x)^2) := by + obtain ⟨c, hc⟩ := E₃.abs_le + rw [isBigO_iff] + refine ⟨exp (-eulerMascheroniConstant) * 2 * c, ?_⟩ + filter_upwards [eventually_ge_atTop 2, eventually_ge_atTop c.exp] with x hx hx2 + rw [prod_one_minus_div_prime_eq (by linarith)] + specialize hc x hx + rw [norm_eq_abs, norm_eq_abs] + calc + _ = |exp (-eulerMascheroniConstant) / log x * (exp (E₃ x) - 1)| := by ring_nf + _ = |exp (-eulerMascheroniConstant) / log x| * |exp (E₃ x) - 1| := by rw [abs_mul] + _ ≤ _ := by + have : |E₃ x| ≤ 1 := by + apply hc.trans + have := log_le_log (exp_pos _) hx2 + rw [log_exp] at this + apply div_le_one_iff.mpr <| Or.inl ⟨log_pos (by linarith), this⟩ + grw [abs_exp_sub_one_le this, hc] + apply le_of_eq + rw [abs_div, abs_div, abs_one, abs_of_nonneg (exp_nonneg _), abs_of_nonneg (log_nonneg (by linarith)), abs_of_nonneg (sq_nonneg _)] + ring + +end Mertens + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Rectangle.lean b/PrimeNumberTheoremAnd/Erdos970/Rectangle.lean new file mode 100644 index 0000000..c87b920 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Rectangle.lean @@ -0,0 +1,264 @@ +import Mathlib.Analysis.Complex.Convex +import Mathlib.Analysis.InnerProductSpace.Basic +import Mathlib.Analysis.Normed.Order.Lattice +import Mathlib.Order.Interval.Set.Monotone + +namespace Erdos970 + +open Complex Set Topology + +open scoped Interval + +variable {z w : ℂ} {c : ℝ} + +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 + +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]] + +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 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 + +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 + +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 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 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 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 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 + +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⟩ + +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 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 Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/ResidueCalcOnRectangles.lean b/PrimeNumberTheoremAnd/Erdos970/ResidueCalcOnRectangles.lean new file mode 100644 index 0000000..b976da3 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/ResidueCalcOnRectangles.lean @@ -0,0 +1,1074 @@ +import Mathlib.Analysis.Complex.CauchyIntegral +import Mathlib.Analysis.Complex.Convex +import Mathlib.Analysis.Complex.RemovableSingularity +import Mathlib.Analysis.SpecialFunctions.Integrals.Basic +import Mathlib.Analysis.Meromorphic.NormalForm +import PrimeNumberTheoremAnd.Erdos970.Rectangle +import PrimeNumberTheoremAnd.Erdos970.Tactic.AdditiveCombination + +namespace Erdos970 + +open _root_.Complex BigOperators Nat Classical Real Topology Filter +open _root_.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₂ σ : ℝ} + +noncomputable def HIntegral (f : ℂ → E) (x₁ x₂ y : ℝ) : E := + ∫ x in x₁..x₂, f (x + y * I) + +noncomputable def VIntegral (f : ℂ → E) (x y₁ y₂ : ℝ) : E := + I • ∫ y in y₁..y₂, f (x + y * I) + +noncomputable def HIntegral' (f : ℂ → E) (x₁ x₂ y : ℝ) : E := + (1 / (2 * π * I)) • HIntegral f x₁ x₂ y + +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] + +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 + +noncomputable abbrev RectangleIntegral' (f : ℂ → E) (z w : ℂ) : E := + (1 / (2 * π * I)) • RectangleIntegral f z w + +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)) + +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)) + +noncomputable def VerticalIntegral (f : ℂ → E) (σ : ℝ) : E := + I • ∫ t : ℝ, f (σ + t * 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] + +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 + +abbrev HolomorphicOn (f : ℂ → E) (s : Set ℂ) : Prop := + DifferentiableOn ℂ f s + +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]⟩ + +theorem HolomorphicOn.vanishesOnRectangle [CompleteSpace E] + {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 + +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 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 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 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 := + ContinuousOn.rectangleBorderNoPIntegrable hf.continuousOn + (not_mem_rectangleBorder_of_rectangle_mem_nhds hp) + +theorem HolomorphicOn.rectangleBorderIntegrable (hf : HolomorphicOn f (Rectangle z w)) : + RectangleBorderIntegrable f z w := ContinuousOn.rectangleBorderIntegrable hf.continuousOn + +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' [CompleteSpace E] {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) := ?_ + have htop : RectangleBorderIntegrable f (↑z₀.re + ↑z₁.im * I) + (↑z₃.re + ↑z₃.im * I) := ?_ + have hleft : RectangleBorderIntegrable f (↑z₀.re + ↑z₁.im * I) + (↑z₃.re + ↑z₂.im * I) := ?_ + have hright : RectangleBorderIntegrable f (↑z₁.re + ↑z₁.im * I) + (↑z₃.re + ↑z₂.im * I) := ?_ + all_goals try { + 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]] := ?_ + have htop' : z₂.im ∈ [[z₁.im, z₃.im]] := ?_ + have hleft' : z₁.re ∈ [[z₀.re, z₃.re]] := ?_ + have hright' : z₂.re ∈ [[z₁.re, z₃.re]] := ?_ + all_goals try { + 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} := ?_ + have htop'' : Rectangle (↑z₀.re + ↑z₂.im * I) (↑z₃.re + ↑z₃.im * I) ⊆ + Rectangle z₀ z₃ \ {p} := ?_ + have hleft'' : Rectangle (↑z₀.re + ↑z₁.im * I) (↑z₁.re + ↑z₂.im * I) ⊆ + Rectangle z₀ z₃ \ {p} := ?_ + have hright'' : Rectangle (↑z₂.re + ↑z₁.im * I) (↑z₃.re + ↑z₂.im * I) ⊆ + Rectangle z₀ z₃ \ {p} := ?_ + all_goals try { 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 * + additive_combination h₁ + h₂ + h₃ + h₄ + h₅ + h₆ + h₇ + h₈ + +lemma RectanglePullToNhdOfPole [CompleteSpace E] {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'' [CompleteSpace E] {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 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 [Complex.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 [*] + +lemma ResidueTheoremAtOrigin : + RectangleIntegral' (fun s ↦ 1 / s) (-1 - I) (1 + I) = 1 := by + rw [RectangleIntegral', ResidueTheoremAtOrigin'] + all_goals simp [field] + +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 + +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) + +noncomputable def residue (f : ℂ → ℂ) (z₀ : ℂ) : ℂ := + Filter.limUnder (nhdsWithin z₀ {z₀}ᶜ) (fun z ↦ (z - z₀) * f z) + +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 + +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)) + +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] + +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) + +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) + +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) + +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 + +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 + +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 + +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 + +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) + +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] + +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 Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/SmoothExistence.lean b/PrimeNumberTheoremAnd/Erdos970/SmoothExistence.lean new file mode 100644 index 0000000..74e2172 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/SmoothExistence.lean @@ -0,0 +1,94 @@ +import Batteries.Tactic.Lemma +import Mathlib.Geometry.Manifold.PartitionOfUnity +import Mathlib.Tactic.Bound +import PrimeNumberTheoremAnd.Erdos970.Mathlib.Algebra.Notation.Support + +namespace Erdos970 + + +open MeasureTheory Set Real +open scoped ContDiff + +lemma smooth_urysohn_support_Ioo {a b c d : ℝ} (h1 : a < b) (h3 : c < d) : + ∃ Ψ : ℝ → ℝ, (ContDiff ℝ ∞ Ψ) ∧ (HasCompactSupport Ψ) ∧ + Set.indicator (Set.Icc b c) 1 ≤ Ψ ∧ Ψ ≤ Set.indicator (Set.Ioo a d) 1 ∧ + (Function.support Ψ = Set.Ioo a d) := by + have := exists_contMDiff_zero_iff_one_iff_of_isClosed (n := ⊤) + (modelWithCornersSelf ℝ ℝ) (s := Set.Iic a ∪ Set.Ici d) (t := Set.Icc b c) + (IsClosed.union isClosed_Iic isClosed_Ici) isClosed_Icc + (by + simp_rw [Set.disjoint_union_left, Set.disjoint_iff, Set.subset_def, + Set.mem_inter_iff, Set.mem_Iic, Set.mem_Icc, Set.mem_empty_iff_false, + and_imp, imp_false, not_le, Set.mem_Ici] + constructor <;> intros <;> linarith) + obtain ⟨Ψ, hΨSmooth, hΨrange, hΨ0, hΨ1⟩ := this + simp only [Set.mem_union, Set.mem_Iic, Set.mem_Ici, Set.mem_Icc] at * + use Ψ + simp only [range_subset_iff, mem_Icc] at hΨrange + refine ⟨ContMDiff.contDiff hΨSmooth, ?_, ?_, ?_, ?_⟩ + · apply HasCompactSupport.of_support_subset_isCompact (K := Set.Icc a d) isCompact_Icc + simp only [Function.support_subset_iff, ne_eq, mem_Icc, ← hΨ0, not_or] + bound + · apply Set.indicator_le' + · intro x hx + rw [hΨ1 x |>.mp, Pi.one_apply] + simpa using hx + · exact fun x _ ↦ (hΨrange x).1 + · intro x + apply Set.le_indicator_apply + · exact fun _ ↦ (hΨrange x).2 + · intro hx + rw [← hΨ0 x |>.mp] + simpa [-not_and, mem_Ioo, not_and_or, not_lt] using hx + · ext x + simp only [Function.mem_support, ne_eq, mem_Ioo, ← hΨ0, not_or, not_le] + +lemma SmoothExistence : + ∃ (ν : ℝ → ℝ), (ContDiff ℝ ∞ ν) ∧ (∀ x, 0 ≤ ν x) ∧ + ν.support ⊆ Icc (1 / 2) 2 ∧ ∫ x in Ici 0, ν x / x = 1 := by + suffices h : ∃ (ν : ℝ → ℝ), (ContDiff ℝ ∞ ν) ∧ (∀ x, 0 ≤ ν x) ∧ + ν.support ⊆ Set.Icc (1 / 2) 2 ∧ 0 < ∫ x in Set.Ici 0, ν x / x by + obtain ⟨ν, hν, hνnonneg, hνsupp, hνpos⟩ := h + let c := (∫ x in Ici 0, ν x / x) + use fun y ↦ ν y / c + refine ⟨hν.div_const c, fun y ↦ div_nonneg (hνnonneg y) (le_of_lt hνpos), ?_, ?_⟩ + · rw [Function.support_div, Function.support_const (ne_of_lt hνpos).symm, inter_univ] + convert hνsupp + · simp only [div_right_comm _ c _, integral_div c, div_self <| ne_of_gt hνpos, c] + have := smooth_urysohn_support_Ioo (a := 1 / 2) (b := 1) (c := 3 / 2) (d := 2) + (by linarith) (by linarith) + obtain ⟨ν, hνContDiff, _, hν0, hν1, hνSupport⟩ := this + use ν, hνContDiff + unfold indicator at hν0 hν1 + simp only [mem_Icc, Pi.one_apply, Pi.le_def, mem_Ioo] at hν0 hν1 + simp only [hνSupport, subset_def, mem_Ioo, mem_Icc, and_imp] + split_ands + · exact fun x ↦ le_trans (by simp [apply_ite]) (hν0 x) + · exact fun y hy hy' ↦ ⟨by linarith, by linarith⟩ + · rw [integral_pos_iff_support_of_nonneg] + · simp only [Function.support_div, measurableSet_Ici, Measure.restrict_apply', + hνSupport, Function.support_id'] + have : (Ioo (1 / 2 : ℝ) 2 ∩ {0}ᶜ ∩ Ici 0) = Ioo (1 / 2) 2 := by + ext x + simp only [one_div, mem_inter_iff, mem_Ioo, mem_compl_iff, mem_singleton_iff, mem_Ici] + bound + simp only [this, volume_Ioo, ENNReal.ofReal_pos, sub_pos, gt_iff_lt] + linarith + · simp_rw [Pi.le_def, Pi.zero_apply] + intro y + by_cases h : y ∈ Function.support ν + · apply div_nonneg <| le_trans (by simp [apply_ite]) (hν0 y) + rw [hνSupport, mem_Ioo] at h + linarith [h.left] + · simp only [Function.mem_support, ne_eq, not_not] at h + simp [h] + · have : (fun x ↦ ν x / x).support ⊆ Icc (1 / 2) 2 := by + rw [Function.support_div, hνSupport] + exact (inter_subset_left).trans Ioo_subset_Icc_self + apply (integrableOn_iff_integrable_of_support_subset this).mp + apply ContinuousOn.integrableOn_compact isCompact_Icc + apply hνContDiff.continuous.continuousOn.div continuousOn_id ?_ + simp only [mem_Icc, ne_eq, and_imp, id_eq] + intros; linarith + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Sobolev.lean b/PrimeNumberTheoremAnd/Erdos970/Sobolev.lean new file mode 100644 index 0000000..3e83353 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Sobolev.lean @@ -0,0 +1,360 @@ +import Mathlib.Analysis.Calculus.Deriv.Support +import Mathlib.Analysis.Distribution.SchwartzSpace.Deriv +import Mathlib.Order.Filter.ZeroAndBoundedAtFilter + +namespace Erdos970 + +open Real Complex MeasureTheory Filter Topology BoundedContinuousFunction SchwartzMap BigOperators +open scoped ContDiff + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {n : ℕ} + +@[ext] structure CS (n : ℕ) (E : Type*) [NormedAddCommGroup E] [NormedSpace ℝ E] where + toFun : ℝ → E + h1 : ContDiff ℝ n toFun + h2 : HasCompactSupport toFun + +structure trunc extends (CS 2 ℝ) where + h3 : (Set.Icc (-1) (1)).indicator 1 ≤ toFun + h4 : toFun ≤ Set.indicator (Set.Ioo (-2) (2)) 1 + +structure W1 (n : ℕ) (E : Type*) [NormedAddCommGroup E] [NormedSpace ℝ E] where + toFun : ℝ → E + smooth : ContDiff ℝ n toFun + integrable : ∀ ⦃k⦄, k ≤ n → Integrable (iteratedDeriv k toFun) + +abbrev W21 := W1 2 ℂ + +section lemmas + +noncomputable def funscale {E : Type*} (g : ℝ → E) (R x : ℝ) : E := g (R⁻¹ • x) + +lemma contDiff_ofReal : ContDiff ℝ ∞ ofReal := by + have key x : HasDerivAt ofReal 1 x := hasDerivAt_id x |>.ofReal_comp + have key' : deriv ofReal = fun _ => 1 := by ext x ; exact (key x).deriv + refine contDiff_infty_iff_deriv.mpr ⟨fun x => (key x).differentiableAt, ?_⟩ + simpa [key'] using contDiff_const + +omit [NormedSpace ℝ E] in +lemma tendsto_funscale {f : ℝ → E} (hf : ContinuousAt f 0) (x : ℝ) : + Tendsto (fun R => funscale f R x) atTop (𝓝 (f 0)) := + hf.tendsto.comp (by simpa using tendsto_inv_atTop_zero.mul_const x) + +end lemmas + +namespace CS + +variable {f : CS n E} {R x v : ℝ} + +instance : CoeFun (CS n E) (fun _ => ℝ → E) where coe := CS.toFun + +instance : Coe (CS n ℝ) (CS n ℂ) where coe f := ⟨fun x => f x, + contDiff_ofReal.of_le (mod_cast le_top) |>.comp f.h1, f.h2.comp_left (g := ofReal) rfl⟩ + +def neg (f : CS n E) : CS n E where + toFun := -f + h1 := f.h1.neg + h2 := by simpa [HasCompactSupport, tsupport] using f.h2 + +instance : Neg (CS n E) where neg := neg + +@[simp] lemma neg_apply {x : ℝ} : (-f) x = - (f x) := rfl + +def smul (R : ℝ) (f : CS n E) : CS n E := ⟨R • f, f.h1.const_smul R, f.h2.smul_left⟩ + +instance : HSMul ℝ (CS n E) (CS n E) where hSMul := smul + +@[simp] lemma smul_apply : (R • f) x = R • f x := rfl + +lemma continuous (f : CS n E) : Continuous f := f.h1.continuous + +noncomputable def deriv (f : CS (n + 1) E) : CS n E where + toFun := _root_.deriv f + h1 := (contDiff_succ_iff_deriv.mp f.h1).2.2 + h2 := f.h2.deriv + +lemma hasDerivAt (f : CS (n + 1) E) (x : ℝ) : HasDerivAt f (f.deriv x) x := + (f.h1.differentiable (by simp)).differentiableAt.hasDerivAt + +lemma deriv_apply {f : CS (n + 1) E} {x : ℝ} : f.deriv x = _root_.deriv f x := rfl + +lemma deriv_smul {f : CS (n + 1) E} : (R • f).deriv = R • f.deriv := by + ext x ; exact (f.hasDerivAt x |>.const_smul R).deriv + +noncomputable def scale (g : CS n E) (R : ℝ) : CS n E := by + by_cases h : R = 0 + · exact ⟨0, contDiff_const, by simp [HasCompactSupport, tsupport]⟩ + · refine ⟨fun x => funscale g R x, ?_, ?_⟩ + · exact g.h1.comp (contDiff_const_smul R⁻¹) + · exact g.h2.comp_smul (inv_ne_zero h) + +lemma deriv_scale {f : CS (n + 1) E} : (f.scale R).deriv = R⁻¹ • f.deriv.scale R := by + ext v ; by_cases hR : R = 0 + · simp [hR, scale, deriv] + · simp only [scale, hR, ↓reduceDIte, smul_apply] + exact ((f.hasDerivAt (R⁻¹ • v)).scomp v + (by simpa using! (hasDerivAt_id v).const_smul R⁻¹)).deriv + +lemma deriv_scale' {f : CS (n + 1) E} : + (f.scale R).deriv v = R⁻¹ • f.deriv (R⁻¹ • v) := by + rw [deriv_scale, smul_apply] + by_cases hR : R = 0 <;> simp [hR, scale, funscale] + +lemma hasDerivAt_scale (f : CS (n + 1) E) (R x : ℝ) : + HasDerivAt (f.scale R) (R⁻¹ • _root_.deriv f (R⁻¹ • x)) x := by + convert hasDerivAt (f.scale R) x ; rw [deriv_scale'] ; rfl + +lemma tendsto_scale (f : CS n E) (x : ℝ) : Tendsto (fun R => f.scale R x) atTop (𝓝 (f 0)) := by + apply (tendsto_funscale f.continuous.continuousAt x).congr' + filter_upwards [eventually_ne_atTop 0] with R hR ; simp [scale, hR] + +lemma bounded : ∃ C, ∀ v, ‖f v‖ ≤ C := by + obtain ⟨x, hx⟩ := + (continuous_norm.comp f.continuous).exists_forall_ge_of_hasCompactSupport f.h2.norm + exact ⟨_, hx⟩ + +end CS + +namespace trunc + +instance : CoeFun trunc (fun _ => ℝ → ℝ) where coe f := f.toFun + +instance : Coe trunc (CS 2 ℝ) where coe := trunc.toCS + +lemma nonneg (g : trunc) (x : ℝ) : 0 ≤ g x := (Set.indicator_nonneg (by simp) x).trans (g.h3 x) + +lemma le_one (g : trunc) (x : ℝ) : g x ≤ 1 := + (g.h4 x).trans <| Set.indicator_le_self' (by simp) x + +lemma zero (g : trunc) : g =ᶠ[𝓝 0] 1 := by + have : Set.Icc (-1) 1 ∈ 𝓝 (0 : ℝ) := by apply Icc_mem_nhds <;> linarith + exact eventually_of_mem this (fun x hx => le_antisymm (g.le_one x) (by simpa [hx] using g.h3 x)) + +@[simp] lemma zero_at {g : trunc} : g 0 = 1 := g.zero.eq_of_nhds + +end trunc + +namespace W1 + +instance : CoeFun (W1 n E) (fun _ => ℝ → E) where coe := W1.toFun + +lemma continuous (f : W1 n E) : Continuous f := f.smooth.continuous + +lemma differentiable (f : W1 (n + 1) E) : Differentiable ℝ f := + f.smooth.differentiable (by simp) + +lemma iteratedDeriv_sub {f g : ℝ → E} (hf : ContDiff ℝ n f) (hg : ContDiff ℝ n g) : + iteratedDeriv n (f - g) = iteratedDeriv n f - iteratedDeriv n g := by + induction n generalizing f g with + | zero => rfl + | succ n ih => + have hf' : ContDiff ℝ n (deriv f) := hf.iterate_deriv' n 1 + have hg' : ContDiff ℝ n (deriv g) := hg.iterate_deriv' n 1 + have hfg : deriv (f - g) = deriv f - deriv g := by + ext x ; apply deriv_sub + · exact (hf.differentiable (by simp)).differentiableAt + · exact (hg.differentiable (by simp)).differentiableAt + simp_rw [iteratedDeriv_succ', ← ih hf' hg', hfg] + +noncomputable def deriv (f : W1 (n + 1) E) : W1 n E where + toFun := _root_.deriv f + smooth := contDiff_succ_iff_deriv.mp f.smooth |>.2.2 + integrable k hk := by + simpa [iteratedDeriv_succ'] using f.integrable (Nat.succ_le_succ hk) + +lemma hasDerivAt (f : W1 (n + 1) E) (x : ℝ) : HasDerivAt f (f.deriv x) x := + f.differentiable.differentiableAt.hasDerivAt + +def sub (f g : W1 n E) : W1 n E where + toFun := f - g + smooth := f.smooth.sub g.smooth + integrable k hk := by + have hf : ContDiff ℝ k f := f.smooth.of_le (by simp [hk]) + have hg : ContDiff ℝ k g := g.smooth.of_le (by simp [hk]) + simpa [iteratedDeriv_sub hf hg] using (f.integrable hk).sub (g.integrable hk) + +instance : Sub (W1 n E) where sub := sub + +lemma integrable_iteratedDeriv_Schwarz {f : 𝓢(ℝ, ℂ)} : Integrable (iteratedDeriv n f) := by + induction n generalizing f with + | zero => exact f.integrable + | succ n ih => simpa [iteratedDeriv_succ'] using! ih (f := SchwartzMap.derivCLM ℝ ℂ f) + +noncomputable def of_Schwartz (f : 𝓢(ℝ, ℂ)) : W1 n ℂ where + toFun := f + smooth := f.smooth n + integrable _ _ := integrable_iteratedDeriv_Schwarz + +end W1 + +namespace W21 + +variable {f : W21} + +noncomputable def norm (f : ℝ → ℂ) : ℝ := + (∫ v, ‖f v‖) + (4 * π ^ 2)⁻¹ * (∫ v, ‖deriv (deriv f) v‖) + +lemma norm_nonneg {f : ℝ → ℂ} : 0 ≤ norm f := + add_nonneg (integral_nonneg (fun t => by simp)) + (mul_nonneg (by positivity) (integral_nonneg (fun t => by simp))) + +noncomputable instance : Norm W21 where norm := norm ∘ W1.toFun + +noncomputable instance : Coe 𝓢(ℝ, ℂ) W21 where coe := W1.of_Schwartz + +def ofCS2 (f : CS 2 ℂ) : W21 := by + refine ⟨f, f.h1, fun k hk => ?_⟩ ; match k with + | 0 => exact f.h1.continuous.integrable_of_hasCompactSupport f.h2 + | 1 => simpa using (f.h1.continuous_deriv one_le_two).integrable_of_hasCompactSupport f.h2.deriv + | 2 => simpa [iteratedDeriv_succ] using + (f.h1.iterate_deriv' 0 2).continuous.integrable_of_hasCompactSupport f.h2.deriv.deriv + +instance : Coe (CS 2 ℂ) W21 where coe := ofCS2 + +instance : HMul (CS 2 ℂ) W21 (CS 2 ℂ) where + hMul g f := ⟨g * f, g.h1.mul f.smooth, g.h2.mul_right⟩ + +instance : HMul (CS 2 ℝ) W21 (CS 2 ℂ) where hMul g f := (g : CS 2 ℂ) * f + +lemma hf (f : W21) : Integrable f := f.integrable zero_le_two + +lemma hf' (f : W21) : Integrable (deriv f) := by + simpa [iteratedDeriv_succ] using f.integrable one_le_two + +lemma hf'' (f : W21) : Integrable (deriv (deriv f)) := by + simpa [iteratedDeriv_succ] using f.integrable le_rfl + +end W21 + +theorem W21_approximation (f : W21) (g : trunc) : + Tendsto (fun R => ‖f - (g.scale R * f : W21)‖) atTop (𝓝 0) := by + + let f' := f.deriv + let f'' := f'.deriv + let g' := (g : CS 2 ℝ).deriv + let g'' := g'.deriv + let h R v := 1 - g.scale R v + let h' R := - (g.scale R).deriv + let h'' R := - (g.scale R).deriv.deriv + + have ch {R} : Continuous (fun v => (h R v : ℂ)) := + continuous_ofReal.comp <| continuous_const.sub (CS.continuous _) + have ch' {R} : Continuous (fun v => (h' R v : ℂ)) := continuous_ofReal.comp (CS.continuous _) + have ch'' {R} : Continuous (fun v => (h'' R v : ℂ)) := continuous_ofReal.comp (CS.continuous _) + have dh R v : HasDerivAt (h R) (h' R v) v := by + convert! CS.hasDerivAt_scale (g : CS 2 ℝ) R v |>.const_sub 1 using 1 + simp [h', CS.deriv_scale', show g.deriv.toFun = deriv g.toFun from rfl] + have dh' R v : HasDerivAt (h' R) (h'' R v) v := ((g.scale R).deriv.hasDerivAt v).neg + have hh1 R v : |h R v| ≤ 1 := by + by_cases hR : R = 0 <;> + simp only [CS.scale, funscale, smul_eq_mul, hR, ↓reduceDIte, Pi.zero_apply, sub_zero, + abs_one, le_refl, h] + rw [abs_le] ; constructor <;> + linarith [g.le_one (R⁻¹ * v), g.nonneg (R⁻¹ * v)] + have vR v : Tendsto (fun R : ℝ => v * R⁻¹) atTop (𝓝 0) := by + simpa using tendsto_inv_atTop_zero.const_mul v + + convert_to Tendsto (fun R => W21.norm (fun v => h R v * f v)) atTop (𝓝 0) + · ext R ; change W21.norm _ = _ ; congr ; ext v ; simp [h, sub_mul] ; rfl + rw [show (0 : ℝ) = 0 + ((4 * π ^ 2)⁻¹ : ℝ) * 0 by simp] + refine Tendsto.add ?_ (Tendsto.const_mul _ ?_) + + · let F R v := ‖h R v * f v‖ + have eh v : ∀ᶠ R in atTop, h R v = 0 := by + filter_upwards [(vR v).eventually g.zero, eventually_ne_atTop 0] with R hR hR' + simp [h, hR, CS.scale, hR', funscale, mul_comm R⁻¹] + have e1 : ∀ᶠ (n : ℝ) in atTop, AEStronglyMeasurable (F n) volume := by + apply Eventually.of_forall ; intro R + exact (ch.mul f.continuous).norm.aestronglyMeasurable + have e2 : ∀ᶠ (n : ℝ) in atTop, ∀ᵐ (a : ℝ), ‖F n a‖ ≤ ‖f a‖ := by + apply Eventually.of_forall ; intro R + apply Eventually.of_forall ; intro v + simpa [F] using mul_le_mul (hh1 R v) le_rfl (by simp) zero_le_one + have e4 : ∀ᵐ (a : ℝ), Tendsto (fun n ↦ F n a) atTop (𝓝 0) := by + apply Eventually.of_forall ; intro v + apply tendsto_nhds_of_eventually_eq ; filter_upwards [eh v] with R hR ; simp [F, hR] + simpa [F] using tendsto_integral_filter_of_dominated_convergence _ e1 e2 f.hf.norm e4 + + · let F R v := ‖h'' R v * f v + 2 * h' R v * f' v + h R v * f'' v‖ + convert_to Tendsto (fun R ↦ ∫ (v : ℝ), F R v) atTop (𝓝 0) + · have this R v : + deriv (deriv (fun v => h R v * f v)) v = + h'' R v * f v + 2 * h' R v * f' v + h R v * f'' v := by + have df v : HasDerivAt f (f' v) v := f.hasDerivAt v + have df' v : HasDerivAt f' (f'' v) v := f'.hasDerivAt v + have l3 v : HasDerivAt (fun v => h R v * f v) (h' R v * f v + h R v * f' v) v := + (dh R v).ofReal_comp.mul (df v) + have l5 : HasDerivAt (fun v => h' R v * f v) (h'' R v * f v + h' R v * f' v) v := + (dh' R v).ofReal_comp.mul (df v) + have l7 : HasDerivAt (fun v => h R v * f' v) (h' R v * f' v + h R v * f'' v) v := + (dh R v).ofReal_comp.mul (df' v) + have d1 : deriv (fun v => h R v * f v) = fun v => h' R v * f v + h R v * f' v := + funext (fun v => (l3 v).deriv) + rw [d1] ; convert! (l5.add l7).deriv using 1 ; ring + simp_rw [this, F] + + obtain ⟨c1, mg'⟩ := g'.bounded + obtain ⟨c2, mg''⟩ := g''.bounded + let bound v := c2 * ‖f v‖ + 2 * c1 * ‖f' v‖ + ‖f'' v‖ + have e1 : ∀ᶠ (n : ℝ) in atTop, AEStronglyMeasurable (F n) volume := by + apply Eventually.of_forall ; intro R ; apply (Continuous.norm ?_).aestronglyMeasurable + exact ((ch''.mul f.continuous).add ((continuous_const.mul ch').mul f.deriv.continuous)).add + (ch.mul f.deriv.deriv.continuous) + have e2 : ∀ᶠ R in atTop, ∀ᵐ (a : ℝ), ‖F R a‖ ≤ bound a := by + have hc1 : ∀ᶠ R in atTop, ∀ v, |h' R v| ≤ c1 := by + filter_upwards [eventually_ge_atTop 1] with R hR v + have hR' : R ≠ 0 := by linarith + have : 0 ≤ R := by linarith + simp only [CS.deriv_scale, CS.neg_apply, CS.smul_apply, smul_eq_mul, abs_neg, abs_mul, + abs_inv, abs_eq_self.mpr this, ge_iff_le, h'] + simp only [CS.scale, hR', ↓reduceDIte, funscale, smul_eq_mul] + convert_to _ ≤ c1 * 1 + · simp + · rw [mul_comm] + apply mul_le_mul (mg' _) + (inv_le_of_inv_le₀ (by linarith) (by simpa using hR)) (by positivity) + exact (abs_nonneg _).trans (mg' 0) + have hc2 : ∀ᶠ R in atTop, ∀ v, |h'' R v| ≤ c2 := by + filter_upwards [eventually_ge_atTop 1] with R hR v + have e1 : 0 ≤ R := by linarith + have e2 : R⁻¹ ≤ 1 := inv_le_of_inv_le₀ (by linarith) (by simpa using hR) + have e3 : R ≠ 0 := by linarith + simp only [CS.deriv_scale, CS.deriv_smul, CS.neg_apply, CS.smul_apply, smul_eq_mul, abs_neg, + abs_mul, abs_inv, abs_eq_self.mpr e1, ge_iff_le, h''] + convert_to _ ≤ 1 * (1 * c2) + · simp + apply mul_le_mul e2 ?_ (by positivity) zero_le_one + apply mul_le_mul e2 ?_ (by positivity) zero_le_one + simp only [CS.scale, e3, ↓reduceDIte, funscale, smul_eq_mul] ; apply mg'' + filter_upwards [hc1, hc2] with R hc1 hc2 + apply Eventually.of_forall ; intro v ; specialize hc1 v ; specialize hc2 v + simp only [F, bound, norm_norm] + refine (norm_add_le _ _).trans ?_ ; apply add_le_add + · refine (norm_add_le _ _).trans ?_ ; apply add_le_add <;> simp only [Complex.norm_mul, + Complex.norm_ofNat, norm_real, norm_eq_abs] <;> gcongr + · simpa using mul_le_mul (hh1 R v) le_rfl (by simp) zero_le_one + have e3 : Integrable bound volume := + (((f.hf.norm).const_mul _).add ((f.hf'.norm).const_mul _)).add f.hf''.norm + have e4 : ∀ᵐ (a : ℝ), Tendsto (fun n ↦ F n a) atTop (𝓝 0) := by + apply Eventually.of_forall ; intro v + have evg' : g' =ᶠ[𝓝 0] 0 := by convert! ← g.zero.deriv ; exact deriv_const' _ + have evg'' : g'' =ᶠ[𝓝 0] 0 := by convert! ← evg'.deriv ; exact deriv_const' _ + refine tendsto_norm_zero.comp <| (ZeroAtFilter.add ?_ ?_).add ?_ + · have eh'' v : ∀ᶠ R in atTop, h'' R v = 0 := by + filter_upwards [(vR v).eventually evg'', eventually_ne_atTop 0] with R hR hR' + simp only [CS.deriv_scale, CS.deriv_smul, CS.neg_apply, CS.smul_apply, smul_eq_mul, + neg_eq_zero, mul_eq_zero, inv_eq_zero, hR', false_or, h''] + simp only [CS.scale, hR', ↓reduceDIte, funscale, smul_eq_mul, mul_comm R⁻¹] + exact hR + apply tendsto_nhds_of_eventually_eq + filter_upwards [eh'' v] with R hR ; simp [hR] + · have eh' v : ∀ᶠ R in atTop, h' R v = 0 := by + filter_upwards [(vR v).eventually evg'] with R hR + simp [g'] at hR + simp [h', CS.deriv_scale', mul_comm R⁻¹, hR] + apply tendsto_nhds_of_eventually_eq + filter_upwards [eh' v] with R hR ; simp [hR] + · simpa [h] using! ((g.tendsto_scale v).const_sub 1).ofReal.mul tendsto_const_nhds + simpa [F] using tendsto_integral_filter_of_dominated_convergence bound e1 e2 e3 e4 + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Tactic/AdditiveCombination.lean b/PrimeNumberTheoremAnd/Erdos970/Tactic/AdditiveCombination.lean new file mode 100644 index 0000000..f79890f --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Tactic/AdditiveCombination.lean @@ -0,0 +1,90 @@ +import Mathlib.Tactic.Abel +import Mathlib.Tactic.LinearCombinationPrime + +namespace Erdos970 + +namespace Mathlib.Tactic.LinearCombinationPrime +open _root_.Mathlib.Tactic.LinearCombinationPrime +open Lean +open Elab Meta Term + +variable {α β : Type*} + +theorem pf_smul_c [SMul α β] {a b : α} (p : a = b) (c : β) : a • c = b • c := p ▸ rfl +theorem c_smul_pf [SMul α β] {b c : β} (p : b = c) (a : α) : a • b = a • c := p ▸ rfl +theorem smul_pf [SMul α β] {a₁ b₁ : α} (p₁ : (a₁ : α) = b₁) {a₂ b₂ : β} (p₂ : a₂ = b₂) : + a₁ • a₂ = b₁ • b₂ := p₁ ▸ p₂ ▸ rfl + +partial def expandAdditiveCombo (ty : Expr) (stx : Syntax.Term) : TermElabM Expanded := withRef stx do + match stx with + | `(($e)) => expandLinearCombo ty e + | `($e₁ + $e₂) => do + match ← expandAdditiveCombo ty e₁, ← expandAdditiveCombo ty e₂ with + | .const c₁, .const c₂ => .const <$> ``($c₁ + $c₂) + | .proof p₁, .const c₂ => .proof <$> ``(pf_add_c $p₁ $c₂) + | .const c₁, .proof p₂ => .proof <$> ``(c_add_pf $p₂ $c₁) + | .proof p₁, .proof p₂ => .proof <$> ``(add_pf $p₁ $p₂) + | `($e₁ - $e₂) => do + match ← expandAdditiveCombo ty e₁, ← expandAdditiveCombo ty e₂ with + | .const c₁, .const c₂ => .const <$> ``($c₁ - $c₂) + | .proof p₁, .const c₂ => .proof <$> ``(pf_sub_c $p₁ $c₂) + | .const c₁, .proof p₂ => .proof <$> ``(c_sub_pf $p₂ $c₁) + | .proof p₁, .proof p₂ => .proof <$> ``(sub_pf $p₁ $p₂) + | `(-$e) => do + match ← expandAdditiveCombo ty e with + | .const c => .const <$> `(-$c) + | .proof p => .proof <$> ``(neg_pf $p) + | `(← $e:term) => do + match ← expandAdditiveCombo ty e with + | .const c => return .const c + | .proof p => .proof <$> ``(Eq.symm $p) + | `($e₁ • $e₂) => do + match ← expandAdditiveCombo ty e₁, ← expandAdditiveCombo ty e₂ with + | .const c₁, .const c₂ => .const <$> ``($c₁ • $c₂) + | .proof p₁, .const c₂ => .proof <$> ``(pf_smul_c $p₁ $c₂) + | .const c₁, .proof p₂ => .proof <$> ``(c_smul_pf $p₂ $c₁) + | .proof p₁, .proof p₂ => .proof <$> ``(smul_pf $p₁ $p₂) + | e => + + withSynthesize do + + let c ← withSynthesizeLight <| Term.elabTerm e ty + if (← whnfR (← inferType c)).isEq then + .proof <$> c.toSyntax + else + .const <$> c.toSyntax + +def elabAdditiveCombination (tk : Syntax) + (norm? : Option Syntax.Tactic) (exp? : Option Syntax.NumLit) (input : Option Syntax.Term) + (twoGoals := false) : Tactic.TacticM Unit := Tactic.withMainContext do + let some (ty, _) := (← (← Tactic.getMainGoal).getType').eq? | + throwError "'additive_combination' only proves equalities" + let p ← match input with + | none => `(Eq.refl 0) + | some e => + match ← expandAdditiveCombo ty e with + | .const c => `(Eq.refl $c) + | .proof p => pure p + let norm := norm?.getD (Unhygienic.run <| withRef tk `(tactic| ((try simp only [smul_add, smul_sub]); abel))) + Term.withoutErrToSorry <| Tactic.evalTactic <| ← withFreshMacroScope <| + if twoGoals then + `(tactic| ( + refine eq_trans₃ $p ?a ?b + case' a => $norm:tactic + case' b => $norm:tactic)) + else + match exp? with + | some n => + if n.getNat = 1 then `(tactic| (refine eq_of_add $p ?a; case' a => $norm:tactic)) + else `(tactic| (refine eq_of_add_pow $n $p ?a; case' a => $norm:tactic)) + | _ => `(tactic| (refine eq_of_add $p ?a; case' a => $norm:tactic)) + +syntax (name := AdditiveCombination) "additive_combination" + (normStx)? (expStx)? (ppSpace colGt term)? : tactic +elab_rules : tactic + | `(tactic| additive_combination%$tk $[(norm := $tac)]? $[(exp := $n)]? $(e)?) => + elabAdditiveCombination tk tac n e + +end Mathlib.Tactic.LinearCombinationPrime + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/Wiener.lean b/PrimeNumberTheoremAnd/Erdos970/Wiener.lean new file mode 100644 index 0000000..3259e31 --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/Wiener.lean @@ -0,0 +1,3571 @@ +import Mathlib.Analysis.Fourier.RiemannLebesgueLemma +import Mathlib.Analysis.Normed.Group.Tannery +import Mathlib.Analysis.SumIntegralComparisons +import Mathlib.NumberTheory.Chebyshev +import Mathlib.NumberTheory.LSeries.PrimesInAP +import Mathlib.NumberTheory.MulChar.Lemmas +import Mathlib.Topology.EMetricSpace.BoundedVariation +import PrimeNumberTheoremAnd.Erdos970.Mathlib.Analysis.Asymptotics.Asymptotics +import PrimeNumberTheoremAnd.Erdos970.Fourier +import PrimeNumberTheoremAnd.Erdos970.SmoothExistence +import Mathlib.Analysis.Convolution + +namespace Erdos970 + + +open Real BigOperators ArithmeticFunction MeasureTheory Filter Set FourierTransform LSeries + _root_.Asymptotics Erdos970.Asymptotics SchwartzMap +open Complex hiding log +open scoped Topology +open scoped ContDiff +open scoped ComplexConjugate + +variable {n : ℕ} {A a b c d u x y t σ' : ℝ} {ψ Ψ : ℝ → ℂ} {F G : ℂ → ℂ} {f : ℕ → ℂ} {𝕜 : Type} + [RCLike 𝕜] + +noncomputable +def nterm (f : ℕ → ℂ) (σ' : ℝ) (n : ℕ) : ℝ := if n = 0 then 0 else ‖f n‖ / n ^ σ' + +lemma nterm_eq_norm_term {f : ℕ → ℂ} : nterm f σ' n = ‖term f σ' n‖ := by + by_cases h : n = 0 <;> simp [nterm, term, h] + +theorem norm_term_eq_nterm_re (s : ℂ) : + ‖term f s n‖ = nterm f (s.re) n := by + simp only [nterm, term, apply_ite (‖·‖), norm_zero, norm_div] + apply ite_congr rfl (fun _ ↦ rfl) + intro h + congr + refine norm_natCast_cpow_of_pos (by omega) s + +lemma hf_coe1 (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hσ : 1 < σ') : + ∑' i, (‖term f σ' i‖₊ : ENNReal) ≠ ⊤ := by + simp_rw [ENNReal.tsum_coe_ne_top_iff_summable_coe, ← norm_toNNReal] + norm_cast + apply Summable.toNNReal + convert hf σ' hσ with i + simp [nterm_eq_norm_term] + +instance instMeasurableSpace : MeasurableSpace Circle := + inferInstanceAs <| MeasurableSpace <| Subtype _ +instance instBorelSpace : BorelSpace Circle := + inferInstanceAs <| BorelSpace <| Subtype (· ∈ Metric.sphere (0 : ℂ) 1) + +attribute [fun_prop] Real.continuous_fourierChar + +lemma first_fourier_aux1 (hψ : AEMeasurable ψ) {x : ℝ} (n : ℕ) : AEMeasurable fun (u : ℝ) ↦ + (‖fourierChar (-(u * ((1 : ℝ) / ((2 : ℝ) * π) * (n / x).log))) • ψ u‖ₑ : ENNReal) := by + fun_prop + +lemma first_fourier_aux2a : + (2 : ℂ) * π * -(y * (1 / (2 * π) * Real.log ((n) / x))) = -(y * ((n) / x).log) := by + calc + _ = -(y * (((2 : ℂ) * π) / (2 * π) * Real.log ((n) / x))) := by ring + _ = _ := by rw [div_self (by norm_num), one_mul] + +lemma first_fourier_aux2 (hx : 0 < x) (n : ℕ) : + term f σ' n * 𝐞 (-(y * (1 / (2 * π) * Real.log (n / x)))) • ψ y = + term f (σ' + y * I) n • (ψ y * x ^ (y * I)) := by + by_cases hn : n = 0 + · simp [term, hn] + simp only [term, hn, ↓reduceIte] + calc + _ = (f n * (cexp ((2 * π * -(y * (1 / (2 * π) * Real.log (n / x)))) * I) / + ↑((n : ℝ) ^ σ'))) • ψ y := by + rw [Circle.smul_def, fourierChar_apply, ofReal_cpow (by norm_num)] + simp only [one_div, mul_inv_rev, mul_neg, ofReal_neg, ofReal_mul, ofReal_ofNat, ofReal_inv, + neg_mul, smul_eq_mul, ofReal_natCast] + ring + _ = (f n * (x ^ (y * I) / n ^ (σ' + y * I))) • ψ y := by + congr 2 + have l1 : 0 < (n : ℝ) := by simpa using Nat.pos_iff_ne_zero.mpr hn + have l2 : (x : ℂ) ≠ 0 := by simp [hx.ne.symm] + have l3 : (n : ℂ) ≠ 0 := by simp [hn] + rw [Real.rpow_def_of_pos l1, Complex.cpow_def_of_ne_zero l2, Complex.cpow_def_of_ne_zero l3] + push_cast + simp_rw [← Complex.exp_sub] + congr 1 + rw [first_fourier_aux2a, Real.log_div l1.ne.symm hx.ne.symm] + push_cast + rw [Complex.ofReal_log hx.le] + ring + _ = _ := by simp ; group + + +lemma first_fourier (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hsupp : Integrable ψ) (hx : 0 < x) (hσ : 1 < σ') : + ∑' n : ℕ, term f σ' n * (𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))) = + ∫ t : ℝ, LSeries f (σ' + t * I) * ψ t * x ^ (t * I) := by + + calc + _ = ∑' n, term f σ' n * ∫ (v : ℝ), 𝐞 (-(v * ((1 : ℝ) / + ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by + simp only [Real.fourier_eq] + simp only [one_div, mul_inv_rev, RCLike.inner_apply', conj_trivial] + _ = ∑' n, ∫ (v : ℝ), term f σ' n * 𝐞 (-(v * ((1 : ℝ) / + ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by + simp [integral_const_mul] + _ = ∫ (v : ℝ), ∑' n, term f σ' n * 𝐞 (-(v * ((1 : ℝ) / + ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by + refine (integral_tsum ?_ ?_).symm + · refine fun _ ↦ AEMeasurable.aestronglyMeasurable ?_ + have := hsupp.aemeasurable + fun_prop + · simp only [enorm_mul] + simp_rw [lintegral_const_mul'' _ (first_fourier_aux1 hsupp.aemeasurable _)] + calc + _ = (∑' (i : ℕ), ‖term f σ' i‖ₑ) * ∫⁻ (a : ℝ), ‖ψ a‖ₑ ∂volume := by + simp [ENNReal.tsum_mul_right, enorm_eq_nnnorm] + _ ≠ ⊤ := ENNReal.mul_ne_top (hf_coe1 hf hσ) + (ne_top_of_lt hsupp.2) + _ = _ := by + congr 1; ext y + simp_rw [mul_assoc (LSeries _ _), ← smul_eq_mul (a := (LSeries _ _)), LSeries] + rw [← Summable.tsum_smul_const] + · simp_rw [first_fourier_aux2 hx] + · apply Summable.of_norm + convert hf σ' hσ with n + rw [norm_term_eq_nterm_re] + simp + +@[continuity] +lemma continuous_multiplicative_ofAdd : Continuous (⇑Multiplicative.ofAdd : ℝ → ℝ) := ⟨fun _ ↦ id⟩ + +attribute [fun_prop] measurable_coe_nnreal_ennreal + +lemma second_fourier_integrable_aux1a (hσ : 1 < σ') : + IntegrableOn (fun (x : ℝ) ↦ cexp (-((x : ℂ) * ((σ' : ℂ) - 1)))) (Ici (-Real.log x)) := by + norm_cast + suffices IntegrableOn (fun (x : ℝ) ↦ (rexp (-(x * (σ' - 1))))) (Ici (-x.log)) _ from this.ofReal + simp_rw [fun (a x : ℝ) ↦ (by ring : -(x * a) = -a * x)] + rw [integrableOn_Ici_iff_integrableOn_Ioi] + apply exp_neg_integrableOn_Ioi + linarith + +lemma second_fourier_integrable_aux1 (hcont : Measurable ψ) (hsupp : Integrable ψ) (hσ : 1 < σ') : + let ν : Measure (ℝ × ℝ) := (volume.restrict (Ici (-Real.log x))).prod volume + Integrable (Function.uncurry fun (u : ℝ) (a : ℝ) ↦ ((rexp (-u * (σ' - 1))) : ℂ) • + (𝐞 (Multiplicative.ofAdd (-(a * (u / (2 * π))))) : ℂ) • ψ a) ν := by + intro ν + constructor + · apply Measurable.aestronglyMeasurable + + simp only [neg_mul, ofReal_exp, ofReal_neg, ofReal_mul, ofReal_sub, ofReal_one, + Multiplicative.ofAdd, smul_eq_mul] + change Measurable (fun v : ℝ × ℝ => + cexp (-((v.1 : ℂ) * ((σ' : ℂ) - 1))) * + ((𝐞 (-(v.2 * (v.1 / (2 * π)))) : ℂ) * ψ v.2)) + fun_prop + · let f1 : ℝ → ENNReal := fun a1 ↦ ‖cexp (-(↑a1 * (↑σ' - 1)))‖ₑ + let f2 : ℝ → ENNReal := fun a2 ↦ ‖ψ a2‖ₑ + suffices ∫⁻ (a : ℝ × ℝ), f1 a.1 * f2 a.2 ∂ν < ⊤ by + simpa [hasFiniteIntegral_iff_enorm, enorm_eq_nnnorm, Function.uncurry] + refine (lintegral_prod_mul ?_ ?_).trans_lt ?_ <;> try fun_prop + exact ENNReal.mul_lt_top (second_fourier_integrable_aux1a hσ).2 hsupp.2 + +lemma second_fourier_integrable_aux2 (hσ : 1 < σ') : + IntegrableOn (fun (u : ℝ) ↦ cexp ((1 - ↑σ' - ↑t * I) * ↑u)) (Ioi (-Real.log x)) := by + refine (integrable_norm_iff (Measurable.aestronglyMeasurable <| by fun_prop)).mp ?_ + suffices IntegrableOn (fun a ↦ rexp (-(σ' - 1) * a)) (Ioi (-x.log)) _ by simpa [Complex.norm_exp] + apply exp_neg_integrableOn_Ioi + linarith + +lemma second_fourier_aux (hx : 0 < x) : + -(cexp (-((1 - ↑σ' - ↑t * I) * ↑(Real.log x))) / (1 - ↑σ' - ↑t * I)) = + ↑(x ^ (σ' - 1)) * (↑σ' + ↑t * I - 1)⁻¹ * ↑x ^ (↑t * I) := by + calc + _ = cexp (↑(Real.log x) * ((↑σ' - 1) + ↑t * I)) * (↑σ' + ↑t * I - 1)⁻¹ := by + rw [← div_neg]; ring_nf + _ = (x ^ ((↑σ' - 1) + ↑t * I)) * (↑σ' + ↑t * I - 1)⁻¹ := by + rw [Complex.cpow_def_of_ne_zero (ofReal_ne_zero.mpr (ne_of_gt hx)), Complex.ofReal_log hx.le] + _ = (x ^ ((σ' : ℂ) - 1)) * (x ^ (↑t * I)) * (↑σ' + ↑t * I - 1)⁻¹ := by + rw [Complex.cpow_add _ _ (ofReal_ne_zero.mpr (ne_of_gt hx))] + _ = _ := by rw [ofReal_cpow hx.le]; push_cast; ring + + +lemma second_fourier (hcont : Measurable ψ) (hsupp : Integrable ψ) + {x σ' : ℝ} (hx : 0 < x) (hσ : 1 < σ') : + ∫ u in Ici (-log x), Real.exp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = + (x^(σ' - 1) : ℝ) * ∫ t, (1 / (σ' + t * I - 1)) * ψ t * x^(t * I) ∂ volume := by + + conv in ↑(rexp _) * _ => { rw [Real.fourier_real_eq, ← smul_eq_mul, ← integral_smul] } + rw [MeasureTheory.integral_integral_swap] + swap + · exact second_fourier_integrable_aux1 hcont hsupp hσ + rw [← integral_const_mul] + congr 1; ext t + dsimp + + simp_rw [mul_smul_comm, ← smul_mul_assoc, integral_mul_const] + rw [fun (a b d : ℂ) ↦ show a * (b * (ψ t) * d) = (a * b * d) * ψ t by ring] + congr 1 + conv => + lhs + enter [2] + ext a + rw [Circle.smul_def, smul_eq_mul] + simp only [Real.fourierChar, Circle.exp] + change cexp ((↑(2 * π * -(t * (a / (2 * π)))) : ℂ) * I) * + (rexp (-a * (σ' - 1)) : ℂ) + push_cast + simp_rw [← Complex.exp_add] + have (u : ℝ) : + 2 * ↑π * -(↑t * (↑u / (2 * ↑π))) * I + -↑u * (↑σ' - 1) = (1 - σ' - t * I) * u := calc + _ = -↑u * (↑σ' - 1) + (2 * ↑π) / (2 * ↑π) * -(↑t * ↑u) * I := by ring + _ = -↑u * (↑σ' - 1) + 1 * -(↑t * ↑u) * I := by rw [div_self (by norm_num)] + _ = _ := by ring + simp_rw [this] + let c : ℂ := (1 - ↑σ' - ↑t * I) + have : c ≠ 0 := by simp [Complex.ext_iff, c, sub_ne_zero.mpr hσ.ne] + let f' (u : ℝ) := cexp (c * u) + let f := fun (u : ℝ) ↦ (f' u) / c + have hderiv : ∀ u ∈ Ici (-Real.log x), HasDerivAt f (f' u) u := by + intro u _ + rw [show f' u = cexp (c * u) * (c * 1) / c by simp only [f']; field_simp] + exact (hasDerivAt_id' u).ofReal_comp.const_mul c |>.cexp.div_const c + have hf : Tendsto f atTop (𝓝 0) := by + apply tendsto_zero_iff_norm_tendsto_zero.mpr + suffices Tendsto (fun (x : ℝ) ↦ ‖cexp (c * ↑x)‖ / ‖c‖) atTop (𝓝 (0 / ‖c‖)) by + simpa [f, f'] using this + apply Filter.Tendsto.div_const + suffices Tendsto (· * (1 - σ')) atTop atBot by simpa [Complex.norm_exp, mul_comm (1 - σ'), c] + exact Tendsto.atTop_mul_const_of_neg (by linarith) fun ⦃s⦄ h ↦ h + rw [integral_Ici_eq_integral_Ioi, + integral_Ioi_of_hasDerivAt_of_tendsto' hderiv (second_fourier_integrable_aux2 hσ) hf] + simpa [f, f'] using second_fourier_aux hx + +lemma one_add_sq_pos (u : ℝ) : 0 < 1 + u ^ 2 := zero_lt_one.trans_le (by simpa using sq_nonneg u) + +theorem prelim_decay (ψ : ℝ → ℂ) (u : ℝ) : ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ ∫ t, ‖ψ t‖ := + VectorFourier.norm_fourierIntegral_le_integral_norm .. + +lemma decay_bounds_key (f : W21) (u : ℝ) : ‖𝓕 (f : ℝ → ℂ) u‖ ≤ ‖f‖ * (1 + u ^ 2)⁻¹ := by + have l1 : 0 < 1 + u ^ 2 := one_add_sq_pos _ + have l2 : 1 + u ^ 2 = ‖(1 : ℂ) + u ^ 2‖ := by + norm_cast ; simp only [Real.norm_eq_abs, abs_eq_self.2 l1.le] + have l3 : ‖1 / ((4 : ℂ) * ↑π ^ 2)‖ ≤ (4 * π ^ 2)⁻¹ := by simp + have key := fourierIntegral_self_add_deriv_deriv f u + simp only [Function.iterate_succ _ 1, Function.iterate_one, Function.comp_apply] at key + rw [F_sub f.hf (f.hf''.const_mul (1 / (4 * ↑π ^ 2)))] at key + rw [← div_eq_mul_inv, le_div_iff₀ l1, mul_comm, l2, ← norm_mul, key, sub_eq_add_neg] + apply norm_add_le _ _ |>.trans + change _ ≤ W21.norm _ + rw [norm_neg, F_mul, norm_mul, W21.norm] + gcongr <;> apply VectorFourier.norm_fourierIntegral_le_integral_norm + +lemma decay_bounds_aux {f : ℝ → ℂ} (hf : AEStronglyMeasurable f volume) + (h : ∀ t, ‖f t‖ ≤ A * (1 + t ^ 2)⁻¹) : + ∫ t, ‖f t‖ ≤ π * A := by + have l1 : Integrable (fun x ↦ A * (1 + x ^ 2)⁻¹) := integrable_inv_one_add_sq.const_mul A + simp_rw [← integral_univ_inv_one_add_sq, mul_comm, ← integral_const_mul] + exact integral_mono (l1.mono' hf (Eventually.of_forall h)).norm l1 h + +theorem decay_bounds_W21 (f : W21) (hA : ∀ t, ‖f t‖ ≤ A / (1 + t ^ 2)) + (hA' : ∀ t, ‖deriv (deriv f) t‖ ≤ A / (1 + t ^ 2)) (u) : + ‖𝓕 (f : ℝ → ℂ) u‖ ≤ (π + 1 / (4 * π)) * A / (1 + u ^ 2) := by + have l0 : 1 * (4 * π)⁻¹ * A = (4 * π ^ 2)⁻¹ * (π * A) := by field_simp + have l1 : ∫ (v : ℝ), ‖f v‖ ≤ π * A := by + apply decay_bounds_aux f.continuous.aestronglyMeasurable + simp_rw [← div_eq_mul_inv] ; exact hA + have l2 : ∫ (v : ℝ), ‖deriv (deriv f) v‖ ≤ π * A := by + apply decay_bounds_aux f.deriv.deriv.continuous.aestronglyMeasurable + simp_rw [← div_eq_mul_inv] ; exact hA' + apply decay_bounds_key f u |>.trans + change W21.norm _ * _ ≤ _ + simp_rw [W21.norm, div_eq_mul_inv, add_mul, l0] ; gcongr + +lemma decay_bounds (ψ : CS 2 ℂ) (hA : ∀ t, ‖ψ t‖ ≤ A / (1 + t ^ 2)) + (hA' : ∀ t, ‖deriv^[2] ψ t‖ ≤ A / (1 + t ^ 2)) : + ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ (π + 1 / (4 * π)) * A / (1 + u ^ 2) := by + exact decay_bounds_W21 ψ hA hA' u + +lemma decay_bounds_cor_aux (ψ : CS 2 ℂ) : ∃ C : ℝ, ∀ u, ‖ψ u‖ ≤ C / (1 + u ^ 2) := by + have l1 : HasCompactSupport (fun u : ℝ => ((1 + u ^ 2) : ℝ) * ψ u) := by exact ψ.h2.mul_left + have := ψ.h1.continuous + obtain ⟨C, hC⟩ := l1.exists_bound_of_continuous (by fun_prop) + refine ⟨C, fun u => ?_⟩ + specialize hC u + simp only [norm_mul, Complex.norm_real, norm_of_nonneg (one_add_sq_pos u).le] at hC + rwa [le_div_iff₀' (one_add_sq_pos _)] + +lemma decay_bounds_cor (ψ : W21) : + ∃ C : ℝ, ∀ u, ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ C / (1 + u ^ 2) := by + simpa only [div_eq_mul_inv] using ⟨_, decay_bounds_key ψ⟩ + +@[continuity, fun_prop] lemma continuous_FourierIntegral (ψ : W21) : Continuous (𝓕 (ψ : ℝ → ℂ)) := + VectorFourier.fourierIntegral_continuous continuous_fourierChar + (by simp only [innerₗ_apply_apply, RCLike.inner_apply', conj_trivial, continuous_mul]) + ψ.hf + +lemma W21.integrable_fourier (ψ : W21) (hc : c ≠ 0) : + Integrable fun u ↦ 𝓕 (ψ : ℝ → ℂ) (u / c) := by + have l1 (C) : Integrable (fun u ↦ C / (1 + (u / c) ^ 2)) volume := by + simpa using! (integrable_inv_one_add_sq.comp_div hc).const_mul C + have l2 : AEStronglyMeasurable (fun u ↦ 𝓕 (ψ : ℝ → ℂ) (u / c)) volume := by + apply Continuous.aestronglyMeasurable ; fun_prop + obtain ⟨C, h⟩ := decay_bounds_cor ψ + apply @Integrable.mono' ℝ ℂ _ volume _ _ (fun u => C / (1 + (u / c) ^ 2)) (l1 C) l2 ?_ + apply Eventually.of_forall (fun x => h _) + +lemma continuous_LSeries_aux (hf : Summable (nterm f σ')) : + Continuous fun x : ℝ => LSeries f (σ' + x * I) := by + + have l1 i : Continuous fun x : ℝ ↦ term f (σ' + x * I) i := by + by_cases h : i = 0 + · simpa [h] using continuous_const + · simpa [h] using! continuous_const.div (continuous_const.cpow (by fun_prop) (by simp [h])) + (fun x => by simp [h]) + have l2 n (x : ℝ) : ‖term f (σ' + x * I) n‖ = nterm f σ' n := by + by_cases h : n = 0 + · simp [h, nterm] + · simp [h, nterm, cpow_add _ _ (Nat.cast_ne_zero.mpr h), + Complex.norm_natCast_cpow_of_pos (Nat.pos_of_ne_zero h)] + exact continuous_tsum l1 hf (fun n x => le_of_eq (l2 n x)) + +lemma limiting_fourier_aux (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 1 ≤ x) (σ' : ℝ) + (hσ' : 1 < σ') : + ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * (x ^ (1 - σ') : ℝ) * ∫ u in Ici (- log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) + (u / (2 * π)) = ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I) := by + have hint : Integrable ψ := ψ.h1.continuous.integrable_of_hasCompactSupport ψ.h2 + have l3 : 0 < x := zero_lt_one.trans_le hx + have l1 (σ') (hσ' : 1 < σ') := first_fourier hf hint l3 hσ' + have l2 (σ') (hσ' : 1 < σ') := second_fourier ψ.h1.continuous.measurable hint l3 hσ' + have l8 : Continuous fun t : ℝ ↦ (x : ℂ) ^ (t * I) := + continuous_const.cpow (continuous_ofReal.mul continuous_const) (by simp [l3]) + have l6 : Continuous fun t : ℝ ↦ LSeries f (↑σ' + ↑t * I) * ψ t * ↑x ^ (↑t * I) := by + apply ((continuous_LSeries_aux (hf _ hσ')).mul ψ.h1.continuous).mul l8 + have l4 : Integrable fun t : ℝ ↦ LSeries f (↑σ' + ↑t * I) * ψ t * ↑x ^ (↑t * I) := by + exact l6.integrable_of_hasCompactSupport ψ.h2.mul_left.mul_right + have e2 (u : ℝ) : σ' + u * I - 1 ≠ 0 := by + intro h ; have := congr_arg Complex.re h ; simp at this ; linarith + have l7 : Continuous fun a ↦ A * ↑(x ^ (1 - σ')) * (↑(x ^ (σ' - 1)) * + (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by + simp only [one_div, ← mul_assoc] + refine ((continuous_const.mul <| Continuous.inv₀ ?_ e2).mul ψ.h1.continuous).mul l8 + fun_prop + have l5 : Integrable fun a ↦ A * ↑(x ^ (1 - σ')) * (↑(x ^ (σ' - 1)) * + (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by + apply l7.integrable_of_hasCompactSupport + exact ψ.h2.mul_left.mul_right.mul_left.mul_left + + simp_rw [l1 σ' hσ', l2 σ' hσ', ← integral_const_mul, ← integral_sub l4 l5] + apply integral_congr_ae + apply Eventually.of_forall + intro u + have e1 : 1 < ((σ' : ℂ) + (u : ℂ) * I).re := by simp [hσ'] + simp_rw [hG' e1, sub_mul, ← mul_assoc] + simp only [one_div, sub_right_inj, mul_eq_mul_right_iff, cpow_eq_zero_iff, ofReal_eq_zero, ne_eq, + mul_eq_zero, I_ne_zero, or_false] + left ; left + field_simp [e2] + norm_cast + simp [mul_assoc, ← rpow_add l3] + +section nabla + +variable {α E : Type*} [OfNat α 1] [Add α] [Sub α] {u : α → ℂ} + +def cumsum [AddCommMonoid E] (u : ℕ → E) (n : ℕ) : E := ∑ i ∈ Finset.range n, u i + +def nabla [Sub E] (u : α → E) (n : α) : E := u (n + 1) - u n + +def nnabla [Sub E] (u : α → E) (n : α) : E := u n - u (n + 1) + +def shift (u : α → E) (n : α) : E := u (n + 1) + +@[simp] lemma cumsum_zero [AddCommMonoid E] {u : ℕ → E} : cumsum u 0 = 0 := by simp [cumsum] + +lemma cumsum_succ [AddCommMonoid E] {u : ℕ → E} (n : ℕ) : + cumsum u (n + 1) = cumsum u n + u n := by + simp [cumsum, Finset.sum_range_succ] + +@[simp] lemma nabla_cumsum [AddCommGroup E] {u : ℕ → E} : nabla (cumsum u) = u := by + ext n ; simp [nabla, cumsum, Finset.range_add_one] + +lemma neg_cumsum [AddCommGroup E] {u : ℕ → E} : -(cumsum u) = cumsum (-u) := + funext (fun n => by simp [cumsum]) + +lemma cumsum_nonneg {u : ℕ → ℝ} (hu : 0 ≤ u) : 0 ≤ cumsum u := + fun _ => Finset.sum_nonneg (fun i _ => hu i) + +omit [Sub α] in +lemma neg_nabla [Ring E] {u : α → E} : -(nabla u) = nnabla u := by ext n ; simp [nabla, nnabla] + +omit [Sub α] in +@[simp] lemma nabla_mul [Ring E] {u : α → E} {c : E} : nabla (fun n => c * u n) = c • nabla u := by + ext n ; simp [nabla, mul_sub] + +omit [Sub α] in +@[simp] lemma nnabla_mul [Ring E] {u : α → E} {c : E} : + nnabla (fun n => c * u n) = c • nnabla u := by + ext n ; simp [nnabla, mul_sub] + +lemma nnabla_cast (u : ℝ → E) [Sub E] : nnabla u ∘ ((↑) : ℕ → ℝ) = nnabla (u ∘ (↑)) := by + ext n ; simp [nnabla] + +end nabla + +lemma Finset.sum_shift_front {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : + cumsum u (n + 1) = u 0 + cumsum (shift u) n := by + simp_rw [add_comm n, cumsum, _root_.Finset.sum_range_add, + _root_.Finset.sum_range_one, add_comm 1] ; rfl + +lemma Finset.sum_shift_front' {E : Type*} [Ring E] {u : ℕ → E} : + shift (cumsum u) = (fun _ => u 0) + cumsum (shift u) := by + ext n ; apply Finset.sum_shift_front + +lemma Finset.sum_shift_back {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : + cumsum u (n + 1) = cumsum u n + u n := by + simp [cumsum, Finset.range_add_one, add_comm] + +lemma Finset.sum_shift_back' {E : Type*} [Ring E] {u : ℕ → E} : + shift (cumsum u) = cumsum u + u := by + ext n ; apply Finset.sum_shift_back + +lemma summation_by_parts {E : Type*} [Ring E] {a A b : ℕ → E} (ha : a = nabla A) {n : ℕ} : + cumsum (a * b) (n + 1) = A (n + 1) * b n - A 0 * b 0 - + cumsum (shift A * fun i => (b (i + 1) - b i)) n := by + have l1 : ∑ x ∈ Finset.range (n + 1), A (x + 1) * b x = ∑ x ∈ Finset.range n, + A (x + 1) * b x + A (n + 1) * b n := + Finset.sum_shift_back + have l2 : ∑ x ∈ Finset.range (n + 1), A x * b x = A 0 * b 0 + ∑ x ∈ Finset.range n, + A (x + 1) * b (x + 1) := + Finset.sum_shift_front + simp only [cumsum, ha, Pi.mul_apply, nabla, sub_mul, Finset.sum_sub_distrib, l1, l2, shift, + mul_sub] + abel + +lemma summation_by_parts' {E : Type*} [Ring E] {a b : ℕ → E} {n : ℕ} : + cumsum (a * b) (n + 1) = cumsum a (n + 1) * b n - cumsum (shift (cumsum a) * nabla b) n := by + simpa using! summation_by_parts (a := a) (b := b) (A := cumsum a) (by simp) + +lemma summation_by_parts'' {E : Type*} [Ring E] {a b : ℕ → E} : + shift (cumsum (a * b)) = shift (cumsum a) * b - cumsum (shift (cumsum a) * nabla b) := by + ext n ; apply summation_by_parts' + +lemma summable_iff_bounded {u : ℕ → ℝ} (hu : 0 ≤ u) : + Summable u ↔ BoundedAtFilter atTop (cumsum u) := by + have l1 : (cumsum u =O[atTop] 1) ↔ _ := isBigO_one_nat_atTop_iff + have l2 n : ‖cumsum u n‖ = cumsum u n := by simpa using cumsum_nonneg hu n + simp only [BoundedAtFilter, l1, l2] + constructor <;> intro ⟨C, h1⟩ + · exact ⟨C, fun n => sum_le_hasSum _ (fun i _ => hu i) h1⟩ + · exact summable_of_sum_range_le hu h1 + +lemma Filter.EventuallyEq.summable {u v : ℕ → ℝ} (h : u =ᶠ[atTop] v) (hu : Summable v) : + Summable u := + summable_of_isBigO_nat hu h.isBigO + +lemma summable_congr_ae {u v : ℕ → ℝ} (huv : u =ᶠ[atTop] v) : Summable u ↔ Summable v := by + exact ⟨Erdos970.Filter.EventuallyEq.summable huv.symm, + Erdos970.Filter.EventuallyEq.summable huv⟩ + +lemma BoundedAtFilter.add_const {u : ℕ → ℝ} {c : ℝ} : + BoundedAtFilter atTop (fun n => u n + c) ↔ BoundedAtFilter atTop u := by + have : u = fun n => (u n + c) + (-c) := by ext n ; ring + simp only [BoundedAtFilter] + constructor <;> intro h + on_goal 1 => rw [this] + all_goals { exact h.add (const_boundedAtFilter _ _) } + +lemma BoundedAtFilter.comp_add {u : ℕ → ℝ} {N : ℕ} : + BoundedAtFilter atTop (fun n => u (n + N)) ↔ BoundedAtFilter atTop u := by + simp only [BoundedAtFilter, isBigO_iff, norm_eq_abs, Pi.one_apply, + eventually_atTop] + constructor <;> intro ⟨C, n₀, h⟩ <;> use C + · refine ⟨n₀ + N, fun n hn => ?_⟩ + obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le' (m := N) (n := n) (by grind) + exact h _ <| Nat.add_le_add_iff_right.mp hn + · exact ⟨n₀, fun n hn => h _ (by grind)⟩ + +lemma summable_iff_bounded' {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, 0 ≤ u n) : + Summable u ↔ BoundedAtFilter atTop (cumsum u) := by + obtain ⟨N, hu⟩ := eventually_atTop.mp hu + have e2 : cumsum (fun i ↦ u (i + N)) = fun n => cumsum u (n + N) - cumsum u N := by + ext n ; simp_rw [cumsum, add_comm _ N, Finset.sum_range_add] ; ring + rw [← summable_nat_add_iff N, summable_iff_bounded (fun n => hu _ <| Nat.le_add_left N n), e2] + simp_rw [sub_eq_add_neg, BoundedAtFilter.add_const, BoundedAtFilter.comp_add] + +lemma bounded_of_shift {u : ℕ → ℝ} (h : BoundedAtFilter atTop (shift u)) : + BoundedAtFilter atTop u := by + simp only [BoundedAtFilter, isBigO_iff, eventually_atTop] at h ⊢ + obtain ⟨C, N, hC⟩ := h + refine ⟨C, N + 1, fun n hn => ?_⟩ + simp only [shift] at hC + have r1 : n - 1 ≥ N := Nat.le_sub_one_of_lt hn + have r2 : n - 1 + 1 = n := Nat.sub_add_cancel (by omega) + simpa [r2] using hC (n - 1) r1 + +lemma dirichlet_test' {a b : ℕ → ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) + (hAb : BoundedAtFilter atTop (shift (cumsum a) * b)) (hbb : ∀ᶠ n in atTop, b (n + 1) ≤ b n) + (h : Summable (shift (cumsum a) * nnabla b)) : Summable (a * b) := by + have l1 : ∀ᶠ n in atTop, 0 ≤ (shift (cumsum a) * nnabla b) n := by + filter_upwards [hbb] with n hb + exact mul_nonneg (by + change 0 ≤ ∑ index ∈ Finset.range (n + 1), a index + exact Finset.sum_nonneg (fun index _ => ha index)) (sub_nonneg.mpr hb) + rw [summable_iff_bounded (mul_nonneg ha hb)] + rw [summable_iff_bounded' l1] at h + apply bounded_of_shift + simpa only [summation_by_parts'', sub_eq_add_neg, neg_cumsum, ← mul_neg, neg_nabla] + using hAb.add h + +lemma exists_antitone_of_eventually {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, u (n + 1) ≤ u n) : + ∃ v : ℕ → ℝ, range v ⊆ range u ∧ Antitone v ∧ v =ᶠ[atTop] u := by + obtain ⟨N, hN⟩ := eventually_atTop.mp hu + let v (n : ℕ) := u (if n < N then N else n) + refine ⟨v, ?_, ?_, ?_⟩ + · exact fun x ⟨n, hn⟩ => ⟨if n < N then N else n, hn⟩ + · refine antitone_nat_of_succ_le (fun n => ?_) + by_cases h : n < N + · by_cases h' : n + 1 < N <;> simp [v, h, h'] + have : n + 1 = N := by linarith + simp [this] + · have : ¬(n + 1 < N) := by linarith + simp only [this, ↓reduceIte, h, ge_iff_le, v] ; apply hN ; linarith + · have : ∀ᶠ n in atTop, ¬(n < N) := by simpa using ⟨N, fun b hb => by linarith⟩ + filter_upwards [this] with n hn ; simp [v, hn] + +lemma summable_inv_mul_log_sq : Summable (fun n : ℕ => (n * (Real.log n) ^ 2)⁻¹) := by + let u (n : ℕ) := (n * (Real.log n) ^ 2)⁻¹ + have l7 : ∀ᶠ n : ℕ in atTop, 1 ≤ Real.log n := + tendsto_atTop.mp (tendsto_log_atTop.comp tendsto_natCast_atTop_atTop) 1 + have l8 : ∀ᶠ n : ℕ in atTop, 1 ≤ n := eventually_ge_atTop 1 + have l9 : ∀ᶠ n in atTop, u (n + 1) ≤ u n := by + filter_upwards [l7, l8] with n l2 l8; dsimp [u]; gcongr <;> simp + obtain ⟨v, l1, l2, l3⟩ := exists_antitone_of_eventually l9 + rw [summable_congr_ae l3.symm] + have l4 (n : ℕ) : 0 ≤ v n := by obtain ⟨k, hk⟩ := l1 ⟨n, rfl⟩ ; rw [← hk] ; positivity + apply (summable_condensed_iff_of_nonneg l4 (fun _ _ _ a ↦ l2 a)).mp + suffices this : ∀ᶠ k : ℕ in atTop, 2 ^ k * v (2 ^ k) = ((k : ℝ) ^ 2)⁻¹ * ((Real.log 2) ^ 2)⁻¹ by + exact (summable_congr_ae this).mpr <| (Real.summable_nat_pow_inv.mpr one_lt_two).mul_right _ + have l5 : ∀ᶠ k in atTop, v (2 ^ k) = u (2 ^ k) := + l3.comp_tendsto <| tendsto_pow_atTop_atTop_of_one_lt Nat.le.refl + filter_upwards [l5, l8] with k l5 l8 + simp only [l5, mul_inv_rev, Nat.cast_pow, Nat.cast_ofNat, log_pow, u] + field_simp + +lemma tendsto_mul_add_atTop {a : ℝ} (ha : 0 < a) (b : ℝ) : + Tendsto (fun x => a * x + b) atTop atTop := + tendsto_atTop_add_const_right _ b (tendsto_id.const_mul_atTop ha) + +lemma isLittleO_const_of_tendsto_atTop {α : Type*} [Preorder α] (a : ℝ) {f : α → ℝ} + (hf : Tendsto f atTop atTop) : (fun _ => a) =o[atTop] f := by + simp [tendsto_norm_atTop_atTop.comp hf] + +lemma isBigO_pow_pow_of_le {m n : ℕ} (h : m ≤ n) : + (fun x : ℝ => x ^ m) =O[atTop] (fun x : ℝ => x ^ n) := by + apply IsBigO.of_bound 1 + filter_upwards [eventually_ge_atTop 1] with x l1 + simpa [abs_eq_self.mpr (zero_le_one.trans l1)] using pow_le_pow_right₀ l1 h + +lemma isLittleO_mul_add_sq (a b : ℝ) : (fun x => a * x + b) =o[atTop] (fun x => x ^ 2) := by + apply IsLittleO.add + · apply IsLittleO.const_mul_left ; simpa using isLittleO_pow_pow_atTop_of_lt (𝕜 := ℝ) one_lt_two + · apply isLittleO_const_of_tendsto_atTop _ <| tendsto_pow_atTop (by linarith) + +lemma log_mul_add_isBigO_log {a : ℝ} (ha : 0 < a) (b : ℝ) : + (fun x => Real.log (a * x + b)) =O[atTop] Real.log := by + apply IsBigO.of_bound (2 : ℕ) + have l2 : ∀ᶠ x : ℝ in atTop, 0 ≤ log x := tendsto_atTop.mp tendsto_log_atTop 0 + have l3 : ∀ᶠ x : ℝ in atTop, 0 ≤ log (a * x + b) := + tendsto_atTop.mp (tendsto_log_atTop.comp (tendsto_mul_add_atTop ha b)) 0 + have l5 : ∀ᶠ x : ℝ in atTop, 1 ≤ a * x + b := tendsto_atTop.mp (tendsto_mul_add_atTop ha b) 1 + have l1 : ∀ᶠ x : ℝ in atTop, a * x + b ≤ x ^ 2 := by + filter_upwards [(isLittleO_mul_add_sq a b).eventuallyLE, l5] with x r2 l5 + simpa [abs_eq_self.mpr (zero_le_one.trans l5)] using r2 + filter_upwards [l1, l2, l3, l5] with x l1 l2 l3 l5 + simpa [abs_eq_self.mpr l2, abs_eq_self.mpr l3, Real.log_pow] using + Real.log_le_log (by linarith) l1 + +lemma isBigO_log_mul_add {a : ℝ} (ha : 0 < a) (b : ℝ) : + Real.log =O[atTop] (fun x => Real.log (a * x + b)) := by + convert! (log_mul_add_isBigO_log (b := -b / a) (inv_pos.mpr ha)).comp_tendsto + (tendsto_mul_add_atTop (b := b) ha) using 1 + ext x + simp only [Function.comp_apply] + congr + field_simp + simp + +lemma log_isbigo_log_div {d : ℝ} (hb : 0 < d) : + (fun n ↦ Real.log n) =O[atTop] (fun n ↦ Real.log (n / d)) := by + convert isBigO_log_mul_add (inv_pos.mpr hb) 0 using 1; simp only [add_zero]; field_simp + +lemma Asymptotics.IsBigO.add_isLittleO_right {f g : ℝ → ℝ} (h : g =o[atTop] f) : + f =O[atTop] (f + g) := by + rw [isLittleO_iff] at h ; specialize h (c := 2⁻¹) (by norm_num) + rw [isBigO_iff''] + refine ⟨2⁻¹, by norm_num, ?_⟩ + filter_upwards [h] with x h + simp only [norm_eq_abs, Pi.add_apply] at h ⊢ + calc _ = |f x| - 2⁻¹ * |f x| := by ring + _ ≤ |f x| - |g x| := by linarith + _ ≤ |(|f x| - |g x|)| := le_abs_self _ + _ ≤ _ := by rw [← sub_neg_eq_add, ← abs_neg (g x)] ; exact abs_abs_sub_abs_le (f x) (-g x) + +lemma Asymptotics.IsBigO.sq {α : Type*} [Preorder α] {f g : α → ℝ} (h : f =O[atTop] g) : + (fun n ↦ f n ^ 2) =O[atTop] (fun n => g n ^ 2) := by + simpa [pow_two] using h.mul h + +lemma log_sq_isbigo_mul {a b : ℝ} (hb : 0 < b) : + (fun x ↦ Real.log x ^ 2) =O[atTop] (fun x ↦ a + Real.log (x / b) ^ 2) := by + apply (Erdos970.Asymptotics.IsBigO.sq (log_isbigo_log_div hb)).trans + simp_rw [add_comm a] + refine IsBigO.add_isLittleO_right <| isLittleO_const_of_tendsto_atTop _ ?_ + exact (tendsto_pow_atTop two_ne_zero).comp <| + tendsto_log_atTop.comp <| tendsto_id.atTop_div_const hb + +theorem log_add_div_isBigO_log (a : ℝ) {b : ℝ} (hb : 0 < b) : + (fun x ↦ Real.log ((x + a) / b)) =O[atTop] fun x ↦ Real.log x := by + convert log_mul_add_isBigO_log (inv_pos.mpr hb) (a / b) using 3 ; ring + +lemma log_add_one_sub_log_le {x : ℝ} (hx : 0 < x) : nabla Real.log x ≤ x⁻¹ := by + have l1 : ContinuousOn Real.log (Icc x (x + 1)) := by + apply continuousOn_log.mono ; intro t ⟨h1, _⟩ ; simp ; linarith + have l2 t (ht : t ∈ Ioo x (x + 1)) : HasDerivAt Real.log t⁻¹ t := + Real.hasDerivAt_log (by linarith [ht.1]) + obtain ⟨t, ⟨ht1, _⟩, htx⟩ := exists_hasDerivAt_eq_slope Real.log (·⁻¹) (by linarith) l1 l2 + simp only [add_sub_cancel_left, div_one] at htx + rw [nabla, ← htx, inv_le_inv₀ (by linarith) hx] + exact ht1.le + +lemma nabla_log_main : nabla Real.log =O[atTop] fun x ↦ 1 / x := by + apply IsBigO.of_bound 1 + filter_upwards [eventually_gt_atTop 0] with x l1 + have l2 : log x ≤ log (x + 1) := log_le_log l1 (by linarith) + simpa [nabla, abs_eq_self.mpr l1.le, abs_eq_self.mpr (sub_nonneg.mpr l2)] using + log_add_one_sub_log_le l1 + +lemma nabla_log {b : ℝ} (hb : 0 < b) : + nabla (fun x => Real.log (x / b)) =O[atTop] (fun x => 1 / x) := by + refine EventuallyEq.trans_isBigO ?_ nabla_log_main + filter_upwards [eventually_gt_atTop 0] with x l2 + rw [nabla, log_div (by linarith) (by linarith), log_div l2.ne.symm (by linarith), nabla] ; ring + +lemma nnabla_mul_log_sq (a : ℝ) {b : ℝ} (hb : 0 < b) : + nabla (fun x => x * (a + Real.log (x / b) ^ 2)) =O[atTop] (fun x => Real.log x ^ 2) := by + + have l1 : nabla (fun n => n * (a + Real.log (n / b) ^ 2)) = fun n => + a + Real.log ((n + 1) / b) ^ 2 + + (n * (Real.log ((n + 1) / b) ^ 2 - Real.log (n / b) ^ 2)) := by + ext n ; simp [nabla] ; ring + have l2 := (isLittleO_const_of_tendsto_atTop a + ((tendsto_pow_atTop two_ne_zero).comp tendsto_log_atTop)).isBigO + have l3 := Erdos970.Asymptotics.IsBigO.sq (log_add_div_isBigO_log 1 hb) + have l4 : (fun x => Real.log ((x + 1) / b) + Real.log (x / b)) =O[atTop] Real.log := by + simpa using (log_add_div_isBigO_log _ hb).add (log_add_div_isBigO_log 0 hb) + have e2 : (fun x : ℝ => x * (Real.log x * (1 / x))) =ᶠ[atTop] Real.log := by + filter_upwards [eventually_ge_atTop 1] with x hx using by field_simp + have l5 : (fun n ↦ n * (Real.log n * (1 / n))) =O[atTop] (fun n ↦ (Real.log n) ^ 2) := + e2.trans_isBigO + (by simpa using! (isLittleO_mul_add_sq 1 0).isBigO.comp_tendsto Real.tendsto_log_atTop) + + simp_rw [l1, _root_.sq_sub_sq] + exact ((l2.add l3).add (isBigO_refl (·) atTop |>.mul (l4.mul (nabla_log hb)) |>.trans l5)) + +lemma nnabla_bound_aux1 (a : ℝ) {b : ℝ} (hb : 0 < b) : + Tendsto (fun x => x * (a + Real.log (x / b) ^ 2)) atTop atTop := + tendsto_id.atTop_mul_atTop₀ <| tendsto_atTop_add_const_left _ _ <| + (tendsto_pow_atTop two_ne_zero).comp <| tendsto_log_atTop.comp <| tendsto_id.atTop_div_const hb + +lemma nnabla_bound_aux2 (a : ℝ) {b : ℝ} (hb : 0 < b) : + ∀ᶠ x in atTop, 0 < x * (a + Real.log (x / b) ^ 2) := + (nnabla_bound_aux1 a hb).eventually (eventually_gt_atTop 0) + +lemma Real.log_eventually_gt_atTop (a : ℝ) : + ∀ᶠ x in atTop, a < Real.log x := + Real.tendsto_log_atTop.eventually (eventually_gt_atTop a) + +@[local gcongr] +theorem norm_lt_norm_of_nonneg (x y : ℝ) (hx : 0 ≤ x) (hxy : x ≤ y) : + ‖x‖ ≤ ‖y‖ := by + simp_rw [Real.norm_eq_abs] + apply abs_le_abs hxy + linarith + +lemma nnabla_bound_aux {x : ℝ} (hx : 0 < x) : + nnabla (fun n ↦ 1 / (n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2))) =O[atTop] + (fun n ↦ 1 / (Real.log n ^ 2 * n ^ 2)) := by + + let d n : ℝ := n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2) + change (fun x_1 ↦ nnabla (fun n ↦ 1 / d n) x_1) =O[atTop] _ + + have l2 : ∀ᶠ n in atTop, 0 < d n := (nnabla_bound_aux2 ((2 * π) ^ 2) hx) + have l3 : ∀ᶠ n in atTop, 0 < d (n + 1) := + (tendsto_atTop_add_const_right atTop (1 : ℝ) tendsto_id).eventually l2 + have l1 : ∀ᶠ n : ℝ in atTop, + nnabla (fun n ↦ 1 / d n) n = (d (n + 1) - d n) * (d n)⁻¹ * (d (n + 1))⁻¹ := by + filter_upwards [l2, l3] with n l2 l3 + rw [nnabla, one_div, one_div, inv_sub_inv l2.ne.symm l3.ne.symm, div_eq_mul_inv, mul_inv, + mul_assoc] + + have l4 : (fun n => (d n)⁻¹) =O[atTop] (fun n => (n * (Real.log n) ^ 2)⁻¹) := by + apply IsBigO.inv_rev + · refine (isBigO_refl _ _).mul <| (log_sq_isbigo_mul hx) + · filter_upwards [Real.log_eventually_gt_atTop 0, eventually_gt_atTop 0] with x hx hx' + rw [← not_imp_not] + intro _ + positivity + have l5 : (fun n => (d (n + 1))⁻¹) =O[atTop] (fun n => (n * (Real.log n) ^ 2)⁻¹) := by + refine IsBigO.trans ?_ l4 + rw [isBigO_iff]; use 1 + have e3 : ∀ᶠ n in atTop, d n ≤ d (n + 1) := by + filter_upwards [eventually_ge_atTop x] with n hn + have e2 : 1 ≤ n / x := (one_le_div hx).mpr hn + have : 0 ≤ n := hx.le.trans hn + simp only [d] + gcongr <;> simp [Real.log_nonneg, *] + filter_upwards [l2, l3, e3] with n e1 e2 e3 + simp_rw [one_mul] + gcongr + + have l6 : (fun n => d (n + 1) - d n) =O[atTop] (fun n => (Real.log n) ^ 2) := by + simpa [d, nabla] using! (nnabla_mul_log_sq ((2 * π) ^ 2) hx) + + apply EventuallyEq.trans_isBigO l1 + + apply ((l6.mul l4).mul l5).trans_eventuallyEq + filter_upwards [eventually_ge_atTop 2, Real.log_eventually_gt_atTop 0] with n hn hn' + field_simp + +lemma nnabla_bound (C : ℝ) {x : ℝ} (hx : 0 < x) : + nnabla (fun n => C / (1 + (Real.log (n / x) / (2 * π)) ^ 2) / n) =O[atTop] + (fun n => (n ^ 2 * (Real.log n) ^ 2)⁻¹) := by + field_simp + simp only [div_eq_mul_inv, mul_inv, nnabla_mul, one_mul] + apply IsBigO.const_mul_left + simpa [div_eq_mul_inv, mul_pow, mul_comm] using nnabla_bound_aux hx + +def chebyWith (C : ℝ) (f : ℕ → ℂ) : Prop := ∀ n, cumsum (‖f ·‖) n ≤ C * n + +def cheby (f : ℕ → ℂ) : Prop := ∃ C, chebyWith C f + +lemma cheby.bigO (h : cheby f) : cumsum (‖f ·‖) =O[atTop] ((↑) : ℕ → ℝ) := by + have l1 : 0 ≤ cumsum (‖f ·‖) := cumsum_nonneg (fun _ => norm_nonneg _) + obtain ⟨C, hC⟩ := h + apply isBigO_of_le' (c := C) atTop + intro n + rw [Real.norm_eq_abs, abs_eq_self.mpr (l1 n)] + simpa using hC n + +lemma limiting_fourier_lim1_aux (hcheby : cheby f) (hx : 0 < x) (C : ℝ) (hC : 0 ≤ C) : + Summable fun n ↦ ‖f n‖ / ↑n * (C / (1 + (1 / (2 * π) * Real.log (↑n / x)) ^ 2)) := by + + let a (n : ℕ) := (C / (1 + (Real.log (↑n / x) / (2 * π)) ^ 2) / ↑n) + replace hcheby := hcheby.bigO + + have l1 : shift (cumsum (‖f ·‖)) =O[atTop] (fun n : ℕ => (↑(n + 1) : ℝ)) := + hcheby.comp_tendsto <| tendsto_add_atTop_nat 1 + have l2 : shift (cumsum (‖f ·‖)) =O[atTop] (fun n => (n : ℝ)) := + l1.trans + (by simpa using (isBigO_refl _ _).add <| isBigO_iff.mpr ⟨1, by simpa using ⟨1, by tauto⟩⟩) + have l5 : BoundedAtFilter atTop (fun n : ℕ => C / (1 + (Real.log (↑n / x) / (2 * π)) ^ 2)) := by + simp only [BoundedAtFilter] + field_simp + apply isBigO_of_le' (c := C) ; intro n + have : 0 ≤ 2 ^ 2 * π ^ 2 + Real.log (n / x) ^ 2 := by positivity + simp only [norm_div, norm_mul, norm_eq_abs, abs_eq_self.mpr hC, norm_pow, + abs_eq_self.mpr pi_nonneg, abs_eq_self.mpr this, Pi.one_apply, one_mem, + CStarRing.norm_of_mem_unitary, mul_one, ge_iff_le, Nat.abs_ofNat] + apply div_le_of_le_mul₀ this hC + rw [mul_add, ← mul_assoc] + apply le_add_of_le_of_nonneg le_rfl + positivity + have l3 : a =O[atTop] (fun n => 1 / (n : ℝ)) := by + simpa [a] using! IsBigO.mul l5 (isBigO_refl (fun n : ℕ => 1 / (n : ℝ)) _) + have l4 : nnabla a =O[atTop] (fun n : ℕ => (n ^ 2 * (Real.log n) ^ 2)⁻¹) := by + convert Erdos970.Asymptotics.IsBigO.natCast (nnabla_bound C hx) + simp [nnabla, a] + + simp_rw [div_mul_eq_mul_div, mul_div_assoc, one_mul] + apply dirichlet_test' + · intro n ; exact norm_nonneg _ + · intro n ; positivity + · apply (l2.mul l3).trans_eventuallyEq + apply eventually_of_mem (Ici_mem_atTop 1) + intro x (hx : 1 ≤ x) + have : x ≠ 0 := Nat.one_le_iff_ne_zero.mp hx + simp [this] + · have : ∀ᶠ n : ℕ in atTop, x ≤ n := by simpa using eventually_ge_atTop ⌈x⌉₊ + filter_upwards [this] with n hn + have e1 : 0 < (n : ℝ) := by linarith + have e2 : 1 ≤ n / x := (one_le_div hx).mpr hn + have e3 := Nat.le_succ n + gcongr + refine div_nonneg (Real.log_nonneg e2) (by norm_num [pi_nonneg]) + · apply summable_of_isBigO_nat summable_inv_mul_log_sq + apply (l2.mul l4).trans_eventuallyEq + apply eventually_of_mem (Ici_mem_atTop 2) + intro x (hx : 2 ≤ x) + have : (x : ℝ) ≠ 0 := by simp ; linarith + have : Real.log x ≠ 0 := by + have ll : 2 ≤ (x : ℝ) := by simp [hx] + simp + grind + field_simp + +theorem limiting_fourier_lim1 (hcheby : cheby f) (ψ : W21) (hx : 0 < x) : + Tendsto (fun σ' : ℝ ↦ + ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (n / x))) (𝓝[>] 1) + (𝓝 (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (n / x)))) := by + + obtain ⟨C, hC⟩ := decay_bounds_cor ψ + have : 0 ≤ C := by simpa using (norm_nonneg _).trans (hC 0) + refine tendsto_tsum_of_dominated_convergence + (limiting_fourier_lim1_aux hcheby hx C this) (fun n => ?_) ?_ + · apply Tendsto.mul_const + by_cases h : n = 0 <;> simp only [term, h, ↓reduceIte, CharP.cast_eq_zero, div_zero, + tendsto_const_nhds_iff] + refine tendsto_const_nhds.div ?_ (by simp [h]) + simpa using ((continuous_ofReal.tendsto 1).mono_left nhdsWithin_le_nhds).const_cpow + · rw [eventually_nhdsWithin_iff] + apply Eventually.of_forall + intro σ' (hσ' : 1 < σ') n + rw [norm_mul, ← nterm_eq_norm_term] + refine mul_le_mul ?_ (hC _) (norm_nonneg _) (div_nonneg (norm_nonneg _) (Nat.cast_nonneg _)) + by_cases h : n = 0 <;> simp only [nterm, h, ↓reduceIte, CharP.cast_eq_zero, div_zero, le_refl] + have : 1 ≤ (n : ℝ) := by simpa using! Nat.pos_iff_ne_zero.mpr h + refine div_le_div₀ (norm_nonneg _) le_rfl (by simpa [Nat.pos_iff_ne_zero]) ?_ + simpa using Real.rpow_le_rpow_of_exponent_le this hσ'.le + +theorem limiting_fourier_lim2_aux (x : ℝ) (C : ℝ) : + Integrable (fun t ↦ max |x| 1 * (C / (1 + (t / (2 * π)) ^ 2))) + (Measure.restrict volume (Ici (-Real.log x))) := by + simp_rw [div_eq_mul_inv C] + exact (((integrable_inv_one_add_sq.comp_div + (by simp [pi_ne_zero])).const_mul _).const_mul _).restrict + +theorem limiting_fourier_lim2 (A : ℝ) (ψ : W21) (hx : 1 ≤ x) : + Tendsto (fun σ' ↦ A * ↑(x ^ (1 - σ')) * + ∫ u in Ici (-Real.log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) + (𝓝[>] 1) (𝓝 (A * ∫ u in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)))) := by + + obtain ⟨C, hC⟩ := decay_bounds_cor ψ + apply Tendsto.mul + · suffices h : Tendsto (fun σ' : ℝ ↦ ofReal (x ^ (1 - σ'))) (𝓝[>] 1) (𝓝 1) by + simpa using h.const_mul ↑A + suffices h : Tendsto (fun σ' : ℝ ↦ x ^ (1 - σ')) (𝓝[>] 1) (𝓝 1) from + (continuous_ofReal.tendsto 1).comp h + have : Tendsto (fun σ' : ℝ ↦ σ') (𝓝 1) (𝓝 1) := fun _ a ↦ a + have : Tendsto (fun σ' : ℝ ↦ 1 - σ') (𝓝[>] 1) (𝓝 0) := + tendsto_nhdsWithin_of_tendsto_nhds (by simpa using this.const_sub 1) + simpa using tendsto_const_nhds.rpow this (Or.inl (zero_lt_one.trans_le hx).ne.symm) + · refine tendsto_integral_filter_of_dominated_convergence _ ?_ ?_ + (limiting_fourier_lim2_aux x C) ?_ + · apply Eventually.of_forall ; intro σ' + apply Continuous.aestronglyMeasurable + have := continuous_FourierIntegral ψ + continuity + · apply eventually_of_mem (U := Ioo 1 2) + · apply Ioo_mem_nhdsGT_of_mem ; simp + · intro σ' ⟨h1, h2⟩ + rw [ae_restrict_iff' measurableSet_Ici] + apply Eventually.of_forall + intro t (ht : - Real.log x ≤ t) + rw [norm_mul] + have hdom_nonneg : 0 ≤ max |x| 1 := by + exact (abs_nonneg x).trans (le_max_left _ _) + refine mul_le_mul ?_ (hC _) (norm_nonneg _) hdom_nonneg + simp only [neg_mul, ofReal_exp, ofReal_neg, ofReal_mul, ofReal_sub, ofReal_one, norm_exp, + neg_re, mul_re, ofReal_re, sub_re, one_re, ofReal_im, sub_im, one_im, sub_self, mul_zero, + sub_zero] + have : -Real.log x * (σ' - 1) ≤ t * (σ' - 1) := mul_le_mul_of_nonneg_right ht (by linarith) + have : -(t * (σ' - 1)) ≤ Real.log x * (σ' - 1) := by simpa using neg_le_neg this + have := Real.exp_monotone this + apply this.trans + have l1 : σ' - 1 ≤ 1 := by linarith + have : 0 ≤ Real.log x := Real.log_nonneg hx + have := mul_le_mul_of_nonneg_left l1 this + refine (Real.exp_monotone this).trans ?_ + have hxabs : |x| = x := abs_of_nonneg (zero_le_one.trans hx) + calc + Real.exp (Real.log x * 1) = |x| := by + simpa [mul_one, hxabs] using (Real.exp_log (zero_lt_one.trans_le hx)) + _ ≤ max |x| 1 := le_max_left _ _ + · apply Eventually.of_forall + intro x + suffices h : Tendsto (fun n ↦ ((rexp (-x * (n - 1))) : ℂ)) (𝓝[>] 1) (𝓝 1) by + simpa using h.mul_const _ + apply Tendsto.mono_left ?_ nhdsWithin_le_nhds + suffices h : Continuous (fun n ↦ ((rexp (-x * (n - 1))) : ℂ)) by simpa using h.tendsto 1 + continuity + +theorem limiting_fourier_lim3 (hG : ContinuousOn G {s | 1 ≤ s.re}) (ψ : CS 2 ℂ) (hx : 1 ≤ x) : + Tendsto (fun σ' : ℝ ↦ ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I)) (𝓝[>] 1) + (𝓝 (∫ t : ℝ, G (1 + t * I) * ψ t * x ^ (t * I))) := by + + by_cases hh : tsupport ψ = ∅ + · simp [tsupport_eq_empty_iff.mp hh] + obtain ⟨a₀, ha₀⟩ := Set.nonempty_iff_ne_empty.mpr hh + + let S : Set ℂ := reProdIm (Icc 1 2) (tsupport ψ) + have l1 : IsCompact S := by + refine Metric.isCompact_iff_isClosed_bounded.mpr ⟨?_, ?_⟩ + · exact isClosed_Icc.reProdIm (isClosed_tsupport ψ) + · exact (Metric.isBounded_Icc 1 2).reProdIm ψ.h2.isBounded + have l2 : S ⊆ {s : ℂ | 1 ≤ s.re} := fun z hz => (mem_reProdIm.mp hz).1.1 + have l3 : ContinuousOn (‖G ·‖) S := (hG.mono l2).norm + have l4 : S.Nonempty := ⟨1 + a₀ * I, by simp [S, mem_reProdIm, ha₀]⟩ + obtain ⟨z, -, hmax⟩ := l1.exists_isMaxOn l4 l3 + let MG := ‖G z‖ + let bound (a : ℝ) : ℝ := MG * ‖ψ a‖ + + apply tendsto_integral_filter_of_dominated_convergence (bound := bound) + · apply eventually_of_mem (U := Icc 1 2) (Icc_mem_nhdsGT_of_mem (by simp)) ; intro u hu + apply Continuous.aestronglyMeasurable + apply Continuous.mul + · exact (hG.comp_continuous (by fun_prop) (by simp [hu.1])).mul ψ.h1.continuous + · apply Continuous.const_cpow (by fun_prop) ; simp ; linarith + · apply eventually_of_mem (U := Icc 1 2) (Icc_mem_nhdsGT_of_mem (by simp)) + intro u hu + apply Eventually.of_forall ; intro v + by_cases h : v ∈ tsupport ψ + · have r1 : u + v * I ∈ S := by simp [S, mem_reProdIm, hu.1, hu.2, h] + have r2 := isMaxOn_iff.mp hmax _ r1 + have r4 : (x : ℂ) ≠ 0 := by simp ; linarith + have r5 : arg x = 0 := by simp [arg_eq_zero_iff] ; linarith + have r3 : ‖(x : ℂ) ^ (v * I)‖ = 1 := by simp [norm_cpow_of_ne_zero r4, r5] + simp_rw [norm_mul, r3, mul_one] + exact mul_le_mul_of_nonneg_right r2 (norm_nonneg _) + · have : v ∉ Function.support ψ := fun a ↦ h (subset_tsupport ψ a) + simp at this ; simp [this, bound] + + · suffices h : Continuous bound by exact h.integrable_of_hasCompactSupport ψ.h2.norm.mul_left + have := ψ.h1.continuous ; fun_prop + · apply Eventually.of_forall ; intro t + apply Tendsto.mul_const + apply Tendsto.mul_const + refine (hG (1 + t * I) (by simp)).tendsto.comp <| tendsto_nhdsWithin_iff.mpr ⟨?_, ?_⟩ + · exact ((continuous_ofReal.tendsto _).add tendsto_const_nhds).mono_left nhdsWithin_le_nhds + · exact eventually_nhdsWithin_of_forall (fun x (hx : 1 < x) => by simp [hx.le]) + +lemma limiting_fourier (hcheby : cheby f) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 1 ≤ x) : + ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = + ∫ (t : ℝ), (G (1 + t * I)) * (ψ t) * x ^ (t * I) := by + + have l1 := limiting_fourier_lim1 hcheby ψ (by linarith) + have l2 := limiting_fourier_lim2 A ψ hx + have l3 := limiting_fourier_lim3 hG ψ hx + apply tendsto_nhds_unique_of_eventuallyEq (l1.sub l2) l3 + simpa [eventuallyEq_nhdsWithin_iff] using! Eventually.of_forall (limiting_fourier_aux hG' hf ψ hx) + +lemma limiting_cor_aux {f : ℝ → ℂ} : Tendsto (fun x : ℝ ↦ ∫ t, f t * x ^ (t * I)) atTop (𝓝 0) := by + + have l1 : ∀ᶠ x : ℝ in atTop, ∀ t : ℝ, x ^ (t * I) = exp (log x * t * I) := by + filter_upwards [eventually_ne_atTop 0, eventually_ge_atTop 0] with x hx hx' t + rw [Complex.cpow_def_of_ne_zero (ofReal_ne_zero.mpr hx), ofReal_log hx'] ; ring_nf + + have l2 : ∀ᶠ x : ℝ in atTop, ∫ t, f t * x ^ (t * I) = ∫ t, f t * exp (log x * t * I) := by + filter_upwards [l1] with x hx + refine integral_congr_ae (Eventually.of_forall (fun x => by simp [hx])) + + simp_rw [tendsto_congr' l2] + have hFourier (x : ℝ) : (∫ t, f t * exp (log x * t * I)) = + 𝓕 f (-Real.log x / (2 * π)) := by + rw [Real.fourier_real_eq_integral_exp_smul] + apply integral_congr_ae + filter_upwards [] with t + rw [smul_eq_mul, mul_comm _ (f t)] + congr 1 + congr 1 + push_cast + field_simp + simp_rw [hFourier] + refine (Real.zero_at_infty_fourier f).comp <| Tendsto.mono_right ?_ _root_.atBot_le_cocompact + exact (tendsto_neg_atBot_iff.mpr tendsto_log_atTop).atBot_mul_const (inv_pos.mpr two_pi_pos) + +lemma limiting_cor (ψ : CS 2 ℂ) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hcheby : cheby f) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := by + + apply limiting_cor_aux.congr' + filter_upwards [eventually_ge_atTop 1] with x hx using + limiting_fourier hcheby hG hG' hf ψ hx |>.symm + +lemma smooth_urysohn (a b c d : ℝ) (h1 : a < b) (h3 : c < d) : ∃ Ψ : ℝ → ℝ, + (ContDiff ℝ ∞ Ψ) ∧ (HasCompactSupport Ψ) ∧ + Set.indicator (Set.Icc b c) 1 ≤ Ψ ∧ Ψ ≤ Set.indicator (Set.Ioo a d) 1 := by + + obtain ⟨ψ, l1, l2, l3, l4, -⟩ := smooth_urysohn_support_Ioo h1 h3 + refine ⟨ψ, l1, l2, l3, l4⟩ + +noncomputable def exists_trunc : trunc := by + choose ψ h1 h2 h3 h4 using smooth_urysohn (-2) (-1) (1) (2) (by linarith) (by linarith) + exact ⟨⟨ψ, h1.of_le (by norm_cast), h2⟩, h3, h4⟩ + +lemma one_div_sub_one (n : ℕ) : 1 / (↑(n - 1) : ℝ) ≤ 2 / n := by + match n with + | 0 => simp + | 1 => simp + | n + 2 => { norm_cast ; rw [div_le_div_iff₀] <;> simp [mul_add] <;> linarith } + +lemma quadratic_pos (a b c x : ℝ) (ha : 0 < a) (hΔ : discrim a b c < 0) : + 0 < a * x ^ 2 + b * x + c := by + have l1 : a * x ^ 2 + b * x + c = a * (x + b / (2 * a)) ^ 2 - discrim a b c / (4 * a) := by + simp only [discrim]; field_simp; ring + have l2 : 0 < - discrim a b c := by linarith + rw [l1, sub_eq_add_neg, ← neg_div] ; positivity + +noncomputable def pp (a x : ℝ) : ℝ := a ^ 2 * (x + 1) ^ 2 + (1 - a) * (1 + a) + +noncomputable def pp' (a x : ℝ) : ℝ := a ^ 2 * (2 * (x + 1)) + +lemma pp_pos {a : ℝ} (ha : a ∈ Ioo (-1) 1) (x : ℝ) : 0 < pp a x := by + simp only [pp] + have : 0 < 1 - a := by linarith [ha.2] + have : 0 < 1 + a := by linarith [ha.1] + positivity + +lemma pp_deriv (a x : ℝ) : HasDerivAt (pp a) (pp' a x) x := by + unfold pp pp' + simpa using hasDerivAt_id x |>.add_const 1 |>.pow 2 |>.const_mul _ + +lemma pp_deriv_eq (a : ℝ) : deriv (pp a) = pp' a := by + ext x ; exact pp_deriv a x |>.deriv + +lemma pp'_deriv (a x : ℝ) : HasDerivAt (pp' a) (a ^ 2 * 2) x := by + simpa using! hasDerivAt_id x |>.add_const 1 |>.const_mul 2 |>.const_mul (a ^ 2) + +lemma pp'_deriv_eq (a : ℝ) : deriv (pp' a) = fun _ => a ^ 2 * 2 := by + ext x ; exact pp'_deriv a x |>.deriv + +noncomputable def hh (a t : ℝ) : ℝ := (t * (1 + (a * log t) ^ 2))⁻¹ + +noncomputable def hh' (a t : ℝ) : ℝ := - pp a (log t) * hh a t ^ 2 + +lemma hh_nonneg (a : ℝ) {t : ℝ} (ht : 0 ≤ t) : 0 ≤ hh a t := by dsimp only [hh] ; positivity + +lemma hh_le (a t : ℝ) (ht : 0 ≤ t) : |hh a t| ≤ t⁻¹ := by + by_cases h0 : t = 0 + · simp [hh, h0] + replace ht : 0 < t := lt_of_le_of_ne ht (by tauto) + unfold hh + rw [abs_inv, inv_le_inv₀ (by positivity) ht, abs_mul, abs_eq_self.mpr ht.le] + convert_to! t * 1 ≤ _ + · simp + apply mul_le_mul le_rfl ?_ zero_le_one ht.le + rw [abs_eq_self.mpr (by positivity)] + simp only [le_add_iff_nonneg_right] + positivity + +lemma hh_deriv (a : ℝ) {t : ℝ} (ht : t ≠ 0) : HasDerivAt (hh a) (hh' a t) t := by + have e1 : t * (1 + (a * log t) ^ 2) ≠ 0 := mul_ne_zero ht (_root_.ne_of_lt (by positivity)).symm + have l5 : HasDerivAt (fun t : ℝ => log t) t⁻¹ t := Real.hasDerivAt_log ht + have l4 : HasDerivAt (fun t : ℝ => a * log t) (a * t⁻¹) t := l5.const_mul _ + have l3 : HasDerivAt (fun t : ℝ => (a * log t) ^ 2) (2 * a ^ 2 * t⁻¹ * log t) t := by + convert! l4.pow 2 using 1 ; ring + have l2 : HasDerivAt (fun t : ℝ => 1 + (a * log t) ^ 2) (2 * a ^ 2 * t⁻¹ * log t) t := + l3.const_add _ + have l1 : HasDerivAt (fun t : ℝ => t * (1 + (a * log t) ^ 2)) + (1 + 2 * a ^ 2 * log t + a ^ 2 * log t ^ 2) t := by + convert! (hasDerivAt_id' t).mul l2 using 1; field_simp; ring + convert! l1.inv e1 using 1; simp only [hh', pp, hh]; field_simp; ring + +lemma hh_continuous (a : ℝ) : ContinuousOn (hh a) (Ioi 0) := + fun t (ht : 0 < t) => (hh_deriv a ht.ne.symm).continuousAt.continuousWithinAt + +lemma hh'_nonpos {a x : ℝ} (ha : a ∈ Ioo (-1) 1) : hh' a x ≤ 0 := by + have := pp_pos ha (log x) + simp only [hh', neg_mul, Left.neg_nonpos_iff, ge_iff_le] + positivity + +lemma hh_antitone {a : ℝ} (ha : a ∈ Ioo (-1) 1) : AntitoneOn (hh a) (Ioi 0) := by + have l1 x (hx : x ∈ interior (Ioi 0)) : + HasDerivWithinAt (hh a) (hh' a x) (interior (Ioi 0)) x := by + have : x ≠ 0 := by contrapose! hx ; simp [hx] + exact (hh_deriv a this).hasDerivWithinAt + apply antitoneOn_of_hasDerivWithinAt_nonpos (convex_Ioi _) (hh_continuous _) l1 + (fun x _ => hh'_nonpos ha) + +noncomputable def gg (x i : ℝ) : ℝ := 1 / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ + +lemma gg_of_hh {x : ℝ} (hx : x ≠ 0) (i : ℝ) : gg x i = x⁻¹ * hh (1 / (2 * π)) (i / x) := by + simp only [gg, hh] + field_simp + +lemma gg_l1 {x : ℝ} (hx : 0 < x) (n : ℕ) : |gg x n| ≤ 1 / n := by + simp only [gg_of_hh hx.ne.symm, one_div, mul_inv_rev, abs_mul] + apply mul_le_mul le_rfl (hh_le _ _ (by positivity)) (by positivity) (by positivity) |>.trans + (le_of_eq ?_) + simp [abs_inv, abs_eq_self.mpr hx.le] ; field_simp + +lemma gg_le_one (i : ℕ) : gg x i ≤ 1 := by + by_cases hi : i = 0 <;> simp only [gg, hi, CharP.cast_eq_zero, div_zero, one_div, mul_inv_rev, + zero_div, Real.log_zero, mul_zero, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, zero_pow, + add_zero, inv_one, mul_one, zero_le_one] + have l1 : 1 ≤ (i : ℝ) := by simp ; omega + have l2 : 1 ≤ 1 + (π⁻¹ * 2⁻¹ * Real.log (↑i / x)) ^ 2 := by + simp only [le_add_iff_nonneg_right] ; positivity + rw [← mul_inv] ; apply inv_le_one_of_one_le₀ ; simpa using mul_le_mul l1 l2 zero_le_one (by simp) + +lemma one_div_two_pi_mem_Ioo : 1 / (2 * π) ∈ Ioo (-1) 1 := by + constructor + · trans 0 + · linarith + · positivity + · rw [div_lt_iff₀ (by positivity)] + convert_to! 1 * 1 < 2 * π + · simp + · simp + apply mul_lt_mul one_lt_two ?_ zero_lt_one zero_le_two + trans 2 + · exact one_le_two + · exact two_le_pi + +lemma sum_telescopic (a : ℕ → ℝ) (n : ℕ) : ∑ i ∈ Finset.range n, (a (i + 1) - a i) = a n - a 0 := by + apply Finset.sum_range_sub + +lemma cancel_aux {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : + ∑ i ∈ Finset.range n, f i * g i ≤ g (n - 1) * (C * n) + (C * (↑(n - 1 - 1) + 1) * g 0 + - C * (↑(n - 1 - 1) + 1) * g (n - 1) - + ((n - 1 - 1) • (C * g 0) - ∑ x ∈ Finset.range (n - 1 - 1), C * g (x + 1))) := by + + have l1 (n : ℕ) : + (g n - g (n + 1)) * ∑ i ∈ Finset.range (n + 1), f i ≤ (g n - g (n + 1)) * (C * (n + 1)) := by + apply mul_le_mul le_rfl (by simpa using! hf' (n + 1)) + (Finset.sum_nonneg (fun index _ => hf index)) ?_ + simp only [sub_nonneg] ; apply hg' ; simp + have l2 (x : ℕ) : C * (↑(x + 1) + 1) - C * (↑x + 1) = C := by simp ; ring + have l3 (n : ℕ) : 0 ≤ cumsum f n := Finset.sum_nonneg (fun index _ => hf index) + + convert_to ∑ i ∈ Finset.range n, (g i) • (f i) ≤ _ + · simp [mul_comm] + rw [Finset.sum_range_by_parts, sub_eq_add_neg, ← Finset.sum_neg_distrib] + simp_rw [← neg_smul, neg_sub, smul_eq_mul] + apply _root_.add_le_add + · exact mul_le_mul le_rfl (hf' n) (l3 n) (hg _) + · apply Finset.sum_le_sum (fun n _ => l1 n) |>.trans + convert_to! ∑ i ∈ Finset.range (n - 1), (C * (↑i + 1)) • (g i - g (i + 1)) ≤ _ + · congr ; ext i ; simp ; ring + rw [Finset.sum_range_by_parts] + simp_rw [Finset.sum_range_sub', l2, smul_sub, smul_eq_mul, Finset.sum_sub_distrib, + Finset.sum_const, Finset.card_range] + apply le_of_eq ; ring_nf + +lemma sum_range_succ (a : ℕ → ℝ) (n : ℕ) : + ∑ i ∈ Finset.range n, a (i + 1) = (∑ i ∈ Finset.range (n + 1), a i) - a 0 := by + have := Finset.sum_range_sub a n + rw [Finset.sum_sub_distrib, sub_eq_iff_eq_add] at this + rw [Finset.sum_range_succ, this] ; ring + +lemma cancel_aux' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : + ∑ i ∈ Finset.range n, f i * g i ≤ + C * n * g (n - 1) + + C * cumsum g (n - 1 - 1 + 1) + - C * (↑(n - 1 - 1) + 1) * g (n - 1) + := by + have := cancel_aux hf hg hf' hg' n + simp only [nsmul_eq_mul, ← Finset.mul_sum, sum_range_succ] at this + convert this using 1 ; unfold cumsum ; ring + +lemma cancel_main {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) (hn : 2 ≤ n) : + cumsum (f * g) n ≤ C * cumsum g n := by + convert! cancel_aux' hf hg hf' hg' n using 1 + match n with + | n + 2 => simp only [cumsum_succ] ; push_cast ; ring + +lemma cancel_main' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hf0 : f 0 = 0) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : + cumsum (f * g) n ≤ C * cumsum g n := by + match n with + | 0 => simp [cumsum] + | 1 => specialize hg 0 ; specialize hf' 1 ; simp only [cumsum, Finset.range_one, + Finset.sum_singleton, hf0, Nat.cast_one, mul_one, Pi.zero_apply, Pi.mul_apply, zero_mul, + ge_iff_le] at hf' hg ⊢ ; positivity + | n + 2 => convert! cancel_aux' hf hg hf' hg' (n + 2) using 1 ; simp [cumsum_succ] ; ring + +theorem sum_le_integral {x₀ : ℝ} {f : ℝ → ℝ} {n : ℕ} (hf : AntitoneOn f (Ioc x₀ (x₀ + n))) + (hfi : IntegrableOn f (Icc x₀ (x₀ + n))) : + (∑ i ∈ Finset.range n, f (x₀ + ↑(i + 1))) ≤ ∫ x in x₀..x₀ + n, f x := by + + cases n with simp only [Nat.cast_add, Nat.cast_one, CharP.cast_eq_zero, add_zero, + lt_self_iff_false, not_false_eq_true, + Ioc_eq_empty, Finset.range_zero, Nat.cast_add, Nat.cast_one, Finset.sum_empty, + intervalIntegral.integral_same, le_refl] at hf ⊢ + | succ n => + have : Finset.range (n + 1) = {0} ∪ Finset.Ico 1 (n + 1) := by + ext i ; by_cases hi : i = 0 <;> simp [hi] ; omega + simp only [this, Finset.singleton_union, Finset.mem_Ico, nonpos_iff_eq_zero, one_ne_zero, + lt_add_iff_pos_left, add_pos_iff, zero_lt_one, or_true, and_true, not_false_eq_true, + Finset.sum_insert, CharP.cast_eq_zero, zero_add, ge_iff_le] + + have l4 : IntervalIntegrable f volume x₀ (x₀ + 1) := by + apply IntegrableOn.intervalIntegrable + simp only [le_add_iff_nonneg_right, zero_le_one, uIcc_of_le] + apply hfi.mono_set + apply Icc_subset_Icc le_rfl + simp + have l5 x (hx : x ∈ Ioc x₀ (x₀ + 1)) : (fun x ↦ f (x₀ + 1)) x ≤ f x := by + rcases hx with ⟨hx1, hx2⟩ + refine hf ⟨hx1, by linarith⟩ ⟨by linarith, by linarith⟩ hx2 + have l6 : ∫ x in x₀..x₀ + 1, f (x₀ + 1) = f (x₀ + 1) := by simp + + have l1 : f (x₀ + 1) ≤ ∫ x in x₀..x₀ + 1, f x := by + rw [← l6] ; apply intervalIntegral.integral_mono_ae_restrict (by linarith) (by simp) l4 + apply eventually_of_mem _ l5 + have : (Ioc x₀ (x₀ + 1))ᶜ ∩ Icc x₀ (x₀ + 1) = {x₀} := by simp [← sdiff_eq_compl_inter] + simp only [mem_ae_iff, Measure.restrict_apply measurableSet_Ioc.compl, this, + measure_singleton] + + have l2 : AntitoneOn (fun x ↦ f (x₀ + x)) (Icc 1 ↑(n + 1)) := by + intro u ⟨hu1, _⟩ v ⟨_, hv2⟩ huv ; push_cast at hv2 + refine hf ⟨?_, ?_⟩ ⟨?_, ?_⟩ ?_ <;> linarith + + have l3 := @AntitoneOn.sum_le_integral_Ico 1 (n + 1) (fun x => f (x₀ + x)) (by simp) + (by simpa using l2) + + simp only [Nat.cast_add, Nat.cast_one, intervalIntegral.integral_comp_add_left] at l3 + convert! _root_.add_le_add l1 l3 + + have := @intervalIntegral.integral_comp_mul_add ℝ _ _ 1 (n + 1) 1 f one_ne_zero x₀ + rw [intervalIntegral.integral_add_adjacent_intervals] + · exact l4 + · apply IntegrableOn.intervalIntegrable + simp only [add_le_add_iff_left, le_add_iff_nonneg_left, Nat.cast_nonneg, uIcc_of_le] + apply hfi.mono_set + apply Icc_subset_Icc + · linarith + · simp + +lemma hh_integrable_aux (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : + (IntegrableOn (fun t ↦ a * hh b (t / c)) (Ici 0)) ∧ + (∫ (t : ℝ) in Ioi 0, a * hh b (t / c) = a * c / b * π) := by + + rw [integrableOn_Ici_iff_integrableOn_Ioi] + simp only [hh] + + let g (x : ℝ) := (a * c / b) * Real.arctan (b * log (x / c)) + let g₀ (x : ℝ) := if x = 0 then ((a * c / b) * (- (π / 2))) else g x + let g' (x : ℝ) := a * (x / c * (1 + (b * Real.log (x / c)) ^ 2))⁻¹ + + have l3 (x) (hx : 0 < x) : HasDerivAt Real.log x⁻¹ x := by apply Real.hasDerivAt_log (by linarith) + have l4 (x) : HasDerivAt (fun t => t / c) (1 / c) x := (hasDerivAt_id x).div_const c + have l2 (x) (hx : 0 < x) : HasDerivAt (fun t => log (t / c)) x⁻¹ x := by + have := @HasDerivAt.comp _ _ _ _ _ _ (fun t => t / c) _ _ _ (l3 (x / c) (by positivity)) (l4 x) + convert! this using 1 ; field_simp + have l5 (x) (hx : 0 < x) := (l2 x hx).const_mul b + have l1 (x) (hx : 0 < x) := (l5 x hx).arctan + have l6 (x) (hx : 0 < x) : HasDerivAt g (g' x) x := by + convert! (l1 x hx).const_mul (a * c / b) using 1 + simp only [g'] + field_simp + have key (x) (hx : 0 < x) : HasDerivAt g₀ (g' x) x := by + apply (l6 x hx).congr_of_eventuallyEq + apply eventually_of_mem <| Ioi_mem_nhds hx + intro y (hy : 0 < y) + simp [g₀, hy.ne.symm] + + have k1 : Tendsto g₀ atTop (𝓝 ((a * c / b) * (π / 2))) := by + have : g =ᶠ[atTop] g₀ := by + apply eventually_of_mem (Ioi_mem_atTop 0) + intro y (hy : 0 < y) + simp [g₀, hy.ne.symm] + apply Tendsto.congr' this + apply Tendsto.const_mul + apply (tendsto_arctan_atTop.mono_right nhdsWithin_le_nhds).comp + apply Tendsto.const_mul_atTop hb + apply tendsto_log_atTop.comp + apply Tendsto.atTop_div_const hc + apply tendsto_id + + have k2 : Tendsto g₀ (𝓝[>] 0) (𝓝 (g₀ 0)) := by + have : g =ᶠ[𝓝[>] 0] g₀ := by + apply eventually_of_mem self_mem_nhdsWithin + intro x (hx : 0 < x) ; simp [g₀, hx.ne.symm] + simp only [g₀] + apply Tendsto.congr' this + apply Tendsto.const_mul + apply (tendsto_arctan_atBot.mono_right nhdsWithin_le_nhds).comp + apply Tendsto.const_mul_atBot hb + apply tendsto_log_nhdsGT_zero.comp + rw [Metric.tendsto_nhdsWithin_nhdsWithin] + intro ε hε + refine ⟨c * ε, by positivity, fun x hx1 hx2 => ⟨?_, ?_⟩⟩ + · simp only [mem_Ioi] at hx1 ⊢ ; positivity + · simp only [dist_zero_right, norm_eq_abs, norm_div, abs_eq_self.mpr hc.le] at hx2 ⊢ + rwa [div_lt_iff₀ hc, mul_comm] + + have k3 : ContinuousWithinAt g₀ (Ici 0) 0 := by + rw [Metric.continuousWithinAt_iff] + rw [Metric.tendsto_nhdsWithin_nhds] at k2 + intro epsilon hepsilon + obtain ⟨delta, hdelta, hbound⟩ := k2 epsilon hepsilon + refine ⟨delta, hdelta, ?_⟩ + intro point hpoint hdist + change 0 ≤ point at hpoint + rcases lt_or_eq_of_le hpoint with hpositive | hzero + · exact hbound hpositive hdist + · simp [g₀, hzero.symm, hepsilon] + + have k4 : ∀ x ∈ Ioi 0, 0 ≤ g' x := by + intro x (hx : 0 < x) ; simp only [mul_inv_rev, inv_div, g'] ; positivity + + constructor + · convert_to IntegrableOn g' _ + exact integrableOn_Ioi_deriv_of_nonneg k3 key k4 k1 + · have := integral_Ioi_of_hasDerivAt_of_nonneg k3 key k4 k1 + simp only [mul_inv_rev, inv_div, mul_neg, ↓reduceIte, sub_neg_eq_add, g', g₀] at this ⊢ + convert this using 1 ; field_simp ; ring + +lemma hh_integrable (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : + IntegrableOn (fun t ↦ a * hh b (t / c)) (Ici 0) := + hh_integrable_aux ha hb hc |>.1 + +lemma hh_integral (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : + ∫ (t : ℝ) in Ioi 0, a * hh b (t / c) = a * c / b * π := + hh_integrable_aux ha hb hc |>.2 + +lemma hh_integral' : ∫ t in Ioi 0, hh (1 / (2 * π)) t = 2 * π ^ 2 := by + have := hh_integral (a := 1) (b := 1 / (2 * π)) (c := 1) + (by positivity) (by positivity) (by positivity) + convert this using 1 <;> simp ; ring + +lemma bound_sum_log {C : ℝ} (hf0 : f 0 = 0) (hf : chebyWith C f) {x : ℝ} (hx : 1 ≤ x) : + ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ + C * (1 + ∫ t in Ioi 0, hh (1 / (2 * π)) t) := by + + let ggg (i : ℕ) : ℝ := if i = 0 then 1 else gg x i + + have l0 : x ≠ 0 := by linarith + have l1 i : 0 ≤ ggg i := by by_cases hi : i = 0 <;> simp only [gg, one_div, mul_inv_rev, hi, + ↓reduceIte, zero_le_one, ggg] ; positivity + have l2 : Antitone ggg := by + intro i j hij ; by_cases hi : i = 0 <;> by_cases hj : j = 0 <;> simp only [hj, ↓reduceIte, hi, + le_refl, ggg] + · exact gg_le_one _ + · omega + · simp only [gg_of_hh l0] + gcongr + apply hh_antitone one_div_two_pi_mem_Ioo + · simp only [mem_Ioi] ; positivity + · simp only [mem_Ioi] ; positivity + · gcongr + have l3 : 0 ≤ C := by simpa [cumsum, hf0] using hf 1 + + have l4 : 0 ≤ ∫ (t : ℝ) in Ioi 0, hh (π⁻¹ * 2⁻¹) t := + setIntegral_nonneg measurableSet_Ioi (fun x hx => hh_nonneg _ (LT.lt.le hx)) + + have l5 {n : ℕ} : AntitoneOn (fun t ↦ x⁻¹ * hh (1 / (2 * π)) (t / x)) (Ioc 0 n) := by + intro u ⟨hu1, _⟩ v ⟨hv1, _⟩ huv + simp only + apply mul_le_mul le_rfl ?_ (hh_nonneg _ (by positivity)) (by positivity) + apply hh_antitone one_div_two_pi_mem_Ioo (by simp only [mem_Ioi] ; positivity) + (by simp only [mem_Ioi] ; positivity) + apply (div_le_div_iff_of_pos_right (by positivity)).mpr huv + + have l6 {n : ℕ} : IntegrableOn (fun t ↦ x⁻¹ * hh (π⁻¹ * 2⁻¹) (t / x)) (Icc 0 n) volume := by + apply IntegrableOn.mono_set + (hh_integrable (by positivity) (by positivity) (by positivity)) Icc_subset_Ici_self + + apply Real.tsum_le_of_sum_range_le (fun n => by positivity) ; intro n + convert_to! ∑ i ∈ Finset.range n, ‖f i‖ * ggg i ≤ _ + · congr ; ext i + by_cases hi : i = 0 + · simp [hi, hf0] + · simp only [gg, hi, ↓reduceIte, ggg] + field_simp + + apply cancel_main' (fun _ => norm_nonneg _) (by simp [hf0]) l1 hf l2 n |>.trans + gcongr ; simp only [cumsum, gg_of_hh l0, one_div, mul_inv_rev, ggg] + + by_cases hn : n = 0 + · simp only [hn, Finset.range_zero, Finset.sum_empty] ; positivity + replace hn : 0 < n := by omega + have : Finset.range n = {0} ∪ Finset.Ico 1 n := by + ext i ; simp ; by_cases hi : i = 0 <;> simp [hi, hn] ; omega + simp only [this, Finset.singleton_union, Finset.mem_Ico, nonpos_iff_eq_zero, one_ne_zero, + false_and, not_false_eq_true, Finset.sum_insert, ↓reduceIte, add_le_add_iff_left, ge_iff_le] + convert_to! ∑ x_1 ∈ Finset.Ico 1 n, x⁻¹ * hh (π⁻¹ * 2⁻¹) (↑x_1 / x) ≤ _ + · apply Finset.sum_congr rfl (fun i hi => ?_) + simp at hi + have : i ≠ 0 := by omega + simp [this] + simp_rw [Finset.sum_Ico_eq_sum_range, add_comm 1] + have := @sum_le_integral 0 (fun t => x⁻¹ * hh (π⁻¹ * 2⁻¹) (t / x)) (n - 1) + (by simpa using l5) (by simpa using l6) + simp only [zero_add] at this + apply this.trans + rw [@intervalIntegral.integral_comp_div ℝ _ _ 0 ↑(n - 1) x (fun t => x⁻¹ * hh (π⁻¹ * 2⁻¹) (t)) l0] + simp only [zero_div, intervalIntegral.integral_const_mul, smul_eq_mul, ← mul_assoc, + mul_inv_cancel₀ l0, one_mul] + have : (0 : ℝ) ≤ ↑(n - 1) / x := by positivity + rw [intervalIntegral.intervalIntegral_eq_integral_uIoc] + simp only [this, ↓reduceIte, uIoc_of_le, smul_eq_mul, one_mul, ge_iff_le] + apply integral_mono_measure + · apply Measure.restrict_mono Ioc_subset_Ioi_self le_rfl + · apply eventually_of_mem (self_mem_ae_restrict measurableSet_Ioi) + intro x (hx : 0 < x) + apply hh_nonneg _ hx.le + · have := (@hh_integrable 1 (1 / (2 * π)) 1 (by positivity) (by positivity) (by positivity)) + simpa using! this.mono_set Ioi_subset_Ici_self + +lemma bound_sum_log0 {C : ℝ} (hf : chebyWith C f) {x : ℝ} (hx : 1 ≤ x) : + ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ + C * (1 + ∫ t in Ioi 0, hh (1 / (2 * π)) t) := by + + let f0 i := if i = 0 then 0 else f i + have l1 : chebyWith C f0 := by + intro n ; refine Finset.sum_le_sum (fun i _ => ?_) |>.trans (hf n) + by_cases hi : i = 0 <;> simp [hi, f0] + have l2 i : ‖f i‖ / i = ‖f0 i‖ / i := by by_cases hi : i = 0 <;> simp [hi, f0] + simp_rw [l2] ; apply bound_sum_log rfl l1 hx + +lemma bound_sum_log' {C : ℝ} (hf : chebyWith C f) {x : ℝ} (hx : 1 ≤ x) : + ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ C * (1 + 2 * π ^ 2) := by + simpa only [hh_integral'] using bound_sum_log0 hf hx + +variable (f x) in +lemma summable_fourier_aux (ψ : W21) (i : ℕ) : + ‖f i / i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (i / x))‖ ≤ + W21.norm ψ * (‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹) := by + convert! mul_le_mul_of_nonneg_left (decay_bounds_key ψ (1 / (2 * π) * log (i / x))) + (norm_nonneg (f i / i)) using 1 + · simp + · change _ = _ * (W21.norm ψ * _) + simp only [W21.norm, mul_inv_rev, one_div, Complex.norm_div, RCLike.norm_natCast] + ring + +lemma summable_fourier (x : ℝ) (hx : 0 < x) (ψ : W21) (hcheby : cheby f) : + Summable fun i ↦ ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑i / x))‖ := by + have l5 : Summable fun i ↦ ‖f i‖ / ↑i * ((1 + (1 / (2 * ↑π) * ↑(Real.log (↑i / x))) ^ 2)⁻¹) := by + simpa using limiting_fourier_lim1_aux hcheby hx 1 (zero_le_one' ℝ) + have l6 := summable_fourier_aux x f ψ + exact Summable.of_nonneg_of_le (fun _ => norm_nonneg _) l6 + (by simpa using l5.const_smul (W21.norm ψ)) + +lemma bound_I1 (x : ℝ) (hx : 0 < x) (ψ : W21) (hcheby : cheby f) : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ + W21.norm ψ • ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ := by + + have l5 : Summable fun i ↦ ‖f i‖ / ↑i * ((1 + (1 / (2 * ↑π) * ↑(Real.log (↑i / x))) ^ 2)⁻¹) := by + simpa using limiting_fourier_lim1_aux hcheby hx 1 (zero_le_one' ℝ) + have l6 := summable_fourier_aux x f ψ + have l1 : Summable fun i ↦ ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑i / x))‖ := by + exact summable_fourier x hx ψ hcheby + apply (norm_tsum_le_tsum_norm l1).trans + simpa only [← Summable.tsum_const_smul _ l5] using! + Summable.tsum_mono l1 (by simpa using l5.const_smul (W21.norm ψ)) l6 + +lemma bound_I1' {C : ℝ} (x : ℝ) (hx : 1 ≤ x) (ψ : W21) (hcheby : chebyWith C f) : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ + W21.norm ψ * C * (1 + 2 * π ^ 2) := by + + apply bound_I1 x (by linarith) ψ ⟨_, hcheby⟩ |>.trans + rw [smul_eq_mul, mul_assoc] + apply mul_le_mul le_rfl (bound_sum_log' hcheby hx) ?_ W21.norm_nonneg + apply tsum_nonneg (fun i => by positivity) + +lemma bound_I2 (x : ℝ) (ψ : W21) : + ‖∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))‖ ≤ W21.norm ψ * (2 * π ^ 2) := by + + have key a : ‖𝓕 (ψ : ℝ → ℂ) (a / (2 * π))‖ ≤ W21.norm ψ * (1 + (a / (2 * π)) ^ 2)⁻¹ := + decay_bounds_key ψ _ + have twopi : 0 ≤ 2 * π := by simp [pi_nonneg] + have l3 : Integrable (fun a ↦ (1 + (a / (2 * π)) ^ 2)⁻¹) := + integrable_inv_one_add_sq.comp_div (by norm_num [pi_ne_zero]) + have l2 : IntegrableOn (fun i ↦ W21.norm ψ * (1 + (i / (2 * π)) ^ 2)⁻¹) (Ici (-Real.log x)) := by + exact (l3.const_mul _).integrableOn + have l1 : IntegrableOn (fun i ↦ ‖𝓕 (ψ : ℝ → ℂ) (i / (2 * π))‖) (Ici (-Real.log x)) := by + refine ((l3.const_mul (W21.norm ψ)).mono' ?_ ?_).integrableOn + · apply Continuous.aestronglyMeasurable ; fun_prop + · simp only [norm_norm, key] ; simp + have l5 : 0 ≤ᵐ[volume] fun a ↦ (1 + (a / (2 * π)) ^ 2)⁻¹ := by + apply Eventually.of_forall ; intro x ; positivity + refine (norm_integral_le_integral_norm _).trans <| (setIntegral_mono l1 l2 key).trans ?_ + rw [integral_const_mul] ; gcongr + · apply W21.norm_nonneg + refine (setIntegral_le_integral l3 l5).trans ?_ + rw [Measure.integral_comp_div (fun x => (1 + x ^ 2)⁻¹) (2 * π)] + simp [abs_eq_self.mpr twopi] ; ring_nf ; rfl + +lemma bound_main {C : ℝ} (A : ℂ) (x : ℝ) (hx : 1 ≤ x) (ψ : W21) + (hcheby : chebyWith C f) : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))‖ ≤ + W21.norm ψ * (C * (1 + 2 * π ^ 2) + ‖A‖ * (2 * π ^ 2)) := by + + have l1 := bound_I1' x hx ψ hcheby + have l2 := mul_le_mul (le_refl ‖A‖) (bound_I2 x ψ) (by positivity) (by positivity) + apply norm_sub_le _ _ |>.trans ; rw [norm_mul] + convert _root_.add_le_add l1 l2 using 1 ; ring + +lemma limiting_cor_W21 (ψ : W21) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := by + + let S1 x (ψ : ℝ → ℂ) := ∑' (n : ℕ), f n / ↑n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑n / x)) + let S2 x (ψ : ℝ → ℂ) := ↑A * ∫ (u : ℝ) in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) + let S x ψ := S1 x ψ - S2 x ψ ; change Tendsto (fun x ↦ S x ψ) atTop (𝓝 0) + + obtain g := exists_trunc + let Ψ R := g.scale R * ψ + have key R : Tendsto (fun x ↦ S x (Ψ R)) atTop (𝓝 0) := limiting_cor (Ψ R) hf hcheby hG hG' + + obtain ⟨C, hcheby⟩ := hcheby + have hC : 0 ≤ C := by + have : ‖f 0‖ ≤ C := by simpa [cumsum] using hcheby 1 + have : 0 ≤ ‖f 0‖ := by positivity + linarith + have key2 : Tendsto (fun R ↦ W21.norm (ψ - Ψ R)) atTop (𝓝 0) := W21_approximation ψ g + simp_rw [Metric.tendsto_nhds] at key key2 ⊢ ; intro ε hε + let M := C * (1 + 2 * π ^ 2) + ‖(A : ℂ)‖ * (2 * π ^ 2) + obtain ⟨R, hRψ⟩ := (key2 ((ε / 2) / (1 + M)) (by positivity)).exists + simp only [dist_zero_right, Real.norm_eq_abs, abs_eq_self.mpr W21.norm_nonneg] at hRψ key + + filter_upwards [eventually_ge_atTop 1, key R (ε / 2) (by positivity)] with x hx key + + have key3 : ‖S x (ψ - Ψ R)‖ < ε / 2 := by + have : ‖S x _‖ ≤ _ * M := @bound_main f C A x hx (ψ - Ψ R) hcheby + apply this.trans_lt + apply (mul_le_mul (d := 1 + M) le_rfl (by simp) (by positivity) W21.norm_nonneg).trans_lt + have : 0 < 1 + M := by positivity + convert! (mul_lt_mul_iff_left₀ this).mpr hRψ using 1 ; field_simp + + have S1_sub_1 x : 𝓕 (⇑ψ - ⇑(Ψ R)) x = 𝓕 (ψ : ℝ → ℂ) x - 𝓕 ⇑(Ψ R) x := by + have l1 : AEStronglyMeasurable (fun x_1 : ℝ ↦ cexp (-(2 * ↑π * (↑x_1 * ↑x) * I))) volume := by + refine (Continuous.mul ?_ continuous_const).neg.cexp.aestronglyMeasurable + apply continuous_const.mul <| contDiff_ofReal.continuous.mul continuous_const + simp only [Real.fourier_eq', neg_mul, RCLike.inner_apply', conj_trivial, ofReal_neg, + ofReal_mul, ofReal_ofNat, Pi.sub_apply, smul_eq_mul, mul_sub] + apply integral_sub + · apply ψ.hf.bdd_mul (c := 1) l1 ; simp [Complex.norm_exp] + · apply (Ψ R : W21) |>.hf |>.bdd_mul (c := 1) l1 + simp [Complex.norm_exp] + + have S1_sub : S1 x (ψ - Ψ R) = S1 x ψ - S1 x (Ψ R) := by + simp only [one_div, mul_inv_rev, S1_sub_1, mul_sub, S1] ; apply Summable.tsum_sub + · have := summable_fourier x (by positivity) ψ ⟨_, hcheby⟩ + rw [summable_norm_iff] at this + simpa using this + · have := summable_fourier x (by positivity) (Ψ R) ⟨_, hcheby⟩ + rw [summable_norm_iff] at this + simpa using! this + + have S2_sub : S2 x (ψ - Ψ R) = S2 x ψ - S2 x (Ψ R) := by + simp only [S1_sub_1, S2] ; rw [integral_sub] + · ring + · exact ψ.integrable_fourier (by positivity) |>.restrict + · exact (Ψ R : W21).integrable_fourier (by positivity) |>.restrict + + have S_sub : S x (ψ - Ψ R) = S x ψ - S x (Ψ R) := by simp [S, S1_sub, S2_sub] ; ring + simpa [S_sub, Ψ] using norm_add_le _ _ |>.trans_lt (_root_.add_lt_add key3 key) + +lemma limiting_cor_schwartz (ψ : 𝓢(ℝ, ℂ)) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := + limiting_cor_W21 ψ hf hcheby hG hG' + +lemma fourier_surjection_on_schwartz (f : 𝓢(ℝ, ℂ)) : ∃ g : 𝓢(ℝ, ℂ), 𝓕 g = f := by + refine ⟨𝓕⁻ f, ?_⟩ + exact FourierTransform.fourier_fourierInv_eq f + +noncomputable def toSchwartz (f : ℝ → ℂ) (h1 : ContDiff ℝ ∞ f) + (h2 : HasCompactSupport f) : 𝓢(ℝ, ℂ) where + toFun := f + smooth' := h1 + decay' k n := by + have l1 : Continuous (fun x => ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖) := by + have : ContDiff ℝ ∞ (iteratedFDeriv ℝ n f) := h1.iteratedFDeriv_right (mod_cast le_top) + exact Continuous.mul (by continuity) this.continuous.norm + have l2 : HasCompactSupport (fun x ↦ ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖) := + (h2.iteratedFDeriv _).norm.mul_left + simpa using l1.bounded_above_of_compact_support l2 + +@[simp] lemma toSchwartz_apply (f : ℝ → ℂ) {h1 h2 x} : SchwartzMap.mk f h1 h2 x = f x := rfl + +lemma comp_exp_support0 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : + ∀ᶠ x in 𝓝 0, Ψ x = 0 := + notMem_tsupport_iff_eventuallyEq.mp (fun h => lt_irrefl 0 <| mem_Ioi.mp (hplus h)) + +lemma comp_exp_support1 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : + ∀ᶠ x in atBot, Ψ (exp x) = 0 := + Real.tendsto_exp_atBot <| comp_exp_support0 hplus + +lemma comp_exp_support2 {Ψ : ℝ → ℂ} (hsupp : HasCompactSupport Ψ) : + ∀ᶠ (x : ℝ) in atTop, (Ψ ∘ rexp) x = 0 := by + simp only [hasCompactSupport_iff_eventuallyEq, coclosedCompact_eq_cocompact, + cocompact_eq_atBot_atTop] at hsupp + exact Real.tendsto_exp_atTop hsupp.2 + +theorem comp_exp_support {Ψ : ℝ → ℂ} (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : HasCompactSupport (Ψ ∘ rexp) := by + simp only [hasCompactSupport_iff_eventuallyEq, coclosedCompact_eq_cocompact, + cocompact_eq_atBot_atTop] + exact ⟨comp_exp_support1 hplus, comp_exp_support2 hsupp⟩ + +lemma wiener_ikehara_smooth_aux (l0 : Continuous Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Ioi 0) (x : ℝ) (hx : 0 < x) : + ∫ (u : ℝ) in Ioi (-Real.log x), ↑(rexp u) * Ψ (rexp u) = ∫ (y : ℝ) in Ioi (1 / x), Ψ y := by + + have l1 : ContinuousOn rexp (Ici (-Real.log x)) := by fun_prop + have l2 : Tendsto rexp atTop atTop := Real.tendsto_exp_atTop + have l3 t (_ : t ∈ Ioi (-log x)) : HasDerivWithinAt rexp (rexp t) (Ioi t) t := + (Real.hasDerivAt_exp t).hasDerivWithinAt + have l4 : ContinuousOn Ψ (rexp '' Ioi (-Real.log x)) := by fun_prop + have l5 : IntegrableOn Ψ (rexp '' Ici (-Real.log x)) volume := + (l0.integrable_of_hasCompactSupport hsupp).integrableOn + have l6 : IntegrableOn (fun x ↦ rexp x • (Ψ ∘ rexp) x) (Ici (-Real.log x)) volume := by + refine (Continuous.integrable_of_hasCompactSupport (by fun_prop) ?_).integrableOn + change HasCompactSupport (rexp • (Ψ ∘ rexp)) + exact (comp_exp_support hsupp hplus).smul_left + have := MeasureTheory.integral_deriv_smul_comp_Ioi l1 l2 l3 l4 l5 l6 + simpa [Real.exp_neg, Real.exp_log hx] using this + +theorem wiener_ikehara_smooth_sub (h1 : Integrable Ψ) + (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : + Tendsto (fun x ↦ (↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y) - ↑A * ∫ (y : ℝ) in Ioi 0, Ψ y) + atTop (𝓝 0) := by + + obtain ⟨ε, hε, hh⟩ := Metric.eventually_nhds_iff.mp <| comp_exp_support0 hplus + apply tendsto_nhds_of_eventually_eq ; filter_upwards [eventually_gt_atTop ε⁻¹] with x hxε + + have l1 : Integrable (indicator (Ioi x⁻¹) (fun x : ℝ => Ψ x)) := h1.indicator measurableSet_Ioi + have l2 : Integrable (indicator (Ioi 0) (fun x : ℝ => Ψ x)) := h1.indicator measurableSet_Ioi + + simp_rw [← MeasureTheory.integral_indicator measurableSet_Ioi, ← mul_sub, ← integral_sub l1 l2] + simp only [mul_eq_zero, ofReal_eq_zero] + right + apply MeasureTheory.integral_eq_zero_of_ae + apply Eventually.of_forall + intro t + simp only [Pi.zero_apply] + + have hε' : 0 < ε⁻¹ := by positivity + have hx : 0 < x := by linarith + have hx' : 0 < x⁻¹ := by positivity + have hεx : x⁻¹ < ε := (inv_lt_comm₀ hε hx).mp hxε + + have l3 : Ioi 0 = Ioc 0 x⁻¹ ∪ Ioi x⁻¹ := by + ext t ; simp only [mem_Ioi, mem_union, mem_Ioc] ; constructor <;> intro h + · simp [h, le_or_gt] + · cases h with + | inl h => exact h.1 + | inr h => exact hx'.trans h + have l4 : Disjoint (Ioc 0 x⁻¹) (Ioi x⁻¹) := by simp + have l5 := Set.indicator_union_of_disjoint l4 Ψ + rw [l3, l5] + simp only + rw [add_comm, sub_add_cancel_left] + by_cases ht : t ∈ Ioc 0 x⁻¹ + · simp only [ht, indicator_of_mem, neg_eq_zero] + apply hh ; simp only [mem_Ioc, dist_zero_right, norm_eq_abs] at ht ⊢ + apply hεx.trans_le' + rw [abs_le] ; constructor <;> linarith + simp [ht] + +lemma wiener_ikehara_smooth (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hcheby : cheby f) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x - A * ∫ y in Set.Ioi 0, Ψ y) + atTop (𝓝 0) := by + + let h (x : ℝ) : ℂ := rexp (2 * π * x) * Ψ (exp (2 * π * x)) + have h1 : ContDiff ℝ ∞ h := by + have : ContDiff ℝ ∞ (fun x : ℝ => (rexp (2 * π * x))) := (contDiff_const.mul contDiff_id).exp + exact (contDiff_ofReal.comp this).mul (hsmooth.comp this) + have h2 : HasCompactSupport h := by + have : 2 * π ≠ 0 := by simp [pi_ne_zero] + simpa using! (comp_exp_support hsupp hplus).comp_smul this |>.mul_left + obtain ⟨g, hg⟩ := fourier_surjection_on_schwartz (toSchwartz h h1 h2) + + have l1 {y} (hy : 0 < y) : y * Ψ y = 𝓕 g (1 / (2 * π) * Real.log y) := by + simp only [one_div, mul_inv_rev, hg, toSchwartz, ofReal_exp, ofReal_mul, ofReal_ofNat, + toSchwartz_apply, ofReal_inv, h] + field_simp + norm_cast + rw [Real.exp_log hy] + + have key := limiting_cor_schwartz g hf hcheby hG hG' + + have l2 : ∀ᶠ x in atTop, ∑' (n : ℕ), f n / ↑n * 𝓕 g (1 / (2 * π) * Real.log (↑n / x)) = + ∑' (n : ℕ), f n * Ψ (↑n / x) / x := by + filter_upwards [eventually_gt_atTop 0] with x hx + congr ; ext n + by_cases hn : n = 0 + · simp [hn, (comp_exp_support0 hplus).self_of_nhds] + rw [← l1 (by positivity)] + have : (n : ℂ) ≠ 0 := by simpa using hn + have : (x : ℂ) ≠ 0 := by simpa using hx.ne.symm + simp only [ofReal_div, ofReal_natCast] + field_simp + + have l3 : ∀ᶠ x in atTop, ↑A * ∫ (u : ℝ) in Ici (-Real.log x), 𝓕 g (u / (2 * π)) = + ↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y := by + filter_upwards [eventually_gt_atTop 0] with x hx + congr 1 + simp only [hg, toSchwartz, ofReal_exp, ofReal_mul, ofReal_ofNat, toSchwartz_apply, + ofReal_div, h] + norm_cast ; field_simp; norm_cast + rw [MeasureTheory.integral_Ici_eq_integral_Ioi] + exact wiener_ikehara_smooth_aux hsmooth.continuous hsupp hplus x hx + + have l4 : Tendsto (fun x => (↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y) - ↑A * ∫ (y : ℝ) in Ioi 0, Ψ y) + atTop (𝓝 0) := by + exact wiener_ikehara_smooth_sub (hsmooth.continuous.integrable_of_hasCompactSupport hsupp) hplus + + simpa [tsum_div_const] using (key.congr' <| EventuallyEq.sub l2 l3) |>.add l4 + +lemma wiener_ikehara_smooth' (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hcheby : cheby f) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x) atTop (nhds (A * ∫ y in Set.Ioi 0, Ψ y)) := + tendsto_sub_nhds_zero_iff.mp <| wiener_ikehara_smooth hf hcheby hG hG' hsmooth hsupp hplus + +local instance {E : Type*} : Coe (E → ℝ) (E → ℂ) := ⟨fun f n => f n⟩ + +@[norm_cast] +theorem set_integral_ofReal {f : ℝ → ℝ} {s : Set ℝ} : ∫ x in s, (f x : ℂ) = ∫ x in s, f x := + integral_ofReal + +lemma wiener_ikehara_smooth_real {f : ℕ → ℝ} {Ψ : ℝ → ℝ} + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x) atTop (nhds (A * ∫ y in Set.Ioi 0, Ψ y)) := by + + let Ψ' := ofReal ∘ Ψ + have l1 : ContDiff ℝ ∞ Ψ' := contDiff_ofReal.comp hsmooth + have l2 : HasCompactSupport Ψ' := hsupp.comp_left rfl + have l3 : closure (Function.support Ψ') ⊆ Ioi 0 := by rwa [Function.support_comp_eq] ; simp + have key := (continuous_re.tendsto _).comp + (@wiener_ikehara_smooth' A Ψ G f hf hcheby hG hG' l1 l2 l3) + simp at key ; norm_cast at key + +lemma interval_approx_inf (ha : 0 < a) (hab : a < b) : + ∀ᶠ ε in 𝓝[>] 0, ∃ ψ : ℝ → ℝ, ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ + closure (Function.support ψ) ⊆ Set.Ioi 0 ∧ + ψ ≤ indicator (Ico a b) 1 ∧ b - a - ε ≤ ∫ y in Ioi 0, ψ y := by + + have l1 : Iio ((b - a) / 3) ∈ 𝓝[>] 0 := nhdsWithin_le_nhds <| Iio_mem_nhds <| by + rw [← sub_pos] at hab + positivity + filter_upwards [self_mem_nhdsWithin, l1] with ε (hε : 0 < ε) (hε' : ε < (b - a) / 3) + have l2 : a < a + ε / 2 := by simp [hε] + have l3 : b - ε / 2 < b := by simp [hε] + obtain ⟨ψ, h1, h2, h3, h4, h5⟩ := smooth_urysohn_support_Ioo l2 l3 + refine ⟨ψ, h1, h2, ?_, ?_, ?_⟩ + · simp [h5, hab.ne, Icc_subset_Ioi_iff hab.le, ha] + · exact h4.trans <| indicator_le_indicator_of_subset Ioo_subset_Ico_self (by simp) + · have l4 : 0 ≤ b - a - ε := by linarith + have l5 : Icc (a + ε / 2) (b - ε / 2) ⊆ Ioi 0 := by + intro t ht + simp only [mem_Icc, mem_Ioi] at ht ⊢ + exact ha.trans <| l2.trans_le <| ht.1 + have l6 : Icc (a + ε / 2) (b - ε / 2) ∩ Ioi 0 = Icc (a + ε / 2) (b - ε / 2) := + inter_eq_left.mpr l5 + have l7 : ∫ y in Ioi 0, indicator (Icc (a + ε / 2) (b - ε / 2)) 1 y = b - a - ε := by + simp only [measurableSet_Icc, integral_indicator_one, measureReal_restrict_apply, l6, + volume_real_Icc] + convert max_eq_left l4 using 1 ; ring_nf + have l8 : IntegrableOn ψ (Ioi 0) volume := + (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + rw [← l7] ; apply setIntegral_mono ?_ l8 h3 + rw [IntegrableOn, integrable_indicator_iff measurableSet_Icc] + apply IntegrableOn.mono ?_ subset_rfl Measure.restrict_le_self + apply integrableOn_const <;> + simp + +lemma interval_approx_sup (ha : 0 < a) (hab : a < b) : + ∀ᶠ ε in 𝓝[>] 0, ∃ ψ : ℝ → ℝ, ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ + closure (Function.support ψ) ⊆ Set.Ioi 0 ∧ + indicator (Ico a b) 1 ≤ ψ ∧ ∫ y in Ioi 0, ψ y ≤ b - a + ε := by + + have l1 : Iio (a / 2) ∈ 𝓝[>] 0 := nhdsWithin_le_nhds <| Iio_mem_nhds (by linarith) + filter_upwards [self_mem_nhdsWithin, l1] with ε (hε : 0 < ε) (hε' : ε < a / 2) + have l2 : a - ε / 2 < a := by linarith + have l3 : b < b + ε / 2 := by linarith + obtain ⟨ψ, h1, h2, h3, h4, h5⟩ := smooth_urysohn_support_Ioo l2 l3 + refine ⟨ψ, h1, h2, ?_, ?_, ?_⟩ + · have l4 : a - ε / 2 < b + ε / 2 := by linarith + have l5 : ε / 2 < a := by linarith + simp [h5, l4.ne, Icc_subset_Ioi_iff l4.le, l5] + · apply le_trans ?_ h3 + apply indicator_le_indicator_of_subset Ico_subset_Icc_self (by simp) + · have l4 : 0 ≤ b - a + ε := by linarith + have l5 : Ioo (a - ε / 2) (b + ε / 2) ⊆ Ioi 0 := by intro t ht ; simp at ht ⊢ ; linarith + have l6 : Ioo (a - ε / 2) (b + ε / 2) ∩ Ioi 0 = Ioo (a - ε / 2) (b + ε / 2) := inter_eq_left.mpr l5 + have l7 : ∫ y in Ioi 0, indicator (Ioo (a - ε / 2) (b + ε / 2)) 1 y = b - a + ε := by + simp only [measurableSet_Ioo, integral_indicator_one, measureReal_restrict_apply, l6, + volume_real_Ioo] + convert max_eq_left l4 using 1 ; ring_nf + have l8 : IntegrableOn ψ (Ioi 0) volume := (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + rw [← l7] + refine setIntegral_mono l8 ?_ h4 + rw [IntegrableOn, integrable_indicator_iff measurableSet_Ioo] + apply IntegrableOn.mono ?_ subset_rfl Measure.restrict_le_self + apply integrableOn_const <;> + simp + +lemma WI_summable {f : ℕ → ℝ} {g : ℝ → ℝ} (hg : HasCompactSupport g) (hx : 0 < x) : + Summable (fun n => f n * g (n / x)) := by + obtain ⟨M, hM⟩ := hg.bddAbove.mono subset_closure + apply summable_of_hasFiniteSupport + unfold Function.HasFiniteSupport + simp only [Function.support_mul] ; apply Finite.inter_of_right ; rw [finite_iff_bddAbove] + exact ⟨Nat.ceil (M * x), fun i hi => by simpa using Nat.ceil_mono ((div_le_iff₀ hx).mp (hM hi))⟩ + +lemma WI_sum_le {f : ℕ → ℝ} {g₁ g₂ : ℝ → ℝ} (hf : 0 ≤ f) (hg : g₁ ≤ g₂) (hx : 0 < x) + (hg₁ : HasCompactSupport g₁) (hg₂ : HasCompactSupport g₂) : + (∑' n, f n * g₁ (n / x)) / x ≤ (∑' n, f n * g₂ (n / x)) / x := by + apply div_le_div_of_nonneg_right ?_ hx.le + exact Summable.tsum_le_tsum (fun n => mul_le_mul_of_nonneg_left (hg _) (hf _)) + (WI_summable hg₁ hx) (WI_summable hg₂ hx) + +lemma WI_sum_Iab_le {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} (hcheby : chebyWith C f) (hb : 0 < b) (hxb : 2 / b < x) : + (∑' n, f n * indicator (Ico a b) 1 (n / x)) / x ≤ C * 2 * b := by + have hb' : 0 < 2 / b := by positivity + have hx : 0 < x := by linarith + have hxb' : 2 < x * b := (div_lt_iff₀ hb).mp hxb + have l1 (i : ℕ) (hi : i ∉ Finset.range ⌈b * x⌉₊) : f i * indicator (Ico a b) 1 (i / x) = 0 := by + simp_all [le_div_iff₀ hx] + have l2 (i : ℕ) (_ : i ∈ Finset.range ⌈b * x⌉₊) : f i * indicator (Ico a b) 1 (i / x) ≤ |f i| := by + rw [abs_eq_self.mpr (hpos _)] + convert_to _ ≤ f i * 1 + · ring + apply mul_le_mul_of_nonneg_left ?_ (hpos _) + by_cases hi : (i / x) ∈ (Ico a b) <;> simp [hi] + rw [tsum_eq_sum l1, div_le_iff₀ hx, mul_assoc, mul_assoc] + apply Finset.sum_le_sum l2 |>.trans + have := hcheby ⌈b * x⌉₊ ; simp only [norm_real, norm_eq_abs] at this ; apply this.trans + have : 0 ≤ C := by have := hcheby 1 ; simp only [cumsum, Finset.range_one, norm_real, + Finset.sum_singleton, Nat.cast_one, mul_one] at this ; exact (abs_nonneg _).trans this + refine mul_le_mul_of_nonneg_left ?_ this + apply (Nat.ceil_lt_add_one (by positivity)).le.trans + linarith + +lemma WI_sum_Iab_le' {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} (hcheby : chebyWith C f) (hb : 0 < b) : + ∀ᶠ x : ℝ in atTop, (∑' n, f n * indicator (Ico a b) 1 (n / x)) / x ≤ C * 2 * b := by + filter_upwards [eventually_gt_atTop (2 / b)] with x hx using WI_sum_Iab_le hpos hcheby hb hx + +lemma le_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[>] b, a ≤ c) : a ≤ b := by + apply le_of_forall_gt ; intro d hd + have key : ∀ᶠ c in 𝓝[>] b, c < d := by + apply eventually_of_mem (U := Iio d) ?_ (fun x hx => hx) + rw [mem_nhdsWithin] + refine ⟨Iio d, isOpen_Iio, hd, inter_subset_left⟩ + obtain ⟨x, h1, h2⟩ := (h.and key).exists + linarith + +lemma ge_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[<] b, c ≤ a) : b ≤ a := by + apply le_of_forall_lt ; intro d hd + have key : ∀ᶠ c in 𝓝[<] b, c > d := by + apply eventually_of_mem (U := Ioi d) ?_ (fun x hx => hx) + rw [mem_nhdsWithin] + refine ⟨Ioi d, isOpen_Ioi, hd, inter_subset_left⟩ + obtain ⟨x, h1, h2⟩ := (h.and key).exists + linarith + +lemma WI_tendsto_aux (a b : ℝ) {A : ℝ} (hA : 0 < A) : + Tendsto (fun c => c / A - (b - a)) (𝓝[>] (A * (b - a))) (𝓝[>] 0) := by + rw [Metric.tendsto_nhdsWithin_nhdsWithin] + intro ε hε + refine ⟨A * ε, by positivity, ?_⟩ + intro x hx1 hx2 + constructor + · simpa [lt_div_iff₀' hA] + · simp only [Real.dist_eq, dist_zero_right, Real.norm_eq_abs] at hx2 ⊢ + have : |x / A - (b - a)| = |x - A * (b - a)| / A := by + rw [← abs_eq_self.mpr hA.le, ← abs_div, abs_eq_self.mpr hA.le] ; congr ; field_simp + rwa [this, div_lt_iff₀' hA] + +lemma WI_tendsto_aux' (a b : ℝ) {A : ℝ} (hA : 0 < A) : + Tendsto (fun c => (b - a) - c / A) (𝓝[<] (A * (b - a))) (𝓝[>] 0) := by + rw [Metric.tendsto_nhdsWithin_nhdsWithin] + intro ε hε + refine ⟨A * ε, by positivity, ?_⟩ + intro x hx1 hx2 + constructor + · simpa [div_lt_iff₀' hA] + · simp only [Real.dist_eq, dist_zero_right, norm_eq_abs] at hx2 ⊢ + have : |(b - a) - x / A| = |A * (b - a) - x| / A := by + rw [← abs_eq_self.mpr hA.le, ← abs_div, abs_eq_self.mpr hA.le] ; congr ; field_simp + rwa [this, div_lt_iff₀' hA, ← neg_sub, abs_neg] + +theorem residue_nonneg {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm (fun n ↦ ↑(f n)) σ')) (hcheby : cheby fun n ↦ ↑(f n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : EqOn G (fun s ↦ LSeries (fun n ↦ ↑(f n)) s - ↑A / (s - 1)) {s | 1 < s.re}) : 0 ≤ A := by + let S (g : ℝ → ℝ) (x : ℝ) := (∑' n, f n * g (n / x)) / x + have hSnonneg {g : ℝ → ℝ} (hg : 0 ≤ g) : ∀ᶠ x : ℝ in atTop, 0 ≤ S g x := by + filter_upwards [eventually_ge_atTop 0] with x hx + exact div_nonneg (tsum_nonneg (fun i => mul_nonneg (hpos _) (hg _))) hx + obtain ⟨ε, ψ, h1, h2, h3, h4, -⟩ := (interval_approx_sup zero_lt_one one_lt_two).exists + have key := @wiener_ikehara_smooth_real A G f ψ hf hcheby hG hG' h1 h2 h3 + have l2 : 0 ≤ ψ := by apply le_trans _ h4 ; apply indicator_nonneg ; simp + have l1 : ∀ᶠ x in atTop, 0 ≤ S ψ x := hSnonneg l2 + have l3 : 0 ≤ A * ∫ (y : ℝ) in Ioi 0, ψ y := ge_of_tendsto key l1 + have l4 : 0 < ∫ (y : ℝ) in Ioi 0, ψ y := by + have r1 : 0 ≤ᵐ[Measure.restrict volume (Ioi 0)] ψ := Eventually.of_forall l2 + have r2 : IntegrableOn (fun y ↦ ψ y) (Ioi 0) volume := + (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + have r3 : Ico 1 2 ⊆ Function.support ψ := by intro x hx ; have := h4 x ; simp [hx] at this ⊢ ; linarith + have r4 : Ico 1 2 ⊆ Function.support ψ ∩ Ioi 0 := by + simp only [subset_inter_iff, r3, true_and] ; apply Ico_subset_Icc_self.trans ; rw [Icc_subset_Ioi_iff] <;> linarith + have r5 : 1 ≤ volume ((Function.support fun y ↦ ψ y) ∩ Ioi 0) := by convert! volume.mono r4 ; norm_num + simpa [setIntegral_pos_iff_support_of_nonneg_ae r1 r2] using! zero_lt_one.trans_le r5 + have := div_nonneg l3 l4.le ; field_simp at this ; exact this + +lemma WienerIkeharaInterval {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * (indicator (Ico a b) 1 (n / x))) / x) atTop (nhds (A * (b - a))) := by + + by_cases hab : a = b + · simp [hab] + replace hb : a < b := lt_of_le_of_ne hb hab ; clear hab + + let S (g : ℝ → ℝ) (x : ℝ) := (∑' n, f n * g (n / x)) / x + have hSnonneg {g : ℝ → ℝ} (hg : 0 ≤ g) : ∀ᶠ x : ℝ in atTop, 0 ≤ S g x := by + filter_upwards [eventually_ge_atTop 0] with x hx + refine div_nonneg ?_ hx + refine tsum_nonneg (fun i => mul_nonneg (hpos _) (hg _)) + have hA : 0 ≤ A := residue_nonneg hpos hf hcheby hG hG' + + let Iab : ℝ → ℝ := indicator (Ico a b) 1 + change Tendsto (S Iab) atTop (𝓝 (A * (b - a))) + have hIab : HasCompactSupport Iab := by simpa [Iab, HasCompactSupport, tsupport, hb.ne] using isCompact_Icc + have Iab_nonneg : ∀ᶠ x : ℝ in atTop, 0 ≤ S Iab x := hSnonneg (indicator_nonneg (by simp)) + have Iab2 : IsBoundedUnder (· ≤ ·) atTop (S Iab) := by + obtain ⟨C, hC⟩ := hcheby ; exact ⟨C * 2 * b, WI_sum_Iab_le' hpos hC (by linarith)⟩ + have Iab3 : IsBoundedUnder (· ≥ ·) atTop (S Iab) := ⟨0, Iab_nonneg⟩ + have Iab0 : IsCoboundedUnder (· ≥ ·) atTop (S Iab) := Iab2.isCoboundedUnder_ge + have Iab1 : IsCoboundedUnder (· ≤ ·) atTop (S Iab) := Iab3.isCoboundedUnder_le + + have sup_le : limsup (S Iab) atTop ≤ A * (b - a) := by + have l_sup : ∀ᶠ ε in 𝓝[>] 0, limsup (S Iab) atTop ≤ A * (b - a + ε) := by + filter_upwards [interval_approx_sup ha hb] with ε ⟨ψ, h1, h2, h3, h4, h6⟩ + have l1 : Tendsto (S ψ) atTop _ := wiener_ikehara_smooth_real hf hcheby hG hG' h1 h2 h3 + have l6 : S Iab ≤ᶠ[atTop] S ψ := by + filter_upwards [eventually_gt_atTop 0] with x hx using WI_sum_le hpos h4 hx hIab h2 + have l5 : IsBoundedUnder (· ≤ ·) atTop (S ψ) := l1.isBoundedUnder_le + have l3 : limsup (S Iab) atTop ≤ limsup (S ψ) atTop := limsup_le_limsup l6 Iab1 l5 + apply l3.trans ; rw [l1.limsup_eq] ; gcongr + obtain rfl | h := eq_or_ne A 0 + · simpa using l_sup + apply le_of_eventually_nhdsWithin + have key : 0 < A := lt_of_le_of_ne hA h.symm + filter_upwards [WI_tendsto_aux a b key l_sup] with x hx + simpa [mul_div_cancel₀ _ h] using hx + + have le_inf : A * (b - a) ≤ liminf (S Iab) atTop := by + have l_inf : ∀ᶠ ε in 𝓝[>] 0, A * (b - a - ε) ≤ liminf (S Iab) atTop := by + filter_upwards [interval_approx_inf ha hb] with ε ⟨ψ, h1, h2, h3, h5, h6⟩ + have l1 : Tendsto (S ψ) atTop _ := wiener_ikehara_smooth_real hf hcheby hG hG' h1 h2 h3 + have l2 : S ψ ≤ᶠ[atTop] S Iab := by + filter_upwards [eventually_gt_atTop 0] with x hx using WI_sum_le hpos h5 hx h2 hIab + have l4 : IsBoundedUnder (· ≥ ·) atTop (S ψ) := l1.isBoundedUnder_ge + have l3 : liminf (S ψ) atTop ≤ liminf (S Iab) atTop := liminf_le_liminf l2 l4 Iab0 + apply le_trans ?_ l3 ; rw [l1.liminf_eq] ; gcongr + obtain rfl | h := eq_or_ne A 0 + · simpa using l_inf + apply ge_of_eventually_nhdsWithin + have key : 0 < A := lt_of_le_of_ne hA h.symm + filter_upwards [WI_tendsto_aux' a b key l_inf] with x hx + simpa [mul_div_cancel₀ _ h] using hx + + have : liminf (S Iab) atTop ≤ limsup (S Iab) atTop := liminf_le_limsup Iab2 Iab3 + refine tendsto_of_liminf_eq_limsup ?_ ?_ Iab2 Iab3 <;> linarith + +lemma le_floor_mul_iff (hb : 0 ≤ b) (hx : 0 < x) : n ≤ ⌊b * x⌋₊ ↔ n / x ≤ b := by + rw [div_le_iff₀ hx, Nat.le_floor_iff] ; positivity + +lemma lt_ceil_mul_iff (hx : 0 < x) : n < ⌈b * x⌉₊ ↔ n / x < b := by + rw [div_lt_iff₀ hx, Nat.lt_ceil] + +lemma ceil_mul_le_iff (hx : 0 < x) : ⌈a * x⌉₊ ≤ n ↔ a ≤ n / x := by + rw [le_div_iff₀ hx, Nat.ceil_le] + +lemma mem_Icc_iff_div (hb : 0 ≤ b) (hx : 0 < x) : n ∈ Finset.Icc ⌈a * x⌉₊ ⌊b * x⌋₊ ↔ n / x ∈ Icc a b := by + rw [Finset.mem_Icc, mem_Icc, ceil_mul_le_iff hx, le_floor_mul_iff hb hx] + +lemma mem_Ico_iff_div (hx : 0 < x) : n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊ ↔ n / x ∈ Ico a b := by + rw [Finset.mem_Ico, mem_Ico, ceil_mul_le_iff hx, lt_ceil_mul_iff hx] + +lemma tsum_indicator {f : ℕ → ℝ} (hx : 0 < x) : + ∑' n, f n * (indicator (Ico a b) 1 (n / x)) = ∑ n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n := by + have l1 : ∀ n ∉ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n * indicator (Ico a b) 1 (↑n / x) = 0 := by + simp [mem_Ico_iff_div hx] ; tauto + rw [tsum_eq_sum l1] ; apply Finset.sum_congr rfl ; simp only [mem_Ico_iff_div hx] ; intro n hn ; simp [hn] + +lemma WienerIkeharaInterval_discrete {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun x : ℝ ↦ (∑ n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n) / x) atTop (nhds (A * (b - a))) := by + apply (WienerIkeharaInterval hpos hf hcheby hG hG' ha hb).congr' + filter_upwards [eventually_gt_atTop 0] with x hx + rw [tsum_indicator hx] + +lemma WienerIkeharaInterval_discrete' {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun N : ℕ ↦ (∑ n ∈ Finset.Ico ⌈a * N⌉₊ ⌈b * N⌉₊, f n) / N) atTop (nhds (A * (b - a))) := + WienerIkeharaInterval_discrete hpos hf hcheby hG hG' ha hb |>.comp tendsto_natCast_atTop_atTop + +lemma tendsto_mul_ceil_div : + Tendsto (fun (p : ℝ × ℕ) => ⌈p.1 * p.2⌉₊ / (p.2 : ℝ)) (𝓝[>] 0 ×ˢ atTop) (𝓝 0) := by + rw [Metric.tendsto_nhds] ; intro δ hδ + have l1 : ∀ᶠ ε : ℝ in 𝓝[>] 0, ε ∈ Ioo 0 (δ / 2) := inter_mem_nhdsWithin _ (Iio_mem_nhds (by positivity)) + have l2 : ∀ᶠ N : ℕ in atTop, 1 ≤ δ / 2 * N := by + apply Tendsto.eventually_ge_atTop + exact tendsto_natCast_atTop_atTop.const_mul_atTop (by positivity) + filter_upwards [l1.prod_mk l2] with (ε, N) ⟨⟨hε, h1⟩, h2⟩ ; dsimp only at * + have l3 : 0 < (N : ℝ) := by + simp only [Nat.cast_pos, Nat.pos_iff_ne_zero] ; rintro rfl ; simp [zero_lt_one.not_ge] at h2 + have l5 : 0 ≤ ε * ↑N := by positivity + have l6 : ε * N ≤ δ / 2 * N := mul_le_mul h1.le le_rfl (by positivity) (by positivity) + simp only [dist_zero_right, norm_div, RCLike.norm_natCast, div_lt_iff₀ l3, gt_iff_lt] + convert (Nat.ceil_lt_add_one l5).trans_le (add_le_add l6 h2) using 1 ; ring + +noncomputable def S (f : ℕ → 𝕜) (ε : ℝ) (N : ℕ) : 𝕜 := (∑ n ∈ Finset.Ico ⌈ε * N⌉₊ N, f n) / N + +lemma S_sub_S {f : ℕ → 𝕜} {ε : ℝ} {N : ℕ} (hε : ε ≤ 1) : S f 0 N - S f ε N = cumsum f ⌈ε * N⌉₊ / N := by + have hceilN : ⌈ε * N⌉₊ ≤ N := by + simp only [Nat.ceil_le] + exact mul_le_of_le_one_left N.cast_nonneg hε + have r1 : Finset.range N = Finset.range ⌈ε * N⌉₊ ∪ Finset.Ico ⌈ε * N⌉₊ N := by + ext n + simp only [Finset.mem_range, Finset.mem_union, Finset.mem_Ico] + omega + have r2 : Disjoint (Finset.range ⌈ε * N⌉₊) (Finset.Ico ⌈ε * N⌉₊ N) := by + rw [Finset.range_eq_Ico] ; apply Finset.Ico_disjoint_Ico_consecutive + simp [S, r1, Finset.sum_union r2, cumsum, add_div] + +lemma tendsto_S_S_zero {f : ℕ → ℝ} (hpos : 0 ≤ f) (hcheby : cheby f) : + TendstoUniformlyOnFilter (S f) (S f 0) (𝓝[>] 0) atTop := by + rw [Metric.tendstoUniformlyOnFilter_iff] ; intro δ hδ + obtain ⟨C, hC⟩ := hcheby + have l1 : ∀ᶠ (p : ℝ × ℕ) in 𝓝[>] 0 ×ˢ atTop, C * ⌈p.1 * p.2⌉₊ / p.2 < δ := by + have r1 := tendsto_mul_ceil_div.const_mul C + simp only [mul_div_assoc', mul_zero] at r1 ; exact r1 (Iio_mem_nhds hδ) + have : Ioc 0 1 ∈ 𝓝[>] (0 : ℝ) := inter_mem_nhdsWithin _ (Iic_mem_nhds zero_lt_one) + filter_upwards [l1, Eventually.prod_inl this _] with (ε, N) h1 h2 + have l2 : ‖cumsum f ⌈ε * ↑N⌉₊ / ↑N‖ ≤ C * ⌈ε * N⌉₊ / N := by + have r1 := hC ⌈ε * N⌉₊ + have r2 : 0 ≤ cumsum f ⌈ε * N⌉₊ := by apply cumsum_nonneg hpos + simp only [norm_real, norm_of_nonneg (hpos _), norm_div, + norm_of_nonneg r2, Real.norm_natCast] at r1 ⊢ + apply div_le_div_of_nonneg_right r1 (by positivity) + simpa [← S_sub_S h2.2] using! l2.trans_lt h1 + +theorem WienerIkeharaTheorem' {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun N => cumsum f N / N) atTop (𝓝 A) := by + + convert_to Tendsto (S f 0) atTop (𝓝 A) ; · ext N ; simp [S, cumsum] + apply (tendsto_S_S_zero hpos hcheby).tendsto_of_eventually_tendsto + · have L0 : Ioc 0 1 ∈ 𝓝[>] (0 : ℝ) := inter_mem_nhdsWithin _ (Iic_mem_nhds zero_lt_one) + apply eventually_of_mem L0 + · intro ε hε + simpa using! WienerIkeharaInterval_discrete' hpos hf hcheby hG hG' hε.1 hε.2 + · have : Tendsto (fun ε : ℝ => ε) (𝓝[>] 0) (𝓝 0) := nhdsWithin_le_nhds + simpa using (this.const_sub 1).const_mul A + +theorem vonMangoldt_cheby : cheby Λ := by + use Real.log 4 + 4 + intro N + by_cases! h : N = 0 + · simp [h, cumsum] + simp only [cumsum, norm_real, norm_eq_abs] + rw [Nat.range_eq_Icc_zero_sub_one _ h, (by simp : N - 1 = ⌊(N : ℝ) - 1⌋₊)] + simp_rw [abs_of_nonneg vonMangoldt_nonneg] + rw [← Chebyshev.psi_eq_sum_Icc] + grw [Chebyshev.psi_le_const_mul_self <| sub_nonneg_of_le <| Nat.one_le_cast_iff_ne_zero.mpr h] + gcongr + linarith + +theorem WeakPNT : Tendsto (fun N ↦ cumsum Λ N / N) atTop (𝓝 1) := by + let F := vonMangoldt.LFunctionResidueClassAux (q := 1) 1 + have hnv := riemannZeta_ne_zero_of_one_le_re + have l1 (n : ℕ) : 0 ≤ Λ n := vonMangoldt_nonneg + have l2 s (hs : 1 < s.re) : F s = LSeries Λ s - 1 / (s - 1) := by + have := vonMangoldt.eqOn_LFunctionResidueClassAux (q := 1) isUnit_one hs + simp only [F, this, vonMangoldt.residueClass, Nat.totient_one, Nat.cast_one, inv_one, one_div, sub_left_inj] + apply LSeries_congr + intro n _ + simp only [ofReal_inj, indicator_apply_eq_self, mem_ofPred_eq] + exact fun hn ↦ absurd (Subsingleton.eq_one _) hn + have l3 : ContinuousOn F {s | 1 ≤ s.re} := vonMangoldt.continuousOn_LFunctionResidueClassAux 1 + have l4 : cheby Λ := vonMangoldt_cheby + have l5 (σ' : ℝ) (hσ' : 1 < σ') : Summable (nterm Λ σ') := by + simpa only [← nterm_eq_norm_term] using (@ArithmeticFunction.LSeriesSummable_vonMangoldt σ' hσ').norm + apply WienerIkeharaTheorem' l1 l5 l4 l3 l2 + +section auto_cheby + +variable {f : ℕ → ℝ} + +lemma norm_x_cpow_it (x t : ℝ) (hx : 0 < x) : ‖(x : ℂ) ^ (t * I)‖ = 1 := by + rw [cpow_def_of_ne_zero <| ofReal_ne_zero.mpr hx.ne', ← ofReal_log hx.le] + convert norm_exp_ofReal_mul_I (t * x.log) using 2 + push_cast; ring_nf + +lemma limiting_fourier_aux_gt_zero (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 0 < x) (σ' : ℝ) (hσ' : 1 < σ') : + ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * (x ^ (1 - σ') : ℝ) * ∫ u in Ici (- log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = + ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I) := by + have hint : Integrable ψ := ψ.h1.continuous.integrable_of_hasCompactSupport ψ.h2 + have l8 : Continuous fun t : ℝ ↦ (x : ℂ) ^ (t * I) := + continuous_const.cpow (continuous_ofReal.mul continuous_const) (by simp [hx]) + have l4 : Integrable fun t : ℝ ↦ LSeries f (↑σ' + ↑t * I) * ψ t * ↑x ^ (↑t * I) := + (((continuous_LSeries_aux (hf _ hσ')).mul ψ.h1.continuous).mul l8).integrable_of_hasCompactSupport + ψ.h2.mul_left.mul_right + have e2 (u : ℝ) : σ' + u * I - 1 ≠ 0 := fun h ↦ by + have := congrArg Complex.re (sub_eq_zero.mp h); simp at this; linarith + have l5 : Integrable fun a ↦ A * ↑(x ^ (1 - σ')) * + (↑(x ^ (σ' - 1)) * (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by + have : Continuous fun a ↦ A * ↑(x ^ (1 - σ')) * + (↑(x ^ (σ' - 1)) * (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by + simp only [one_div, ← mul_assoc] + exact ((continuous_const.mul (Continuous.inv₀ (by fun_prop) e2)).mul ψ.h1.continuous).mul l8 + exact this.integrable_of_hasCompactSupport ψ.h2.mul_left.mul_right.mul_left.mul_left + simp_rw [first_fourier hf hint hx hσ', second_fourier ψ.h1.continuous.measurable hint hx hσ', + ← integral_const_mul, ← integral_sub l4 l5] + refine integral_congr_ae (.of_forall fun u ↦ ?_) + have e1 : 1 < ((σ' : ℂ) + (u : ℂ) * I).re := by simp [hσ'] + simp_rw [hG' e1, sub_mul, ← mul_assoc] + simp only [one_div, sub_right_inj, mul_eq_mul_right_iff, cpow_eq_zero_iff, ofReal_eq_zero, ne_eq, + mul_eq_zero, I_ne_zero, or_false] + field_simp [e2]; norm_cast; simp [mul_assoc, ← rpow_add hx] + +theorem limiting_fourier_lim2_gt_zero (A : ℝ) (ψ : W21) (hx : 0 < x) : + Tendsto (fun σ' ↦ A * ↑(x ^ (1 - σ')) * + ∫ u in Ici (-Real.log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) + (𝓝[>] 1) (𝓝 (A * ∫ u in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)))) := by + obtain ⟨C, hC⟩ := decay_bounds_cor ψ + refine Tendsto.mul ?_ (tendsto_integral_filter_of_dominated_convergence _ + (.of_forall fun _ ↦ (by continuity : Continuous _).aestronglyMeasurable) ?_ + (limiting_fourier_lim2_aux x C) (.of_forall fun u ↦ ?_)) + · suffices Tendsto (fun σ' : ℝ ↦ x ^ (1 - σ')) (𝓝[>] 1) (𝓝 1) by + simpa using ((continuous_ofReal.tendsto 1).comp this).const_mul ↑A + have : Tendsto (fun σ' : ℝ ↦ 1 - σ') (𝓝[>] 1) (𝓝 0) := + tendsto_nhdsWithin_of_tendsto_nhds (by simpa using (continuous_id.tendsto (1 : ℝ)).const_sub 1) + simpa using tendsto_const_nhds.rpow this (Or.inl hx.ne') + · refine eventually_of_mem (Ioo_mem_nhdsGT_of_mem (by norm_num : (1 : ℝ) ∈ Set.Ico 1 2)) fun σ' hσ' ↦ ?_ + obtain ⟨h1, h2⟩ := hσ' + rw [ae_restrict_iff' measurableSet_Ici] + refine .of_forall fun t ht ↦ ?_ + simp only [norm_mul, neg_mul, ofReal_exp, ofReal_neg, ofReal_mul, ofReal_sub, ofReal_one, + norm_exp, neg_re, mul_re, ofReal_re, sub_re, one_re, ofReal_im, sub_im, one_im, + sub_self, mul_zero, sub_zero] + refine mul_le_mul ?_ (hC _) (norm_nonneg _) ((abs_nonneg x).trans (le_max_left _ _)) + have hα0 : 0 ≤ σ' - 1 := by linarith + have hα1 : σ' - 1 ≤ 1 := by linarith + have hmul1 : (-x.log) * (σ' - 1) ≤ t * (σ' - 1) := mul_le_mul_of_nonneg_right ht hα0 + calc Real.exp (-(t * (σ' - 1))) + ≤ Real.exp (x.log * (σ' - 1)) := Real.exp_monotone (by linarith) + _ ≤ max |x| 1 := by + by_cases hx1 : 1 ≤ x + · calc _ ≤ Real.exp x.log := + Real.exp_monotone (mul_le_of_le_one_right (Real.log_nonneg hx1) hα1) + _ = |x| := by rw [Real.exp_log hx, abs_of_pos hx] + _ ≤ _ := le_max_left _ _ + · calc _ ≤ 1 := (Real.exp_monotone (mul_nonpos_of_nonpos_of_nonneg + ((Real.log_neg_iff hx).2 (by linarith)).le hα0)).trans_eq Real.exp_zero + _ ≤ _ := le_max_right _ _ + · suffices Tendsto (fun n ↦ ((rexp (-u * (n - 1))) : ℂ)) (𝓝[>] 1) (𝓝 1) by simpa using this.mul_const _ + refine Tendsto.mono_left ?_ nhdsWithin_le_nhds + have : Continuous (fun n ↦ ((rexp (-u * (n - 1))) : ℂ)) := by continuity + simpa using this.tendsto 1 + +theorem limiting_fourier_lim3_gt_zero + (hG : ContinuousOn G {s | 1 ≤ s.re}) (ψ : CS 2 ℂ) (hx : 0 < x) : + Tendsto (fun σ' : ℝ ↦ ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I)) (𝓝[>] 1) + (𝓝 (∫ t : ℝ, G (1 + t * I) * ψ t * x ^ (t * I))) := by + by_cases hh : tsupport ψ = ∅ + · simp [tsupport_eq_empty_iff.mp hh] + obtain ⟨a₀, ha₀⟩ := Set.nonempty_iff_ne_empty.mpr hh + let S : Set ℂ := reProdIm (Icc 1 2) (tsupport ψ) + have l1 : IsCompact S := Metric.isCompact_iff_isClosed_bounded.mpr + ⟨isClosed_Icc.reProdIm (isClosed_tsupport ψ), (Metric.isBounded_Icc 1 2).reProdIm ψ.h2.isBounded⟩ + have l2 : S ⊆ {s : ℂ | 1 ≤ s.re} := fun z hz => (mem_reProdIm.mp hz).1.1 + obtain ⟨z, -, hmax⟩ := l1.exists_isMaxOn ⟨1 + a₀ * I, by simp [S, mem_reProdIm, ha₀]⟩ (hG.mono l2).norm + have hxC : (x : ℂ) ≠ 0 := ofReal_ne_zero.mpr hx.ne' + refine tendsto_integral_filter_of_dominated_convergence (bound := fun a ↦ ‖G z‖ * ‖ψ a‖) + (eventually_of_mem (Icc_mem_nhdsGT_of_mem (by norm_num : (1 : ℝ) ∈ Set.Ico 1 2)) fun u hu ↦ + ((hG.comp_continuous (by fun_prop) (by simp [hu.1])).mul ψ.h1.continuous).mul + (by simpa using Continuous.const_cpow (by fun_prop) (Or.inl hxC)) |>.aestronglyMeasurable) + (eventually_of_mem (Icc_mem_nhdsGT_of_mem (by norm_num : (1 : ℝ) ∈ Set.Ico 1 2)) fun u hu ↦ + .of_forall fun v ↦ ?_) + ((continuous_const.mul ψ.h1.continuous.norm).integrable_of_hasCompactSupport ψ.h2.norm.mul_left) + (.of_forall fun t ↦ ?_) + · by_cases h : v ∈ tsupport ψ + · simp_rw [norm_mul, norm_x_cpow_it x v hx, mul_one] + exact mul_le_mul_of_nonneg_right (isMaxOn_iff.mp hmax _ (by simp [S, mem_reProdIm, hu.1, hu.2, h])) (norm_nonneg _) + · have : v ∉ Function.support ψ := fun a ↦ h (subset_tsupport ψ a) + simp [Function.notMem_support.mp this] + · exact ((hG (1 + t * I) (by simp)).tendsto.comp <| tendsto_nhdsWithin_iff.mpr + ⟨((continuous_ofReal.tendsto _).add tendsto_const_nhds).mono_left nhdsWithin_le_nhds, + eventually_nhdsWithin_of_forall fun _ hx' ↦ by simp [(Set.mem_Ioi.mp hx').le]⟩).mul_const _ |>.mul_const _ + +lemma tendsto_tsum_of_monotone_convergence + {β : Type*} {f : ℕ → β → ENNReal} {g : β → ENNReal} + (hmono : ∀ k, Monotone (fun n => f n k)) + (hlim : ∀ k, Tendsto (fun n => f n k) atTop (𝓝 (g k))) : + Tendsto (fun n => ∑' k, f n k) atTop (𝓝 (∑' k, g k)) := by + let : MeasurableSpace β := ⊤ + let μ : Measure β := Measure.count + have hg_iSup (k : β) : (⨆ n : ℕ, f n k) = g k := iSup_eq_of_tendsto (hmono k) (hlim k) + have h_tend_lint : Tendsto (fun n => ∫⁻ k, f n k ∂μ) atTop (𝓝 (∫⁻ k, (⨆ n, f n k) ∂μ)) := by + have hmeas : ∀ n, Measurable fun k : β => f n k := fun _ _ _ ↦ trivial + have hmono_fn : Monotone (fun n => fun k : β => f n k) := fun _ _ hnm k ↦ hmono k hnm + simpa [lintegral_iSup hmeas hmono_fn] using + tendsto_atTop_iSup fun _ _ hmn ↦ lintegral_mono fun k ↦ hmono k hmn + simpa [μ, lintegral_count, hg_iSup] using h_tend_lint + +lemma tendsto_tsum_of_monotone_convergence_nhdsGT_one + {F : ℝ → ℕ → ℝ} + (hF_nonneg : ∀ σ n, 0 ≤ F σ n) + (hF_antitone : ∀ n, AntitoneOn (fun σ : ℝ => F σ n) (Set.Ioi (1 : ℝ))) + (hF_tend : ∀ n, Tendsto (fun σ : ℝ => F σ n) (𝓝[>] (1 : ℝ)) (𝓝 (F 1 n))) + (hSumm : ∀ σ, 1 < σ → Summable (fun n : ℕ => F σ n)) + (hbounded : + BoundedAtFilter (𝓝[>] (1 : ℝ)) (fun σ : ℝ => (∑' n : ℕ, F σ n))) : + Tendsto (fun σ : ℝ => ∑' n : ℕ, F σ n) (𝓝[>] (1 : ℝ)) (𝓝 (∑' n : ℕ, F 1 n)) := by + let T : ℝ → ℝ := fun σ => ∑' n : ℕ, F σ n + have hT_antitone : AntitoneOn T (Set.Ioi (1 : ℝ)) := fun a ha b hb hab ↦ + (hSumm b hb).tsum_le_tsum_of_inj (fun n ↦ n) (fun _ _ h ↦ h) (fun c hc ↦ (hc ⟨c, rfl⟩).elim) + (fun n ↦ hF_antitone n ha hb hab) (hSumm a ha) + have hT_bdd : BddAbove (T '' Set.Ioi (1 : ℝ)) := by + obtain ⟨C, hC⟩ := isBigO_iff.1 hbounded + have hC' : ∀ᶠ σ : ℝ in 𝓝[>] (1 : ℝ), T σ ≤ C := by + filter_upwards [hC] with σ hσ + calc T σ ≤ |T σ| := le_abs_self _ + _ = ‖T σ‖ := (Real.norm_eq_abs _).symm + _ ≤ C * ‖(1 : ℝ → ℝ) σ‖ := hσ + _ = C := by simp + obtain ⟨U, hU, V, hV, hUV⟩ := Filter.mem_inf_iff_superset.1 hC' + obtain ⟨ε, hε, hball⟩ := Metric.mem_nhds_iff.1 hU + have hIoi_sub : Set.Ioi (1 : ℝ) ⊆ V := Filter.mem_principal.mp hV + have hUsub : U ∩ Set.Ioi (1 : ℝ) ⊆ {σ : ℝ | T σ ≤ C} := fun σ hσ ↦ hUV ⟨hσ.1, hIoi_sub hσ.2⟩ + have hσ0_Ioi : 1 + ε / 2 ∈ Set.Ioi (1 : ℝ) := by simp [half_pos hε] + have hσ0_leC : T (1 + ε / 2) ≤ C := + hUsub ⟨hball (by simp only [Metric.mem_ball, Real.dist_eq, add_sub_cancel_left, + abs_of_pos (half_pos hε)]; exact half_lt_self hε), hσ0_Ioi⟩ + refine ⟨C, ?_⟩ + rintro _ ⟨σ, hσIoi, rfl⟩ + by_cases hσlt : σ < 1 + ε / 2 + · exact hUsub ⟨hball (by + simp only [Metric.mem_ball, Real.dist_eq] + rw [abs_of_pos (sub_pos.2 (Set.mem_Ioi.mp hσIoi))] + linarith [half_lt_self hε]), hσIoi⟩ + · exact (hT_antitone hσ0_Ioi hσIoi (le_of_not_gt hσlt)).trans hσ0_leC + have hT_tend_sup : Tendsto T (𝓝[>] (1 : ℝ)) (𝓝 (sSup (T '' Set.Ioi (1 : ℝ)))) := + hT_antitone.tendsto_nhdsGT hT_bdd + let σseq : ℕ → ℝ := fun k => 1 + 1 / (k + 1 : ℝ) + have hσseq_mem (k) : σseq k ∈ Set.Ioi (1 : ℝ) := by + simp only [σseq, Set.mem_Ioi, lt_add_iff_pos_right] + positivity + have hσseq_tend_nhds : Tendsto σseq atTop (𝓝 (1 : ℝ)) := by + have : Tendsto (fun k : ℕ => (1 : ℝ) + ((k + 1 : ℕ) : ℝ)⁻¹) atTop (𝓝 ((1 : ℝ) + 0)) := + tendsto_const_nhds.add (tendsto_inv_atTop_nhds_zero_nat.comp (tendsto_add_atTop_nat 1)) + simp only [add_zero] at this + convert this using 1; ext k; simp [σseq, one_div] + have hσseq_tend_nhdsWithin : Tendsto σseq atTop (𝓝[>] (1 : ℝ)) := + tendsto_nhdsWithin_of_tendsto_nhds_of_eventually_within _ hσseq_tend_nhds + (.of_forall hσseq_mem) + have hσseq_antitone : Antitone σseq := fun k₁ k₂ hk ↦ by simp only [σseq]; gcongr + have hmono_seq (n) : Monotone (fun k => F (σseq k) n) := fun k₁ k₂ hk ↦ + hF_antitone n (hσseq_mem k₂) (hσseq_mem k₁) (hσseq_antitone hk) + have htend_seq (n) : Tendsto (fun k => F (σseq k) n) atTop (𝓝 (F 1 n)) := + (hF_tend n).comp hσseq_tend_nhdsWithin + have hTseq : Tendsto (fun k : ℕ => T (σseq k)) atTop (𝓝 (T 1)) := by + have hsum1 : Summable (fun n : ℕ => F (1 : ℝ) n) := by + obtain ⟨C, hC⟩ := hT_bdd + refine summable_of_sum_range_le (hF_nonneg 1) fun m ↦ le_of_tendsto + (tendsto_finsetSum _ fun i _ ↦ hF_tend i) + (eventually_of_mem self_mem_nhdsWithin fun σ hσ ↦ + ((hSumm σ hσ).sum_le_tsum _ (fun n _ ↦ hF_nonneg σ n)).trans (hC ⟨σ, hσ, rfl⟩)) + have hg_ne_top : (∑' n : ℕ, ENNReal.ofReal (F 1 n)) ≠ ⊤ := hsum1.tsum_ofReal_ne_top + have hENN : Tendsto (fun k => ∑' n, ENNReal.ofReal (F (σseq k) n)) atTop + (𝓝 (∑' n, ENNReal.ofReal (F 1 n))) := + tendsto_tsum_of_monotone_convergence (fun n _ _ hk ↦ ENNReal.ofReal_le_ofReal (hmono_seq n hk)) + (fun n ↦ ENNReal.tendsto_ofReal (htend_seq n)) + have hrew (σ) : (∑' n, ENNReal.ofReal (F σ n)).toReal = ∑' n, F σ n := by + rw [ENNReal.tsum_toReal_eq (fun n ↦ by simp)] + exact tsum_congr fun n ↦ by simp [hF_nonneg σ n] + simp only [T, ← hrew]; exact (ENNReal.tendsto_toReal hg_ne_top).comp hENN + have hsSup_eq : sSup (T '' Set.Ioi (1 : ℝ)) = T 1 := + tendsto_nhds_unique (hT_tend_sup.comp hσseq_tend_nhdsWithin) hTseq + simpa [T, hsSup_eq] using hT_tend_sup + +lemma limiting_fourier_variant_lim1_aux + {f : ℕ → ℝ} {x : ℝ} (ψ : CS 2 ℂ) + (hpos : 0 ≤ f) + (hf : ∀ (σ : ℝ), 1 < σ → Summable (nterm f σ)) + (hψpos : ∀ y, 0 ≤ (𝓕 (ψ : ℝ → ℂ) y).re ∧ (𝓕 (ψ : ℝ → ℂ) y).im = 0) : + ∀ (σ : ℝ), 1 < σ → + Summable (fun n : ℕ => + (if n = 0 then 0 else f n / ((n : ℝ) ^ σ)) * + (𝓕 ψ.toFun (1 / (2 * π) * Real.log ((n : ℝ) / x))).re) := by + intro σ hσ + let y : ℕ → ℝ := fun n => (1 / (2 * π)) * Real.log ((n : ℝ) / x) + let W : ℕ → ℝ := fun n => (𝓕 ψ.toFun (y n)).re + let base : ℕ → ℝ := fun n => if n = 0 then 0 else f n / ((n : ℝ) ^ σ) + obtain ⟨C, hC⟩ := decay_bounds_cor (W21.ofCS2 ψ) + have hC_nonneg : 0 ≤ C := (norm_nonneg _).trans ((hC 0).trans (by simp)) + have hW_nonneg (n : ℕ) : 0 ≤ W n := (hψpos (y n)).1 + have hnorm_four (n : ℕ) : ‖𝓕 ψ.toFun (y n)‖ = W n := by + have him0 : (𝓕 ψ.toFun (y n)).im = 0 := (hψpos (y n)).2 + rw [show 𝓕 ψ.toFun (y n) = W n by exact Complex.ext rfl him0] + simp [abs_of_nonneg (hW_nonneg n)] + have hW_le_C (n : ℕ) : W n ≤ C := by + rw [← hnorm_four]; exact (hC (y n)).trans (div_le_self hC_nonneg (by nlinarith [sq_nonneg (y n)])) + have hbase_summ : Summable base := by + convert hf σ hσ using 1; ext n + by_cases hn : n = 0 <;> simp [nterm, base, hn, Real.norm_eq_abs, abs_of_nonneg (hpos n)] + refine (hbase_summ.mul_left C).of_norm_bounded fun n ↦ ?_ + by_cases hn : n = 0 + · simp [base, hn] + · have hnpos : 0 < (n : ℝ) := Nat.cast_pos.mpr (Nat.pos_of_ne_zero hn) + have hbase_nonneg : 0 ≤ base n := by + simp only [base, hn, ite_false] + exact div_nonneg (hpos n) (Real.rpow_pos_of_pos hnpos σ).le + calc |base n * W n| = base n * W n := abs_of_nonneg (mul_nonneg hbase_nonneg (hW_nonneg n)) + _ ≤ base n * C := mul_le_mul_of_nonneg_left (hW_le_C n) hbase_nonneg + _ = C * base n := mul_comm _ _ + +theorem limiting_fourier_variant_lim1 + {f : ℕ → ℝ} {x : ℝ} {ψ : CS 2 ℂ} + (hpos : 0 ≤ f) + (hψpos : ∀ y, 0 ≤ (𝓕 (ψ : ℝ → ℂ) y).re ∧ (𝓕 (ψ : ℝ → ℂ) y).im = 0) + (S : ℝ → ℂ) + (hSdef : + ∀ σ' : ℝ, + S σ' = + ∑' n : ℕ, + term (fun n ↦ (f n : ℂ)) (σ' : ℝ) n * + 𝓕 ψ.toFun (π⁻¹ * 2⁻¹ * Real.log ((n : ℝ) / x))) + (hbounded : BoundedAtFilter (𝓝[>] (1 : ℝ)) (fun σ' : ℝ => ‖S σ'‖)) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) : + Tendsto + (fun σ' : ℝ => + ∑' n : ℕ, + term (fun n ↦ (f n : ℂ)) (σ' : ℝ) n * + 𝓕 ψ.toFun (π⁻¹ * 2⁻¹ * Real.log ((n : ℝ) / x))) + (𝓝[>] (1 : ℝ)) + (𝓝 + (∑' n : ℕ, + (f n : ℂ) / (n : ℂ) * + 𝓕 ψ.toFun (π⁻¹ * 2⁻¹ * Real.log ((n : ℝ) / x)))) := by + + let y : ℕ → ℝ := fun n => (π⁻¹ * 2⁻¹) * Real.log ((n : ℝ) / x) + let w : ℕ → ℝ := fun n => (𝓕 ψ.toFun (y n)).re + + have hw_nonneg : ∀ n, 0 ≤ w n := by + intro n + exact (hψpos (y n)).1 + + have hFour_eq_ofReal : ∀ n, 𝓕 ψ.toFun (y n) = Complex.ofReal (w n) := by + intro n + have h := hψpos (y n) + refine Complex.ext ?_ ?_ + · simp [w] + · simp [w, h.2] + + let rterm : ℝ → ℕ → ℝ := + fun σ n => + if h0 : n = 0 then 0 else (f n) / ((n : ℝ) ^ σ) * (w n) + + have summand_eq_ofReal : + ∀ (σ : ℝ) (n : ℕ), + term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n) + = Complex.ofReal (rterm σ n) := by + intro σ n + by_cases hn : n = 0 + · subst hn + simp [rterm, y] + · have hnpos : (0 : ℝ) < (n : ℝ) := by + exact_mod_cast (Nat.pos_of_ne_zero hn) + have hn0 : 0 ≤ (n : ℝ) := le_of_lt hnpos + have hcpow : + ( (n : ℂ) ^ ((σ : ℝ) : ℂ) ) = ( ( (n : ℝ) ^ σ : ℝ) : ℂ ) := by + simpa using (Complex.ofReal_cpow hn0 σ).symm + have hpow_ne : ((n : ℝ) ^ σ) ≠ 0 := by + exact (ne_of_gt (Real.rpow_pos_of_pos hnpos σ)) + calc + term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n) + = + ((f n : ℂ) / ((n : ℂ) ^ ((σ : ℝ) : ℂ))) * ( (w n : ℝ) : ℂ ) := by + simp [term, LSeries.term, hn, hFour_eq_ofReal] + _ = + ((f n : ℂ) / (((n : ℝ) ^ σ : ℝ) : ℂ)) * ((w n : ℝ) : ℂ) := by + simp [hcpow] + _ = + (( (f n : ℝ) : ℂ) / (((n : ℝ) ^ σ : ℝ) : ℂ)) * ((w n : ℝ) : ℂ) := by + simp + _ = + ( ( (f n : ℝ) / ((n : ℝ) ^ σ) : ℝ) : ℂ ) * ((w n : ℝ) : ℂ) := by + simp [Complex.ofReal_div] + _ = + ( ( (f n : ℝ) / ((n : ℝ) ^ σ) * (w n) : ℝ ) : ℂ ) := by + simp [Complex.ofReal_mul] + _ = + Complex.ofReal (rterm σ n) := by + simp [rterm, hn] + + let T : ℝ → ℝ := fun σ => ∑' n, rterm σ n + + have tsum_eq_ofReal_T : ∀ σ : ℝ, + (∑' n : ℕ, term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) + = Complex.ofReal (T σ) := by + intro σ + have hcongr : + (∑' n : ℕ, term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) + = ∑' n : ℕ, (Complex.ofReal (rterm σ n)) := by + refine tsum_congr ?_ + intro n + simpa using (summand_eq_ofReal σ n) + + calc + (∑' n : ℕ, term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) + = ∑' n : ℕ, (Complex.ofReal (rterm σ n)) := hcongr + _ = Complex.ofReal (∑' n : ℕ, rterm σ n) := by + simpa using (Complex.ofReal_tsum (fun n : ℕ => rterm σ n)).symm + _ = Complex.ofReal (T σ) := by rfl + + have hS_ofReal_T : ∀ σ : ℝ, S σ = Complex.ofReal (T σ) := by + intro σ + simpa [hSdef σ, y] using (tsum_eq_ofReal_T σ) + + have rterm_nonneg : ∀ σ n, 0 ≤ rterm σ n := by + intro σ n + by_cases hn : n = 0 + · subst hn; simp [rterm] + · have hf : 0 ≤ f n := hpos n + have hw : 0 ≤ w n := hw_nonneg n + have hnpos : 0 < (n : ℝ) := by + exact_mod_cast (Nat.pos_of_ne_zero hn) + have hden : 0 < (n : ℝ) ^ σ := Real.rpow_pos_of_pos hnpos σ + have : 0 ≤ (f n) / ((n : ℝ) ^ σ) := div_nonneg hf (le_of_lt hden) + simp [rterm, hn, mul_nonneg this hw] + + have T_nonneg : ∀ σ, 0 ≤ T σ := by + intro σ + exact tsum_nonneg (fun n => rterm_nonneg σ n) + + have hT_eq_normS : ∀ σ, T σ = ‖S σ‖ := by + intro σ + have := hS_ofReal_T σ + calc + T σ = ‖Complex.ofReal (T σ)‖ := by simp [abs_of_nonneg (T_nonneg σ)] + _ = ‖S σ‖ := by simp [this] + + have hboundedT : BoundedAtFilter (𝓝[>] (1 : ℝ)) (fun σ : ℝ => T σ) := by + have : (fun σ : ℝ => T σ) = (fun σ : ℝ => ‖S σ‖) := by + funext σ; exact hT_eq_normS σ + simpa [this] using hbounded + + have rterm_antitone : ∀ n, AntitoneOn (fun σ => rterm σ n) (Set.Ioi 1) := by + intro n σ₁ hσ₁ σ₂ hσ₂ hσ₁₂ + by_cases hn : n = 0 + · subst hn; simp [rterm] + · have hf : 0 ≤ f n := hpos n + have hw : 0 ≤ w n := hw_nonneg n + have hnpos : 0 < (n : ℝ) := by exact_mod_cast (Nat.pos_of_ne_zero hn) + have hn1 : (1 : ℝ) ≤ (n : ℝ) := by + exact_mod_cast (Nat.one_le_iff_ne_zero.mpr hn) + have hpow : (n : ℝ) ^ σ₁ ≤ (n : ℝ) ^ σ₂ := + Real.rpow_le_rpow_of_exponent_le hn1 hσ₁₂ + have hinv : + (1 / ((n : ℝ) ^ σ₂)) ≤ (1 / ((n : ℝ) ^ σ₁)) := by + have hpos1 : 0 < (n : ℝ) ^ σ₁ := Real.rpow_pos_of_pos hnpos σ₁ + exact one_div_le_one_div_of_le hpos1 hpow + have hinv_inv : ((n : ℝ) ^ σ₂)⁻¹ ≤ ((n : ℝ) ^ σ₁)⁻¹ := by + simpa [one_div] using hinv + have hmul1 : + (f n) * (((n : ℝ) ^ σ₂)⁻¹) ≤ (f n) * (((n : ℝ) ^ σ₁)⁻¹) := + mul_le_mul_of_nonneg_left hinv_inv hf + have hmul2 : + ((f n) * (((n : ℝ) ^ σ₂)⁻¹)) * (w n) + ≤ ((f n) * (((n : ℝ) ^ σ₁)⁻¹)) * (w n) := + mul_le_mul_of_nonneg_right hmul1 hw + simpa [rterm, hn, div_eq_mul_inv, mul_assoc] using hmul2 + + have rterm_tend : ∀ n, Tendsto (fun σ : ℝ => rterm σ n) (𝓝[>] (1 : ℝ)) (𝓝 (rterm 1 n)) := by + intro n + have hterm : + Tendsto (fun σ : ℝ => term (fun n ↦ (f n : ℂ)) (σ : ℝ) n) + (𝓝[>] (1 : ℝ)) (𝓝 ((f n : ℂ) / (n : ℂ))) := by + by_cases hn : n = 0 + · subst hn + simp [term, LSeries.term] + · have hden : + Tendsto (fun σ : ℝ => ((n : ℂ) ^ ((σ : ℝ) : ℂ))) (𝓝[>] (1 : ℝ)) (𝓝 ((n : ℂ) ^ (1 : ℂ))) := by + simpa using ((continuous_ofReal.tendsto (1 : ℝ)).mono_left nhdsWithin_le_nhds).const_cpow + + have hden' : + Tendsto (fun σ : ℝ => ((n : ℂ) ^ ((σ : ℝ) : ℂ))) (𝓝[>] (1 : ℝ)) (𝓝 (n : ℂ)) := by + simpa using hden + + have hnC : (n : ℂ) ≠ 0 := by + exact_mod_cast hn + + have hterm : + Tendsto (fun σ : ℝ => term (fun n ↦ (f n : ℂ)) (σ : ℝ) n) + (𝓝[>] (1 : ℝ)) (𝓝 ((f n : ℂ) / (n : ℂ))) := by + have hnC : (n : ℂ) ≠ 0 := by + exact_mod_cast hn + simpa [term, LSeries.term, hn] using! + (tendsto_const_nhds.div hden' hnC) + exact hterm + + have hsummand : + Tendsto + (fun σ : ℝ => + term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) + (𝓝[>] (1 : ℝ)) + (𝓝 (((f n : ℂ) / (n : ℂ)) * 𝓕 ψ.toFun (y n))) := by + simpa [mul_assoc, mul_left_comm, mul_comm] using (hterm.mul_const (𝓕 ψ.toFun (y n))) + + have hre : ∀ σ, rterm σ n = + (term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)).re := by + intro σ + have := congrArg Complex.re (summand_eq_ofReal σ n) + simpa [Complex.ofReal_re] using this.symm + + have hRe : Tendsto + (fun σ : ℝ => + (term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)).re) + (𝓝[>] (1 : ℝ)) + (𝓝 ((((f n : ℂ) / (n : ℂ)) * 𝓕 ψ.toFun (y n)).re)) := + (continuous_re.tendsto _).comp hsummand + + have hlimit_re : + (f n / (n : ℝ)) * (𝓕 ψ.toFun (y n)).re = rterm 1 n := by + have h0 : + (term (fun n ↦ (f n : ℂ)) (1 : ℝ) n * 𝓕 ψ.toFun (y n)).re = rterm 1 n := by + have := congrArg Complex.re (summand_eq_ofReal (σ := (1 : ℝ)) n) + simpa [Complex.ofReal_re] using this + + by_cases hn : n = 0 + · subst hn + simp [rterm, y] + · have h1 : + (term (fun n ↦ (f n : ℂ)) (1 : ℝ) n * 𝓕 ψ.toFun (y n)).re + = (f n / (n : ℝ)) * (𝓕 ψ.toFun (y n)).re := by + simp [Complex.mul_re, term, LSeries.term, hn, y, + (hψpos (y n)).2] + + exact (h1.symm.trans h0) + + simpa [hre, hlimit_re] using hRe + + have hSumm_rterm : ∀ σ : ℝ, 1 < σ → Summable (fun n : ℕ => rterm σ n) := by + simpa [rterm] using limiting_fourier_variant_lim1_aux (ψ := ψ) + (f := f) (x := x) hpos hf hψpos + + have hT_tend : + Tendsto T (𝓝[>] (1 : ℝ)) (𝓝 (T 1)) := by + have : + Tendsto (fun σ : ℝ => ∑' n : ℕ, rterm σ n) + (𝓝[>] (1 : ℝ)) + (𝓝 (∑' n : ℕ, rterm (1 : ℝ) n)) := by + refine tendsto_tsum_of_monotone_convergence_nhdsGT_one + (F := rterm) + (hF_nonneg := rterm_nonneg) + (hF_antitone := rterm_antitone) + (hF_tend := rterm_tend) + (hSumm := hSumm_rterm) + (hbounded := hboundedT) + + simpa [T] using this + + have hToReal : + Tendsto (fun σ => Complex.ofReal (T σ)) (𝓝[>] (1 : ℝ)) (𝓝 (Complex.ofReal (T 1))) := + (continuous_ofReal.tendsto _).comp hT_tend + + have hsource : + (fun σ : ℝ => + ∑' n : ℕ, + term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) + = fun σ : ℝ => Complex.ofReal (T σ) := by + funext σ + exact (tsum_eq_ofReal_T σ) + + have hσ1 : + (∑' n : ℕ, term (fun n ↦ (f n : ℂ)) (↑(1:ℝ)) n * 𝓕 ψ.toFun (y n)) + = (↑(T 1) : ℂ) := + by simpa using (tsum_eq_ofReal_T (σ := (1:ℝ))) + have hterm1 : + ∀ n : ℕ, term (fun n ↦ (f n : ℂ)) (1 : ℂ) n = (f n : ℂ) / (n : ℂ) := by + intro n + by_cases hn : n = 0 + · subst hn + simp [term, LSeries.term] + · simp [term, LSeries.term, hn] + + have hrewrite : + (∑' n : ℕ, + term (fun n ↦ (f n : ℂ)) (1 : ℂ) n * 𝓕 ψ.toFun (y n)) + = + (∑' n : ℕ, + (f n : ℂ) / (n : ℂ) * 𝓕 ψ.toFun (y n)) := by + refine tsum_congr ?_ + intro n + simp [hterm1 n] + + have htarget : + (∑' n : ℕ, + (f n : ℂ) / (n : ℂ) * 𝓕 ψ.toFun (y n)) + = (↑(T 1) : ℂ) := by + exact (hrewrite.symm.trans hσ1) + + simpa [hsource, htarget, y] using hToReal + +lemma limiting_fourier_variant + (hpos : 0 ≤ f) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (ψ : CS 2 ℂ) + (hψpos : ∀ y, 0 ≤ (𝓕 (ψ : ℝ → ℂ) y).re ∧ (𝓕 (ψ : ℝ → ℂ) y).im = 0) + (hx : 0 < x) : + ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = + ∫ (t : ℝ), (G (1 + t * I)) * (ψ t) * x ^ (t * I) := by + + have l2 := limiting_fourier_lim2_gt_zero (A := A) (x := x) ψ hx + have l3 := limiting_fourier_lim3_gt_zero (G := G) (x := x) hG ψ hx + + let S : ℝ → ℂ := fun σ' => + ∑' n : ℕ, + term (fun n ↦ (f n : ℂ)) σ' n * + 𝓕 ψ.toFun (1 / (2 * π) * Real.log ((n : ℝ) / x)) + let Pole : ℝ → ℂ := fun σ' => + (A : ℂ) * ((x ^ (1 - σ') : ℝ) : ℂ) * + ∫ u in Set.Ici (-Real.log x), + (rexp (-u * (σ' - 1)) : ℂ) * + 𝓕 (W21.ofCS2 ψ).toFun (u / (2 * π)) + let RHS : ℝ → ℂ := fun σ' => + ∫ t : ℝ, G (σ' + t * I) * ψ.toFun t * (x : ℂ) ^ (t * I) + + have haux : + (fun σ' : ℝ ↦ + ∑' (n : ℕ), + term (fun n ↦ (f n : ℂ)) (σ' : ℂ) n * + 𝓕 ψ.toFun (π⁻¹ * 2⁻¹ * Real.log ((n : ℝ) / x)) + - (A : ℂ) * ((x ^ (1 - σ') : ℝ) : ℂ) * + ∫ (u : ℝ) in Ici (-Real.log x), + cexp (-( (u : ℂ) * ((σ' : ℂ) - 1))) * + 𝓕 (W21.ofCS2 ψ).toFun (u / (2 * π))) + =ᶠ[𝓝[>] (1 : ℝ)] + (fun σ' : ℝ ↦ + ∫ (t : ℝ), G ((σ' : ℂ) + (t : ℂ) * I) * ψ.toFun t * (x : ℂ) ^ ((t : ℂ) * I)) := by + rw [Filter.EventuallyEq] + + refine eventually_nhdsWithin_of_forall ?_ + intro σ' hσ' + have hσ' : (1 : ℝ) < σ' := by + simpa [Set.mem_Ioi] using hσ' + simpa using! (limiting_fourier_aux_gt_zero (G := G) (f := f) (A := A) hG' hf ψ hx σ' hσ') + + have haux' : + (fun σ' : ℝ => S σ') =ᶠ[𝓝[>] (1 : ℝ)] (fun σ' : ℝ => RHS σ' + Pole σ') := by + rw [Filter.EventuallyEq] at haux ⊢ + filter_upwards [haux] with σ' hσ' + have hσ'' : S σ' - Pole σ' = RHS σ' := by + simpa [S, Pole, RHS] using hσ' + have hadd : (S σ' - Pole σ') + Pole σ' = RHS σ' + Pole σ' := + congrArg (fun z : ℂ => z + Pole σ') hσ'' + simpa [sub_eq_add_neg, add_assoc, add_left_comm, add_comm] using hadd + + let Pole₁ : ℂ := (A : ℂ) * ∫ u in Set.Ici (-Real.log x), 𝓕 (W21.ofCS2 ψ).toFun (u / (2 * π)) + let RHS₁ : ℂ := ∫ t : ℝ, G (1 + (t : ℂ) * I) * ψ.toFun t * (x : ℂ) ^ ((t : ℂ) * I) + + have hRHS_le : + ∀ᶠ σ' : ℝ in 𝓝[>] (1 : ℝ), ‖RHS σ'‖ ≤ ‖RHS₁‖ + 1 := by + have hball : Metric.ball RHS₁ (1 : ℝ) ∈ 𝓝 RHS₁ := by + simpa using (Metric.ball_mem_nhds (x := RHS₁) (ε := (1 : ℝ)) (by norm_num)) + have hpre : {σ' : ℝ | RHS σ' ∈ Metric.ball RHS₁ (1 : ℝ)} ∈ (𝓝[>] (1 : ℝ)) := + l3 hball + filter_upwards [hpre] with σ' hmem + have hdist' : dist (RHS σ') RHS₁ < (1 : ℝ) := by + simpa [Metric.mem_ball] using hmem + have hdist : ‖RHS σ' - RHS₁‖ < (1 : ℝ) := by + simpa [dist_eq_norm] using hdist' + have htri : ‖RHS σ'‖ ≤ ‖RHS₁‖ + ‖RHS σ' - RHS₁‖ := by + have h := norm_add_le (RHS σ' - RHS₁) RHS₁ + simpa [sub_add_cancel, add_comm, add_left_comm, add_assoc] using h + have hle : ‖RHS₁‖ + ‖RHS σ' - RHS₁‖ ≤ ‖RHS₁‖ + (1 : ℝ) := by + exact add_le_add_right (le_of_lt hdist) ‖RHS₁‖ + exact htri.trans hle + + have hPole_le : + ∀ᶠ σ' : ℝ in 𝓝[>] (1 : ℝ), ‖Pole σ'‖ ≤ ‖Pole₁‖ + 1 := by + have hball : Metric.ball Pole₁ 1 ∈ 𝓝 Pole₁ := by + simpa using (Metric.ball_mem_nhds Pole₁ (by norm_num : (0 : ℝ) < 1)) + have hpre : {σ' : ℝ | Pole σ' ∈ Metric.ball Pole₁ 1} ∈ (𝓝[>] (1 : ℝ)) := l2 hball + filter_upwards [hpre] with σ' hmem + have hdist : ‖Pole σ' - Pole₁‖ < 1 := by + simpa [Metric.mem_ball, dist_eq_norm] using hmem + have htri : ‖Pole σ'‖ ≤ ‖Pole₁‖ + ‖Pole σ' - Pole₁‖ := by + have hdecomp : Pole σ' = Pole₁ + (Pole σ' - Pole₁) := by abel + have hnorm_eq : ‖Pole σ'‖ = ‖Pole₁ + (Pole σ' - Pole₁)‖ := by + simp [congrArg (fun z : ℂ => ‖z‖) hdecomp] + calc + ‖Pole σ'‖ = ‖Pole₁ + (Pole σ' - Pole₁)‖ := hnorm_eq + _ ≤ ‖Pole₁‖ + ‖Pole σ' - Pole₁‖ := norm_add_le _ _ + have hdist_le : ‖Pole σ' - Pole₁‖ ≤ 1 := le_of_lt hdist + have hsum : ‖Pole₁‖ + ‖Pole σ' - Pole₁‖ ≤ ‖Pole₁‖ + 1 := by + simpa [add_comm, add_left_comm, add_assoc] using (add_le_add_left hdist_le ‖Pole₁‖) + exact htri.trans hsum + + have hS_le : + ∀ᶠ σ' : ℝ in 𝓝[>] (1 : ℝ), + ‖S σ'‖ ≤ (‖RHS₁‖ + 1) + (‖Pole₁‖ + 1) := by + rw [Filter.EventuallyEq] at haux' + filter_upwards [haux', hRHS_le, hPole_le] with σ' hEq hR hP + calc + ‖S σ'‖ = ‖RHS σ' + Pole σ'‖ := by simp [hEq] + _ ≤ ‖RHS σ'‖ + ‖Pole σ'‖ := norm_add_le _ _ + _ ≤ (‖RHS₁‖ + 1) + (‖Pole₁‖ + 1) := by + exact add_le_add hR hP + + have hbounded : BoundedAtFilter (𝓝[>] (1 : ℝ)) (fun σ' : ℝ => ‖S σ'‖) := by + let C : ℝ := ‖RHS₁‖ + 1 + (‖Pole₁‖ + 1) + simp only [BoundedAtFilter, Asymptotics.IsBigO, Asymptotics.IsBigOWith] + refine ⟨C, ?_⟩ + filter_upwards [hS_le] with σ' hσ' + simpa [Real.norm_eq_abs, abs_of_nonneg (norm_nonneg (S σ'))] using hσ' + + have hcoef : (1 / (2 * π) : ℝ) = (π⁻¹ * 2⁻¹ : ℝ) := by field_simp [pi_ne_zero] + + have l1 := + limiting_fourier_variant_lim1 + (f := f) (x := x) (ψ := ψ) + hpos hψpos + (S := S) + (hSdef := by + intro σ + simp [S, hcoef] ) + hbounded + hf + have l1S : + Tendsto S (𝓝[>] (1 : ℝ)) + (𝓝 (∑' n : ℕ, (f n : ℂ) / (n : ℂ) * 𝓕 ψ.toFun (1 / (2 * π) * Real.log (↑n / x)))) := by + simpa [S, hcoef] using l1 + + have l12 : Tendsto (fun σ' : ℝ => S σ' - Pole σ') (𝓝[>] (1 : ℝ)) + (𝓝 ((∑' n : ℕ, (f n : ℂ) / (n : ℂ) * 𝓕 ψ.toFun (1 / (2 * π) * Real.log (↑n / x))) - Pole₁)) := + l1S.sub l2 + + have hPole : (Pole : ℝ → ℂ) =ᶠ[𝓝[>] (1 : ℝ)] Pole := by simp + have haux_sub : + (fun σ' : ℝ => S σ' - Pole σ') =ᶠ[𝓝[>] (1 : ℝ)] RHS := by + filter_upwards [haux'] with σ' hσ' + calc + S σ' - Pole σ' + = (RHS σ' + Pole σ') - Pole σ' := by simp [hσ'] + _ = RHS σ' := by simp + have hlim := + tendsto_nhds_unique_of_eventuallyEq (l1S.sub l2) l3 haux_sub + + simpa [Pole₁, RHS₁] using! hlim + +lemma norm_mul_integral_Ici_le_integral_norm + (A : ℂ) (F : ℝ → ℂ) (a : ℝ) + (hF : IntegrableOn F (Set.Ici a)) + (hnorm : Integrable (fun u : ℝ => ‖F u‖)) : + ‖A * (∫ u in Set.Ici a, F u)‖ ≤ ‖A‖ * (∫ u : ℝ, ‖F u‖) := by + have hmul : ‖A * (∫ u in Set.Ici a, F u)‖ = ‖A‖ * ‖∫ u in Set.Ici a, F u‖ := by + simp + have hnormI : + ‖∫ u in Set.Ici a, F u‖ ≤ ∫ u in Set.Ici a, ‖F u‖ := by + have _ : Integrable F (Measure.restrict volume (Set.Ici a)) := hF + have h : + ‖∫ u, F u ∂Measure.restrict volume (Set.Ici a)‖ + ≤ ∫ u, ‖F u‖ ∂Measure.restrict volume (Set.Ici a) := + norm_integral_le_integral_norm (μ := Measure.restrict volume (Set.Ici a)) (f := F) + simpa using h + + have hdom : + (∫ u in Set.Ici a, ‖F u‖) ≤ ∫ u : ℝ, ‖F u‖ := by + have hEq : + (∫ u in Set.Ici a, ‖F u‖) = + ∫ u : ℝ, Set.indicator (Set.Ici a) (fun u => ‖F u‖) u := by + have h := (integral_indicator (μ := (volume : Measure ℝ)) + (s := Set.Ici a) (f := fun u => ‖F u‖)) + have h' := h measurableSet_Ici + simpa using h'.symm + have hind_int : + Integrable (Set.indicator (Set.Ici a) (fun u => ‖F u‖)) := + hnorm.indicator measurableSet_Ici + have hpoint : + Set.indicator (Set.Ici a) (fun u => ‖F u‖) + ≤ᵐ[volume] (fun u : ℝ => ‖F u‖) := by + filter_upwards with u + by_cases hu : u ∈ Set.Ici a + · simp [Set.indicator_of_mem hu] + · simp [Set.indicator_of_notMem hu] + have hmono := + integral_mono_ae (μ := (volume : Measure ℝ)) + hind_int hnorm hpoint + simpa [hEq] using hmono + + calc + ‖A * (∫ u in Set.Ici a, F u)‖ + = ‖A‖ * ‖∫ u in Set.Ici a, F u‖ := hmul + _ ≤ ‖A‖ * (∫ u in Set.Ici a, ‖F u‖) := + mul_le_mul_of_nonneg_left hnormI (by simp) + _ ≤ ‖A‖ * (∫ u : ℝ, ‖F u‖) := + mul_le_mul_of_nonneg_left hdom (by simp) + +lemma fourier_decay_of_CS2 + (ψ : CS 2 ℂ) : + ∃ C : ℝ, ∀ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ C / (1 + u ^ 2) := by + let ψ' : W21 := (ψ : W21) + obtain ⟨C, hC⟩ : + ∃ C : ℝ, ∀ u : ℝ, ‖𝓕 (ψ' : ℝ → ℂ) u‖ ≤ C / (1 + u ^ 2) := by + simpa using (decay_bounds_cor (ψ := ψ')) + refine ⟨C, ?_⟩ + intro u + simpa [ψ'] using! (hC u) + +lemma integrable_norm_fourier_scaled_of_CS2 + (ψ : CS 2 ℂ) : + Integrable (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := by + obtain ⟨C, hdecay⟩ := fourier_decay_of_CS2 (ψ := ψ) + have hC_nonneg : 0 ≤ C := by + have h0 := hdecay 0 + have hnorm : 0 ≤ ‖𝓕 (ψ : ℝ → ℂ) 0‖ := norm_nonneg _ + have hC' : ‖𝓕 (ψ : ℝ → ℂ) 0‖ ≤ C := by simpa using h0 + exact hnorm.trans hC' + have hmaj_int : Integrable (fun u : ℝ => (C : ℝ) / (1 + (u / (2 * Real.pi))^2)) := by + have hbase : Integrable (fun u : ℝ => (1 + u ^ 2)⁻¹) := integrable_inv_one_add_sq + have hscale : + Integrable (fun u : ℝ => (1 + (u / (2 * Real.pi)) ^ 2)⁻¹) := + hbase.comp_div (by nlinarith [Real.pi_pos]) + simpa [div_eq_mul_inv, mul_comm, mul_left_comm, mul_assoc, pow_two] using + hscale.const_mul C + have hle : + (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) + ≤ᵐ[volume] + (fun u : ℝ => (C : ℝ) / (1 + (u / (2 * Real.pi))^2)) := by + refine Filter.Eventually.of_forall ?_ + intro u + simpa using (hdecay (u / (2 * Real.pi))) + have hle_norm : + (fun u : ℝ => ‖‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖‖) + ≤ᵐ[volume] + (fun u : ℝ => ‖(C : ℝ) / (1 + (u / (2 * Real.pi))^2)‖) := by + refine hle.mono ?_ + intro u hu + have hden_pos : 0 < 1 + (u / (2 * Real.pi)) ^ 2 := by nlinarith + have hnonneg : 0 ≤ (C : ℝ) / (1 + (u / (2 * Real.pi))^2) := + div_nonneg hC_nonneg hden_pos.le + have hleft_nonneg : 0 ≤ ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖ := norm_nonneg _ + have hbound : ‖‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖‖ ≤ + (C : ℝ) / (1 + (u / (2 * Real.pi))^2) := by + simpa [Real.norm_eq_abs, abs_of_nonneg hleft_nonneg] using hu + have hC_abs : |C| = C := abs_of_nonneg hC_nonneg + have hden_abs : |1 + (u / (2 * Real.pi))^2| = 1 + (u / (2 * Real.pi))^2 := by + have : 0 ≤ 1 + (u / (2 * Real.pi))^2 := by nlinarith + simpa using abs_of_nonneg this + have hnorm : + ‖(C : ℝ) / (1 + (u / (2 * Real.pi))^2)‖ = + (C : ℝ) / (1 + (u / (2 * Real.pi))^2) := by + have hrec : + ‖(C : ℝ) / (1 + (u / (2 * Real.pi))^2)‖ = + |C| / |1 + (u / (2 * Real.pi))^2| := by + simp [Real.norm_eq_abs] + simp [hC_abs, hden_abs, hrec] + simpa [hnorm] using hbound + have hmaj_int_norm : + Integrable (fun u : ℝ => ‖(C : ℝ) / (1 + (u / (2 * Real.pi))^2)‖) := + hmaj_int.norm + have hmeas : + AEStronglyMeasurable (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := by + have hcont : Continuous fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) u := by + simpa using! continuous_FourierIntegral (ψ : W21) + have hcont_scaled : Continuous fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi)) := + hcont.comp (by continuity) + exact hcont_scaled.aestronglyMeasurable.norm + exact hmaj_int_norm.mono' hmeas hle_norm + +lemma exists_bound_norm_G_on_tsupport + (hG : ContinuousOn G {s : ℂ | 1 ≤ s.re}) + (ψ : CS 2 ℂ) : + ∃ K : ℝ, ∀ t : ℝ, t ∈ tsupport (ψ : ℝ → ℂ) → + ‖G (1 + t * Complex.I)‖ ≤ K := by + let s : Set ℝ := tsupport (ψ : ℝ → ℂ) + have hscompact : IsCompact s := by + simpa [s] using (ψ.h2.isCompact : IsCompact (tsupport (ψ : ℝ → ℂ))) + have hphi_cont : Continuous (fun t : ℝ => (1 : ℂ) + t * Complex.I) := by continuity + have hphi_maps : + Set.MapsTo (fun t : ℝ => (1 : ℂ) + t * Complex.I) s {z : ℂ | 1 ≤ z.re} := by + intro t ht + simp + have hGcomp : ContinuousOn (fun t : ℝ => G ((1 : ℂ) + t * Complex.I)) s := + hG.comp hphi_cont.continuousOn hphi_maps + have hnorm_contOn : ContinuousOn (fun t : ℝ => ‖G ((1 : ℂ) + t * Complex.I)‖) s := hGcomp.norm + have hbdd : BddAbove ((fun t : ℝ => ‖G ((1 : ℂ) + t * Complex.I)‖) '' s) := + (hscompact.image_of_continuousOn hnorm_contOn).bddAbove + refine ⟨sSup ((fun t : ℝ => ‖G ((1 : ℂ) + t * Complex.I)‖) '' s), ?_⟩ + intro t ht + have : ‖G ((1 : ℂ) + t * Complex.I)‖ ∈ + (fun t : ℝ => ‖G ((1 : ℂ) + t * Complex.I)‖) '' s := ⟨t, ht, rfl⟩ + exact le_csSup hbdd this + +lemma norm_integrand_le_K_mul_norm_psi + {x K : ℝ} + (hx : 0 < x) + (hK : ∀ t : ℝ, t ∈ Function.support ψ → ‖G (1 + t * Complex.I)‖ ≤ K) : + ∀ t : ℝ, + ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ ≤ K * ‖ψ t‖ := by + intro t + by_cases ht : t ∈ Function.support ψ + · have hxnorm : ‖((x : ℂ) ^ (t * Complex.I))‖ = 1 := norm_x_cpow_it x t hx + calc + ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ + = ‖G (1 + t * Complex.I)‖ * ‖ψ t‖ * ‖((x : ℂ) ^ (t * Complex.I))‖ := by + simp [mul_left_comm, mul_comm] + _ = ‖G (1 + t * Complex.I)‖ * ‖ψ t‖ * 1 := by simp [hxnorm] + _ ≤ K * ‖ψ t‖ := by + have hGle : ‖G (1 + t * Complex.I)‖ ≤ K := hK t ht + have : ‖G (1 + t * Complex.I)‖ * ‖ψ t‖ ≤ K * ‖ψ t‖ := + mul_le_mul_of_nonneg_right hGle (norm_nonneg _) + simpa [mul_assoc, mul_left_comm, mul_comm] using this + · have hψ0 : ψ t = 0 := by + by_contra hψ0 + exact ht (by simpa [Function.support] using hψ0) + simp [hψ0, mul_comm] + +lemma norm_error_integral_le + (ψ : ℝ → ℂ) (x K : ℝ) + (hGline_meas : Measurable (fun t : ℝ => G (1 + t * I))) + (hψ_meas : AEStronglyMeasurable ψ) + (hx : 0 < x) + (hK : ∀ t : ℝ, t ∈ Function.support ψ → ‖G (1 + t * Complex.I)‖ ≤ K) + (hψ : Integrable (fun t : ℝ => ‖ψ t‖) ) : + ‖∫ t : ℝ, (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ + ≤ K * (∫ t : ℝ, ‖ψ t‖) := by + have h1 : ‖∫ t : ℝ, (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ + ≤ ∫ t : ℝ, ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ := by + simpa using (norm_integral_le_integral_norm + (f := fun t : ℝ => (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I)))) + have hmeas_main : AEStronglyMeasurable + (fun t : ℝ => (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))) := by + have hG' : AEMeasurable fun t : ℝ => G (1 + t * Complex.I) := hGline_meas.aemeasurable + have hψ_meas' : AEMeasurable ψ := hψ_meas.aemeasurable + have hx_ne : (x : ℂ) ≠ 0 := by exact_mod_cast (ne_of_gt hx) + have hx_ne' : NeZero (x : ℂ) := ⟨hx_ne⟩ + have hxpow_meas : AEMeasurable fun t : ℝ => ((x : ℂ) ^ (t * Complex.I)) := by + have hcontℂ : Continuous fun z : ℂ => ((x : ℂ) ^ z) := + continuous_const_cpow (z := (x : ℂ)) + have hcont : Continuous fun t : ℝ => ((x : ℂ) ^ ((t : ℂ) * Complex.I)) := + hcontℂ.comp (by + have h : Continuous fun t : ℝ => (t : ℂ) * Complex.I := by + simpa using! (continuous_ofReal.mul continuous_const) + simpa [mul_comm] using h) + exact hcont.measurable.aemeasurable + have hGψ_meas : AEMeasurable fun t : ℝ => (G (1 + t * Complex.I)) * (ψ t) := hG'.mul hψ_meas' + have htotal : AEMeasurable (fun t : ℝ => + (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))) := + hGψ_meas.mul hxpow_meas + exact htotal.aestronglyMeasurable + have hpt : (fun t : ℝ => + ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖) + ≤ᵐ[volume] (fun t : ℝ => K * ‖ψ t‖) := by + refine Eventually.of_forall ?_ + intro t + exact norm_integrand_le_K_mul_norm_psi (hx := hx) (hK := hK) t + have hR : Integrable (fun t : ℝ => K * ‖ψ t‖) := hψ.const_mul K + have hL : Integrable (fun t : ℝ => + ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖) := by + have hpt_norm : + (fun t : ℝ => ‖‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖‖) + ≤ᵐ[volume] (fun t : ℝ => K * ‖ψ t‖) := hpt.mono (by + intro t ht + simpa [norm_mul, mul_comm, mul_left_comm, mul_assoc] using ht) + exact hR.mono' hmeas_main.norm hpt_norm + have h2 : (∫ t : ℝ, ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖) + ≤ ∫ t : ℝ, K * ‖ψ t‖ := integral_mono_ae (μ := (volume : Measure ℝ)) hL hR hpt + have h3 : (∫ t : ℝ, K * ‖ψ t‖) = K * (∫ t : ℝ, ‖ψ t‖) := by + simp [integral_const_mul] + calc + ‖∫ t : ℝ, (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ + ≤ ∫ t : ℝ, ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ := h1 + _ ≤ ∫ t : ℝ, K * ‖ψ t‖ := h2 + _ = K * (∫ t : ℝ, ‖ψ t‖) := h3 + +lemma crude_upper_bound + (hpos : 0 ≤ f) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (ψ : CS 2 ℂ) + (hψpos : ∀ y, 0 ≤ (𝓕 (ψ : ℝ → ℂ) y).re ∧ (𝓕 (ψ : ℝ → ℂ) y).im = 0) : + ∃ B : ℝ, ∀ x : ℝ, 0 < x → ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ B := by + + have hψ_int : MeasureTheory.Integrable (ψ : ℝ → ℂ) := by + simpa using (ψ.h1.continuous.integrable_of_hasCompactSupport ψ.h2) + have hψ_norm_int : MeasureTheory.Integrable (fun t : ℝ => ‖(ψ : ℝ → ℂ) t‖) := + hψ_int.norm + have hψ_meas : MeasureTheory.AEStronglyMeasurable (ψ : ℝ → ℂ) := + hψ_int.aestronglyMeasurable + + rcases exists_bound_norm_G_on_tsupport (G := G) hG ψ with ⟨K, hK_ts⟩ + have hK_support : + ∀ t : ℝ, t ∈ Function.support (ψ : ℝ → ℂ) → ‖G (1 + t * Complex.I)‖ ≤ K := by + have hbnG (hKts : ∀ t : ℝ, t ∈ tsupport ψ → ‖G (1 + t * Complex.I)‖ ≤ K) : + ∀ t : ℝ, t ∈ Function.support ψ → ‖G (1 + t * Complex.I)‖ ≤ K := by + intro t ht + exact hKts t ((subset_tsupport ψ) ht) + exact hbnG hK_ts + + have hGline_meas : Measurable (fun t : ℝ => G (1 + t * Complex.I)) := by + have hline_cont : Continuous (fun t : ℝ => (1 : ℂ) + t * Complex.I) := by + continuity + have hmem : ∀ t : ℝ, ((1 : ℂ) + t * Complex.I) ∈ {s : ℂ | 1 ≤ s.re} := by + intro t + simp + have hcont : Continuous (G ∘ fun t : ℝ => (1 : ℂ) + t * Complex.I) := + hG.comp_continuous hline_cont hmem + simpa [Function.comp] using! hcont.measurable + + have hF_norm_int : + MeasureTheory.Integrable (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := + integrable_norm_fourier_scaled_of_CS2 ψ + have hF_meas : + MeasureTheory.AEStronglyMeasurable + (fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) := by + have hcont : Continuous fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) u := by + simpa using! continuous_FourierIntegral (ψ : W21) + have hcont_scaled : Continuous fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi)) := + hcont.comp (by continuity) + exact hcont_scaled.aestronglyMeasurable + have hF_int : + MeasureTheory.Integrable (fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) := + by + have hfin_norm : + MeasureTheory.HasFiniteIntegral + (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := + hF_norm_int.hasFiniteIntegral + have hfin : + MeasureTheory.HasFiniteIntegral + (fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) := by + simpa [MeasureTheory.hasFiniteIntegral_iff_norm] using hfin_norm + exact ⟨hF_meas, hfin⟩ + refine ⟨K * (∫ t : ℝ, ‖(ψ : ℝ → ℂ) t‖) + + ‖A‖ * (∫ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖), ?_⟩ + intro x hx + set I : ℂ := ∫ u in Set.Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi)) with hI + + have hlim := + limiting_fourier_variant (f := f) (A := A) (G := G) + hpos hG hG' hf ψ hψpos hx + have hlim' : + (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * Real.pi) * Real.log (n / x))) + - A * I + = ∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I) := by + simpa [hI] using hlim + + have htsum : + (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * Real.pi) * Real.log (n / x))) + = (∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I := by + have h' : + (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * Real.pi) * Real.log (n / x))) + = (∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I := + eq_add_of_sub_eq hlim' + simpa [add_comm, mul_comm, mul_left_comm, mul_assoc] using h' + + have hRHS_bound : + ‖∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)‖ + ≤ K * (∫ t : ℝ, ‖(ψ : ℝ → ℂ) t‖) := + norm_error_integral_le (G := G) (ψ := (ψ : ℝ → ℂ)) (x := x) (K := K) + hGline_meas hψ_meas hx hK_support hψ_norm_int + + have hA_bound : + ‖A * I‖ ≤ ‖A‖ * (∫ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := by + have hF_on : MeasureTheory.IntegrableOn + (fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) + (Set.Ici (-Real.log x)) := + hF_int.integrableOn + simpa [hI] using + norm_mul_integral_Ici_le_integral_norm (A := A) + (F := fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) + (a := -Real.log x) hF_on hF_norm_int + + have htsum_std : + (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * Real.pi) * Real.log ((n : ℝ) / x))) + = (∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I := by + simpa [one_div, mul_comm, mul_left_comm, mul_assoc] using htsum + + have hbound : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) + (1 / (2 * Real.pi) * Real.log ((n : ℝ) / x))‖ + ≤ K * (∫ t : ℝ, ‖(ψ : ℝ → ℂ) t‖) + + ‖A‖ * (∫ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := by + have hnorm : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) + (1 / (2 * Real.pi) * Real.log ((n : ℝ) / x))‖ = + ‖(∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I‖ := + congrArg norm htsum_std + calc + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) + (1 / (2 * Real.pi) * Real.log ((n : ℝ) / x))‖ + = ‖(∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I‖ := hnorm + _ ≤ ‖∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)‖ + ‖A * I‖ := + norm_add_le _ _ + _ ≤ K * (∫ t : ℝ, ‖(ψ : ℝ → ℂ) t‖) + + ‖A‖ * (∫ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := + add_le_add hRHS_bound hA_bound + exact hbound + +lemma Real.fourierIntegral_convolution {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) : + 𝓕 (convolution f g (ContinuousLinearMap.mul ℂ ℂ) volume) = 𝓕 f * 𝓕 g := by + ext y + simp only [Pi.mul_apply, FourierTransform.fourier, MeasureTheory.convolution, + VectorFourier.fourierIntegral, ContinuousLinearMap.mul_apply'] + have h_int : Integrable (fun p : ℝ × ℝ ↦ 𝐞 (-(y * p.1)) • (f p.2 * g (p.1 - p.2))) := by + simp only [Circle.smul_def, smul_eq_mul] + refine (Integrable.convolution_integrand (ContinuousLinearMap.mul ℂ ℂ) hf hg).bdd_mul + (c := 1) ?_ ?_ + · exact (by continuity : Continuous _).aestronglyMeasurable + · filter_upwards with p; simp + calc ∫ v, 𝐞 (-(y * v)) • ∫ t, f t * g (v - t) + = ∫ v, ∫ t, 𝐞 (-(y * v)) • (f t * g (v - t)) := by + simp only [Circle.smul_def, smul_eq_mul, ← integral_const_mul] + _ = ∫ t, ∫ v, 𝐞 (-(y * v)) • (f t * g (v - t)) := integral_integral_swap h_int + _ = ∫ t, f t • ∫ v, 𝐞 (-(y * v)) • g (v - t) := by + simp only [Circle.smul_def, smul_eq_mul, mul_left_comm, integral_const_mul] + _ = ∫ t, f t • ∫ u, 𝐞 (-(y * (u + t))) • g u := by + congr 1; ext t + rw [← integral_add_right_eq_self (fun v ↦ 𝐞 (-(y * v)) • g (v - t)) t]; simp + _ = ∫ t, f t • ∫ u, (𝐞 (-(y * t)) * 𝐞 (-(y * u))) • g u := by + congr 2 with t; congr 1 + simp only [mul_add, neg_add, mul_comm, Real.fourierChar.map_add_eq_mul] + _ = ∫ t, 𝐞 (-(y * t)) • f t • ∫ u, 𝐞 (-(y * u)) • g u := by + congr 1; ext t + simp only [mul_smul, Circle.smul_def, smul_eq_mul, integral_const_mul]; ring + _ = (∫ t, 𝐞 (-(y * t)) • f t) * ∫ u, 𝐞 (-(y * u)) • g u := by + simp only [Circle.smul_def, smul_eq_mul, ← mul_assoc, integral_mul_const] + +lemma Real.fourierIntegral_conj_neg {f : ℝ → ℂ} (y : ℝ) : + 𝓕 (fun x ↦ conj (f (-x))) y = conj (𝓕 f y) := by + simp only [fourier_real_eq] + have h_conj : ∀ x, 𝐞 (-(x * y)) • conj (f (-x)) = conj (𝐞 (x * y) • f (-x)) := fun x ↦ by + simp only [Circle.smul_def, Real.fourierChar_apply, map_mul, smul_eq_mul, neg_mul, + Complex.ofReal_neg, mul_neg] + congr 1 + rw [← Complex.exp_conj] + simp only [map_mul, Complex.conj_I, Complex.conj_ofReal, mul_neg] + calc ∫ x, 𝐞 (-(x * y)) • conj (f (-x)) + = ∫ x, conj (𝐞 (x * y) • f (-x)) := by congr 1; ext x; exact h_conj x + _ = conj (∫ x, 𝐞 (x * y) • f (-x)) := integral_conj + _ = conj (∫ x, 𝐞 (-(x * y)) • f x) := by + rw [← integral_neg_eq_self (fun x => 𝐞 (-(x * y)) • f x)] + congr 2 with x; ring_nf + +lemma auto_cheby_exists_smooth_nonneg_fourier_kernel : + ∃ (ψ : ℝ → ℂ), ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ + (∀ y, 0 ≤ (𝓕 ψ y).re ∧ (𝓕 ψ y).im = 0) ∧ 0 < (𝓕 ψ 0).re := by + obtain ⟨φ_real, hφSmooth, hφCompact, hφIcc, _, hφsupp⟩ := + smooth_urysohn_support_Ioo (a := 1/2) (b := 1) (c := 1) (d := 2) (by norm_num) (by norm_num) + let φ : ℝ → ℂ := Complex.ofReal ∘ φ_real + let φ_rev : ℝ → ℂ := fun x ↦ conj (φ (-x)) + let ψ_fun : ℝ → ℂ := convolution φ φ_rev (ContinuousLinearMap.mul ℂ ℂ) volume + have hφSmooth' : ContDiff ℝ ∞ φ := contDiff_ofReal.comp hφSmooth + have hφCompact' : HasCompactSupport φ := hφCompact.comp_left rfl + have hφRevSmooth : ContDiff ℝ ∞ φ_rev := Complex.conjCLE.contDiff.comp (hφSmooth'.comp contDiff_neg) + have hφRevCompact : HasCompactSupport φ_rev := (hφCompact'.comp_homeomorph (Homeomorph.neg ℝ)).comp_left (by simp) + have hφInt : Integrable φ := hφSmooth'.continuous.integrable_of_hasCompactSupport hφCompact' + have hφRevInt : Integrable φ_rev := hφRevSmooth.continuous.integrable_of_hasCompactSupport hφRevCompact + have hψSmooth : ContDiff ℝ ∞ ψ_fun := by + convert! hφRevCompact.contDiff_convolution_right (ContinuousLinearMap.mul ℝ ℂ) + (hφSmooth'.continuous.locallyIntegrable (μ := volume)) hφRevSmooth + have hψCompact : HasCompactSupport ψ_fun := + HasCompactSupport.convolution (ContinuousLinearMap.mul ℂ ℂ) hφCompact' hφRevCompact + refine ⟨ψ_fun, hψSmooth, hψCompact, fun y ↦ ?_, ?_⟩ + · rw [Real.fourierIntegral_convolution hφInt hφRevInt, Pi.mul_apply, + Real.fourierIntegral_conj_neg y, mul_comm, ← Complex.normSq_eq_conj_mul_self] + exact ⟨Complex.normSq_nonneg _, rfl⟩ + · have hφ_nonneg : ∀ x, 0 ≤ φ_real x := fun x ↦ by + have hx := hφIcc x; by_cases h : x ∈ Set.Icc (1:ℝ) 1 + · simp only [Set.indicator_of_mem h, Pi.one_apply] at hx; linarith + · simp only [Set.indicator_of_notMem h] at hx; exact hx + have hvol_supp : (1 : ENNReal) ≤ volume (Function.support φ_real) := by + have hsub : Set.Ico (1:ℝ) 2 ⊆ Function.support φ_real := fun x hx ↦ + hφsupp.symm ▸ Set.mem_Ioo.mpr ⟨by linarith [hx.1], hx.2⟩ + calc _ = volume (Set.Ico (1:ℝ) 2) := by simp [Real.volume_Ico]; norm_num + _ ≤ _ := volume.mono hsub + have hφint_pos : 0 < ∫ x, φ_real x := + (integral_pos_iff_support_of_nonneg_ae (.of_forall hφ_nonneg) + (hφSmooth.continuous.integrable_of_hasCompactSupport hφCompact)).2 + (lt_of_lt_of_le (by simp) hvol_supp) + have hFφ0_re : 0 < (𝓕 φ 0).re := by + simp only [φ, fourier_real_eq, mul_zero, neg_zero, AddChar.map_zero_eq_one, one_smul, + Function.comp_apply] + have hint : Integrable (fun x => (φ_real x : ℂ)) := + (hφSmooth.continuous.integrable_of_hasCompactSupport hφCompact).ofReal + calc (∫ x, (φ_real x : ℂ)).re = ∫ x, (φ_real x : ℂ).re := (integral_re hint).symm + _ = ∫ x, φ_real x := by simp only [Complex.ofReal_re] + _ > 0 := hφint_pos + rw [Real.fourierIntegral_convolution hφInt hφRevInt, Pi.mul_apply, + Real.fourierIntegral_conj_neg 0, mul_comm, ← Complex.normSq_eq_conj_mul_self] + exact Complex.normSq_pos.2 (fun h ↦ (ne_of_gt hFφ0_re) (by simp [h])) + +lemma auto_cheby_fourier_summable (hpos : 0 ≤ f) (hf : ∀ σ', 1 < σ' → Summable (nterm f σ')) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ψ : ℝ → ℂ) (hψSmooth : ContDiff ℝ ∞ ψ) (hψCompact : HasCompactSupport ψ) + (hψpos : ∀ y, 0 ≤ (𝓕 ψ y).re ∧ (𝓕 ψ y).im = 0) (x : ℝ) (hx : 1 ≤ x) : + Summable fun n ↦ (f n : ℂ) / n * 𝓕 ψ (1 / (2 * π) * Real.log (n / x)) := by + let ψCS : CS 2 ℂ := ⟨ψ, hψSmooth.of_le (by norm_cast), hψCompact⟩ + let S : ℝ → ℂ := fun σ' ↦ ∑' n, term (f · : ℕ → ℂ) σ' n * 𝓕 ψCS.toFun (1 / (2 * π) * Real.log (n / x)) + let Pole : ℝ → ℂ := fun σ' ↦ (A : ℂ) * (x ^ (1 - σ') : ℝ) * + ∫ u in Set.Ici (-Real.log x), (rexp (-u * (σ' - 1)) : ℂ) * 𝓕 (W21.ofCS2 ψCS).toFun (u / (2 * π)) + let RHS : ℝ → ℂ := fun σ' ↦ ∫ t : ℝ, G (σ' + t * I) * ψCS.toFun t * (x : ℂ) ^ (t * I) + have l2 := limiting_fourier_lim2 (A := A) (x := x) ψCS hx + have l3 := limiting_fourier_lim3 (G := G) hG ψCS hx + have haux : (fun σ' ↦ S σ' - Pole σ') =ᶠ[𝓝[>] 1] RHS := eventually_nhdsWithin_of_forall fun σ' hσ' ↦ by + simpa [S, Pole, RHS] using! limiting_fourier_aux hG' hf ψCS hx σ' hσ' + have hS_tendsto : Tendsto S (𝓝[>] 1) (𝓝 (RHS 1 + A * ∫ u in Set.Ici (-Real.log x), + 𝓕 (W21.ofCS2 ψCS).toFun (u / (2 * π)))) := by + convert! (l3.congr' haux.symm).add l2 using 1; ext σ'; simp [S, Pole] + have hbounded : BoundedAtFilter (𝓝[>] 1) (fun σ' ↦ ‖S σ'‖) := by + simp only [BoundedAtFilter] + let L := ‖RHS 1 + A * ∫ u in Set.Ici (-Real.log x), 𝓕 (W21.ofCS2 ψCS).toFun (u / (2 * π))‖ + have : ∀ᶠ σ' in 𝓝[>] 1, ‖S σ'‖ < L + 1 := + hS_tendsto.norm.eventually_lt tendsto_const_nhds (lt_add_one L) + exact Asymptotics.IsBigO.of_bound (L + 1) (by filter_upwards [this] with σ h; simpa using h.le) + let y : ℕ → ℝ := fun n ↦ (1 / (2 * π)) * Real.log (n / x) + let w : ℕ → ℝ := fun n ↦ (𝓕 ψCS.toFun (y n)).re + have hw : ∀ n, 0 ≤ w n := fun n ↦ (hψpos (y n)).1 + let rt : ℝ → ℕ → ℝ := fun σ n ↦ if n = 0 then 0 else f n / (n : ℝ) ^ σ * w n + have rt_nn σ n : 0 ≤ rt σ n := by + simp only [rt]; split_ifs with hn + · rfl + · exact mul_nonneg (div_nonneg (hpos n) (Real.rpow_pos_of_pos (Nat.cast_pos.mpr + (Nat.pos_of_ne_zero hn)) σ).le) (hw n) + have hS_eq σ' (hσ' : 1 < σ') : S σ' = ↑(∑' n, rt σ' n) := by + rw [Complex.ofReal_tsum]; apply tsum_congr; intro n + simp only [rt, term, LSeries.term, y, w, one_div, mul_inv_rev] + split_ifs with hn <;> simp only [hn, CharP.cast_eq_zero, Complex.ofReal_zero, zero_mul, + Complex.ofReal_mul, Complex.ofReal_div] + rw [Complex.ofReal_cpow (Nat.cast_nonneg n)]; congr 1 + exact Complex.ext rfl (hψpos _).2 + have hMono n : AntitoneOn (fun σ ↦ rt σ n) (Set.Ioi 1) := fun σ₁ _ σ₂ _ h ↦ by + simp only [rt]; split_ifs with hn; · rfl + apply mul_le_mul_of_nonneg_right _ (hw n) + apply div_le_div_of_nonneg_left (hpos n) (Real.rpow_pos_of_pos (Nat.cast_pos.mpr + (Nat.pos_of_ne_zero hn)) σ₁) + exact Real.rpow_le_rpow_of_exponent_le (Nat.one_le_cast.mpr (Nat.pos_of_ne_zero hn)) h + have hT_bdd : BoundedAtFilter (𝓝[>] 1) fun σ ↦ ∑' n, rt σ n := by + rw [BoundedAtFilter, Asymptotics.isBigO_iff] at hbounded ⊢ + obtain ⟨C, hC⟩ := hbounded + refine ⟨C, ?_⟩ + filter_upwards [hC, self_mem_nhdsWithin] with σ hnorm hσ + rw [hS_eq σ hσ] at hnorm; simpa using hnorm + have hSumm σ (hσ : 1 < σ) : Summable (rt σ ·) := by + simpa [rt, w, y] using limiting_fourier_variant_lim1_aux ψCS hpos hf hψpos σ hσ + have hSumm_1 : Summable (rt 1 ·) := by + let σ_seq : ℕ → ℝ := fun k ↦ 1 + 1 / ((k : ℝ) + 1) + have hσ_gt k : 1 < σ_seq k := by simp only [σ_seq, lt_add_iff_pos_right, one_div]; positivity + have h_tendsto : Tendsto σ_seq atTop (𝓝[>] 1) := by + rw [tendsto_nhdsWithin_iff] + refine ⟨?_, by filter_upwards with k; exact hσ_gt k⟩ + have : Tendsto (fun k : ℕ ↦ 1 / ((k : ℝ) + 1)) atTop (𝓝 0) := by + simp only [one_div]; exact (tendsto_natCast_atTop_atTop.atTop_add tendsto_const_nhds).inv_tendsto_atTop + simpa [σ_seq] using tendsto_const_nhds.add this + have h_ptwise n : Tendsto (fun k ↦ rt (σ_seq k) n) atTop (𝓝 (rt 1 n)) := by + simp only [rt]; split_ifs with hn; · exact tendsto_const_nhds + refine ((tendsto_const_nhds.rpow (tendsto_nhdsWithin_iff.mp h_tendsto).1 (Or.inl ?_)).inv₀ + (by simp [hn])).const_mul (f n) |>.mul_const (w n) + exact (Nat.cast_pos.mpr (Nat.pos_of_ne_zero hn)).ne' + obtain ⟨C, hC⟩ := Asymptotics.isBigO_iff.mp (hT_bdd.comp_tendsto h_tendsto) + refine summable_of_sum_range_le (c := C) (rt_nn 1) fun m ↦ le_of_tendsto (tendsto_finsetSum _ + fun i _ ↦ h_ptwise i) ?_ + filter_upwards [h_tendsto.eventually self_mem_nhdsWithin, hC] with k hk hCk + calc ∑ i ∈ Finset.range m, rt (σ_seq k) i + ≤ ∑' n, rt (σ_seq k) n := (hSumm _ hk).sum_le_tsum _ fun n _ ↦ rt_nn _ n + _ ≤ |∑' n, rt (σ_seq k) n| := le_abs_self _ + _ ≤ C := by simpa using hCk + rw [show (fun n ↦ (f n : ℂ) / n * 𝓕 ψ (1 / (2 * π) * Real.log (n / x))) = + Complex.ofRealCLM ∘ (rt 1 ·) from ?_] + · exact hSumm_1.map Complex.ofRealCLM Complex.ofRealCLM.continuous + ext n; simp only [rt, Real.rpow_one, one_div, w, y, Function.comp_apply] + split_ifs with hn; · simp [hn] + have him0 : (𝓕 ψCS.toFun ((2 * π)⁻¹ * Real.log (n / x))).im = 0 := (hψpos _).2 + have hre_eq : 𝓕 ψCS.toFun ((2 * π)⁻¹ * Real.log (n / x)) = + Complex.ofReal ((𝓕 ψCS.toFun ((2 * π)⁻¹ * Real.log (n / x))).re) := by + rw [← Complex.re_add_im (𝓕 ψCS.toFun _), him0]; simp + conv_lhs => rw [show ψ = ψCS.toFun from rfl, hre_eq] + simp only [Complex.ofRealCLM_apply, Complex.ofReal_div, Complex.ofReal_mul, Complex.ofReal_natCast] + +lemma auto_cheby_short_interval_bound (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (B : ℝ) (ψ : ℝ → ℂ) (hψSmooth : ContDiff ℝ ∞ ψ) (hψCompact : HasCompactSupport ψ) + (hψpos : ∀ y, 0 ≤ (𝓕 ψ y).re ∧ (𝓕 ψ y).im = 0) (hψ0 : 0 < (𝓕 ψ 0).re) + (hB_bound : ∀ x ≥ 1, ‖∑' n, f n / n * 𝓕 ψ (1 / (2 * Real.pi) * Real.log (n / x))‖ ≤ B) : + ∃ (ε : ℝ) (C : ℝ), ε > 0 ∧ ε < 1 ∧ C > 0 ∧ ∀ x ≥ 1, + ∑' n, (f n) * (Set.indicator (Set.Ioc ((1 - ε) * x) x) (fun _ ↦ 1) (n : ℝ)) ≤ C * x := by + have hF : Continuous (𝓕 ψ) := VectorFourier.fourierIntegral_continuous Real.continuous_fourierChar + (by continuity) (hψSmooth.continuous.integrable_of_hasCompactSupport hψCompact) + have hg : Continuous fun y ↦ (𝓕 ψ y).re := Complex.continuous_re.comp hF + obtain ⟨δ, hδpos, hball⟩ := Metric.mem_nhds_iff.1 <| + hg.continuousAt.preimage_mem_nhds (IsOpen.mem_nhds isOpen_Ioi (half_lt_self hψ0)) + let c := (𝓕 ψ 0).re / 2 + have hcpos : 0 < c := by dsimp only [c]; linarith + have h_psi_ge_c : ∀ y, |y| < δ → c ≤ (𝓕 ψ y).re := fun y hy ↦ (hball (mem_ball_zero_iff.mpr hy)).le + let ε := 1 - Real.exp (-2 * π * δ) + have hε : 0 < ε ∧ ε < 1 := by + have h1 : Real.exp (-2 * π * δ) < 1 := Real.exp_lt_one_iff.mpr (by nlinarith [Real.pi_pos]) + exact ⟨by simp only [ε]; linarith, by simp only [ε]; linarith [Real.exp_pos (-2 * π * δ)]⟩ + have hB_nonneg : 0 ≤ B := (norm_nonneg _).trans (hB_bound 1 le_rfl) + refine ⟨ε, B / c + 1, hε.1, hε.2, by positivity, fun x hx ↦ ?_⟩ + have h_summable : Summable fun n ↦ (f n : ℂ) / n * 𝓕 ψ (1 / (2 * π) * Real.log (n / x)) := + auto_cheby_fourier_summable hpos hf hG hG' ψ hψSmooth hψCompact hψpos x hx + have hx_pos : 0 < x := by linarith + have h_sum_lower : c / x * ∑' n, f n * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (n : ℝ) + ≤ ∑' n, f n / n * (𝓕 ψ (1 / (2 * π) * Real.log (n / x))).re := by + rw [← tsum_mul_left] + refine Summable.tsum_le_tsum (fun n ↦ ?_) ?_ ?_ + · by_cases hn : (n : ℝ) ∈ Set.Ioc ((1 - ε) * x) x + · rw [Set.indicator_of_mem hn, Pi.one_apply, mul_one] + have hn_pos : 0 < (n : ℝ) := by nlinarith [hn.1, hε.2] + let y := (1 / (2 * π)) * Real.log (n / x) + have h_arg_small : |y| < δ := by + have h2pi : 0 < 2 * π := by linarith [Real.pi_pos] + simp only [y, abs_mul, abs_div, abs_one, abs_of_pos h2pi] + field_simp [ne_of_gt h2pi]; rw [mul_comm, abs_lt] + have h_log_lower : -2 * π * δ < Real.log (n / x) := by + rw [← Real.log_exp (-2 * π * δ), Real.log_lt_log_iff (Real.exp_pos _) (by positivity)] + have : Real.exp (-2 * π * δ) = 1 - ε := by simp only [ε]; ring + rw [this]; field_simp; exact hn.1 + have h_log_upper : Real.log (n / x) ≤ 0 := + Real.log_nonpos (by positivity) (div_le_one_of_le₀ hn.2 hx_pos.le) + constructor <;> nlinarith [Real.pi_pos] + have h1 : x⁻¹ ≤ (n : ℝ)⁻¹ := by rw [inv_le_inv₀ hx_pos hn_pos]; exact hn.2 + have h2 : c ≤ (𝓕 ψ y).re := h_psi_ge_c y h_arg_small + have hfn : 0 ≤ f n := hpos n + have hre : 0 ≤ (𝓕 ψ y).re := (hψpos y).1 + have hn_inv : 0 ≤ (n : ℝ)⁻¹ := inv_nonneg.mpr hn_pos.le + calc c / x * f n = c * x⁻¹ * f n := by rw [div_eq_mul_inv] + _ ≤ c * (n : ℝ)⁻¹ * f n := by gcongr + _ ≤ (𝓕 ψ y).re * (n : ℝ)⁻¹ * f n := by gcongr + _ = (n : ℝ)⁻¹ * (𝓕 ψ y).re * f n := by ring + _ = f n / n * (𝓕 ψ y).re := by ring + · rw [Set.indicator_of_notMem hn, mul_zero, mul_zero] + exact mul_nonneg (div_nonneg (hpos n) (Nat.cast_nonneg n)) (hψpos _).1 + · refine summable_of_hasFiniteSupport <| (Set.finite_le_nat ⌊x⌋₊).subset fun n hn ↦ ?_ + simp only [Function.mem_support, ne_eq, mul_eq_zero, not_or, Set.indicator_apply_ne_zero] at hn + exact Nat.le_floor hn.2.2.1.2 + · rw [← Complex.summable_ofReal]; convert h_summable using 1; ext n + rw [Complex.ofReal_mul, Complex.ofReal_div] + norm_cast + rw [Complex.ofReal_mul] + congr 1 + apply Complex.ext + · simp only [Complex.ofReal_re] + · simp only [Complex.ofReal_im]; exact (hψpos _).2.symm + have h_real_eq : ∑' n, f n / n * (𝓕 ψ (1 / (2 * π) * Real.log (n / x))).re = + (∑' n, (f n : ℂ) / n * 𝓕 ψ (1 / (2 * π) * Real.log (n / x))).re := by + rw [Complex.re_tsum h_summable]; congr with n + rw [Complex.mul_re]; norm_cast; simp only [zero_mul, sub_zero] + calc ∑' n, f n * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (n : ℝ) + = x / c * (c / x * ∑' n, f n * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (n : ℝ)) := by + field_simp [ne_of_gt hcpos, ne_of_gt hx_pos] + _ ≤ x / c * B := by + gcongr; rw [h_real_eq] at h_sum_lower + exact h_sum_lower.trans ((Complex.re_le_norm _).trans (hB_bound x hx)) + _ = (B / c) * x := by field_simp [ne_of_gt hcpos] + _ ≤ (B / c + 1) * x := by nlinarith + +lemma auto_cheby_bootstrap_induction (hpos : 0 ≤ f) + (h_short : ∃ (ε : ℝ) (C : ℝ), ε > 0 ∧ ε < 1 ∧ C > 0 ∧ ∀ x ≥ 1, + ∑' n, (f n) * (Set.indicator (Set.Ioc ((1 - ε) * x) x) (fun _ ↦ 1) (n : ℝ)) ≤ C * x) : + cheby f := by + obtain ⟨ε, C₀, hε, hε1, hC₀, h_bound⟩ := h_short + let C := C₀ / ε + f 0 + 1 + have hf0 : (0 : ℝ) ≤ f 0 := hpos 0 + have hdiv : 0 ≤ C₀ / ε := div_nonneg hC₀.le hε.le + have hC : 0 ≤ C := by linarith + refine ⟨C, fun n ↦ ?_⟩ + induction n using Nat.strong_induction_on with | h n ih => + rcases lt_or_ge n 2 with hn | hn + · interval_cases n + · simp [cumsum] + · simp only [cumsum, Finset.sum_range_one, Complex.norm_real, Real.norm_eq_abs, abs_of_nonneg hf0, + Nat.cast_one, mul_one, C] + linarith + let x := (n : ℝ) - 1 + have hx : x ≥ 1 := by simp only [x, ge_iff_le, le_sub_iff_add_le]; norm_cast + let m := ⌊(1 - ε) * x⌋₊ + 1 + have hm_lt : m < n := by + simp only [m, x] + have h1 : (1 - ε) * (n - 1 : ℝ) < (n - 1 : ℕ) := by + calc (1 - ε) * (↑n - 1) < 1 * (↑n - 1) := by gcongr; linarith + _ = ↑n - 1 := by ring + _ = ↑(n - 1) := by simp [Nat.cast_sub (by omega : 1 ≤ n)] + have h2 : ⌊(1 - ε) * (n - 1 : ℝ)⌋₊ < n - 1 := + (Nat.floor_lt (mul_nonneg (by linarith) (by linarith : (0 : ℝ) ≤ n - 1))).mpr h1 + omega + have hm_gt : (m : ℝ) > (1 - ε) * x := by + simp only [m, Nat.cast_add, Nat.cast_one, gt_iff_lt] + exact Nat.lt_floor_add_one ((1 - ε) * x) + have h_decomp : cumsum (fun k ↦ ‖(f k : ℂ)‖) n = cumsum (fun k ↦ ‖(f k : ℂ)‖) m + ∑ k ∈ Finset.Ico m n, f k := by + simp only [cumsum, Complex.norm_real, Real.norm_eq_abs, abs_of_nonneg (hpos _), + Finset.sum_range_add_sum_Ico _ (by omega : m ≤ n)] + have h_Ico : ∑ k ∈ Finset.Ico m n, f k ≤ C₀ * x := by + calc ∑ k ∈ Finset.Ico m n, f k + = ∑ k ∈ Finset.Ico m n, f k * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (k : ℝ) := by + refine Finset.sum_congr rfl fun k hk ↦ ?_ + have ⟨hkm, hkn⟩ := Finset.mem_Ico.mp hk + have hk_gt : (k : ℝ) > (1 - ε) * x := by linarith [hm_gt, (Nat.cast_le (α := ℝ)).mpr hkm] + have hk_le : (k : ℝ) ≤ x := by + have h1 : k ≤ n - 1 := Nat.le_pred_of_lt hkn + have h2 : (k : ℝ) ≤ (n - 1 : ℕ) := by exact_mod_cast h1 + simp only [Nat.cast_sub (by omega : 1 ≤ n), Nat.cast_one, x] at h2 ⊢; exact h2 + simp only [Set.indicator_of_mem (Set.mem_Ioc.mpr ⟨hk_gt, hk_le⟩), Pi.one_apply, mul_one] + _ ≤ ∑' k, f k * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (k : ℝ) := by + refine Summable.sum_le_tsum _ (fun k _ ↦ mul_nonneg (hpos k) (Set.indicator_nonneg (by simp) _)) ?_ + refine summable_of_hasFiniteSupport <| (Set.finite_le_nat ⌊x⌋₊).subset fun k hk ↦ ?_ + simp only [Function.mem_support, ne_eq, mul_eq_zero, not_or, Set.indicator_apply_ne_zero] at hk + exact Nat.le_floor hk.2.1.2 + _ ≤ C₀ * x := h_bound x hx + have hm_le : (m : ℝ) ≤ (1 - ε) * x + 1 := by + have hpos' : 0 ≤ (1 - ε) * x := mul_nonneg (by linarith) (by linarith : (0 : ℝ) ≤ x) + simp only [m, Nat.cast_add, Nat.cast_one] + linarith [Nat.floor_le hpos'] + have hnorm : ∀ k, ‖(f k : ℂ)‖ = f k := fun k ↦ by simp [abs_of_nonneg (hpos k)] + simp only [hnorm] at h_decomp ih ⊢ + calc cumsum f n = cumsum f m + ∑ k ∈ Finset.Ico m n, f k := h_decomp + _ ≤ C * m + C₀ * x := by linarith [ih m hm_lt, h_Ico] + _ ≤ C * ((1 - ε) * x + 1) + C₀ * x := by nlinarith [hC] + _ = (C * (1 - ε) + C₀) * x + C := by ring + _ ≤ C * x + C := by + have : C₀ ≤ C * ε := by + calc C₀ = (C₀ / ε) * ε := by field_simp [ne_of_gt hε] + _ ≤ (C₀ / ε + f 0 + 1) * ε := by gcongr; linarith [hpos 0] + _ = C * ε := by simp only [C] + nlinarith [hε, hε1, hx] + _ ≤ C * n := by simp only [x]; ring_nf; linarith [hC] + +lemma auto_cheby (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : cheby f := by + obtain ⟨ψ_fun, hψSmooth, hψCompact, hψpos, hψ0⟩ := auto_cheby_exists_smooth_nonneg_fourier_kernel + obtain ⟨B, hB⟩ := crude_upper_bound hpos hG hG' hf ⟨ψ_fun, hψSmooth.of_le ENat.LEInfty.out, hψCompact⟩ hψpos + exact auto_cheby_bootstrap_induction hpos <| auto_cheby_short_interval_bound hpos hf hG hG' B ψ_fun + hψSmooth hψCompact hψpos hψ0 fun x hx ↦ hB x (by linarith) + +theorem WienerIkeharaTheorem'' (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun N => cumsum f N / N) atTop (𝓝 A) := + WienerIkeharaTheorem' hpos hf (auto_cheby (f := f) (A := A) (G := G) hpos hf hG hG') hG hG' + +end auto_cheby + +theorem WeakPNT_character + {q a : ℕ} (hq : q ≥ 1) (ha : Nat.Coprime a q) (ha' : a < q) {s : ℂ} (hs : 1 < s.re) : + LSeries (fun n ↦ if n % q = a then Λ n else 0) s = + - (∑' χ : DirichletCharacter ℂ q, + ((starRingEnd ℂ) (χ a) * ((deriv (LSeries (fun n:ℕ ↦ χ n)) s)) / + (LSeries (fun n:ℕ ↦ χ n) s))) / (Nat.totient q : ℂ) := by + have : NeZero q := ⟨by omega⟩ + convert vonMangoldt.LSeries_residueClass_eq ((ZMod.isUnit_iff_coprime a q).mpr ha) hs using 1 + · congr with n + have : n % q = a ↔ (n : ZMod q) = a := by + rw [ZMod.natCast_eq_natCast_iff', Nat.mod_eq_of_lt ha'] + simp [this] + split_ifs <;> simp [*] + · rw [div_eq_inv_mul, neg_mul_comm, tsum_fintype] + congr 3 with χ + rw [DirichletCharacter.deriv_LFunction_eq_deriv_LSeries _ hs, + DirichletCharacter.LFunction_eq_LSeries _ hs, mul_div] + congr 2 + rw [starRingEnd_apply, MulChar.star_apply', MulChar.inv_apply_eq_inv', + ← ZMod.coe_unitOfCoprime a ha, ZMod.inv_coe_unit, map_units_inv] + +theorem WeakPNT_AP_prelim {q : ℕ} {a : ℕ} (hq : q ≥ 1) (ha : Nat.Coprime a q) (ha' : a < q) : + ∃ G: ℂ → ℂ, (ContinuousOn G {s | 1 ≤ s.re}) ∧ + (Set.EqOn G (fun s ↦ LSeries (fun n ↦ if n % q = a then Λ n else 0) s - 1 / + ((Nat.totient q) * (s - 1))) {s | 1 < s.re}) := by + have : NeZero q := NeZero.of_pos hq + have hG : ∃ G : ℂ → ℂ, ContinuousOn G {s | 1 ≤ s.re} ∧ Set.EqOn G + (fun s ↦ LSeries (fun n ↦ if (n : ZMod q) = a then Λ n else 0) s - (q.totient : ℂ)⁻¹ / (s - 1)) {s | 1 < s.re} := by + use vonMangoldt.LFunctionResidueClassAux (a : ZMod q), vonMangoldt.continuousOn_LFunctionResidueClassAux (q := q) (a := a) + have := vonMangoldt.eqOn_LFunctionResidueClassAux ((ZMod.isUnit_iff_coprime a q).mpr ha) + convert this using 6; split <;> simp_all + convert hG using 6 + · simp [ZMod.natCast_eq_natCast_iff', Nat.mod_eq_of_lt ha'] + · rw [inv_eq_one_div, div_div] + +lemma summable_vonMangoldt_div_rpow {s : ℝ} (hs : 1 < s) : Summable (fun n ↦ Λ n / n ^ s) := by + have h_log_bound : ∀ n : ℕ, (Λ n : ℝ) ≤ Real.log n := fun n ↦ vonMangoldt_le_log + suffices h_log_sum : Summable fun n : ℕ ↦ Real.log n / (n : ℝ) ^ s by + exact .of_nonneg_of_le (fun n ↦ div_nonneg vonMangoldt_nonneg (by positivity)) + (fun n ↦ div_le_div_of_nonneg_right (h_log_bound n) (by positivity)) h_log_sum + have h_log_le_n_eps : ∀ ε > 0, ∃ C > 0, ∀ n : ℕ, n ≥ 2 → Real.log n / (n : ℝ) ^ s ≤ C * (n : ℝ) ^ (ε - s) := by + intro ε hε_pos + obtain ⟨C, hC_pos, hC⟩ : ∃ C > 0, ∀ n : ℕ, n ≥ 2 → Real.log n ≤ C * (n : ℝ) ^ ε := by + refine ⟨1 / ε, by positivity, fun n hn ↦ ?_⟩ + have := log_le_sub_one_of_pos (by positivity : 0 < (n : ℝ) ^ ε) + rw [log_rpow (by positivity)] at this + nlinarith [rpow_pos_of_pos (by positivity : 0 < (n : ℝ)) ε, mul_div_cancel₀ 1 hε_pos.ne'] + refine ⟨C, hC_pos, fun n hn ↦ ?_⟩ + rw [rpow_sub (by positivity)] + exact le_trans (div_le_div_of_nonneg_right (hC n hn) (by positivity)) (by rw [div_eq_mul_inv]; ring_nf; norm_num) + obtain ⟨C, _, hC⟩ : ∃ C > 0, ∀ n : ℕ, n ≥ 2 → Real.log n / (n : ℝ) ^ s ≤ C * (n : ℝ) ^ ((s - 1) / 2 - s) := + h_log_le_n_eps ((s - 1) / 2) (by linarith) + rw [← summable_nat_add_iff 2] + exact Summable.of_nonneg_of_le (fun n ↦ div_nonneg (log_nonneg (by norm_cast; omega)) + (rpow_nonneg (by positivity) _)) (fun n ↦ hC _ (by omega)) (Summable.mul_left _ <| by + simpa using summable_nat_add_iff 2 |>.2 <| summable_nat_rpow.2 <| by linarith) + +theorem WeakPNT_AP {q : ℕ} {a : ℕ} (hq : q ≥ 1) (ha : a.Coprime q) (ha' : a < q) : + Tendsto (fun N ↦ cumsum (fun n ↦ if n % q = a then Λ n else 0) N / N) atTop (𝓝 (1 / q.totient)) := by + have h_summable : ∀ s : ℝ, 1 < s → Summable (fun n ↦ (if n % q = a then Λ n else 0) / n ^ s) := by + intro s hs + refine .of_nonneg_of_le (fun n ↦ ?_) (fun n ↦ ?_) (summable_vonMangoldt_div_rpow hs) + · split_ifs <;> positivity + · split_ifs <;> norm_num; exact div_nonneg vonMangoldt_nonneg (by positivity) + obtain ⟨G, hG₁, hG₂⟩ := WeakPNT_AP_prelim hq ha ha' + convert WienerIkeharaTheorem'' _ _ _ _ using 1 + · use G + · intro n + simp_all only [ge_iff_le, one_div, mul_inv_rev, Pi.ofNat_apply] + split + next h => subst h; simp_all only [vonMangoldt_nonneg] + next h => simp_all only [le_refl] + · intro σ' hσ' + specialize h_summable σ' hσ' + simp_all only [ge_iff_le, one_div, mul_inv_rev] + convert h_summable using 1 + ext + simp only [nterm, norm_real, norm_eq_abs] + ring_nf + split_ifs <;> simp [*, mul_comm] + · assumption + · convert hG₂ using 3 + · exact tsum_congr fun n ↦ by cases n <;> aesop + · norm_num [div_eq_mul_inv, mul_assoc, mul_comm, mul_left_comm] + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/ZetaBounds.lean b/PrimeNumberTheoremAnd/Erdos970/ZetaBounds.lean new file mode 100644 index 0000000..84113af --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/ZetaBounds.lean @@ -0,0 +1,2982 @@ +import Batteries.Tactic.Lemma +import Mathlib.MeasureTheory.Function.Floor +import Mathlib.MeasureTheory.Order.Group.Lattice +import Mathlib.NumberTheory.Harmonic.Bounds +import Mathlib.NumberTheory.LSeries.Nonvanishing +import PrimeNumberTheoremAnd.Erdos970.Auxiliary +import PrimeNumberTheoremAnd.Erdos970.Fourier +import PrimeNumberTheoremAnd.Erdos970.Mathlib.Analysis.SpecialFunctions.Log.Basic +import PrimeNumberTheoremAnd.Erdos970.ResidueCalcOnRectangles +import PrimeNumberTheoremAnd.Erdos970.EulerMaclaurin + +namespace Erdos970 + + +open _root_.Complex Topology Filter Interval _root_.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 + +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 + + 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 + + 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₀) + + 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‖ + + 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 + +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 + +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 + +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 + +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 + +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 + + have h_decomp : ∀ s, f s = (f s - A * (s - p)⁻¹) + A * (s - p)⁻¹ := by + intro s + ring + + obtain ⟨M, hM⟩ := f_near_p + + have A_norm_pos : 0 < ‖A‖ := norm_pos_iff.mpr A_ne_zero + + 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) + + obtain ⟨V, hV_open, hV_mem, hV_sub⟩ : ∃ V, IsOpen V ∧ p ∈ V ∧ V ⊆ U ∩ Metric.ball p δ := by + + 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 + + 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 + + rw [h_decomp s] + + have bound_first : ‖f s - A * (s - p)⁻¹‖ ≤ M := by + apply hM + exact ⟨s, ⟨hs_in_U, hs_ne_p⟩, rfl⟩ + + 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 + + by_contra h_zero + + rw [add_eq_zero_iff_eq_neg] at h_zero + rw [h_zero, norm_neg] at bound_first + + 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 + +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 + + 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] + + 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 + +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 _)))) + +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 + +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 + + 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 + + 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 ?_ + + have g_cont : ContinuousAt g p := by + + exact (g_holc.continuousOn.continuousWithinAt p_in_U).continuousAt U_in_nhds + + have := g_cont.norm.isBoundedUnder_le.isBigO_one ℂ + exact IsBigO.mono this inf_le_left + · + + 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 + + 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 + +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] + +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) + +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 + +lemma 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 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] + +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 ↦ _root_.Erdos970.Complex.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 + + +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 _root_.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 + +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 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 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 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 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 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 + +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 _root_.Erdos970.Complex.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 <| _root_.Erdos970.Complex.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 + +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] + +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] + +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 + +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 + +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 + +lemma HolomorphicOn_riemannZeta : + HolomorphicOn ζ {s : ℂ | s ≠ 1} := by + intro z hz + simp only [mem_ofPred_eq] at hz + exact (differentiableAt_riemannZeta hz).differentiableWithinAt + +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 + +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₂ + +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 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); + 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 + +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) + 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 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 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 := 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 + +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 + +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 + +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} + +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 + +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 + + 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 _) + +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σ + + have lower := ZetaLowerBound2 (t := t) σ_gt + apply le_trans _ lower + + 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 + + have σ_in_range : σ ∈ Icc (1 - A / Real.log |2 * t|) 2 := by + constructor + · + 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 + + 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)) + + 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 + + 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 + + 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 + +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] + +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', _root_.Erdos970.deriv_ofReal, mul_one] at this + exact this + · apply DifferentiableAt.add_const _ <| _root_.Erdos970.Complex.differentiableAt_ofReal σ + + +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) <| _root_.Erdos970.Complex.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 + +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 + +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; norm_cast; simp + 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 + +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 + + 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⟩=>?_⟩ + + 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 + · bound + 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 : ℕ) := by + bound + have : 1 ≤ Real.log t ^ (9 : ℝ) := by + exact_mod_cast this + 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 + +lemma ZetaZeroFree : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)), + ∀ (σ : ℝ) + (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Ico (1 - A / (Real.log |t|) ^ 9) 1), + ζ (σ + t * I) ≠ 0 := by + obtain ⟨A, hA, c, hc, h_lower⟩ := ZetaLowerBnd + + refine ⟨A, hA, ?_⟩ + + 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 + +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') + exact pow_nonneg (zero_le_one.trans logt_gt.le) _ + 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) ?_ + exact le_self_pow₀ logt_gt.le (by norm_num) + 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) + norm_cast + + _ ≤ 2 := by linarith + ⟩ + simp only [norm_div] + convert! mul_le_mul h h' (by simp) ?_ using 1 <;> (norm_cast; ring_nf); positivity + +lemma ZetaNoZerosOn1Line (t : ℝ) : ζ (1 + t * I) ≠ 0 := by + refine riemannZeta_ne_zero_of_one_le_re ?_ + simp + +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 + +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 + +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 + +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 + +theorem LogDerivZetaHolcLargeT : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)), ∀ (T : ℝ) (_ : 3 ≤ T), + HolomorphicOn (fun (s : ℂ) ↦ ζ' s / (ζ s)) + (( (Icc ((1 : ℝ) - A / Real.log T ^ 9) 2) ×ℂ (Icc (-T) T) ) \ {1}) := by + obtain ⟨A, A_inter, restOfZetaZeroFree⟩ := ZetaZeroFree + obtain ⟨σ₁, σ₁_lt_one, noZerosInBox⟩ := ZetaNoZerosInBox 3 + let A₀ := min A ((1 - σ₁) * Real.log 3 ^ 9) + 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 ^ 9 := 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 ^ 9 := by exact this.1.1 + _ ≥ 1 - A₀ / Real.log 3 ^ 9 := by + gcongr + apply le_min A_inter.1.le + bound + _ ≥ 1 - (((1 - σ₁) * Real.log 3 ^ 9)) / Real.log 3 ^ 9:= by + gcongr + apply min_le_right + _ = _ := by field_simp; simp + +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 + +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 + + 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 + + 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 only [ENNReal.ofReal_one, ENNReal.addLECancellable_iff_ne, ne_eq, + ENNReal.one_ne_top, not_false_eq_true, AddLECancellable.add_tsub_cancel_left] + _ < ε.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 only [ENNReal.ofReal_one, ENNReal.addLECancellable_iff_ne, ne_eq, + ENNReal.one_ne_top, not_false_eq_true, AddLECancellable.add_tsub_cancel_left] + _ < ε.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 + +lemma LogDerivZetaBndUnif : + ∃ (A : ℝ) (_ : A ∈ Ioc 0 (1 / 2)) (C : ℝ) (_ : 0 < C), ∀ (σ : ℝ) (t : ℝ) (_ : 3 < |t|) + (_ : σ ∈ Ici (1 - A / Real.log |t| ^ 9)), ‖ζ' (σ + t * I) / ζ (σ + t * I)‖ ≤ + C * Real.log |t| ^ 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; simp only [le_add_iff_nonneg_right]; positivity + +end Erdos970 diff --git a/PrimeNumberTheoremAnd/Erdos970/ZetaConj.lean b/PrimeNumberTheoremAnd/Erdos970/ZetaConj.lean new file mode 100644 index 0000000..79c01fe --- /dev/null +++ b/PrimeNumberTheoremAnd/Erdos970/ZetaConj.lean @@ -0,0 +1,32 @@ +import Mathlib.Analysis.Calculus.Deriv.Star +import Mathlib.Analysis.Normed.Module.Connected +import Mathlib.NumberTheory.Harmonic.ZetaAsymp + +namespace Erdos970 + +open scoped Complex ComplexConjugate + +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 + +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 + + +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 Erdos970 diff --git a/PrimeNumberTheoremAnd/Fourier.lean b/PrimeNumberTheoremAnd/Fourier.lean index 99e15a0..1a8cf07 100644 --- a/PrimeNumberTheoremAnd/Fourier.lean +++ b/PrimeNumberTheoremAnd/Fourier.lean @@ -1,57 +1,29 @@ -import Mathlib.Analysis.Distribution.SchwartzSpace.Deriv -import Mathlib.MeasureTheory.Integral.IntegralEqImproper +/- +Adapted from PrimeNumberTheoremAnd by Alex Kontorovich and contributors. +Licensed under the Apache License, Version 2.0; see the upstream LICENSE. +This compatibility port retains the proven declarations used by this project. +-/ import Mathlib.Topology.ContinuousMap.Bounded.Basic -import Mathlib.Order.Filter.ZeroAndBoundedAtFilter import Mathlib.Analysis.Fourier.FourierTransformDeriv import PrimeNumberTheoremAnd.Sobolev open FourierTransform Real Complex MeasureTheory Filter Topology BoundedContinuousFunction SchwartzMap VectorFourier BigOperators -local instance {E : Type*} : Coe (E → ℝ) (E → ℂ) := ⟨fun f n => f n⟩ - section lemmas -@[simp] -theorem nnnorm_eq_of_mem_circle (z : Circle) : ‖z.val‖₊ = 1 := - NNReal.coe_eq_one.mp (by simp) - -@[simp] -theorem nnnorm_circle_smul (z : Circle) (s : ℂ) : ‖z • s‖₊ = ‖s‖₊ := by - simp [show z • s = z.val * s from rfl] - -noncomputable def e (u : ℝ) : ℝ →ᵇ ℂ where - toFun v := 𝐞 (-v * u) - map_bounded' := - ⟨2, fun x y => (dist_le_norm_add_norm _ _).trans (by simp [Circle.norm_coe, one_add_one_eq_two])⟩ - -@[simp] lemma e_apply (u : ℝ) (v : ℝ) : e u v = 𝐞 (-v * u) := rfl - -theorem hasDerivAt_e {u x : ℝ} : HasDerivAt (e u) (-2 * π * u * I * e u x) x := by - have l2 : HasDerivAt (fun v => -v * u) (-u) x := by - simpa only [neg_mul_comm] using hasDerivAt_mul_const (-u) - convert! (hasDerivAt_fourierChar (-x * u)).scomp x l2 using 1 - change _ = ((-u : ℝ) : ℂ) * _ -- `scomp` introduces ℝ-smul on ℂ, which we undo - simp ; ring - -lemma fourierIntegral_deriv_aux2 (e : ℝ →ᵇ ℂ) {f : ℝ → ℂ} (hf : Integrable f) : - Integrable (⇑e * f) := - hf.bdd_mul e.continuous.aestronglyMeasurable (ae_of_all _ e.norm_coe_le_norm) - -@[simp] lemma F_neg {f : ℝ → ℂ} {u : ℝ} : 𝓕 (fun x => -f x) u = - 𝓕 f u := by +@[simp] theorem F_neg {f : ℝ → ℂ} {u : ℝ} : 𝓕 (fun x => -f x) u = - 𝓕 f u := by simp [fourier_eq, integral_neg] -@[simp] lemma F_add {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) (x : ℝ) : +@[simp] theorem F_add {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) (x : ℝ) : 𝓕 (fun x => f x + g x) x = 𝓕 f x + 𝓕 g x := by - have : Continuous fun p : ℝ × ℝ ↦ ((innerₗ ℝ) p.1) p.2 := continuous_inner - have := fourierIntegral_add continuous_fourierChar this hf hg - exact congr_fun this x + exact congr_fun (fourierIntegral_add continuous_fourierChar continuous_inner hf hg) x -@[simp] lemma F_sub {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) (x : ℝ) : +@[simp] theorem F_sub {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) (x : ℝ) : 𝓕 (fun x => f x - g x) x = 𝓕 f x - 𝓕 g x := by simpa [sub_eq_add_neg, Pi.neg_def] using F_add hf hg.neg x -@[simp] lemma F_mul {f : ℝ → ℂ} {c : ℂ} {u : ℝ} : +@[simp] theorem F_mul {f : ℝ → ℂ} {c : ℂ} {u : ℝ} : 𝓕 (fun x => c * f x) u = c * 𝓕 f u := by exact congr_fun (VectorFourier.fourierIntegral_const_smul 𝐞 _ _ f c) u @@ -67,121 +39,5 @@ theorem fourierIntegral_self_add_deriv_deriv (f : W21) (u : ℝ) : simp [f.hf, l1, add_mul, Real.fourier_deriv f.hf' l5 f.hf'', Real.fourier_deriv f.hf l4 f.hf'] field_simp [pi_ne_zero] ; ring_nf ; simp -@[simp] lemma deriv_ofReal : deriv ofReal = fun _ => 1 := by +@[simp] theorem deriv_ofReal : deriv ofReal = fun _ => 1 := by ext x ; exact ((hasDerivAt_id x).ofReal_comp).deriv - -/-- If, eventually in `T`, the integrand `f T` is bounded on `uIoc lo hi` by `B T` -and `B T * |hi - lo| → 0`, then the interval integral `∫ x in lo..hi, f T x → 0`. -/ -lemma tendsto_intervalIntegral_zero_of_uniform_norm_bound - {f : ℝ → ℝ → ℂ} {lo hi : ℝ} {B : ℝ → ℝ} - (hB : Filter.Tendsto (fun T : ℝ => B T * |hi - lo|) Filter.atTop (nhds 0)) - (hf : ∀ᶠ T in Filter.atTop, ∀ x ∈ Set.uIoc lo hi, ‖f T x‖ ≤ B T) : - Filter.Tendsto (fun T : ℝ => ∫ x in lo..hi, f T x) Filter.atTop (nhds 0) := by - rw [tendsto_zero_iff_norm_tendsto_zero] - refine squeeze_zero' (Eventually.of_forall fun T => norm_nonneg _) ?_ hB - filter_upwards [hf] with T hT - exact intervalIntegral.norm_integral_le_of_norm_le_const (fun x hx => hT x hx) - -/-- The decay `K * (log (T + 2) / (T + 2)) → 0` as `T → ∞`, for any constant `K`. -/ -lemma tendsto_const_mul_log_add_two_div_add_two_atTop (K : ℝ) : - Filter.Tendsto (fun T : ℝ => K * (Real.log (T + 2) / (T + 2))) - Filter.atTop (nhds 0) := by - have h0 : Filter.Tendsto (fun x : ℝ => Real.log x / x) Filter.atTop (nhds 0) := by - simpa using (Real.tendsto_pow_log_div_mul_add_atTop 1 0 1 (by norm_num : (1 : ℝ) ≠ 0)) - have hshift : Filter.Tendsto (fun T : ℝ => Real.log (T + 2) / (T + 2)) - Filter.atTop (nhds 0) := by - have := h0.comp (tendsto_atTop_add_const_right Filter.atTop 2 tendsto_id) - simpa [Function.comp_def] using this - simpa using hshift.const_mul K - -/-- Fourier-transform decay from an integrable derivative: for integrable, -differentiable `g` with integrable derivative, `‖𝓕 g w‖ ≤ (∫ ‖deriv g x‖) / (2π·|w|)`. -/ -lemma norm_fourier_le_integral_deriv_div - (g : ℝ → ℂ) (hg : Integrable g) (hdiff : Differentiable ℝ g) - (hg' : Integrable (deriv g)) {w : ℝ} (hw : w ≠ 0) : - ‖𝓕 g w‖ ≤ (∫ x, ‖deriv g x‖ ∂volume) / ((2 * Real.pi) * |w|) := by - have hmul : - 𝓕 (deriv g) w = (2 * Real.pi * Complex.I * (w : ℂ)) * 𝓕 g w := by - have h := congrFun (Real.fourier_deriv hg hdiff hg') w - simpa [smul_eq_mul, mul_assoc] using h - have h_fourier : - ‖𝓕 (deriv g) w‖ ≤ ∫ x, ‖deriv g x‖ ∂volume := by - exact VectorFourier.norm_fourierIntegral_le_integral_norm 𝐞 volume (innerₗ ℝ) - (deriv g) w - have hleft : - ((2 * Real.pi) * |w|) * ‖𝓕 g w‖ = - ‖(2 * Real.pi * Complex.I * (w : ℂ)) * 𝓕 g w‖ := by - have htwopi : ‖(2 * ↑Real.pi : ℂ)‖ = 2 * Real.pi := by - rw [norm_mul, Complex.norm_two, Complex.norm_of_nonneg Real.pi_pos.le] - have hwc : ‖(w : ℂ)‖ = |w| := by rw [norm_real, Real.norm_eq_abs] - rw [norm_mul, norm_mul, norm_mul, htwopi, norm_I, hwc] - ring - have hmain : ((2 * Real.pi) * |w|) * ‖𝓕 g w‖ ≤ ∫ x, ‖deriv g x‖ ∂volume := by - rw [hleft, ← hmul] - exact h_fourier - have hpos : 0 < (2 * Real.pi) * |w| := by - positivity - exact (le_div_iff₀ hpos).mpr (by simpa [mul_comm, mul_left_comm, mul_assoc] using hmain) - -/-- The oscillatory-integral form of the decay bound: for `0 < T`, -`‖∫ g y · exp(T·i·y)‖ ≤ (∫ ‖deriv g x‖) / T`. -/ -lemma norm_oscillatory_integral_le_integral_deriv_div - (g : ℝ → ℂ) (hg : Integrable g) (hdiff : Differentiable ℝ g) - (hg' : Integrable (deriv g)) {T : ℝ} (hT : 0 < T) : - ‖∫ y, g y * exp ((T : ℂ) * Complex.I * (y : ℂ)) ∂volume‖ ≤ - (∫ x, ‖deriv g x‖ ∂volume) / T := by - have hw : -T / (2 * Real.pi) ≠ 0 := by - exact div_ne_zero (neg_ne_zero.mpr hT.ne') (mul_ne_zero two_ne_zero Real.pi_ne_zero) - have hfourier := norm_fourier_le_integral_deriv_div g hg hdiff hg' hw - have heq : - (∫ y, g y * exp ((T : ℂ) * Complex.I * (y : ℂ)) ∂volume) = - 𝓕 g (-T / (2 * Real.pi)) := by - rw [Real.fourier_real_eq_integral_exp_smul] - apply integral_congr_ae - filter_upwards with y - rw [smul_eq_mul] - rw [mul_comm (g y)] - congr 1 - congr 1 - push_cast - field_simp [Real.pi_ne_zero] - rw [heq] - refine hfourier.trans_eq ?_ - congr 1 - have hden : (2 * Real.pi) * |-T / (2 * Real.pi)| = T := by - have htwopi_pos : 0 < 2 * Real.pi := by positivity - have hneg : -T / (2 * Real.pi) < 0 := div_neg_of_neg_of_pos (neg_neg_of_pos hT) htwopi_pos - rw [abs_of_neg hneg] - field_simp [Real.pi_ne_zero] - rw [hden] - -/-- The `|T|` variant of the oscillatory-integral decay bound: for `T ≠ 0`, -`‖∫ g y · exp(T·i·y)‖ ≤ (∫ ‖deriv g x‖) / |T|`. -/ -lemma norm_oscillatory_integral_le_integral_deriv_div_abs - (g : ℝ → ℂ) (hg : Integrable g) (hdiff : Differentiable ℝ g) - (hg' : Integrable (deriv g)) {T : ℝ} (hT : T ≠ 0) : - ‖∫ y, g y * exp ((T : ℂ) * Complex.I * (y : ℂ)) ∂volume‖ ≤ - (∫ x, ‖deriv g x‖ ∂volume) / |T| := by - have hw : -T / (2 * Real.pi) ≠ 0 := by - exact div_ne_zero (neg_ne_zero.mpr hT) (mul_ne_zero two_ne_zero Real.pi_ne_zero) - have hfourier := norm_fourier_le_integral_deriv_div g hg hdiff hg' hw - have heq : - (∫ y, g y * exp ((T : ℂ) * Complex.I * (y : ℂ)) ∂volume) = - 𝓕 g (-T / (2 * Real.pi)) := by - rw [Real.fourier_real_eq_integral_exp_smul] - apply integral_congr_ae - filter_upwards with y - rw [smul_eq_mul] - rw [mul_comm (g y)] - congr 1 - congr 1 - push_cast - field_simp [Real.pi_ne_zero] - rw [heq] - refine hfourier.trans_eq ?_ - congr 1 - have hden : (2 * Real.pi) * |-T / (2 * Real.pi)| = |T| := by - have htwopi_pos : 0 < 2 * Real.pi := by positivity - rw [abs_div, abs_neg, abs_of_pos htwopi_pos] - field_simp [Real.pi_ne_zero] - rw [hden] diff --git a/PrimeNumberTheoremAnd/SiegelZeros/CartanBounds.lean b/PrimeNumberTheoremAnd/SiegelZeros/CartanBounds.lean new file mode 100644 index 0000000..f378d4b --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/CartanBounds.lean @@ -0,0 +1,843 @@ +import Mathlib +import PrimeNumberTheoremAnd.SiegelZeros.Products +import PrimeNumberTheoremAnd.SiegelZeros.Counting + +namespace SiegelZeros + +section +namespace Complex + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℂ F] + +theorem norm_le_of_mem_ball_of_forall_sphere_norm_le {f : ℂ → F} {r C : ℝ} {z : ℂ} + (hd : Differentiable ℂ f) (hrpos : 0 < r) + (hz : z ∈ Metric.ball (0 : ℂ) r) (hsphere : ∀ u : ℂ, ‖u‖ = r → ‖f u‖ ≤ C) : + ‖f z‖ ≤ C := by + let U : Set ℂ := Metric.ball (0 : ℂ) r + have hfront : ∀ u ∈ frontier U, ‖f u‖ ≤ C := by + intro u hu + have hur : ‖u‖ = r := by + have hfront' : frontier (Metric.ball (0 : ℂ) r) = Metric.sphere (0 : ℂ) r := by + simpa using (frontier_ball (x := (0 : ℂ)) (r := r) (ne_of_gt hrpos)) + have : u ∈ Metric.sphere (0 : ℂ) r := by simpa [U, hfront'] using hu + simpa [Metric.mem_sphere, dist_zero_right] using this + exact hsphere u hur + exact _root_.Complex.norm_le_of_forall_mem_frontier_norm_le (f := f) (U := U) Metric.isBounded_ball + hd.diffContOnCl hfront (subset_closure hz) + +end Complex +end +section +namespace Complex +namespace CartanBound + +open _root_.Real _root_.SiegelZeros.Real MeasureTheory intervalIntegral +open scoped Topology ENNReal + +private lemma neg_log_le_sqrt_two_div {x : ℝ} (hx : 0 < x) (hxle : x ≤ 1) : + -Real.log x ≤ Real.sqrt (2 / x) := by + have hx0 : 0 ≤ x := le_of_lt hx + have ht : 0 ≤ -Real.log x := by + have : Real.log x ≤ 0 := Real.log_nonpos hx0 hxle + linarith + have hsq_div_two_le_exp : ∀ {t : ℝ}, 0 ≤ t → t ^ 2 / 2 ≤ Real.exp t := by + intro t ht + let g : ℝ → ℝ := fun u => Real.exp u - u ^ 2 / 2 + have hg_cont : ContinuousOn g (Set.Ici (0 : ℝ)) := by + have : Continuous g := by fun_prop + simpa using this.continuousOn + have hg_diff : DifferentiableOn ℝ g (interior (Set.Ici (0 : ℝ))) := by + intro u hu + have : DifferentiableAt ℝ g u := by fun_prop + exact this.differentiableWithinAt + have hg'_nonneg : ∀ u ∈ interior (Set.Ici (0 : ℝ)), 0 ≤ deriv g u := by + intro u hu + have hu0 : 0 < u := by simpa [interior_Ici] using hu + have hderiv : deriv g u = Real.exp u - u := by + have hExp : HasDerivAt Real.exp (Real.exp u) u := Real.hasDerivAt_exp u + have hpow2 : HasDerivAt (fun z : ℝ => z ^ 2) (2 * u) u := by + simpa using! ((hasDerivAt_id u).pow 2) + have hpow2_div : HasDerivAt (fun z : ℝ => z ^ 2 / 2) u u := by + simpa using (hpow2.div_const (2 : ℝ)) + have hG : HasDerivAt g (Real.exp u - u) u := by + simpa [g] using! hExp.sub hpow2_div + exact hG.deriv + have hu_le : u ≤ Real.exp u := by + have h1 : u + 1 ≤ Real.exp u := Real.add_one_le_exp u + exact (le_trans (le_add_of_nonneg_right (by norm_num)) h1) + have : 0 ≤ Real.exp u - u := sub_nonneg.2 hu_le + simpa [hderiv] using this + have hg_mono : MonotoneOn g (Set.Ici (0 : ℝ)) := + monotoneOn_of_deriv_nonneg (D := Set.Ici (0 : ℝ)) (hD := convex_Ici 0) + hg_cont hg_diff hg'_nonneg + have hg0 : g 0 = 1 := by simp [g] + have hle : g 0 ≤ g t := hg_mono (by simp) (by simpa [Set.mem_Ici] using ht) ht + have : (1 : ℝ) ≤ Real.exp t - t ^ 2 / 2 := by simpa [g, hg0] using hle + linarith + have hmain : (-Real.log x) ^ 2 / 2 ≤ Real.exp (-Real.log x) := hsq_div_two_le_exp ht + have hexp : Real.exp (-Real.log x) = x⁻¹ := by simp [Real.exp_neg, Real.exp_log hx] + have hsq2 : (-Real.log x) ^ 2 ≤ 2 * Real.exp (-Real.log x) := by nlinarith [hmain] + have hsq' : (-Real.log x) ^ 2 ≤ 2 / x := by simpa [hexp, div_eq_mul_inv, mul_assoc] using hsq2 + have hy : 0 ≤ 2 / x := div_nonneg (by norm_num) (le_of_lt hx) + exact (Real.le_sqrt ht hy).2 hsq' + +lemma posLog_log_one_div_abs_one_sub_le_sqrt {t : ℝ} : + Real.posLog (1 / |1 - t|) ≤ Real.sqrt (2 / |1 - t|) := by + by_cases ht : |1 - t| ≤ 1 + · by_cases h0 : |1 - t| = 0 + · have : t = 1 := by + have : 1 - t = 0 := by simpa [abs_eq_zero] using h0 + linarith + subst this + simp + · have hpos : 0 < |1 - t| := lt_of_le_of_ne (abs_nonneg _) (Ne.symm h0) + have hle : -Real.log |1 - t| ≤ Real.sqrt (2 / |1 - t|) := + neg_log_le_sqrt_two_div (x := |1 - t|) hpos ht + have hlog : Real.log (1 / |1 - t|) = -Real.log |1 - t| := by simp [Real.log_inv] + have hnonneg : 0 ≤ Real.log (1 / |1 - t|) := by + exact Real.log_nonneg ((one_le_div hpos).2 ht) + have hmax : Real.posLog (1 / |1 - t|) = Real.log (1 / |1 - t|) := + max_eq_right hnonneg + calc + Real.posLog (1 / |1 - t|) = Real.log (1 / |1 - t|) := hmax + _ = -Real.log |1 - t| := hlog + _ ≤ Real.sqrt (2 / |1 - t|) := hle + · have hlt : 1 < |1 - t| := lt_of_not_ge ht + have hle0 : Real.log (1 / |1 - t|) ≤ 0 := by + have hpos : 0 < |1 - t| := lt_trans (by norm_num) hlt + have : (1 / |1 - t| : ℝ) ≤ 1 := (div_le_one hpos).2 (le_of_lt hlt) + exact le_trans (Real.log_le_log (by positivity) this) (by simp) + have hmax : Real.posLog (1 / |1 - t|) = 0 := max_eq_left hle0 + have hrhs : 0 ≤ Real.sqrt (2 / |1 - t|) := by + exact Real.sqrt_nonneg _ + rw [hmax] + exact hrhs + +noncomputable def φ (t : ℝ) : ℝ := + log⁺ (1 / |1 - t|) + +lemma measurable_phi : Measurable φ := by + unfold φ + simpa [Real.posLog_def, Real.posLog] using + (by fun_prop : Measurable fun t : ℝ => max 0 (Real.log (1 / |1 - t|))) + +lemma phi_le_log_two_of_le_half {t : ℝ} (ht : t ≤ (1 / 2 : ℝ)) : φ t ≤ Real.log 2 := by + have hnonneg : 0 ≤ (1 - t : ℝ) := by linarith + have hden : (1 / 2 : ℝ) ≤ |1 - t| := by + have : (1 / 2 : ℝ) ≤ (1 - t : ℝ) := by linarith + simpa [abs_of_nonneg hnonneg] using this + have hfrac : (1 / |1 - t| : ℝ) ≤ 2 := by + have hhalfpos : (0 : ℝ) < (1 / 2 : ℝ) := by norm_num + have := one_div_le_one_div_of_le hhalfpos hden + simpa [one_div, div_eq_mul_inv] using this + have hposLog : log⁺ (1 / |1 - t|) ≤ log⁺ (2 : ℝ) := + Real.posLog_le_posLog ((by trans (0 : ℝ); norm_num; positivity)) hfrac + have habs : (1 : ℝ) ≤ |(2 : ℝ)| := by + simp + have hposLog2 : (log⁺ (2 : ℝ)) = Real.log 2 := by + simpa using (Real.posLog_eq_log habs) + simpa [φ, hposLog2] using hposLog + +lemma phi_eq_zero_of_one_le_abs_one_sub {t : ℝ} (ht : (1 : ℝ) ≤ |1 - t|) : φ t = 0 := by + have hpos : 0 < |1 - t| := lt_of_lt_of_le (by norm_num) ht + have hfrac : (1 / |1 - t| : ℝ) ≤ 1 := (div_le_one hpos).2 ht + have habs : |(1 / |1 - t| : ℝ)| ≤ 1 := by + have hnonneg : 0 ≤ (1 / |1 - t| : ℝ) := by positivity + simpa [abs_of_nonneg hnonneg] using hfrac + have : log⁺ (1 / |1 - t|) = 0 := (Real.posLog_eq_zero_iff _).2 habs + simpa [φ] using this + +lemma φ_nonneg (t : ℝ) : 0 ≤ φ t := by + simpa [φ] using (Real.posLog_nonneg (x := (1 / |1 - t|))) + +lemma φ_le_sqrt (t : ℝ) : φ t ≤ Real.sqrt (2 / |1 - t|) := by + simpa [φ, Real.posLog] using + posLog_log_one_div_abs_one_sub_le_sqrt (t := t) + +lemma ae_restrict_norm_phi_le_of_forall_mem {A B : ℝ} (hAB : A ≤ B) {g : ℝ → ℝ} + (hg : ∀ t, 0 ≤ g t) (h : ∀ t ∈ Set.Icc A B, φ t ≤ g t) : + (fun t : ℝ => ‖φ t‖) ≤ᶠ[ae (volume.restrict (Set.uIoc A B))] fun t => ‖g t‖ := by + refine + MeasureTheory.ae_restrict_of_forall_mem (μ := (volume : MeasureTheory.Measure ℝ)) + (s := Set.uIoc A B) + (by simpa using (measurableSet_uIoc : MeasurableSet (Set.uIoc A B))) ?_ + intro t ht + have htIoc : t ∈ Set.Ioc A B := by + simpa [Set.uIoc_of_le hAB] using ht + have htIcc : t ∈ Set.Icc A B := ⟨le_of_lt htIoc.1, htIoc.2⟩ + have hle : φ t ≤ g t := h t htIcc + have hφ0 : 0 ≤ φ t := φ_nonneg t + have hg0 : 0 ≤ g t := hg t + simpa [Real.norm_eq_abs, abs_of_nonneg hφ0, abs_of_nonneg hg0] using hle + +lemma log_norm_one_sub_div_ge_neg_phi {u a : ℂ} {r : ℝ} + (hur : ‖u‖ = r) (ha : a ≠ 0) (hr : r ≠ ‖a‖) : + Real.log ‖(1 : ℂ) - u / a‖ ≥ -φ (r / ‖a‖) := by + have ha_norm : 0 < ‖a‖ := norm_pos_iff.2 ha + have hnorm_eq : ‖(1 : ℂ) - u / a‖ = ‖a - u‖ / ‖a‖ := by + have : (1 : ℂ) - u / a = (a - u) / a := by + field_simp [ha] + calc + ‖(1 : ℂ) - u / a‖ = ‖(a - u) / a‖ := by simp [this] + _ = ‖a - u‖ / ‖a‖ := by simp + have hrev : |‖a‖ - ‖u‖| ≤ ‖a - u‖ := by + simpa using (abs_norm_sub_norm_le a u) + have hdiv : |‖a‖ - ‖u‖| / ‖a‖ ≤ ‖a - u‖ / ‖a‖ := + div_le_div_of_nonneg_right hrev (le_of_lt ha_norm) + have habs : |1 - (r / ‖a‖)| = |‖a‖ - ‖u‖| / ‖a‖ := by + have hu : ‖u‖ = r := hur + have ha0 : (‖a‖ : ℝ) ≠ 0 := ha_norm.ne' + have h1 : (1 : ℝ) - (r / ‖a‖) = (‖a‖ - r) / ‖a‖ := by + field_simp [ha0] + calc + |1 - (r / ‖a‖)| = |(‖a‖ - r) / ‖a‖| := by simp [h1] + _ = |‖a‖ - r| / ‖a‖ := by simp [abs_div, abs_of_pos ha_norm] + _ = |‖a‖ - ‖u‖| / ‖a‖ := by simp [hu] + have hnorm_ge : |1 - (r / ‖a‖)| ≤ ‖(1 : ℂ) - u / a‖ := by + have : |1 - (r / ‖a‖)| ≤ ‖a - u‖ / ‖a‖ := by + rw [habs] + exact hdiv + rwa [hnorm_eq] + have hx0 : 0 < |1 - (r / ‖a‖)| := by + have : (1 - (r / ‖a‖) : ℝ) ≠ 0 := by + intro h0 + have : r = ‖a‖ := by + have : r / ‖a‖ = (1 : ℝ) := by linarith + simpa using (div_eq_iff ha_norm.ne').1 this + exact hr this + have : |1 - (r / ‖a‖)| ≠ 0 := by + simpa [abs_eq_zero] using this + exact lt_of_le_of_ne (abs_nonneg _) (Ne.symm this) + have hlogx : + Real.log |1 - (r / ‖a‖)| ≥ -φ (r / ‖a‖) := by + have := Real.neg_posLog_inv_le_log (x := |1 - (r / ‖a‖)|) + simpa [φ, one_div, inv_inv, abs_sub_comm, sub_eq_add_neg] using this + have hlog_mono : + Real.log |1 - (r / ‖a‖)| ≤ Real.log ‖(1 : ℂ) - u / a‖ := + Real.log_le_log (by positivity) hnorm_ge + linarith [hlog_mono, hlogx] + +noncomputable def K : ℝ := + ∫ (t : ℝ) in (1 / 4 : ℝ)..(4 : ℝ), Real.sqrt (2 / |1 - t|) ∂volume + +lemma K_nonneg : 0 ≤ K := by + have hle : (1 / 4 : ℝ) ≤ (4 : ℝ) := by norm_num + have hnn : ∀ t ∈ Set.Icc (1 / 4 : ℝ) (4 : ℝ), 0 ≤ Real.sqrt (2 / |1 - t|) := by + intro _t _ht + exact Real.sqrt_nonneg _ + simpa [K] using (intervalIntegral.integral_nonneg + (μ := (volume : MeasureTheory.Measure ℝ)) hle hnn) + +noncomputable def Cφ : ℝ := + Real.log 2 + 4 * K + 1 + +lemma Cφ_pos : 0 < Cφ := by + have hlog : 0 < Real.log 2 := by + simpa using Real.log_pos (by norm_num : (1 : ℝ) < 2) + have hK : 0 ≤ K := K_nonneg + have : 0 < Real.log 2 + 4 * K := by nlinarith + have : 0 < Real.log 2 + 4 * K + 1 := by linarith + simpa [Cφ] using this + +lemma intervalIntegrable_sqrt_two_div_abs_one_sub_Icc : + IntervalIntegrable + (fun t : ℝ => Real.sqrt (2 / |1 - t|)) + volume (1 / 4 : ℝ) (4 : ℝ) := by + let f : ℝ → ℝ := fun u => Real.sqrt (2 / |u|) + have hf0 : IntervalIntegrable f volume (0 : ℝ) (3 : ℝ) := by + have hpow : + IntervalIntegrable (fun u : ℝ => u ^ (- (2⁻¹ : ℝ))) volume (0 : ℝ) (3 : ℝ) := by + simpa using + (intervalIntegral.intervalIntegrable_rpow' (a := (0 : ℝ)) (b := (3 : ℝ)) + (r := (- (2⁻¹ : ℝ))) (by linarith : (-1 : ℝ) < - (2⁻¹ : ℝ))) + have hpow2 : + IntervalIntegrable (fun u : ℝ => Real.sqrt 2 * u ^ (- (2⁻¹ : ℝ))) volume (0 : ℝ) (3 : ℝ) := + hpow.const_mul (Real.sqrt 2) + have hEq : + Set.EqOn f (fun u : ℝ => Real.sqrt 2 * u ^ (- (2⁻¹ : ℝ))) (Set.uIoc (0 : ℝ) (3 : ℝ)) := by + intro u hu + have hu' : u ∈ Set.Ioc (0 : ℝ) (3 : ℝ) := by + simpa [Set.uIoc_of_le (show (0 : ℝ) ≤ 3 by norm_num)] using hu + have hu0 : 0 < u := hu'.1 + have hu0' : 0 ≤ u := le_of_lt hu0 + have habs : |u| = u := abs_of_nonneg hu0' + have : f u = Real.sqrt (2 / u) := by simp [f, habs] + calc + f u = Real.sqrt (2 / u) := this + _ = Real.sqrt 2 / Real.sqrt u := by simp + _ = Real.sqrt 2 * (Real.sqrt u)⁻¹ := by simp [div_eq_mul_inv] + _ = Real.sqrt 2 * (u ^ (2⁻¹ : ℝ))⁻¹ := by simp [Real.sqrt_eq_rpow] + _ = Real.sqrt 2 * u ^ (- (2⁻¹ : ℝ)) := by + have h : (u ^ (2⁻¹ : ℝ))⁻¹ = u ^ (- (2⁻¹ : ℝ)) := by + simpa using (Real.rpow_neg hu0' (2⁻¹ : ℝ)).symm + simp [h] + exact + (IntervalIntegrable.congr (a := (0 : ℝ)) (b := (3 : ℝ)) + (μ := (volume : MeasureTheory.Measure ℝ)) + (f := fun u : ℝ => Real.sqrt 2 * u ^ (- (2⁻¹ : ℝ))) (g := f) hEq.symm) + hpow2 + have hf0' : IntervalIntegrable f volume (0 : ℝ) (3 / 4 : ℝ) := + hf0.mono_set (by + intro u hu + have hsub : Set.uIcc (0 : ℝ) (3 / 4 : ℝ) ⊆ Set.uIcc (0 : ℝ) (3 : ℝ) := by + refine Set.uIcc_subset_uIcc ?_ ?_ + · simp + · have h0 : (0 : ℝ) ≤ (3 / 4 : ℝ) := by nlinarith + have h1 : (3 / 4 : ℝ) ≤ (3 : ℝ) := by nlinarith + exact (Set.mem_uIcc).2 (Or.inl ⟨h0, h1⟩) + exact hsub hu) + have hleft : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) volume (1 / 4 : ℝ) (1 : ℝ) := by + have htmp : + IntervalIntegrable (fun t : ℝ => f (1 - t)) volume (1 : ℝ) ((1 : ℝ) - (3 / 4 : ℝ)) := by + simpa using (hf0'.comp_sub_left (c := (1 : ℝ))) + have htmp' : + IntervalIntegrable (fun t : ℝ => f (1 - t)) volume ((1 : ℝ) - (3 / 4 : ℝ)) (1 : ℝ) := + htmp.symm + have hsub : ((1 : ℝ) - (3 / 4 : ℝ)) = (1 / 4 : ℝ) := by norm_num + have htmp'' : IntervalIntegrable (fun t : ℝ => f (1 - t)) volume (1 / 4 : ℝ) (1 : ℝ) := by + simpa [hsub] using htmp' + simpa [f] using htmp'' + have hright : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) volume (1 : ℝ) (4 : ℝ) := by + have htmp : + IntervalIntegrable (fun t : ℝ => f (t - 1)) volume (1 : ℝ) ((3 : ℝ) + (1 : ℝ)) := by + simpa using (hf0.comp_sub_right (c := (1 : ℝ))) + have hsub : ((3 : ℝ) + (1 : ℝ)) = (4 : ℝ) := by norm_num + have htmp' : IntervalIntegrable (fun t : ℝ => f (t - 1)) volume (1 : ℝ) (4 : ℝ) := by + simpa [hsub] using htmp + have hcongr : + Set.EqOn (fun t : ℝ => f (t - 1)) (fun t : ℝ => Real.sqrt (2 / |1 - t|)) + (Set.uIoc (1 : ℝ) (4 : ℝ)) := by + intro t _ht + simp [f, abs_sub_comm] + exact + (IntervalIntegrable.congr (a := (1 : ℝ)) (b := (4 : ℝ)) + (μ := (volume : MeasureTheory.Measure ℝ)) + (f := fun t : ℝ => f (t - 1)) (g := fun t : ℝ => Real.sqrt (2 / |1 - t|)) hcongr) + htmp' + exact hleft.trans hright + +lemma phi_le_log_two_on_dyadic_of_le_quarter {A t : ℝ} (hA : A ≤ (1 / 4 : ℝ)) + (ht : t ∈ Set.Icc A (2 * A)) : + φ t ≤ Real.log 2 := by + have ht_le : t ≤ (1 / 2 : ℝ) := by + exact ht.2.trans (by nlinarith [hA]) + exact phi_le_log_two_of_le_half ht_le + +lemma phi_eq_zero_of_two_le {t : ℝ} (ht : (2 : ℝ) ≤ t) : φ t = 0 := by + have hden : (1 : ℝ) ≤ |1 - t| := by + have : (1 : ℝ) ≤ t - 1 := by linarith + have : (1 : ℝ) ≤ |t - 1| := by + simpa [abs_of_nonneg (by linarith : 0 ≤ t - 1)] using this + simpa [abs_sub_comm] using this + exact phi_eq_zero_of_one_le_abs_one_sub hden + +lemma intervalIntegrable_phi_dyadic_small {A : ℝ} (hA0 : 0 ≤ A) + (hA : A ≤ (1 / 4 : ℝ)) : + IntervalIntegrable φ volume A (2 * A) := by + have hA_le : A ≤ 2 * A := by nlinarith + have hconst : IntervalIntegrable (fun _ : ℝ => (Real.log 2 : ℝ)) volume A (2 * A) := + intervalIntegrable_const + have hmeas : + AEStronglyMeasurable (fun t : ℝ => φ t) (volume.restrict (Set.uIoc A (2 * A))) := + (measurable_phi.aestronglyMeasurable : _) + have hdom : + (fun t : ℝ => ‖φ t‖) ≤ᶠ[ae (volume.restrict (Set.uIoc A (2 * A)))] + fun _ => ‖(Real.log 2 : ℝ)‖ := by + refine ae_restrict_norm_phi_le_of_forall_mem (A := A) (B := 2 * A) hA_le + (g := fun _ => (Real.log 2 : ℝ)) (hg := fun _ => ?_) ?_ + · simpa using (Real.log_nonneg (by norm_num : (1 : ℝ) ≤ 2)) + · intro t ht + exact phi_le_log_two_on_dyadic_of_le_quarter hA ht + exact IntervalIntegrable.mono_fun hconst hmeas hdom + +lemma intervalIntegrable_phi_dyadic_large {A : ℝ} (hA : (2 : ℝ) ≤ A) : + IntervalIntegrable φ volume A (2 * A) := by + have hA_le : A ≤ 2 * A := by nlinarith + have hEq : Set.EqOn (fun t : ℝ => φ t) (fun _ => (0 : ℝ)) (Set.uIoc A (2 * A)) := by + intro t ht + have htIoc : t ∈ Set.Ioc A (2 * A) := by + simpa [Set.uIoc_of_le hA_le] using ht + exact phi_eq_zero_of_two_le (le_trans hA (le_of_lt htIoc.1)) + have hz : IntervalIntegrable (fun _ : ℝ => (0 : ℝ)) volume A (2 * A) := + intervalIntegrable_const + exact (IntervalIntegrable.congr (a := A) (b := (2 * A)) + (μ := (volume : MeasureTheory.Measure ℝ)) + (f := fun _ => (0 : ℝ)) (g := fun t => φ t) (by + intro t ht + simpa using (hEq (x := t) ht).symm)) hz + +lemma intervalIntegrable_sqrt_two_div_abs_one_sub_dyadic_middle {A : ℝ} + (hA_lower : (1 / 4 : ℝ) ≤ A) (hA_upper : A ≤ (2 : ℝ)) : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) volume A (2 * A) := by + have hsqrt_big : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) + (volume : MeasureTheory.Measure ℝ) (1 / 4 : ℝ) (4 : ℝ) := + intervalIntegrable_sqrt_two_div_abs_one_sub_Icc + refine hsqrt_big.mono_set ?_ + refine Set.uIcc_subset_uIcc ?_ ?_ + · exact (Set.mem_uIcc).2 (Or.inl ⟨hA_lower, by nlinarith [hA_upper]⟩) + · exact (Set.mem_uIcc).2 (Or.inl ⟨by nlinarith [hA_lower], by nlinarith [hA_upper]⟩) + +lemma intervalIntegrable_phi_dyadic_middle {A : ℝ} + (hA_lower : (1 / 4 : ℝ) ≤ A) (hA_upper : A ≤ (2 : ℝ)) : + IntervalIntegrable φ volume A (2 * A) := by + have hA_le : A ≤ 2 * A := by nlinarith [hA_lower] + have hsqrt : + IntervalIntegrable (fun t : ℝ => Real.sqrt (2 / |1 - t|)) volume A (2 * A) := + intervalIntegrable_sqrt_two_div_abs_one_sub_dyadic_middle hA_lower hA_upper + have hmeas : + AEStronglyMeasurable (fun t : ℝ => φ t) (volume.restrict (Set.uIoc A (2 * A))) := + (measurable_phi.aestronglyMeasurable : _) + have hdom : + (fun t : ℝ => ‖φ t‖) ≤ᶠ[ae (volume.restrict (Set.uIoc A (2 * A)))] + fun t => ‖Real.sqrt (2 / |1 - t|)‖ := by + refine ae_restrict_norm_phi_le_of_forall_mem (A := A) (B := 2 * A) hA_le + (g := fun t => Real.sqrt (2 / |1 - t|)) (hg := fun _ => Real.sqrt_nonneg _) ?_ + intro t _ht + exact φ_le_sqrt t + exact IntervalIntegrable.mono_fun hsqrt hmeas hdom + +lemma intervalIntegrable_phi_dyadic {A : ℝ} (hA : 0 ≤ A) : + IntervalIntegrable φ volume A (2 * A) := by + by_cases hA0 : A = 0 + · subst hA0 + simp + cases le_total A (1 / 4 : ℝ) with + | inl hsmall => + exact intervalIntegrable_phi_dyadic_small hA hsmall + | inr hge_quarter => + cases le_total (2 : ℝ) A with + | inl hbig => + exact intervalIntegrable_phi_dyadic_large hbig + | inr hA_le_two => + exact intervalIntegrable_phi_dyadic_middle hge_quarter hA_le_two + +lemma intervalIntegrable_phi_div {a R : ℝ} (ha : 0 < a) (hR : 0 ≤ R) : + IntervalIntegrable (fun r : ℝ => φ (r / a)) volume R (2 * R) := by + have ha0 : a ≠ 0 := ne_of_gt ha + have hRa_nonneg : 0 ≤ R / a := by + exact div_nonneg hR (le_of_lt ha) + have hφ : IntervalIntegrable φ volume (R / a) (2 * (R / a)) := + intervalIntegrable_phi_dyadic (A := (R / a)) hRa_nonneg + have := (hφ.comp_mul_right (c := (a⁻¹ : ℝ))) + have hupper : a * (R * (a⁻¹ * 2)) = (2 * R) := by + field_simp [ha0] + simpa [div_eq_mul_inv, ha0, hupper, mul_assoc, mul_left_comm, mul_comm] using this + +lemma log_two_le_Cφ : Real.log 2 ≤ Cφ := by + dsimp [Cφ] + have hK : 0 ≤ K := K_nonneg + linarith [hK] + +lemma four_mul_K_add_one_le_Cφ : (4 * K + 1 : ℝ) ≤ Cφ := by + dsimp [Cφ] + have hlog_nonneg : 0 ≤ Real.log 2 := Real.log_nonneg (by norm_num) + linarith [hlog_nonneg] + +lemma integral_phi_le_Cφ_mul_small {A : ℝ} (hA0 : 0 ≤ A) (hA : A ≤ (1 / 4 : ℝ)) : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) ≤ Cφ * A := by + have hA_le : A ≤ 2 * A := by nlinarith + have hφ_int : IntervalIntegrable φ volume A (2 * A) := + intervalIntegrable_phi_dyadic_small hA0 hA + have hconst : IntervalIntegrable (fun _ : ℝ => (Real.log 2 : ℝ)) volume A (2 * A) := + intervalIntegrable_const + have hle_int : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) + ≤ ∫ (t : ℝ) in A..(2 * A), (Real.log 2 : ℝ) ∂volume := by + refine intervalIntegral.integral_mono_on (μ := (volume : MeasureTheory.Measure ℝ)) + hA_le hφ_int hconst ?_ + intro t ht + exact phi_le_log_two_on_dyadic_of_le_quarter hA ht + have hRHS : + (∫ (t : ℝ) in A..(2 * A), (Real.log 2 : ℝ) ∂volume) = A * Real.log 2 := by + simp [intervalIntegral.integral_const, sub_eq_add_neg, add_assoc, two_mul] + have hcoef : A * Real.log 2 ≤ Cφ * A := by + have := mul_le_mul_of_nonneg_left log_two_le_Cφ hA0 + simpa [mul_assoc, mul_left_comm, mul_comm] using this + exact le_trans (by simpa [hRHS] using hle_int) hcoef + +lemma integral_phi_le_Cφ_mul_large {A : ℝ} (hA : (2 : ℝ) ≤ A) : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) ≤ Cφ * A := by + have hA_le : A ≤ 2 * A := by nlinarith + have hφ0 : Set.EqOn (fun t : ℝ => φ t) (fun _ => (0 : ℝ)) (Set.uIcc A (2 * A)) := by + intro t ht + have ht' : t ∈ Set.Icc A (2 * A) := by + simpa [Set.uIcc_of_le hA_le] using ht + exact phi_eq_zero_of_two_le (le_trans hA ht'.1) + have hzero : (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) = 0 := by + simpa using intervalIntegral.integral_congr (μ := (volume : MeasureTheory.Measure ℝ)) hφ0 + have hnonneg : (0 : ℝ) ≤ Cφ * A := mul_nonneg (le_of_lt Cφ_pos) (by linarith) + simpa [hzero] using hnonneg + +lemma integral_sqrt_two_div_abs_one_sub_le_K_dyadic_middle {A : ℝ} + (hA_lower : (1 / 4 : ℝ) ≤ A) (hA_upper : A ≤ (2 : ℝ)) : + (∫ (t : ℝ) in A..(2 * A), Real.sqrt (2 / |1 - t|) ∂volume) ≤ K := by + let s (t : ℝ) : ℝ := Real.sqrt (2 / |1 - t|) + have hA_le : A ≤ 2 * A := by nlinarith [hA_lower] + have hA_upper' : (2 * A : ℝ) ≤ 4 := by nlinarith [hA_upper] + have hsqrt_big : IntervalIntegrable s volume (1 / 4 : ℝ) (4 : ℝ) := by + simpa [s] using intervalIntegrable_sqrt_two_div_abs_one_sub_Icc + have hle_K : + (∫ (t : ℝ) in A..(2 * A), s t ∂volume) + ≤ ∫ (t : ℝ) in (1 / 4 : ℝ)..(4 : ℝ), s t ∂volume := by + refine intervalIntegral.integral_mono_interval (μ := (volume : MeasureTheory.Measure ℝ)) + (c := (1 / 4 : ℝ)) (d := (4 : ℝ)) (a := A) (b := (2 * A)) + hA_lower hA_le hA_upper' ?_ hsqrt_big + exact Filter.Eventually.of_forall (fun _t => Real.sqrt_nonneg _) + simpa [K, s] using hle_K + +lemma K_le_four_mul_K_add_one_mul_of_quarter_le {A : ℝ} (hA : (1 / 4 : ℝ) ≤ A) : + K ≤ (4 * K + 1) * A := by + have hcoef : 1 ≤ 4 * A := by nlinarith [hA] + have hK : 0 ≤ K := K_nonneg + nlinarith [hK, hcoef] + +lemma integral_phi_le_Cφ_mul_middle {A : ℝ} + (hA_lower : (1 / 4 : ℝ) ≤ A) (hA_upper : A ≤ (2 : ℝ)) : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) ≤ Cφ * A := by + let s (t : ℝ) : ℝ := Real.sqrt (2 / |1 - t|) + have hA_le : A ≤ 2 * A := by nlinarith [hA_lower] + have hφ_int : IntervalIntegrable φ volume A (2 * A) := + intervalIntegrable_phi_dyadic_middle hA_lower hA_upper + have hsqrt : IntervalIntegrable s volume A (2 * A) := by + simpa [s] using + intervalIntegrable_sqrt_two_div_abs_one_sub_dyadic_middle hA_lower hA_upper + have hle_int : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) + ≤ ∫ (t : ℝ) in A..(2 * A), s t ∂volume := by + refine intervalIntegral.integral_mono_on + (μ := (volume : MeasureTheory.Measure ℝ)) hA_le hφ_int hsqrt ?_ + intro t _ht + exact φ_le_sqrt t + have hsqrt_le : (∫ (t : ℝ) in A..(2 * A), s t ∂volume) ≤ (4 * K + 1) * A := by + have hK : (∫ (t : ℝ) in A..(2 * A), s t ∂volume) ≤ K := by + simpa [s] using integral_sqrt_two_div_abs_one_sub_le_K_dyadic_middle hA_lower hA_upper + exact le_trans hK (K_le_four_mul_K_add_one_mul_of_quarter_le hA_lower) + have hcoef : (4 * K + 1 : ℝ) * A ≤ Cφ * A := + mul_le_mul_of_nonneg_right four_mul_K_add_one_le_Cφ (by nlinarith [hA_lower]) + exact le_trans hle_int (le_trans hsqrt_le hcoef) + +lemma integral_phi_le_Cφ_mul {A : ℝ} (hA : 0 ≤ A) : + (∫ (t : ℝ) in A..(2 * A), φ t ∂volume) ≤ Cφ * A := by + by_cases hA0 : A = 0 + · subst hA0 + simp [Cφ, φ, K] + cases le_total A (1 / 4 : ℝ) with + | inl hsmall => + exact integral_phi_le_Cφ_mul_small hA hsmall + | inr hge_quarter => + cases le_total (2 : ℝ) A with + | inl hbig => + exact integral_phi_le_Cφ_mul_large hbig + | inr hA_le_two => + exact integral_phi_le_Cφ_mul_middle hge_quarter hA_le_two + +open scoped BigOperators + +lemma volume_Ioc_two_mul_ne_zero {R : ℝ} (hR : 0 < R) : + (volume : MeasureTheory.Measure ℝ) (Set.Ioc R (2 * R)) ≠ 0 := by + have hpos : (0 : ℝ) < 2 * R - R := by nlinarith [hR] + simp [Real.volume_Ioc, ENNReal.ofReal_eq_zero, not_le_of_gt hpos] + +lemma volume_Ioc_two_mul_diff_finset_ne_zero (bad : Finset ℝ) {R : ℝ} (hR : 0 < R) : + (volume : MeasureTheory.Measure ℝ) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) ≠ 0 := by + have hbad_meas : (volume : MeasureTheory.Measure ℝ) (bad : Set ℝ) = 0 := by + simpa using (bad.measure_zero (μ := (volume : MeasureTheory.Measure ℝ))) + have hdiff : + (volume : MeasureTheory.Measure ℝ) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) + = (volume : MeasureTheory.Measure ℝ) (Set.Ioc R (2 * R)) := by + simpa [Set.sdiff_eq, Set.inter_assoc, Set.inter_left_comm, Set.inter_comm] using + (MeasureTheory.measure_sdiff_null (s := Set.Ioc R (2 * R)) (t := (bad : Set ℝ)) + hbad_meas) + simpa [hdiff] using volume_Ioc_two_mul_ne_zero hR + +lemma restrict_volume_Ioc_two_mul_diff_finset_ne_zero (bad : Finset ℝ) {R : ℝ} (hR : 0 < R) : + (volume.restrict (Set.Ioc R (2 * R))) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) ≠ 0 := by + have hsubset : Set.Ioc R (2 * R) \ (bad : Set ℝ) ⊆ Set.Ioc R (2 * R) := by + intro r hr + exact hr.1 + have hinter : + (Set.Ioc R (2 * R) \ (bad : Set ℝ)) ∩ Set.Ioc R (2 * R) + = (Set.Ioc R (2 * R) \ (bad : Set ℝ)) := by + exact Set.inter_eq_left.mpr hsubset + simpa [MeasureTheory.Measure.restrict_apply, measurableSet_Ioc, hinter] using + volume_Ioc_two_mul_diff_finset_ne_zero bad hR + +lemma integral_phi_div_le_Cφ_mul {a R : ℝ} (ha : 0 < a) (hR : 0 ≤ R) : + (∫ (r : ℝ) in R..(2 * R), φ (r / a) ∂volume) ≤ Cφ * R := by + have ha0 : a ≠ 0 := ne_of_gt ha + have hrew : + (∫ (r : ℝ) in R..(2 * R), φ (r / a) ∂volume) + = a * (∫ (t : ℝ) in (R / a)..(2 * R / a), φ t ∂volume) := by + simp [smul_eq_mul, mul_left_comm, mul_comm, div_eq_mul_inv, ha0] + rw [hrew] + have hA : 0 ≤ R / a := by + exact div_nonneg hR ha.le + have hle : (∫ (t : ℝ) in (R / a)..(2 * (R / a)), φ t ∂volume) ≤ Cφ * (R / a) := + integral_phi_le_Cφ_mul (A := R / a) hA + have hEq : (2 * R / a) = 2 * (R / a) := by ring + have hle' : + (∫ (t : ℝ) in (R / a)..(2 * R / a), φ t ∂volume) ≤ Cφ * (R / a) := by + simpa [hEq] using hle + have ha_nonneg : 0 ≤ a := ha.le + have := mul_le_mul_of_nonneg_left hle' ha_nonneg + have hRHS : a * (Cφ * (R / a)) = Cφ * R := by + field_simp [ha0] + simpa [hRHS, mul_assoc, mul_left_comm, mul_comm] using this + +lemma intervalIntegrable_sum_mul_phi_div + {ι : Type} (s : Finset ι) (w : ι → ℝ) (a : ι → ℝ) + (ha : ∀ i ∈ s, 0 < a i) {R : ℝ} (hR : 0 ≤ R) : + IntervalIntegrable (∑ i ∈ s, fun r : ℝ => w i * φ (r / a i)) + volume R (2 * R) := by + refine IntervalIntegrable.sum (μ := volume) (a := R) (b := 2 * R) + (s := s) (f := fun i : ι => fun r : ℝ => w i * φ (r / a i)) ?_ + intro i hi + have hφi : IntervalIntegrable (fun r : ℝ => φ (r / a i)) volume R (2 * R) := + intervalIntegrable_phi_div (a := a i) (R := R) (ha i hi) hR + simpa [mul_assoc] using hφi.const_mul (w i) + +lemma integral_sum_mul_phi_div_le_Cφ_mul_sum + {ι : Type} (s : Finset ι) (w : ι → ℝ) (a : ι → ℝ) + (hw : ∀ i ∈ s, 0 ≤ w i) (ha : ∀ i ∈ s, 0 < a i) {R : ℝ} (hR : 0 ≤ R) : + (∫ r in R..(2 * R), (∑ i ∈ s, fun r : ℝ => w i * φ (r / a i)) r ∂volume) + ≤ Cφ * (∑ i ∈ s, w i) * R := by + have hint : ∀ i ∈ s, IntervalIntegrable (fun r : ℝ => w i * φ (r / a i)) + volume R (2 * R) := by + intro i hi + have hφi : IntervalIntegrable (fun r : ℝ => φ (r / a i)) volume R (2 * R) := + intervalIntegrable_phi_div (a := a i) (R := R) (ha i hi) hR + simpa [mul_assoc] using hφi.const_mul (w i) + have hsum_int : + (∫ r in R..(2 * R), (∑ i ∈ s, fun r : ℝ => w i * φ (r / a i)) r ∂volume) + = ∑ i ∈ s, ∫ r in R..(2 * R), (fun r : ℝ => w i * φ (r / a i)) r + ∂volume := by + simpa using + (intervalIntegral.integral_finsetSum (μ := volume) (a := R) (b := 2 * R) + (s := s) (f := fun i : ι => fun r : ℝ => w i * φ (r / a i)) hint) + rw [hsum_int] + have hsum_le : + (∑ i ∈ s, ∫ r in R..(2 * R), (fun r : ℝ => w i * φ (r / a i)) r ∂volume) + ≤ ∑ i ∈ s, w i * (Cφ * R) := by + refine Finset.sum_le_sum ?_ + intro i hi + have hphi : + (∫ r in R..(2 * R), φ (r / a i) ∂volume) ≤ Cφ * R := + integral_phi_div_le_Cφ_mul (a := a i) (R := R) (ha i hi) hR + have := mul_le_mul_of_nonneg_left hphi (hw i hi) + simpa [mul_assoc, mul_left_comm, mul_comm] using this + refine le_trans hsum_le ?_ + have : (∑ i ∈ s, w i * (Cφ * R)) = Cφ * (∑ i ∈ s, w i) * R := by + calc + (∑ i ∈ s, w i * (Cφ * R)) = (∑ i ∈ s, w i) * (Cφ * R) := by + simp [Finset.sum_mul] + _ = Cφ * (∑ i ∈ s, w i) * R := by + ac_rfl + exact le_of_eq this + +lemma exists_radius_Ioc_sum_mul_phi_div_le_Cφ_mul_sum_avoid + {ι : Type} (s : Finset ι) (w : ι → ℝ) (a : ι → ℝ) + (hw : ∀ i ∈ s, 0 ≤ w i) (ha : ∀ i ∈ s, 0 < a i) + (bad : Finset ℝ) {R : ℝ} (hR : 0 < R) : + ∃ r ∈ Set.Ioc R (2 * R), r ∉ bad ∧ + (∑ i ∈ s, w i * φ (r / a i)) ≤ Cφ * (∑ i ∈ s, w i) := by + by_contra hbad + have hforall : + ∀ r ∈ Set.Ioc R (2 * R), r ∉ bad → + Cφ * (∑ i ∈ s, w i) < (∑ i ∈ s, w i * φ (r / a i)) := by + intro r hr hrbad + have : ¬(∑ i ∈ s, w i * φ (r / a i)) ≤ Cφ * (∑ i ∈ s, w i) := by + intro hle + exact hbad ⟨r, hr, hrbad, hle⟩ + exact lt_of_not_ge this + let g : ℝ → ℝ := ∑ i ∈ s, fun r : ℝ => w i * φ (r / a i) + have hg_int : IntervalIntegrable g volume R (2 * R) := by + simpa [g] using intervalIntegrable_sum_mul_phi_div s w a ha hR.le + have hconst_int : + IntervalIntegrable (fun _r : ℝ => Cφ * (∑ i ∈ s, w i)) volume R (2 * R) := + intervalIntegrable_const + have hlt_meas : + (volume.restrict (Set.Ioc R (2 * R))) + {r | Cφ * (∑ i ∈ s, w i) < g r} ≠ 0 := by + have hall : Set.Ioc R (2 * R) \ (bad : Set ℝ) ⊆ {r | Cφ * (∑ i ∈ s, w i) < g r} := by + intro r hr + have hrIoc : r ∈ Set.Ioc R (2 * R) := hr.1 + have hrbad : r ∉ bad := by simpa using hr.2 + simpa [g] using hforall r hrIoc hrbad + have hle : + (volume.restrict (Set.Ioc R (2 * R))) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) + ≤ (volume.restrict (Set.Ioc R (2 * R))) {r | Cφ * (∑ i ∈ s, w i) < g r} := + MeasureTheory.measure_mono hall + have hpos' : + (volume.restrict (Set.Ioc R (2 * R))) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) ≠ 0 := by + exact restrict_volume_Ioc_two_mul_diff_finset_ne_zero bad hR + intro hzero + have : (volume.restrict (Set.Ioc R (2 * R))) (Set.Ioc R (2 * R) \ (bad : Set ℝ)) = 0 := + le_antisymm (le_trans hle (le_of_eq hzero)) (by positivity) + exact hpos' this + have hlt_int : + (∫ r in R..(2 * R), (Cφ * (∑ i ∈ s, w i)) ∂volume) + < ∫ r in R..(2 * R), g r ∂volume := by + have hab : R ≤ 2 * R := by nlinarith [hR.le] + refine intervalIntegral.integral_lt_integral_of_ae_le_of_measure_setOfPred_lt_ne_zero (μ := volume) + (a := R) (b := 2 * R) (f := fun _ => (Cφ * (∑ i ∈ s, w i))) (g := g) + hab hconst_int hg_int ?_ hlt_meas + have hmem : ∀ᵐ r ∂ (volume.restrict (Set.Ioc R (2 * R))), r ∈ Set.Ioc R (2 * R) := + MeasureTheory.ae_restrict_mem (by simp) + have hnotBad : + ∀ᵐ r ∂ (volume.restrict (Set.Ioc R (2 * R))), r ∉ (bad : Set ℝ) := by + simpa using + (bad.finite_toSet.countable.ae_notMem (μ := (volume.restrict (Set.Ioc R (2 * R))))) + filter_upwards [hmem, hnotBad] with r hrIoc hrNotBad + have hrNotBad' : r ∉ bad := by simpa using hrNotBad + exact le_of_lt (by simpa [g] using hforall r hrIoc hrNotBad') + have hconst_eval : + (∫ r in R..(2 * R), (Cφ * (∑ i ∈ s, w i)) ∂volume) = Cφ * (∑ i ∈ s, w i) * R := by + simp [intervalIntegral.integral_const, sub_eq_add_neg, mul_comm] + ring + have hg_le : + (∫ r in R..(2 * R), g r ∂volume) ≤ Cφ * (∑ i ∈ s, w i) * R := by + simpa [g] using integral_sum_mul_phi_div_le_Cφ_mul_sum s w a hw ha hR.le + have : ¬(Cφ * (∑ i ∈ s, w i) * R < Cφ * (∑ i ∈ s, w i) * R) := lt_irrefl _ + have hcontra : Cφ * (∑ i ∈ s, w i) * R < Cφ * (∑ i ∈ s, w i) * R := by + have := hlt_int + simpa [hconst_eval] using (this.trans_le hg_le) + exact this hcontra + +end CartanBound +end Complex +end +section +noncomputable section + +namespace Complex.Hadamard + +open _root_.SiegelZeros.Complex _root_.Real _root_.SiegelZeros.Real + +lemma max_one_norm_div_pow_le_one_add_rpow + {m : ℕ} {τ r : ℝ} {u a : ℂ} + (hur : ‖u‖ = r) + (hmτ : (m : ℝ) ≤ τ) : + max 1 (‖u / a‖ ^ m) ≤ 1 + (r / ‖a‖) ^ τ := by + by_cases hx : ‖u / a‖ ≤ 1 + · have hpowm_le1 : ‖u / a‖ ^ m ≤ 1 := pow_le_one₀ (norm_nonneg (u / a)) hx + have hr0 : 0 ≤ r := by simpa [hur] using (norm_nonneg u) + have hbase : 0 ≤ r / ‖a‖ := div_nonneg hr0 (norm_nonneg a) + have hnonneg : 0 ≤ (r / ‖a‖) ^ τ := Real.rpow_nonneg hbase τ + have hle1 : (1 : ℝ) ≤ 1 + (r / ‖a‖) ^ τ := le_add_of_nonneg_right hnonneg + have hle2 : ‖u / a‖ ^ m ≤ 1 + (r / ‖a‖) ^ τ := hpowm_le1.trans hle1 + exact (max_le_iff).2 ⟨hle1, hle2⟩ + · have hx1 : 1 < ‖u / a‖ := lt_of_not_ge hx + have hpow : + (‖u / a‖ : ℝ) ^ (m : ℝ) ≤ (‖u / a‖ : ℝ) ^ τ := + Real.rpow_le_rpow_of_exponent_le (le_of_lt hx1) hmτ + have hpow' : ‖u / a‖ ^ m ≤ (‖u / a‖ : ℝ) ^ τ := by + simpa [Real.rpow_natCast] using hpow + have hmax_add : max 1 (‖u / a‖ ^ m) ≤ 1 + ‖u / a‖ ^ m := by + refine max_le (le_add_of_nonneg_right (by positivity)) (le_add_of_nonneg_left (by positivity)) + have : max 1 (‖u / a‖ ^ m) ≤ 1 + (‖u / a‖ : ℝ) ^ τ := + hmax_add.trans (by nlinarith [hpow']) + simpa [norm_div, hur] using this + +lemma norm_inv_weierstrassFactor_le_exp_near + {m : ℕ} {τ r : ℝ} {u a : ℂ} + (hur : ‖u‖ = r) (ha : a ≠ 0) (hr : r ≠ ‖a‖) + (hmτ : (m : ℝ) ≤ τ) : + ‖(weierstrassFactor m (u / a))⁻¹‖ + ≤ Real.exp (CartanBound.φ (r / ‖a‖) + (m : ℝ) * (1 + (r / ‖a‖) ^ τ)) := by + have hlog_one : + Real.log ‖(1 : ℂ) - u / a‖ ≥ -CartanBound.φ (r / ‖a‖) := + CartanBound.log_norm_one_sub_div_ge_neg_phi (hur := hur) (ha := ha) (hr := hr) + have hbase := + log_norm_weierstrassFactor_ge_log_norm_one_sub_sub (m := m) (z := (u / a)) + have hlogE : + Real.log ‖weierstrassFactor m (u / a)‖ + ≥ -CartanBound.φ (r / ‖a‖) - (m : ℝ) * max 1 (‖u / a‖ ^ m) := by + have hpls := + norm_partialLogSum_le_nat_mul_max_one_norm_pow m (u / a) + linarith [hbase, hlog_one, hpls] + have hmax : + max 1 (‖u / a‖ ^ m) ≤ 1 + (r / ‖a‖) ^ τ := + max_one_norm_div_pow_le_one_add_rpow (m := m) (τ := τ) (r := r) (u := u) (a := a) hur hmτ + have hneglog : + -Real.log ‖weierstrassFactor m (u / a)‖ + ≤ CartanBound.φ (r / ‖a‖) + (m : ℝ) * (1 + (r / ‖a‖) ^ τ) := by + have : -Real.log ‖weierstrassFactor m (u / a)‖ + ≤ CartanBound.φ (r / ‖a‖) + (m : ℝ) * max 1 (‖u / a‖ ^ m) := by + linarith [hlogE] + have hm0 : 0 ≤ (m : ℝ) := by exact_mod_cast (Nat.zero_le m) + exact this.trans (by nlinarith [mul_le_mul_of_nonneg_left hmax hm0]) + have hpos : 0 < ‖weierstrassFactor m (u / a)‖ := by + have : weierstrassFactor m (u / a) ≠ 0 := by + intro h0 + have : u / a = (1 : ℂ) := (weierstrassFactor_eq_zero_iff m (u / a)).1 h0 + have : u = a := (div_eq_one_iff_eq ha).1 this + have : r = ‖a‖ := by simpa [this] using hur.symm + exact (hr this).elim + exact norm_pos_iff.2 this + have hEq : + ‖(weierstrassFactor m (u / a))⁻¹‖ = + Real.exp (-Real.log ‖weierstrassFactor m (u / a)‖) := by + simp [norm_inv, Real.exp_neg, Real.exp_log hpos] + have := Real.exp_le_exp.2 hneglog + simpa [hEq] using this + +lemma norm_inv_weierstrassFactor_le_exp_far + {m : ℕ} {τ r : ℝ} {u a : ℂ} + (hur : ‖u‖ = r) (ha : a ≠ 0) + (hz : ‖u / a‖ ≤ (1 / 2 : ℝ)) (hτ_le : τ ≤ (m + 1 : ℝ)) : + ‖(weierstrassFactor m (u / a))⁻¹‖ ≤ Real.exp ((2 : ℝ) * (r / ‖a‖) ^ τ) := by + by_cases hu : u = 0 + · subst hu + have hr0 : r = 0 := by simpa [hur] using (norm_zero : ‖(0 : ℂ)‖ = 0) + subst hr0 + have h0 : 0 ≤ ((0 : ℝ) / ‖a‖) ^ τ := by + exact Real.rpow_nonneg (by positivity : (0 : ℝ) ≤ 0 / ‖a‖) τ + have h0' : 0 ≤ (2 : ℝ) * ((0 : ℝ) / ‖a‖) ^ τ := mul_nonneg (by norm_num) h0 + have hexp : (1 : ℝ) ≤ Real.exp ((2 : ℝ) * ((0 : ℝ) / ‖a‖) ^ τ) := + (Real.one_le_exp_iff).2 h0' + simpa using hexp + have hlogE := + log_norm_weierstrassFactor_ge_neg_two_pow (m := m) (z := (u / a)) hz + have hneglog : -Real.log ‖weierstrassFactor m (u / a)‖ ≤ (2 : ℝ) * (r / ‖a‖) ^ τ := by + have h1 : -Real.log ‖weierstrassFactor m (u / a)‖ ≤ (2 : ℝ) * ‖u / a‖ ^ (m + 1) := by + linarith [hlogE] + set x : ℝ := ‖u / a‖ + have hx1 : x ≤ 1 := le_trans (by simpa [x] using hz) (by norm_num) + have hxpos : 0 < x := by + simpa [x] using (norm_pos_iff.2 (div_ne_zero hu ha)) + have hτ_le' : τ ≤ ((m + 1 : ℕ) : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one] using hτ_le + have hpow_rpow : x ^ ((m + 1 : ℕ) : ℝ) ≤ x ^ τ := + Real.rpow_le_rpow_of_exponent_ge hxpos hx1 hτ_le' + have hpow : x ^ (m + 1) ≤ x ^ τ := by + simpa [← Real.rpow_natCast] using hpow_rpow + have h2x : (2 : ℝ) * x ^ (m + 1) ≤ (2 : ℝ) * x ^ τ := + mul_le_mul_of_nonneg_left hpow (by positivity) + have h2 : (2 : ℝ) * ‖u / a‖ ^ (m + 1) ≤ (2 : ℝ) * (‖u / a‖ : ℝ) ^ τ := by + simpa [x] using h2x + have h3 : (‖u‖ / ‖a‖) ^ τ = (r / ‖a‖) ^ τ := by + simp [hur] + exact (h1.trans h2).trans_eq (by simp [h3]) + have hpos : 0 < ‖weierstrassFactor m (u / a)‖ := by + have : weierstrassFactor m (u / a) ≠ 0 := by + intro h0 + have : u / a = (1 : ℂ) := (weierstrassFactor_eq_zero_iff m (u / a)).1 h0 + have : u = a := (div_eq_one_iff_eq ha).1 this + have : (‖u / a‖ : ℝ) = 1 := by simpa [this] using (by simp [ha]) + linarith [hz, this] + exact norm_pos_iff.2 this + have hEq : + ‖(weierstrassFactor m (u / a))⁻¹‖ = + Real.exp (-Real.log ‖weierstrassFactor m (u / a)‖) := by + simp [norm_inv, Real.exp_neg, Real.exp_log hpos] + have := Real.exp_le_exp.2 hneglog + simpa [hEq] using this + +end Complex.Hadamard +end +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/Counting.lean b/PrimeNumberTheoremAnd/SiegelZeros/Counting.lean new file mode 100644 index 0000000..cc47f9c --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/Counting.lean @@ -0,0 +1,689 @@ +import Mathlib + +namespace SiegelZeros + +open _root_.Real _root_.Function _root_.Function.locallyFinsuppWithin + +section +open Filter Function MeromorphicOn Metric Real Set + +namespace Function.locallyFinsuppWithin + +variable {E : Type*} [NormedAddCommGroup E] + +lemma norm_le_abs_of_mem_toClosedBall_support {D : locallyFinsupp E ℤ} {r : ℝ} {z : E} + (hz : z ∈ (toClosedBall r D).support) : ‖z‖ ≤ |r| := by + have hz_ball : z ∈ closedBall (0 : E) |r| := (toClosedBall r D).supportWithinDomain hz + simpa [mem_closedBall, dist_zero_right] using hz_ball + +lemma toClosedBall_eval_eq_of_norm_le_abs {D : locallyFinsupp E ℤ} {r : ℝ} {z : E} + (hz : ‖z‖ ≤ |r|) : toClosedBall r D z = D z := by + have hz_ball : z ∈ closedBall (0 : E) |r| := by + simpa [mem_closedBall, dist_zero_right] using hz + simpa using toClosedBall_eval_within (f := D) hz_ball + +lemma mem_toClosedBall_support_of_mem_support_of_norm_le_abs + {D : locallyFinsupp E ℤ} {r : ℝ} {z : E} (hzD : z ∈ D.support) (hzR : ‖z‖ ≤ |r|) : + z ∈ (toClosedBall r D).support := by + rw [Function.mem_support] + rw [toClosedBall_eval_eq_of_norm_le_abs hzR] + rwa [Function.mem_support] at hzD + +lemma mem_support_of_mem_toClosedBall_support {D : locallyFinsupp E ℤ} {r : ℝ} {z : E} + (hz : z ∈ (toClosedBall r D).support) : z ∈ D.support := by + have hnorm : ‖z‖ ≤ |r| := norm_le_abs_of_mem_toClosedBall_support hz + rw [Function.mem_support] at hz ⊢ + rw [toClosedBall_eval_eq_of_norm_le_abs hnorm] at hz + exact hz + +noncomputable def massClosedBall₀ {E : Type*} [NormedAddCommGroup E] [ProperSpace E] + (D : locallyFinsupp E ℤ) (R : ℝ) : ℝ := by + classical + exact + (((finiteSupport (toClosedBall R D) (isCompact_closedBall (0 : E) |R|)).toFinset).filter + (fun z => z ≠ (0 : E))).sum fun z => (D z : ℝ) + +end Function.locallyFinsuppWithin + +namespace Function.locallyFinsuppWithin + +theorem logCounting_divisor_eq_circleAverage_sub_const_of_differentiable + {R : ℝ} {f : ℂ → ℂ} (hf : Differentiable ℂ f) (hR : R ≠ 0) : + logCounting (divisor f ⊤) R = + circleAverage (log ‖f ·‖) 0 R - log ‖meromorphicTrailingCoeffAt f 0‖ := by + have hmero : Meromorphic f := fun z => (hf.analyticAt z).meromorphicAt + simpa [top_eq_univ] using + logCounting_divisor_eq_circleAverage_sub_const (f := f) hmero hR + +end Function.locallyFinsuppWithin +end +section +namespace Real + +theorem log_one_add_exp_le_add_log_two {x : ℝ} (hx : 0 ≤ x) : + log (1 + exp x) ≤ x + log 2 := by + have hexp_one : (1 : ℝ) ≤ exp x := by + simpa using (one_le_exp_iff.2 hx) + have hadd : 1 + exp x ≤ 2 * exp x := by linarith + have hlog : log (1 + exp x) ≤ log (2 * exp x) := + log_le_log (by positivity) hadd + calc + log (1 + exp x) ≤ log (2 * exp x) := hlog + _ = log 2 + x := by simp [log_mul, add_comm] + _ = x + log 2 := by ring + +theorem log_one_add_le_add_log_two_of_le_exp {x y : ℝ} (hy : 0 ≤ y) (hx : 0 ≤ x) + (hxy : y ≤ exp x) : + log (1 + y) ≤ x + log 2 := by + have hpos : 0 < (1 : ℝ) + y := by linarith + have hle : (1 : ℝ) + y ≤ 1 + exp x := by linarith + exact (log_le_log hpos hle).trans (log_one_add_exp_le_add_log_two hx) + +theorem le_exp_of_log_one_add_le {x y : ℝ} (hy : 0 ≤ y) (hxy : log (1 + y) ≤ x) : + y ≤ exp x := by + have hpos : 0 < (1 : ℝ) + y := by linarith + have hone : 1 + y ≤ exp x := (log_le_iff_le_exp hpos).1 hxy + linarith + +theorem neg_posLog_inv_le_log (x : ℝ) : -log⁺ x⁻¹ ≤ log x := by + linarith [posLog_sub_posLog_inv (x := x), posLog_nonneg (x := x)] + +end Real +end +section +namespace Real + +variable {α E : Type*} [SeminormedAddCommGroup E] + +theorem log_norm_le_log_one_add_norm (w : E) : + Real.log ‖w‖ ≤ Real.log (1 + ‖w‖) := by + by_cases h0 : ‖w‖ = 0 + · simp [h0] + · have hpos : 0 < ‖w‖ := lt_of_le_of_ne (norm_nonneg w) (Ne.symm h0) + exact Real.log_le_log hpos (by linarith [norm_nonneg w]) + +variable {F : Type*} [NormedAddCommGroup F] + +theorem log_nonneg_mul_inv_norm_of_norm_le {z : F} {r : ℝ} (hz : ‖z‖ ≤ r) : + 0 ≤ Real.log (r * ‖z‖⁻¹) := by + by_cases hz0 : z = 0 + · simp [hz0] + · have hzpos : 0 < ‖z‖ := norm_pos_iff.2 hz0 + have : (1 : ℝ) ≤ r * ‖z‖⁻¹ := by + have : (1 : ℝ) ≤ r / ‖z‖ := (one_le_div hzpos).2 hz + simpa [div_eq_mul_inv] using this + exact Real.log_nonneg this + +theorem log_two_le_log_two_mul_mul_inv_norm_of_norm_le {z : F} {R : ℝ} (hz0 : z ≠ 0) + (hz : ‖z‖ ≤ R) : + Real.log 2 ≤ Real.log ((2 * R) * ‖z‖⁻¹) := by + have hzpos : 0 < ‖z‖ := norm_pos_iff.2 hz0 + have hRdiv : (1 : ℝ) ≤ R / ‖z‖ := (one_le_div hzpos).2 hz + have hle2 : (2 : ℝ) ≤ (2 * R) * ‖z‖⁻¹ := by + have : (2 : ℝ) ≤ 2 * (R / ‖z‖) := by nlinarith + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using this + exact Real.log_le_log (by norm_num) hle2 + +theorem norm_le_exp_mul_rpow_of_exponent_le + {f : α → E} {r : α → ℝ} {C ρ τ : ℝ} (hC : 0 ≤ C) (hr : ∀ x, 1 ≤ r x) (hρτ : ρ ≤ τ) + (hbound : ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ ρ)) : ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ τ) := by + intro x + refine (hbound x).trans (Real.exp_le_exp.2 ?_) + exact mul_le_mul_of_nonneg_left (Real.rpow_le_rpow_of_exponent_le (hr x) hρτ) hC + +theorem norm_le_exp_mul_rpow_of_log_growth + {f : α → E} {r : α → ℝ} {C ρ τ : ℝ} (hC : 0 ≤ C) (hr : ∀ x, 1 ≤ r x) (hρτ : ρ ≤ τ) + (hlog : ∀ x, Real.log (1 + ‖f x‖) ≤ C * (r x) ^ ρ) : ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ τ) := by + intro x + have hpow : (r x) ^ ρ ≤ (r x) ^ τ := + Real.rpow_le_rpow_of_exponent_le (hr x) hρτ + have hlogτ : Real.log (1 + ‖f x‖) ≤ C * (r x) ^ τ := + (hlog x).trans (mul_le_mul_of_nonneg_left hpow hC) + exact Real.le_exp_of_log_one_add_le (norm_nonneg (f x)) hlogτ + +theorem log_growth_of_norm_le_exp_mul_rpow + {f : α → E} {r : α → ℝ} {C τ : ℝ} (hC : 0 < C) (hτ : 0 ≤ τ) + (hr : ∀ x, 1 ≤ r x) (hbound : ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ τ)) : + ∃ C' > 0, ∀ x, Real.log (1 + ‖f x‖) ≤ C' * (r x) ^ τ := by + refine ⟨C + Real.log 2, by + have hlog2 : 0 ≤ Real.log 2 := Real.log_nonneg (by norm_num) + linarith, ?_⟩ + intro x + have hX : (1 : ℝ) ≤ (r x) ^ τ := Real.one_le_rpow (hr x) hτ + have hB : 0 ≤ C * (r x) ^ τ := + mul_nonneg hC.le (Real.rpow_nonneg (le_trans zero_le_one (hr x)) _) + have hlog : + Real.log (1 + ‖f x‖) ≤ C * (r x) ^ τ + Real.log 2 := + Real.log_one_add_le_add_log_two_of_le_exp (norm_nonneg _) hB (hbound x) + have hlog2_nonneg : 0 ≤ Real.log 2 := Real.log_nonneg (by norm_num) + nlinarith [hlog, hX, hlog2_nonneg] + +theorem exists_norm_le_exp_mul_pow_of_rpow_bound + {f : α → E} {r : α → ℝ} {τ : ℝ} {n : ℕ} (hr : ∀ x, 1 ≤ r x) (hτn : τ < (n : ℝ)) + (hbound : ∃ C > 0, ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ τ)) : + ∃ C > 0, ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ n) := by + rcases hbound with ⟨C, hCpos, hC⟩ + have hweak : + ∀ x, ‖f x‖ ≤ Real.exp (C * (r x) ^ (n : ℝ)) := + norm_le_exp_mul_rpow_of_exponent_le + (f := f) (r := r) hCpos.le hr (le_of_lt hτn) hC + refine ⟨C, hCpos, ?_⟩ + intro x + have hpow : (r x) ^ (n : ℝ) = (r x) ^ n := Real.rpow_natCast (r x) n + simpa [hpow] using hweak x + +theorem one_add_le_three_mul_one_add_of_le_two_mul_max {x r : ℝ} (hx : 0 ≤ x) + (hr : r ≤ 2 * max x 1) : 1 + r ≤ 3 * (1 + x) := by + have hmax : max x 1 ≤ 1 + x := max_le_iff.2 ⟨by linarith, by linarith⟩ + nlinarith + +theorem exp_mul_rpow_le_exp_mul_rpow_of_le_mul + {A B x y τ : ℝ} (hA : 0 ≤ A) (hB : 0 ≤ B) (hx : 0 ≤ x) (hy : 0 ≤ y) + (hτ : 0 ≤ τ) (hxy : x ≤ B * y) : Real.exp (A * x ^ τ) ≤ Real.exp ((A * B ^ τ) * y ^ τ) := by + refine Real.exp_le_exp.2 ?_ + have hpow : x ^ τ ≤ (B * y) ^ τ := Real.rpow_le_rpow hx hxy hτ + have hsplit : (B * y) ^ τ = B ^ τ * y ^ τ := by + simpa using (Real.mul_rpow (x := B) (y := y) (z := τ) hB hy) + simpa [mul_assoc] using mul_le_mul_of_nonneg_left (hpow.trans_eq hsplit) hA + +theorem exists_between_self_and_floor_add_one_same_floor {ρ : ℝ} (hρ : 0 ≤ ρ) : + ∃ τ : ℝ, ρ < τ ∧ τ < (Nat.floor ρ + 1 : ℝ) ∧ 0 ≤ τ ∧ Nat.floor τ = Nat.floor ρ := by + set m : ℕ := Nat.floor ρ + set τ : ℝ := (ρ + (m + 1 : ℝ)) / 2 + have hm : ρ < (m + 1 : ℝ) := by simpa [m] using Nat.lt_floor_add_one (a := ρ) + have hτ : ρ < τ := by dsimp [τ]; linarith + have hτ_lt : τ < (m + 1 : ℝ) := by dsimp [τ]; linarith + have hτ_nonneg : 0 ≤ τ := le_trans hρ (le_of_lt hτ) + have hfloorτ : Nat.floor τ = m := by + have hm_le_τ : (m : ℝ) ≤ τ := le_trans (Nat.floor_le hρ) (le_of_lt hτ) + have hτ_lt_m1 : τ < (m : ℝ) + 1 := by simpa [add_assoc, add_comm, add_left_comm] using hτ_lt + exact (Nat.floor_eq_iff hτ_nonneg).2 ⟨hm_le_τ, hτ_lt_m1⟩ + exact ⟨τ, hτ, by simpa [m] using hτ_lt, hτ_nonneg, by simpa [m] using hfloorτ⟩ + +open Metric Complex + +theorem log_norm_le_of_log_one_add_growth_on_sphere {f : ℂ → ℂ} {C ρ R : ℝ} + (hC : ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) {z : ℂ} + (hz : z ∈ sphere (0 : ℂ) |R|) : Real.log ‖f z‖ ≤ C * (1 + |R|) ^ ρ := by + have hz_norm : ‖z‖ = |R| := by + simpa [mem_sphere, dist_zero_right] using hz + simpa [hz_norm] using le_trans (log_norm_le_log_one_add_norm (f z)) (hC z) + +end Real +end +section +open Filter _root_.SiegelZeros.Function MeromorphicOn Metric Real Set + +namespace Function.locallyFinsuppWithin + +theorem logCounting_divisor_le_of_log_growth {f : ℂ → ℂ} {ρ C : ℝ} (hf : Differentiable ℂ f) + (hC : ∀ z : ℂ, log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) {R : ℝ} (hR0 : 0 < R) : + logCounting (divisor f (Set.univ : Set ℂ)) R + ≤ C * (1 + |R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + have hR : R ≠ 0 := ne_of_gt hR0 + have hEq := + logCounting_divisor_eq_circleAverage_sub_const_of_differentiable (f := f) hf hR + have hf_sphere : MeromorphicOn f (sphere (0 : ℂ) |R|) := by + intro z hz + exact (hf.analyticAt z).meromorphicAt + have hInt : CircleIntegrable (fun z : ℂ => log ‖f z‖) 0 R := + MeromorphicOn.circleIntegrable_log_norm hf_sphere + have hbound_circle : ∀ z ∈ sphere (0 : ℂ) |R|, + log ‖f z‖ ≤ C * (1 + |R|) ^ ρ := by + intro z hz + exact log_norm_le_of_log_one_add_growth_on_sphere hC hz + have hCircleAvg_le : + circleAverage (fun z : ℂ => log ‖f z‖) 0 R ≤ C * (1 + |R|) ^ ρ := + circleAverage_mono_on_of_le_circle (c := (0 : ℂ)) (R := R) + (f := fun z => log ‖f z‖) hInt hbound_circle + calc + logCounting (divisor f (Set.univ : Set ℂ)) R + = circleAverage (fun z : ℂ => log ‖f z‖) 0 R + - log ‖meromorphicTrailingCoeffAt f 0‖ := by + simpa [top_eq_univ] using hEq + _ ≤ circleAverage (fun z : ℂ => log ‖f z‖) 0 R + + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + have : + -log ‖meromorphicTrailingCoeffAt f 0‖ + ≤ |log ‖meromorphicTrailingCoeffAt f 0‖| := + neg_le_abs (log ‖meromorphicTrailingCoeffAt f 0‖) + linarith + _ ≤ C * (1 + |R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + nlinarith [hCircleAvg_le] + +variable {E : Type*} [NormedAddCommGroup E] [ProperSpace E] + +theorem log_two_mul_massClosedBall₀_le_logCounting {D : locallyFinsupp E ℤ} (hDnonneg : 0 ≤ D) + {R : ℝ} (hR : 1 ≤ R) : + (log 2) * massClosedBall₀ D R ≤ logCounting D (2 * R) := by + classical + have hR0 : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hR + set r : ℝ := 2 * R + have hrpos : 0 < r := by dsimp [r]; nlinarith + let Dr := toClosedBall r D + have hDr_fin : Set.Finite Dr.support := Dr.finiteSupport (isCompact_closedBall (0 : E) |r|) + let F : Finset E := hDr_fin.toFinset + let SR : Finset E := + (finiteSupport (toClosedBall R D) (isCompact_closedBall (0 : E) |R|)).toFinset + let S : Finset E := SR.filter fun z => z ≠ (0 : E) + have hS_sub : S ⊆ F := by + intro z hzS + have hz_mem_SR : z ∈ SR := (Finset.mem_filter.1 hzS).1 + have hzR : z ∈ (toClosedBall R D).support := by + exact (finiteSupport (toClosedBall R D) (isCompact_closedBall (0 : E) |R|)).mem_toFinset.1 + hz_mem_SR + have hz_norm_le_R : ‖z‖ ≤ R := by + have := norm_le_abs_of_mem_toClosedBall_support hzR + simpa [abs_of_pos hR0] using this + have hz_norm_le_r : ‖z‖ ≤ |r| := by + have : ‖z‖ ≤ r := le_trans hz_norm_le_R (by dsimp [r]; nlinarith) + simpa [abs_of_pos hrpos] using this + have hzD : z ∈ D.support := mem_support_of_mem_toClosedBall_support hzR + have : z ∈ Dr.support := by + simpa [Dr] using + mem_toClosedBall_support_of_mem_support_of_norm_le_abs (D := D) (r := r) hzD hz_norm_le_r + exact hDr_fin.mem_toFinset.2 this + have hlogCounting : + logCounting D r + = (F.sum fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) + (D 0 : ℝ) * log r := by + have hsupp : Function.support (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) ⊆ F := by + intro z hz + have : Dr z ≠ 0 := by + by_contra h0 + simp [Function.mem_support, h0] at hz + have : z ∈ Dr.support := by simpa [Function.mem_support] using this + exact hDr_fin.mem_toFinset.2 this + simp [logCounting, Dr, r, + finsum_eq_sum_of_support_subset (f := fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) (s := F) hsupp] + have hsum_le : + (log 2) * (S.sum fun z => (D z : ℝ)) + ≤ F.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) := by + have hterm_nonneg : ∀ z ∈ F, 0 ≤ (Dr z : ℝ) * log (r * ‖z‖⁻¹) := by + intro z hzF + have hz_sup : z ∈ Dr.support := hDr_fin.mem_toFinset.1 hzF + have hDz : 0 ≤ Dr z := by + have hDz' : 0 ≤ D z := hDnonneg z + have hDrz : Dr z = D z := + toClosedBall_eval_eq_of_norm_le_abs (norm_le_abs_of_mem_toClosedBall_support hz_sup) + simpa [hDrz] using hDz' + have hlog : 0 ≤ log (r * ‖z‖⁻¹) := by + have hzle : ‖z‖ ≤ r := by + have hnorm := norm_le_abs_of_mem_toClosedBall_support hz_sup + simpa [abs_of_pos hrpos] using hnorm + exact log_nonneg_mul_inv_norm_of_norm_le hzle + exact mul_nonneg (by exact_mod_cast hDz) hlog + have hsumSF : + S.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) + ≤ F.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) := + Finset.sum_le_sum_of_subset_of_nonneg hS_sub (by + intro z hzF _; exact hterm_nonneg z hzF) + have hterm_ge : ∀ z ∈ S, (log 2) * (D z : ℝ) ≤ (Dr z : ℝ) * log (r * ‖z‖⁻¹) := by + intro z hzS + have hz0 : z ≠ (0 : E) := (Finset.mem_filter.1 hzS).2 + have hz_norm_le_R : ‖z‖ ≤ R := by + have hz_mem_SR : z ∈ SR := (Finset.mem_filter.1 hzS).1 + have hzRsup : z ∈ (toClosedBall R D).support := by + exact (finiteSupport (toClosedBall R D) (isCompact_closedBall (0 : E) |R|)).mem_toFinset.1 + hz_mem_SR + have hnorm := norm_le_abs_of_mem_toClosedBall_support hzRsup + simpa [abs_of_pos hR0] using hnorm + have hlog_le : log 2 ≤ log (r * ‖z‖⁻¹) := by + simpa [r] using log_two_le_log_two_mul_mul_inv_norm_of_norm_le hz0 hz_norm_le_R + have hDz_nonneg : 0 ≤ D z := hDnonneg z + have hz_in_ballr : z ∈ closedBall (0 : E) |r| := by + have : ‖z‖ ≤ r := le_trans hz_norm_le_R (by dsimp [r]; nlinarith) + simpa [mem_closedBall, dist_zero_right, abs_of_pos hrpos] using this + have hDrz : Dr z = D z := by + have hz_norm_le : ‖z‖ ≤ |r| := by + simpa [mem_closedBall, dist_zero_right] using hz_in_ballr + simpa [Dr] using toClosedBall_eval_eq_of_norm_le_abs (D := D) (r := r) (z := z) hz_norm_le + have : (log 2) * (D z : ℝ) ≤ (log (r * ‖z‖⁻¹)) * (D z : ℝ) := + mul_le_mul_of_nonneg_right hlog_le (by exact_mod_cast hDz_nonneg) + simpa [hDrz, mul_assoc, mul_left_comm, mul_comm] using this + calc + (log 2) * (S.sum fun z => (D z : ℝ)) + = S.sum (fun z => (log 2) * (D z : ℝ)) := by simp [Finset.mul_sum] + _ ≤ S.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) := + Finset.sum_le_sum fun z hz => hterm_ge z hz + _ ≤ F.sum (fun z => (Dr z : ℝ) * log (r * ‖z‖⁻¹)) := hsumSF + have hcenter_nonneg : 0 ≤ (D 0 : ℝ) * log r := by + have hD0 : 0 ≤ D 0 := hDnonneg 0 + have hlogr : 0 ≤ log r := log_nonneg (by nlinarith [hR]) + exact mul_nonneg (by exact_mod_cast hD0) hlogr + have : (log 2) * (S.sum fun z => (D z : ℝ)) ≤ logCounting D r := by + rw [hlogCounting] + nlinarith [hsum_le, hcenter_nonneg] + simpa [massClosedBall₀, r, S, SR] using this + +theorem massClosedBall₀_divisor_le_of_log_growth {f : ℂ → ℂ} {ρ C : ℝ} + (hf : Differentiable ℂ f) + (hC : ∀ z : ℂ, log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) {R : ℝ} (hR : 1 ≤ R) : + massClosedBall₀ (divisor f (Set.univ : Set ℂ)) R + ≤ (C * (1 + |2 * R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖|) / log 2 := by + have hR0 : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hR + have hlog2pos : 0 < log 2 := log_pos (by norm_num : (1 : ℝ) < 2) + have hlow : + (log 2) * massClosedBall₀ (divisor f (Set.univ : Set ℂ)) R + ≤ logCounting (divisor f (Set.univ : Set ℂ)) (2 * R) := + log_two_mul_massClosedBall₀_le_logCounting + (D := divisor f (Set.univ : Set ℂ)) + (MeromorphicOn.AnalyticOnNhd.divisor_nonneg + (hf.differentiableOn.analyticOnNhd isOpen_univ)) hR + have hupp : + logCounting (divisor f (Set.univ : Set ℂ)) (2 * R) + ≤ C * (1 + |2 * R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + have h2R0 : 0 < 2 * R := by nlinarith [hR0] + simpa using logCounting_divisor_le_of_log_growth (f := f) (ρ := ρ) (C := C) hf hC + (R := 2 * R) h2R0 + have hmul : + (log 2) * massClosedBall₀ (divisor f (Set.univ : Set ℂ)) R + ≤ C * (1 + |2 * R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := + hlow.trans hupp + have hmul' : + massClosedBall₀ (divisor f (Set.univ : Set ℂ)) R * log 2 + ≤ C * (1 + |2 * R|) ^ ρ + |log ‖meromorphicTrailingCoeffAt f 0‖| := by + simpa [mul_assoc, mul_left_comm, mul_comm] using hmul + exact (le_div_iff₀ hlog2pos).2 hmul' + +end Function.locallyFinsuppWithin +end +section +open Set + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] [CompleteSpace E] + +theorem Differentiable.divisor_nonneg {f : ℂ → E} (hf : Differentiable ℂ f) : + 0 ≤ MeromorphicOn.divisor f (univ : Set ℂ) := + MeromorphicOn.AnalyticOnNhd.divisor_nonneg (hf.differentiableOn.analyticOnNhd isOpen_univ) +end +section +noncomputable section + +open scoped BigOperators +open Filter + +namespace Real + +lemma two_pow_floor_logb_le {x : ℝ} (hx : 1 ≤ x) : + (2 : ℝ) ^ (⌊Real.logb 2 x⌋₊ : ℝ) ≤ x := by + have hx0 : 0 < x := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hx + have hlog_nonneg : 0 ≤ Real.logb 2 x := + Real.logb_nonneg (b := (2 : ℝ)) (by norm_num : (1 : ℝ) < 2) hx + have hfloor_le : (⌊Real.logb 2 x⌋₊ : ℝ) ≤ Real.logb 2 x := by + simpa using (Nat.floor_le hlog_nonneg) + exact (Real.le_logb_iff_rpow_le (b := (2 : ℝ)) + (x := (⌊Real.logb 2 x⌋₊ : ℝ)) (y := x) + (by norm_num : (1 : ℝ) < 2) hx0).1 hfloor_le + +lemma lt_two_pow_floor_logb_add_one {x : ℝ} (hx : 1 ≤ x) : + x < (2 : ℝ) ^ ((⌊Real.logb 2 x⌋₊ : ℝ) + 1) := by + have hx0 : 0 < x := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hx + have hlt : Real.logb 2 x < (⌊Real.logb 2 x⌋₊ : ℝ) + 1 := by + simpa using (Nat.lt_floor_add_one (Real.logb 2 x)) + exact (Real.logb_lt_iff_lt_rpow (b := (2 : ℝ)) (x := x) + (y := (⌊Real.logb 2 x⌋₊ : ℝ) + 1) + (by norm_num : (1 : ℝ) < 2) hx0).1 hlt + +lemma dyadicShell_lower_bound {r0 x : ℝ} {k : ℕ} (hr0 : 0 < r0) (hx : r0 ≤ x) + (hk : ⌊Real.logb 2 (x / r0)⌋₊ = k) : + r0 * (2 : ℝ) ^ (k : ℝ) ≤ x := by + have hr0ne : r0 ≠ 0 := ne_of_gt hr0 + have hx1 : (1 : ℝ) ≤ x / r0 := by + have : r0 / r0 ≤ x / r0 := div_le_div_of_nonneg_right hx hr0.le + simpa [hr0ne] using this + have hle : (2 : ℝ) ^ (k : ℝ) ≤ x / r0 := by + have := Real.two_pow_floor_logb_le (x := x / r0) hx1 + simpa [hk] using this + have := mul_le_mul_of_nonneg_left hle hr0.le + have hxEq : r0 * (x / r0) = x := by + field_simp [hr0ne] + simpa [mul_assoc, hxEq] using this + +lemma dyadicShell_upper_bound {r0 x : ℝ} {k : ℕ} (hr0 : 0 < r0) (hx : r0 ≤ x) + (hk : ⌊Real.logb 2 (x / r0)⌋₊ = k) : + x ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1) := by + have hr0ne : r0 ≠ 0 := ne_of_gt hr0 + have hx1 : (1 : ℝ) ≤ x / r0 := by + have : r0 / r0 ≤ x / r0 := div_le_div_of_nonneg_right hx hr0.le + simpa [hr0ne] using this + have hlt : x / r0 < (2 : ℝ) ^ ((k : ℝ) + 1) := by + have := Real.lt_two_pow_floor_logb_add_one (x := x / r0) hx1 + simpa [hk] using this + have := mul_lt_mul_of_pos_left hlt hr0 + have hxEq : r0 * (x / r0) = x := by + field_simp [hr0ne] + exact le_of_lt (by simpa [mul_assoc, hxEq] using this) + +lemma exists_nat_le_two_pow (A : ℝ) : + ∃ k0 : ℕ, ∀ n ≥ k0, A ≤ (2 : ℝ) ^ n := by + have htend : Tendsto (fun n : ℕ => (2 : ℝ) ^ n) atTop atTop := + tendsto_pow_atTop_atTop_of_one_lt (r := (2 : ℝ)) (by norm_num : (1 : ℝ) < 2) + exact eventually_atTop.1 ((tendsto_atTop.1 htend) A) + +lemma one_le_dyadicRadius_succ_of_inv_le_two_pow + {r0 : ℝ} {k0 kk : ℕ} (hr0 : 0 < r0) + (hk0 : ∀ n ≥ k0, (1 / r0 : ℝ) ≤ (2 : ℝ) ^ n) (hkk : k0 ≤ kk + 1) : + (1 : ℝ) ≤ r0 * (2 : ℝ) ^ ((kk : ℝ) + 1) := by + have hr0ne : r0 ≠ 0 := ne_of_gt hr0 + have hpow_nat : (1 / r0 : ℝ) ≤ (2 : ℝ) ^ (kk + 1) := hk0 (kk + 1) hkk + have hpow_rpow : (1 / r0 : ℝ) ≤ (2 : ℝ) ^ ((kk : ℝ) + 1) := by + have hcast : (2 : ℝ) ^ ((kk : ℝ) + 1) = (2 : ℝ) ^ (kk + 1) := by + calc + (2 : ℝ) ^ ((kk : ℝ) + 1) = (2 : ℝ) ^ ((kk + 1 : ℕ) : ℝ) := by + simp [Nat.cast_add, Nat.cast_one] + _ = (2 : ℝ) ^ (kk + 1) := by + simpa using (Real.rpow_natCast (2 : ℝ) (kk + 1)) + simpa [hcast] using hpow_nat + have : (r0 * (1 / r0) : ℝ) ≤ r0 * (2 : ℝ) ^ ((kk : ℝ) + 1) := + mul_le_mul_of_nonneg_left hpow_rpow hr0.le + simpa [one_div, hr0ne, mul_assoc] using this + +lemma one_add_abs_two_mul_dyadicRadius_rpow_le {r0 ρ : ℝ} (k : ℕ) + (hr0 : 0 < r0) (hρ : 0 ≤ ρ) : + (1 + |2 * (r0 * (2 : ℝ) ^ ((k : ℝ) + 1))|) ^ ρ + ≤ (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ ρ) ^ k := by + let Rk : ℝ := r0 * (2 : ℝ) ^ ((k : ℝ) + 1) + have hRk' : |2 * Rk| = 4 * r0 * (2 : ℝ) ^ (k : ℝ) := by + have hnonneg : 0 ≤ (2 : ℝ) * Rk := by + have : 0 ≤ Rk := by + dsimp [Rk] + exact mul_nonneg hr0.le (le_of_lt (Real.rpow_pos_of_pos (by norm_num) _)) + nlinarith + have hmul : (2 : ℝ) * Rk = 4 * r0 * (2 : ℝ) ^ (k : ℝ) := by + dsimp [Rk] + calc + (2 : ℝ) * (r0 * (2 : ℝ) ^ ((k : ℝ) + 1)) + = (2 * r0) * (2 : ℝ) ^ ((k : ℝ) + 1) := by ring + _ = (2 * r0) * ((2 : ℝ) ^ (k : ℝ) * (2 : ℝ) ^ (1 : ℝ)) := by + simp [Real.rpow_add, mul_assoc] + _ = (2 * r0) * ((2 : ℝ) ^ (k : ℝ) * 2) := by simp [Real.rpow_one] + _ = 4 * r0 * (2 : ℝ) ^ (k : ℝ) := by ring + calc + |2 * Rk| = 2 * Rk := abs_of_nonneg hnonneg + _ = 4 * r0 * (2 : ℝ) ^ (k : ℝ) := hmul + have hbase : + (1 + |2 * Rk|) ≤ (1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ) := by + have h1 : (1 : ℝ) ≤ (2 : ℝ) ^ (k : ℝ) := by + have : (1 : ℝ) ≤ (2 : ℝ) ^ (k : ℕ) := by + simpa using (one_le_pow₀ (by norm_num : (1 : ℝ) ≤ (2 : ℝ))) + simpa [Real.rpow_natCast] using this + have habs : + 1 + |2 * Rk| ≤ (2 : ℝ) ^ (k : ℝ) + (4 * r0) * (2 : ℝ) ^ (k : ℝ) := by + rw [hRk'] + simpa [add_assoc, add_left_comm, add_comm, mul_assoc, mul_left_comm, mul_comm] using + (add_le_add_right h1 ((4 * r0) * (2 : ℝ) ^ (k : ℝ))) + have hfac : + (2 : ℝ) ^ (k : ℝ) + (4 * r0) * (2 : ℝ) ^ (k : ℝ) + = (1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ) := by + ring + exact habs.trans (le_of_eq hfac) + have hRnonneg : 0 ≤ (1 + |2 * Rk|) := by linarith [abs_nonneg (2 * Rk)] + have : + (1 + |2 * Rk|) ^ ρ ≤ ((1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ)) ^ ρ := + Real.rpow_le_rpow hRnonneg hbase hρ + have hsplit : + ((1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ)) ^ ρ + = (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ (k : ℝ)) ^ ρ := by + have h1 : 0 ≤ (1 + 4 * r0) := by nlinarith [hr0.le] + have h2 : 0 ≤ (2 : ℝ) ^ (k : ℝ) := + le_of_lt (Real.rpow_pos_of_pos (by norm_num) _) + simpa using (Real.mul_rpow h1 h2 (z := ρ)) + have hpow : ((2 : ℝ) ^ (k : ℝ)) ^ ρ = ((2 : ℝ) ^ ρ) ^ k := by + have h2nonneg : (0 : ℝ) ≤ 2 := by norm_num + calc + ((2 : ℝ) ^ (k : ℝ)) ^ ρ = (2 : ℝ) ^ ((k : ℝ) * ρ) := by + simp [Real.rpow_mul] + _ = ((2 : ℝ) ^ ρ) ^ (k : ℝ) := by + simpa [mul_comm] using + (Real.rpow_mul (x := (2 : ℝ)) (y := ρ) (z := (k : ℝ)) h2nonneg) + _ = ((2 : ℝ) ^ ρ) ^ k := by + simp [Real.rpow_natCast] + calc + (1 + |2 * (r0 * (2 : ℝ) ^ ((k : ℝ) + 1))|) ^ ρ + = (1 + |2 * Rk|) ^ ρ := by rfl + _ ≤ ((1 + 4 * r0) * (2 : ℝ) ^ (k : ℝ)) ^ ρ := this + _ = (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ (k : ℝ)) ^ ρ := hsplit + _ = (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ ρ) ^ k := by + simpa [mul_assoc] using congrArg (fun t => (1 + 4 * r0) ^ ρ * t) hpow + +lemma tsum_inv_rpow_le_card_mul_of_lower_bound {α : Type*} [Fintype α] {a : α → ℝ} + {R τ : ℝ} (hR : 0 < R) (hτ : 0 < τ) (ha_nonneg : ∀ x, 0 ≤ a x) + (ha_lower : ∀ x, R ≤ a x) : + (∑' x : α, (a x)⁻¹ ^ τ) ≤ (Fintype.card α : ℝ) * (R⁻¹ ^ τ) := by + have hsum_le : + (∑ x : α, (a x)⁻¹ ^ τ) ≤ ∑ _x : α, R⁻¹ ^ τ := by + refine Finset.sum_le_sum ?_ + intro x _hx + have hinv : (a x)⁻¹ ≤ R⁻¹ := by + simpa using (inv_anti₀ hR (ha_lower x)) + exact Real.rpow_le_rpow (inv_nonneg.2 (ha_nonneg x)) hinv hτ.le + simpa [tsum_fintype, Finset.sum_const, nsmul_eq_mul, mul_comm] using hsum_le + +lemma inv_dyadicRadius_rpow_eq (r0 τ : ℝ) (k : ℕ) (hr0 : 0 ≤ r0) : + (r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ = + (r0⁻¹ : ℝ) ^ τ * ((2 : ℝ) ^ (-τ)) ^ k := by + have h2k_nonneg : 0 ≤ (2 : ℝ) ^ (k : ℝ) := + le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) _) + calc + (r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ = + (r0 * (2 : ℝ) ^ (k : ℝ)) ^ (-τ) := by + simpa using (Real.rpow_neg_eq_inv_rpow (r0 * (2 : ℝ) ^ (k : ℝ)) τ).symm + _ = r0 ^ (-τ) * (((2 : ℝ) ^ (k : ℝ)) ^ (-τ)) := by + simpa using (Real.mul_rpow hr0 h2k_nonneg (z := -τ)) + _ = (r0⁻¹ : ℝ) ^ τ * ((2 : ℝ) ^ (-τ)) ^ k := by + have hr0' : r0 ^ (-τ) = (r0⁻¹ : ℝ) ^ τ := by + simp [Real.rpow_neg_eq_inv_rpow] + have h2' : ((2 : ℝ) ^ (k : ℝ)) ^ (-τ) = ((2 : ℝ) ^ (-τ)) ^ k := by + have h2nonneg : (0 : ℝ) ≤ (2 : ℝ) := by norm_num + calc + ((2 : ℝ) ^ (k : ℝ)) ^ (-τ) = (2 : ℝ) ^ ((k : ℝ) * (-τ)) := by + exact (Real.rpow_mul (x := (2 : ℝ)) (y := (k : ℝ)) (z := -τ) + h2nonneg).symm + _ = (2 : ℝ) ^ ((-τ) * (k : ℝ)) := by ring_nf + _ = ((2 : ℝ) ^ (-τ)) ^ (k : ℝ) := by + exact Real.rpow_mul (x := (2 : ℝ)) (y := -τ) (z := (k : ℝ)) h2nonneg + _ = ((2 : ℝ) ^ (-τ)) ^ k := by + simp [Real.rpow_natCast] + calc + r0 ^ (-τ) * (((2 : ℝ) ^ (k : ℝ)) ^ (-τ)) + = (r0⁻¹ : ℝ) ^ τ * (((2 : ℝ) ^ (k : ℝ)) ^ (-τ)) := by + rw [hr0'] + _ = (r0⁻¹ : ℝ) ^ τ * ((2 : ℝ) ^ (-τ)) ^ k := by + rw [h2'] + +lemma two_rpow_sub_eq_mul_neg (ρ τ : ℝ) : + (2 : ℝ) ^ (ρ - τ) = (2 : ℝ) ^ ρ * (2 : ℝ) ^ (-τ) := by + have h2pos : (0 : ℝ) < (2 : ℝ) := by norm_num + calc + (2 : ℝ) ^ (ρ - τ) = (2 : ℝ) ^ (ρ + (-τ)) := by ring_nf + _ = (2 : ℝ) ^ ρ * (2 : ℝ) ^ (-τ) := by + simp [Real.rpow_add h2pos] + +lemma two_rpow_sub_pow_eq_mul_pow (ρ τ : ℝ) (k : ℕ) : + ((2 : ℝ) ^ (ρ - τ)) ^ k = + ((2 : ℝ) ^ ρ) ^ k * (((2 : ℝ) ^ (-τ)) ^ k) := by + simp [two_rpow_sub_eq_mul_neg, mul_pow] + +lemma dyadic_growth_inv_term_eq (C L M r0 ρ τ : ℝ) (k : ℕ) (hr0 : 0 ≤ r0) : + ((C / L) * (M * ((2 : ℝ) ^ ρ) ^ k)) * + ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + = (((C / L) * M) * (r0⁻¹ : ℝ) ^ τ) * ((2 : ℝ) ^ (ρ - τ)) ^ k := by + have hrk_inv : + (r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ = + (r0⁻¹ : ℝ) ^ τ * (((2 : ℝ) ^ (-τ)) ^ k) := + inv_dyadicRadius_rpow_eq r0 τ k hr0 + rw [hrk_inv, two_rpow_sub_pow_eq_mul_pow] + ac_rfl + +lemma dyadic_trailing_inv_term_le (C L r0 τ : ℝ) (k : ℕ) (hr0 : 0 ≤ r0) : + (C / L) * ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + ≤ (((C / L) + 1) * (r0⁻¹ : ℝ) ^ τ) * ((2 : ℝ) ^ (-τ)) ^ k := by + rw [inv_dyadicRadius_rpow_eq r0 τ k hr0] + have hcoeff : C / L ≤ C / L + 1 := by linarith + have hr0Inv_nonneg : 0 ≤ (r0⁻¹ : ℝ) ^ τ := + Real.rpow_nonneg (inv_nonneg.2 hr0) _ + have hmul : + (C / L) * ((r0⁻¹ : ℝ) ^ τ) + ≤ ((C / L) + 1) * ((r0⁻¹ : ℝ) ^ τ) := + mul_le_mul_of_nonneg_right hcoeff hr0Inv_nonneg + have hqpow_nonneg : 0 ≤ ((2 : ℝ) ^ (-τ)) ^ k := + pow_nonneg (le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) _)) _ + have := mul_le_mul_of_nonneg_right hmul hqpow_nonneg + simpa [mul_assoc, mul_left_comm, mul_comm] using this + +lemma dyadic_growth_mass_mul_inv_le_geometric {C L M X T Ctrail r0 ρ τ : ℝ} {k : ℕ} + (hL : 0 < L) (hC : 0 ≤ C) (hr0 : 0 ≤ r0) + (hX : X ≤ M * ((2 : ℝ) ^ ρ) ^ k) + (hT : T ≤ ((C * X + Ctrail) / L) * ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ)) : + T ≤ (((C / L) * M) * (r0⁻¹ : ℝ) ^ τ) * ((2 : ℝ) ^ (ρ - τ)) ^ k + + (((Ctrail / L) + 1) * (r0⁻¹ : ℝ) ^ τ) * ((2 : ℝ) ^ (-τ)) ^ k := by + have hmul : C * X ≤ C * (M * ((2 : ℝ) ^ ρ) ^ k) := + mul_le_mul_of_nonneg_left hX hC + have hnum : C * X + Ctrail ≤ C * (M * ((2 : ℝ) ^ ρ) ^ k) + Ctrail := + add_le_add hmul le_rfl + have hdiv : + (C * X + Ctrail) / L ≤ (C * (M * ((2 : ℝ) ^ ρ) ^ k) + Ctrail) / L := + div_le_div_of_nonneg_right hnum hL.le + have h2k_nonneg : 0 ≤ (2 : ℝ) ^ (k : ℝ) := + le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) (k : ℝ)) + have hrk_nonneg : 0 ≤ r0 * (2 : ℝ) ^ (k : ℝ) := + mul_nonneg hr0 h2k_nonneg + have hfactor_nonneg : 0 ≤ ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) := + Real.rpow_nonneg (inv_nonneg.2 hrk_nonneg) τ + have hmul' := + mul_le_mul_of_nonneg_right hdiv hfactor_nonneg + have hdecomp : + ((C * (M * ((2 : ℝ) ^ ρ) ^ k) + Ctrail) / L) * + ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + = + ((C / L) * (M * ((2 : ℝ) ^ ρ) ^ k)) * + ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + + ((Ctrail / L) * ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ)) := by + let Y : ℝ := (r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ + have : + ((C * (M * ((2 : ℝ) ^ ρ) ^ k) + Ctrail) / L) * Y + = ((C / L) * (M * ((2 : ℝ) ^ ρ) ^ k)) * Y + + ((Ctrail / L) * Y) := by + ring + simpa [Y] + have hpre : + T ≤ ((C / L) * (M * ((2 : ℝ) ^ ρ) ^ k)) * + ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ) + + ((Ctrail / L) * ((r0 * (2 : ℝ) ^ (k : ℝ))⁻¹ ^ τ)) := + hT.trans (hmul'.trans_eq hdecomp) + have hA := le_of_eq (dyadic_growth_inv_term_eq C L M r0 ρ τ k hr0) + have hB := dyadic_trailing_inv_term_le Ctrail L r0 τ k hr0 + exact hpre.trans (by + simpa [mul_assoc, mul_left_comm, mul_comm] using add_le_add hA hB) + +lemma two_geometric_shift_add (A B q qσ : ℝ) (k k0 : ℕ) : + A * q ^ (k + k0) + B * qσ ^ (k + k0) + = (A * q ^ k0) * q ^ k + (B * qσ ^ k0) * qσ ^ k := by + rw [pow_add, pow_add] + ac_rfl + +end Real +end +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/DivisorBasics.lean b/PrimeNumberTheoremAnd/SiegelZeros/DivisorBasics.lean new file mode 100644 index 0000000..e5a553a --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/DivisorBasics.lean @@ -0,0 +1,590 @@ +import Mathlib +import PrimeNumberTheoremAnd.SiegelZeros.Products + +namespace SiegelZeros + +section +open Filter Topology Set + +namespace MeromorphicOn + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {U K : Set 𝕜} {z : 𝕜} + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + +lemma divisor_support_inter_compact_finite (f : 𝕜 → E) {U K : Set 𝕜} + (hK : IsCompact K) (hKU : K ⊆ U) : + (K ∩ (MeromorphicOn.divisor f U).support).Finite := by + classical + set D : Function.locallyFinsuppWithin U ℤ := MeromorphicOn.divisor f U + have hloc : + ∀ x ∈ K, ∃ V : Set 𝕜, V ∈ 𝓝 x ∧ Set.Finite (V ∩ D.support) := by + intro x hxK + rcases D.supportLocallyFiniteWithinDomain x (hKU hxK) with ⟨V, hV, hfin⟩ + exact ⟨V, hV, hfin⟩ + choose V hVnhds hVfin using hloc + rcases hK.elim_nhds_subcover' (U := fun x hx => V x hx) (hU := fun x hx => hVnhds x hx) with + ⟨t, ht⟩ + have hsub : + K ∩ D.support ⊆ ⋃ x ∈ t, (V (x : 𝕜) x.2 ∩ D.support) := by + intro y hy + rcases hy with ⟨hyK, hyS⟩ + have hycov : y ∈ ⋃ x ∈ t, V (x : 𝕜) x.2 := ht hyK + rcases Set.mem_iUnion.1 hycov with ⟨x, hycov'⟩ + rcases Set.mem_iUnion.1 hycov' with ⟨hxT, hyV⟩ + refine Set.mem_iUnion.2 ⟨x, Set.mem_iUnion.2 ?_⟩ + exact ⟨hxT, ⟨hyV, hyS⟩⟩ + have hfinU : Set.Finite (⋃ x ∈ t, (V (x : 𝕜) x.2 ∩ D.support)) := by + classical + refine (t.finite_toSet).biUnion ?_ + intro x hx + simpa using (hVfin (x : 𝕜) x.2) + exact hfinU.subset hsub + +end MeromorphicOn +end +section +open Set + +namespace Complex.Hadamard + +def divisorZeroIndex (f : ℂ → ℂ) (U : Set ℂ) : Type := + Σ z : ℂ, Fin (Int.toNat (MeromorphicOn.divisor f U z)) + +abbrev divisorZeroIndex₀ (f : ℂ → ℂ) (U : Set ℂ) : Type := + {p : divisorZeroIndex f U // p.1 ≠ 0} + +abbrev divisorZeroIndex₀Val {f : ℂ → ℂ} {U : Set ℂ} (p : divisorZeroIndex₀ f U) : ℂ := + p.1.1 + +@[simp] +lemma divisorZeroIndex₀Val_ne_zero {f : ℂ → ℂ} {U : Set ℂ} (p : divisorZeroIndex₀ f U) : + divisorZeroIndex₀Val p ≠ 0 := p.2 + +@[simp] +lemma divisorZeroIndex₀Val_mem_divisor_support {f : ℂ → ℂ} {U : Set ℂ} + (p : divisorZeroIndex₀ f U) : + MeromorphicOn.divisor f U (divisorZeroIndex₀Val p) ≠ 0 := by + have hn : + Int.toNat (MeromorphicOn.divisor f U (divisorZeroIndex₀Val p)) ≠ 0 := by + intro h0 + have q0 : Fin 0 := by + simpa [divisorZeroIndex₀Val, h0] using p.1.2 + exact Fin.elim0 q0 + intro hdiv + have : Int.toNat (MeromorphicOn.divisor f U (divisorZeroIndex₀Val p)) = 0 := by + simp [hdiv] + exact hn this + +noncomputable def divisorCanonicalProduct (m : ℕ) (f : ℂ → ℂ) (U : Set ℂ) (z : ℂ) : ℂ := + ∏' p : divisorZeroIndex₀ f U, weierstrassFactor m (z / divisorZeroIndex₀Val p) + +@[simp] +lemma divisorCanonicalProduct_zero (m : ℕ) (f : ℂ → ℂ) (U : Set ℂ) : + divisorCanonicalProduct m f U 0 = 1 := by + simp [divisorCanonicalProduct] + +end Complex.Hadamard +end +section +namespace Complex + +section UniformMul + +theorem _root_.SiegelZeros.TendstoUniformlyOn.mul_left_bounded {ι : Type*} {p : Filter ι} {K : Set ℂ} + {F : ι → ℂ → ℂ} {f : ℂ → ℂ} {h : ℂ → ℂ} + (hF : TendstoUniformlyOn F f p K) (hh : ∃ C, ∀ z ∈ K, ‖h z‖ ≤ C) : + TendstoUniformlyOn (fun n z => h z * F n z) (fun z => h z * f z) p K := by + intro u hu + rcases Metric.mem_uniformity_dist.1 hu with ⟨ε, hεpos, hεu⟩ + rcases hh with ⟨C, hC⟩ + set C' : ℝ := max C 1 + have hC'pos : 0 < C' := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + have hC' : ∀ z ∈ K, ‖h z‖ ≤ C' := fun z hz => le_trans (hC z hz) (le_max_left _ _) + have hv : {p : ℂ × ℂ | dist p.1 p.2 < ε / C'} ∈ uniformity ℂ := + Metric.mem_uniformity_dist.2 ⟨ε / C', div_pos hεpos hC'pos, fun _ _ hab => hab⟩ + have hF' : ∀ᶠ n in p, ∀ z : ℂ, z ∈ K → dist (f z) (F n z) < ε / C' := hF _ hv + filter_upwards [hF'] with n hn z hzK + have hn' : ‖f z - F n z‖ < ε / C' := by simpa [dist_eq_norm] using hn z hzK + have hle : ‖h z‖ * ‖f z - F n z‖ ≤ C' * ‖f z - F n z‖ := + mul_le_mul_of_nonneg_right (hC' z hzK) (norm_nonneg _) + have hlt : C' * ‖f z - F n z‖ < C' * (ε / C') := mul_lt_mul_of_pos_left hn' hC'pos + have hnorm : + ‖h z * f z - h z * F n z‖ = ‖h z‖ * ‖f z - F n z‖ := by + calc + ‖h z * f z - h z * F n z‖ = ‖h z * (f z - F n z)‖ := by simp [mul_sub] + _ = ‖h z‖ * ‖f z - F n z‖ := by simp + have hdist : dist (h z * f z) (h z * F n z) < ε := by + rw [dist_eq_norm, hnorm] + have hlt' : ‖h z‖ * ‖f z - F n z‖ < ε := by + calc + ‖h z‖ * ‖f z - F n z‖ ≤ C' * ‖f z - F n z‖ := hle + _ < C' * (ε / C') := hlt + _ = ε := by field_simp [hC'pos.ne'] + exact hlt' + exact hεu hdist + +end UniformMul + +end Complex +end +section +open Filter Function _root_.SiegelZeros.Complex _root_.Function.Complex Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +lemma finite_divisorZeroIndex₀_subtype_norm_le {f : ℂ → ℂ} {U : Set ℂ} (B : ℝ) + (hBU : Metric.closedBall (0 : ℂ) B ⊆ U) : + Finite {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ B} := by + set D : Function.locallyFinsuppWithin U ℤ := MeromorphicOn.divisor f U + have hK : IsCompact (Metric.closedBall (0 : ℂ) B) := isCompact_closedBall _ _ + have hpts0 : ((Metric.closedBall (0 : ℂ) B) ∩ D.support).Finite := + MeromorphicOn.divisor_support_inter_compact_finite (f := f) (U := U) + (K := Metric.closedBall (0 : ℂ) B) hK hBU + set pts : Set ℂ := ((Metric.closedBall (0 : ℂ) B) ∩ D.support) \ {0} + have hpts : pts.Finite := hpts0.sdiff + let : Fintype pts := hpts.fintype + let T : Type := Σ z : pts, Fin (Int.toNat (D z.1)) + have : Finite T := by infer_instance + let F : + {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ B} → T := fun p => + ⟨⟨divisorZeroIndex₀Val p.1, by + have hball : divisorZeroIndex₀Val p.1 ∈ Metric.closedBall (0 : ℂ) B := by + simpa [Metric.mem_closedBall, dist_zero_right] using p.2 + have hsupport : divisorZeroIndex₀Val p.1 ∈ D.support := by + have hne_toNat : + Int.toNat (MeromorphicOn.divisor f U (divisorZeroIndex₀Val p.1)) ≠ 0 := by + intro h0 + have hpfin : + Fin (Int.toNat (MeromorphicOn.divisor f U (divisorZeroIndex₀Val p.1))) := by + simpa [D] using p.1.1.2 + have : Fin 0 := by simpa [h0] using hpfin + exact Fin.elim0 this + have hne_D : D (divisorZeroIndex₀Val p.1) ≠ 0 := by + intro hD0 + apply hne_toNat + simp [D, hD0] + simp [D, Function.locallyFinsuppWithin.support, Function.support] + have hne0 : divisorZeroIndex₀Val p.1 ≠ 0 := divisorZeroIndex₀Val_ne_zero p.1 + exact ⟨⟨hball, hsupport⟩, by simp [Set.mem_singleton_iff]⟩⟩, + p.1.1.2⟩ + refine Finite.of_injective F ?_ + intro p q hpq + apply Subtype.ext + apply Subtype.ext + have h' := (Sigma.mk.inj_iff.1 hpq) + have hz : divisorZeroIndex₀Val p.1 = divisorZeroIndex₀Val q.1 := congrArg Subtype.val h'.1 + apply (Sigma.mk.inj_iff).2 + refine ⟨hz, ?_⟩ + exact h'.2 + +lemma divisorZeroIndex₀_norm_le_finite {f : ℂ → ℂ} {U : Set ℂ} (B : ℝ) + (hBU : Metric.closedBall (0 : ℂ) B ⊆ U) : + ({p : divisorZeroIndex₀ f U | ‖divisorZeroIndex₀Val p‖ ≤ B} : Set _).Finite := by + let s : Set (divisorZeroIndex₀ f U) := {p | ‖divisorZeroIndex₀Val p‖ ≤ B} + have : Finite (↥s) := + finite_divisorZeroIndex₀_subtype_norm_le (f := f) (U := U) B hBU + exact Set.toFinite s + +lemma norm_div_le_half_of_norm_le_of_two_mul_lt {z a : ℂ} {R : ℝ} + (hR : 0 < R) (hz : ‖z‖ ≤ R) (ha : (2 * R : ℝ) < ‖a‖) : + ‖z / a‖ ≤ (1 / 2 : ℝ) := by + have h2R_pos : 0 < (2 * R : ℝ) := by nlinarith [hR] + have hinv : ‖a‖⁻¹ < (2 * R)⁻¹ := by + simpa [one_div] using one_div_lt_one_div_of_lt h2R_pos ha + have hmul_le : ‖z‖ * ‖a‖⁻¹ ≤ R * ‖a‖⁻¹ := + mul_le_mul_of_nonneg_right hz (inv_nonneg.2 (norm_nonneg a)) + have hmul_lt : R * ‖a‖⁻¹ < R * (2 * R)⁻¹ := + mul_lt_mul_of_pos_left hinv hR + have hRhalf : R * (2 * R)⁻¹ = (1 / 2 : ℝ) := by + have hRne : (R : ℝ) ≠ 0 := hR.ne' + rw [show R * (2 * R)⁻¹ = R / (2 * R) by simp [div_eq_mul_inv]] + field_simp [hRne] + have hnorm : ‖z / a‖ = ‖z‖ * ‖a‖⁻¹ := by + simp [div_eq_mul_inv] + exact le_of_lt <| by + calc + ‖z / a‖ = ‖z‖ * ‖a‖⁻¹ := hnorm + _ ≤ R * ‖a‖⁻¹ := hmul_le + _ < R * (2 * R)⁻¹ := hmul_lt + _ = (1 / 2 : ℝ) := hRhalf + +theorem summable_logDerivTerms_divisorZeroIndex₀_of_summable_inv_sq + {f : ℂ → ℂ} {z : ℂ} + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (2 : ℕ))) + (hz : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), z ≠ divisorZeroIndex₀Val p) : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + 1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := by + let R : ℝ := max ‖z‖ 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + have hzle : ‖z‖ ≤ R := le_max_left _ _ + let u : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (2 * R) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (2 : ℕ)) + have hu : Summable u := h_sum.mul_left (2 * R) + refine hu.of_norm_bounded_eventually ?_ + have h_big : + ∀ᶠ p : divisorZeroIndex₀ f (Set.univ : Set ℂ) in Filter.cofinite, + (2 * R : ℝ) < ‖divisorZeroIndex₀Val p‖ := by + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ + 2 * R} : Set _).Finite := by + have : Metric.closedBall (0 : ℂ) (2 * R) ⊆ (Set.univ : Set ℂ) := by simp + exact divisorZeroIndex₀_norm_le_finite + (f := f) (U := (Set.univ : Set ℂ)) (B := 2 * R) this + have := hfin.eventually_cofinite_notMem + filter_upwards [this] with p hp + have : ¬ ‖divisorZeroIndex₀Val p‖ ≤ 2 * R := by simpa using hp + exact lt_of_not_ge this + filter_upwards [h_big] with p hp + let a : ℂ := divisorZeroIndex₀Val p + have ha0 : a ≠ 0 := divisorZeroIndex₀Val_ne_zero p + have hza0 : z - a ≠ 0 := sub_ne_zero.mpr (hz p) + have hterm : 1 / (z - a) + 1 / a = z / (a * (z - a)) := by + field_simp [ha0, hza0] + ring + have htri : ‖a‖ ≤ ‖z‖ + ‖z - a‖ := by + have hraw : ‖a‖ ≤ ‖z‖ + ‖a - z‖ := by + have h := norm_add_le z (a - z) + simpa [a, sub_eq_add_neg, add_assoc, add_left_comm, add_comm] using h + simpa [norm_sub_rev] using hraw + have hza_lower : ‖a‖ / 2 ≤ ‖z - a‖ := by + nlinarith [htri, hzle, hp] + have hnorm : ‖1 / (z - a) + 1 / a‖ ≤ (2 * R) * (‖a‖⁻¹ ^ (2 : ℕ)) := by + rw [hterm, norm_div, norm_mul] + have ha_norm_pos : 0 < ‖a‖ := norm_pos_iff.mpr ha0 + have hza_norm_pos : 0 < ‖z - a‖ := norm_pos_iff.mpr hza0 + rw [div_eq_mul_inv] + calc + ‖z‖ * (‖a‖ * ‖z - a‖)⁻¹ + = ‖z‖ * ‖a‖⁻¹ * ‖z - a‖⁻¹ := by + field_simp [ha_norm_pos.ne', hza_norm_pos.ne'] + _ ≤ R * ‖a‖⁻¹ * ‖z - a‖⁻¹ := by + gcongr + _ ≤ R * ‖a‖⁻¹ * (2 * ‖a‖⁻¹) := by + gcongr + have hhalf_pos : 0 < ‖a‖ / 2 := by positivity + have hinv : ‖z - a‖⁻¹ ≤ (‖a‖ / 2)⁻¹ := by + simpa [one_div] using one_div_le_one_div_of_le hhalf_pos hza_lower + have hhalf_inv : (‖a‖ / 2)⁻¹ = 2 * ‖a‖⁻¹ := by field_simp [ha_norm_pos.ne'] + simpa [hhalf_inv] using hinv + _ = (2 * R) * (‖a‖⁻¹ ^ (2 : ℕ)) := by ring + simpa [u, a] using hnorm + +theorem hasProdUniformlyOn_divisorCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) {K : Set ℂ} (hK : IsCompact K) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + HasProdUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) K := by + rcases (isBounded_iff_forall_norm_le.1 hK.isBounded) with ⟨R0, hR0⟩ + set R : ℝ := max R0 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + have hnormK : ∀ z ∈ K, ‖z‖ ≤ R := fun z hzK => le_trans (hR0 z hzK) (le_max_left _ _) + let g : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p z => weierstrassFactor m (z / divisorZeroIndex₀Val p) - 1 + let u : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (4 * R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) + have hu : Summable u := h_sum.mul_left (4 * R ^ (m + 1)) + have h_big : + ∀ᶠ p : divisorZeroIndex₀ f (Set.univ : Set ℂ) in Filter.cofinite, + (2 * R : ℝ) < ‖divisorZeroIndex₀Val p‖ := by + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ 2 * R} : + Set _).Finite := by + have : Metric.closedBall (0 : ℂ) (2 * R) ⊆ (Set.univ : Set ℂ) := by simp + exact divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) (B := 2 * R) this + have := hfin.eventually_cofinite_notMem + filter_upwards [this] with p hp + have : ¬ ‖divisorZeroIndex₀Val p‖ ≤ 2 * R := by simpa using hp + exact lt_of_not_ge this + have hBound : + ∀ᶠ p in Filter.cofinite, ∀ z ∈ K, ‖g p z‖ ≤ u p := by + filter_upwards [h_big] with p hp z hzK + have hzle : ‖z‖ ≤ R := hnormK z hzK + have hz_div : ‖z / divisorZeroIndex₀Val p‖ ≤ (1 / 2 : ℝ) := by + exact norm_div_le_half_of_norm_le_of_two_mul_lt hRpos hzle hp + have hE : + ‖weierstrassFactor m (z / divisorZeroIndex₀Val p) - 1‖ ≤ + 4 * ‖z / divisorZeroIndex₀Val p‖ ^ (m + 1) := + weierstrassFactor_sub_one_pow_bound (m := m) (z := z / divisorZeroIndex₀Val p) hz_div + have hz_pow : + ‖z / divisorZeroIndex₀Val p‖ ^ (m + 1) ≤ + (R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + have : ‖z / divisorZeroIndex₀Val p‖ = ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + rw [this] + have : (‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹) ^ (m + 1) = + ‖z‖ ^ (m + 1) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + simp [mul_pow] + rw [this] + have hzle_pow : ‖z‖ ^ (m + 1) ≤ R ^ (m + 1) := + pow_le_pow_left₀ (norm_nonneg z) hzle (m + 1) + gcongr + dsimp [g, u] + nlinarith [hE, hz_pow] + have hcts : ∀ p, ContinuousOn (g p) K := by + intro p + have hcontE : Continuous (fun z : ℂ => weierstrassFactor m z) := + (differentiable_weierstrassFactor m).continuous + have hdiv : Continuous fun z : ℂ => z / divisorZeroIndex₀Val p := by + simpa [div_eq_mul_inv] using! (continuous_id.mul continuous_const) + have hcont : Continuous fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) := + hcontE.comp hdiv + simpa only [g] using hcont.continuousOn.fun_sub continuous_const.continuousOn + have hprod : + HasProdUniformlyOn (fun p z ↦ 1 + g p z) (fun z ↦ ∏' p, (1 + g p z)) K := by + simpa using + Summable.hasProdUniformlyOn_one_add (f := g) (u := u) (K := K) hK hu hBound hcts + simpa [g, divisorCanonicalProduct, sub_eq_add_neg, add_assoc, add_left_comm, add_comm] + using! hprod + +theorem hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + (Set.univ : Set ℂ) := by + refine hasProdLocallyUniformlyOn_of_forall_compact + (f := fun p z => weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (g := divisorCanonicalProduct m f (Set.univ : Set ℂ)) + (s := (Set.univ : Set ℂ)) isOpen_univ ?_ + intro K hKU hK + simpa using + (hasProdUniformlyOn_divisorCanonicalProduct_univ (m := m) (f := f) (K := K) hK h_sum) + +theorem differentiableOn_divisorCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + DifferentiableOn ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) (Set.univ : Set ℂ) := by + have hloc : + TendstoLocallyUniformlyOn + (fun (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) => + ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + Filter.atTop (Set.univ : Set ℂ) := by + simpa [HasProdLocallyUniformlyOn] using + (hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum) + have hF : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in Filter.atTop, + DifferentiableOn ℂ + (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (Set.univ : Set ℂ) := by + refine Filter.Eventually.of_forall ?_ + intro s + have hdiff : + Differentiable ℂ + (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) := by + let F : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p z => weierstrassFactor m (z / divisorZeroIndex₀Val p) + have hF' : ∀ p ∈ s, Differentiable ℂ (F p) := by + intro p hp + have hdiv : Differentiable ℂ (fun z : ℂ => z / divisorZeroIndex₀Val p) := by + have : Differentiable ℂ (fun z : ℂ => z * ((divisorZeroIndex₀Val p)⁻¹)) := + (differentiable_id : Differentiable ℂ (fun z : ℂ => z)).mul_const + ((divisorZeroIndex₀Val p)⁻¹) + simp [div_eq_mul_inv] + exact (differentiable_weierstrassFactor m).comp hdiv + simpa [F] using (Differentiable.fun_finsetProd (𝕜 := ℂ) (f := F) (u := s) hF') + simpa using hdiff.differentiableOn + have : (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))).NeBot := + Filter.atTop_neBot + exact hloc.differentiableOn hF isOpen_univ + +theorem differentiableAt_divisorCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) (z : ℂ) : + DifferentiableAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := + ((differentiableOn_divisorCanonicalProduct_univ m f h_sum) z (by simp)).differentiableAt + (by simp) + +theorem logDeriv_divisorCanonicalProduct_one_eq_tsum + {f : ℂ → ℂ} {z : ℂ} + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (2 : ℕ))) + (hz : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), z ≠ divisorZeroIndex₀Val p) + (hprod_ne : divisorCanonicalProduct 1 f (Set.univ : Set ℂ) z ≠ 0) : + logDeriv (divisorCanonicalProduct 1 f (Set.univ : Set ℂ)) z = + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := by + let Φ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p w => weierstrassFactor 1 (w / divisorZeroIndex₀Val p) + have hf : ∀ p, Φ p z ≠ 0 := by + intro p + have hp0 : divisorZeroIndex₀Val p ≠ 0 := divisorZeroIndex₀Val_ne_zero p + refine weierstrassFactor_ne_zero_of_ne_one 1 ?_ + intro h + exact hz p ((div_eq_one_iff_eq hp0).1 h) + have hd : ∀ p, DifferentiableOn ℂ (Φ p) (Set.univ : Set ℂ) := by + intro p + have hdiv : Differentiable ℂ (fun w : ℂ => w / divisorZeroIndex₀Val p) := by + have : Differentiable ℂ (fun w : ℂ => w * ((divisorZeroIndex₀Val p)⁻¹)) := + (differentiable_id : Differentiable ℂ (fun w : ℂ => w)).mul_const + ((divisorZeroIndex₀Val p)⁻¹) + simp [div_eq_mul_inv] + exact ((differentiable_weierstrassFactor 1).comp hdiv).differentiableOn + have hm' : Summable fun p => logDeriv (Φ p) z := by + have hm : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + 1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := + summable_logDerivTerms_divisorZeroIndex₀_of_summable_inv_sq h_sum hz + refine hm.congr ?_ + intro p + have hp0 : divisorZeroIndex₀Val p ≠ 0 := divisorZeroIndex₀Val_ne_zero p + simpa [Φ] using + (Complex.logDeriv_weierstrassFactor_one_div + (a := divisorZeroIndex₀Val p) (z := z) hp0 (hz p)).symm + have htend : MultipliableLocallyUniformlyOn Φ (Set.univ : Set ℂ) := by + have hprod := hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ + (m := 1) (f := f) h_sum + simpa [Φ, divisorCanonicalProduct] using hprod.multipliableLocallyUniformlyOn + have hnez : (∏' p, Φ p z) ≠ 0 := by + simpa [Φ, divisorCanonicalProduct] using hprod_ne + have hlog : logDeriv (∏' p, Φ p ·) z = ∑' p, logDeriv (Φ p) z := + logDeriv_tprod_eq_tsum (s := (Set.univ : Set ℂ)) isOpen_univ (by simp) + hf hd hm' htend hnez + calc + logDeriv (divisorCanonicalProduct 1 f (Set.univ : Set ℂ)) z + = ∑' p, logDeriv (Φ p) z := by + simpa [Φ, divisorCanonicalProduct] using! hlog + _ = ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := by + refine tsum_congr fun p => ?_ + have hp0 : divisorZeroIndex₀Val p ≠ 0 := divisorZeroIndex₀Val_ne_zero p + simpa [Φ] using + Complex.logDeriv_weierstrassFactor_one_div + (a := divisorZeroIndex₀Val p) (z := z) hp0 (hz p) + +end Complex.Hadamard +end +section +noncomputable section + +open Set +open scoped Topology BigOperators + +namespace Complex.Hadamard + +lemma divisor_univ_eq_analyticOrderNatAt_int {f : ℂ → ℂ} (hf : Differentiable ℂ f) (z : ℂ) : + MeromorphicOn.divisor f (Set.univ : Set ℂ) z = (analyticOrderNatAt f z : ℤ) := by + have hmero : MeromorphicOn f (Set.univ : Set ℂ) := by + intro w hw + exact (Differentiable.analyticAt (f := f) hf w).meromorphicAt + simp only + [MeromorphicOn.divisor_apply hmero (by simp : z ∈ (Set.univ : Set ℂ)), analyticOrderNatAt] + have han : AnalyticAt ℂ f z := Differentiable.analyticAt (f := f) hf z + cases h : analyticOrderAt f z with + | top => + simp [han.meromorphicOrderAt_eq, h] + | coe n => + simp [han.meromorphicOrderAt_eq, h] + +theorem divisorZeroIndex₀_fiber_finite (f : ℂ → ℂ) (z₀ : ℂ) : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | divisorZeroIndex₀Val p = z₀} : + Set _).Finite := by + have hsub : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | divisorZeroIndex₀Val p = z₀} : Set _) + ⊆ ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ ‖z₀‖} : + Set _) := by + intro p hp + have : divisorZeroIndex₀Val p = z₀ := hp + simp [this] + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ ‖z₀‖} : + Set _).Finite := by + have : Metric.closedBall (0 : ℂ) ‖z₀‖ ⊆ (Set.univ : Set ℂ) := by simp + simpa using (divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) + (B := ‖z₀‖) this) + exact hfin.subset hsub + +def divisorZeroIndex₀FiberFinset (f : ℂ → ℂ) (z₀ : ℂ) : + Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + (divisorZeroIndex₀_fiber_finite (f := f) z₀).toFinset + +@[simp] +lemma mem_divisorZeroIndex₀FiberFinset (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) : + p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ ↔ divisorZeroIndex₀Val p = z₀ := by + simp [divisorZeroIndex₀FiberFinset] + +theorem eventually_atTop_subset_fiberFinset + (f : ℂ → ℂ) (z₀ : ℂ) : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in (Filter.atTop : Filter _), + divisorZeroIndex₀FiberFinset (f := f) z₀ ⊆ s := by + refine (Filter.eventually_atTop.2 ?_) + refine ⟨divisorZeroIndex₀FiberFinset (f := f) z₀, ?_⟩ + intro s hs + exact hs + +lemma divisorZeroIndex₀FiberFinset_card_eq_toNat_divisor (f : ℂ → ℂ) {z₀ : ℂ} (hz₀ : z₀ ≠ 0) : + (divisorZeroIndex₀FiberFinset (f := f) z₀).card = + Int.toNat (MeromorphicOn.divisor f (Set.univ : Set ℂ) z₀) := by + let S : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := {p | divisorZeroIndex₀Val p = z₀} + have hS : S.Finite := divisorZeroIndex₀_fiber_finite (f := f) z₀ + set n : ℕ := Int.toNat (MeromorphicOn.divisor f (Set.univ : Set ℂ) z₀) + have hcard : Nat.card S = n := by + classical + have : Fintype S := hS.fintype + + let e : S ≃ Fin n := + { toFun := by + intro x + rcases x with ⟨p, hp⟩ + rcases p with ⟨⟨z, q⟩, hz⟩ + have hzEq : z = z₀ := by simpa [divisorZeroIndex₀Val] using! hp + subst hzEq + simpa [n] using q + invFun := by + intro q + refine ⟨⟨⟨z₀, ?_⟩, hz₀⟩, ?_⟩ + · simpa [n] using q + · simp [S, divisorZeroIndex₀Val] + left_inv := by + rintro ⟨p, hp⟩ + rcases p with ⟨⟨z, q⟩, hz⟩ + have hzEq : z = z₀ := by simpa [divisorZeroIndex₀Val] using! hp + subst hzEq + (ext; rfl) + right_inv := by + intro q + rfl } + have h := Nat.card_congr (α := S) (β := Fin n) e + simpa using (h.trans (by simp)) + have hSncard : S.ncard = n := by + simpa [Nat.card_coe_set_eq] using hcard + have hto : hS.toFinset = divisorZeroIndex₀FiberFinset (f := f) z₀ := by + rfl + have htoFinset : S.ncard = (divisorZeroIndex₀FiberFinset (f := f) z₀).card := by + have h' : S.ncard = hS.toFinset.card := Set.ncard_eq_toFinset_card S hS + simpa [hto] using h' + exact htoFinset.symm.trans hSncard + +lemma divisorZeroIndex₀FiberFinset_card_eq_analyticOrderNatAt + {f : ℂ → ℂ} (hf : Differentiable ℂ f) {z₀ : ℂ} (hz₀ : z₀ ≠ 0) : + (divisorZeroIndex₀FiberFinset (f := f) z₀).card = analyticOrderNatAt f z₀ := by + have hdiv : + MeromorphicOn.divisor f (Set.univ : Set ℂ) z₀ = (analyticOrderNatAt f z₀ : ℤ) := + divisor_univ_eq_analyticOrderNatAt_int (f := f) hf z₀ + have htoNat : Int.toNat (MeromorphicOn.divisor f (Set.univ : Set ℂ) z₀) = + analyticOrderNatAt f z₀ := by + simp [hdiv] + exact (divisorZeroIndex₀FiberFinset_card_eq_toNat_divisor (f := f) (z₀ := z₀) hz₀).trans htoNat + +lemma not_mem_divisorZeroIndex₀FiberFinset_iff_val_ne + {f : ℂ → ℂ} (z₀ : ℂ) (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) : + p ∉ divisorZeroIndex₀FiberFinset (f := f) z₀ ↔ divisorZeroIndex₀Val p ≠ z₀ := by + simp [mem_divisorZeroIndex₀FiberFinset] + +end Complex.Hadamard +end +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/DivisorLimits.lean b/PrimeNumberTheoremAnd/SiegelZeros/DivisorLimits.lean new file mode 100644 index 0000000..4325f1f --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/DivisorLimits.lean @@ -0,0 +1,422 @@ +import Mathlib +import PrimeNumberTheoremAnd.SiegelZeros.DivisorProducts + +namespace SiegelZeros + +section +open Filter Function _root_.SiegelZeros.Complex _root_.Function.Complex Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +theorem differentiableOn_divisorPartialProduct_div_pow_sub + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) (k : ℕ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) : + DifferentiableOn ℂ (fun z : ℂ => (divisorPartialProduct m f s z) / (z - z₀) ^ k) + ((Set.univ : Set ℂ) \ {z₀}) := by + have hdiff_prod : DifferentiableOn ℂ (divisorPartialProduct m f s) (Set.univ : Set ℂ) := by + exact (differentiable_divisorPartialProduct m f s).differentiableOn + have hdiff_den : DifferentiableOn ℂ (fun z : ℂ => (z - z₀) ^ k) ((Set.univ : Set ℂ) \ {z₀}) := by + have : Differentiable ℂ (fun z : ℂ => (z - z₀) ^ k) := by + fun_prop + exact this.differentiableOn + by_cases hk : k = 0 + · subst hk + simpa [pow_zero] using! (hdiff_prod.mono (by intro z hz; exact hz.1)) + · have hne : ∀ z ∈ ((Set.univ : Set ℂ) \ {z₀}), (fun z : ℂ => (z - z₀) ^ k) z ≠ 0 := by + intro z hz + have hz' : z ≠ z₀ := by + simpa [Set.mem_sdiff, Set.mem_singleton_iff] using hz.2 + exact pow_ne_zero _ (sub_ne_zero.mpr hz') + have hdiff_inv : + DifferentiableOn ℂ (fun z : ℂ => ((z - z₀) ^ k)⁻¹) ((Set.univ : Set ℂ) \ {z₀}) := + hdiff_den.inv hne + simpa [div_eq_mul_inv] using! (hdiff_prod.mono (by intro z hz; exact hz.1)).mul hdiff_inv + +theorem differentiableOn_divisorCanonicalProduct_div_pow_sub + (m : ℕ) (f : ℂ → ℂ) (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) (k : ℕ) : DifferentiableOn ℂ + (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ k) + ((Set.univ : Set ℂ) \ {z₀}) := by + have hopen : IsOpen ((Set.univ : Set ℂ) \ {z₀}) := by + have hset : ((Set.univ : Set ℂ) \ {z₀}) = ({z₀} : Set ℂ)ᶜ := by + ext z; simp + simp [hset] + have hconv := + tendstoLocallyUniformlyOn_divisorPartialProduct_div_pow_sub + (m := m) (f := f) h_sum (z₀ := z₀) (k := k) + refine hconv.differentiableOn ?_ hopen + refine Filter.Eventually.of_forall ?_ + intro s + exact differentiableOn_divisorPartialProduct_div_pow_sub (m := m) (f := f) (z₀ := z₀) (k := k) s + +theorem differentiableOn_update_limUnder_divisorCanonicalProduct_div_pow + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : ∃ r > 0, DifferentiableOn ℂ (Function.update + (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) z₀ + (limUnder (𝓝[≠] z₀) (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card))) + (Metric.ball z₀ r) := by + rcases bddAbove_norm_divisorCanonicalProduct_div_pow_puncturedBall (m := m) (f := f) + (h_sum := h_sum) (z₀ := z₀) with ⟨r, hrpos, hbdd⟩ + refine ⟨r, hrpos, ?_⟩ + have hnhds : Metric.ball z₀ r ∈ 𝓝 z₀ := Metric.ball_mem_nhds z₀ hrpos + have hdiff : DifferentiableOn ℂ (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + ((Metric.ball z₀ r) \ {z₀}) := by + have hglob := + differentiableOn_divisorCanonicalProduct_div_pow_sub + (m := m) (f := f) h_sum (z₀ := z₀) + (k := (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + refine hglob.mono ?_ + intro z hz + exact ⟨by simp, hz.2⟩ + have hb : BddAbove (norm ∘ (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) '' + ((Metric.ball z₀ r) \ {z₀})) := hbdd + simpa using + (Complex.differentiableOn_update_limUnder_of_bddAbove (f := fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + (s := Metric.ball z₀ r) (c := z₀) hnhds hdiff hb) + +theorem analyticAt_update_limUnder_divisorCanonicalProduct_div_pow + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : AnalyticAt ℂ (Function.update (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) z₀ + (limUnder (𝓝[≠] z₀) (fun z : ℂ => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card))) + z₀ := by + rcases + differentiableOn_update_limUnder_divisorCanonicalProduct_div_pow + (m := m) (f := f) h_sum (z₀ := z₀) with ⟨r, hrpos, hdiff⟩ + let g : ℂ → ℂ := + Function.update + (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + z₀ + (limUnder (𝓝[≠] z₀) fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + have hcont : ContinuousAt g z₀ := + (hdiff.differentiableAt (Metric.ball_mem_nhds z₀ hrpos)).continuousAt + have hd : + ∀ᶠ z in 𝓝[≠] z₀, DifferentiableAt ℂ g z := by + have hballWithin : Metric.ball z₀ r ∈ 𝓝[≠] z₀ := by + refine mem_nhdsWithin_iff_exists_mem_nhds_inter.2 ?_ + refine ⟨Metric.ball z₀ r, Metric.ball_mem_nhds z₀ hrpos, ?_⟩ + intro z hz + exact hz.1 + filter_upwards [hballWithin] with z hz + exact (hdiff z hz).differentiableAt (Metric.isOpen_ball.mem_nhds hz) + simpa [g] using Complex.analyticAt_of_differentiable_on_punctured_nhds_of_continuousAt hd hcont + +theorem exists_analyticAt_divisorCanonicalProduct_quotient + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : + ∃ q : ℂ → ℂ, + AnalyticAt ℂ q z₀ ∧ + q z₀ = + limUnder (𝓝[≠] z₀) (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) ∧ + ∀ z : ℂ, z ≠ z₀ → + q z = + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card := by + let q : ℂ → ℂ := + Function.update + (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + z₀ + (limUnder (𝓝[≠] z₀) fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) + refine ⟨q, ?_, ?_, ?_⟩ + · simpa [q] using + analyticAt_update_limUnder_divisorCanonicalProduct_div_pow + (m := m) (f := f) (h_sum := h_sum) (z₀ := z₀) + · simp [q] + · intro z hz + simp [q, Function.update_of_ne hz] + +theorem analyticOrderNatAt_divisorCanonicalProduct_eq_fiber_card + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z₀ = + (divisorZeroIndex₀FiberFinset (f := f) z₀).card := by + set k : ℕ := (divisorZeroIndex₀FiberFinset (f := f) z₀).card + let F : ℂ → ℂ := divisorCanonicalProduct m f (Set.univ : Set ℂ) + let q0 : ℂ → ℂ := fun z => F z / (z - z₀) ^ k + rcases exists_analyticAt_divisorCanonicalProduct_quotient + (m := m) (f := f) (h_sum := h_sum) (z₀ := z₀) with + ⟨q, hqA, hq_self, hq_ne⟩ + have hdiff_univ : DifferentiableOn ℂ F (Set.univ : Set ℂ) := + differentiableOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + have han : AnalyticAt ℂ F z₀ := by + refine (Complex.analyticAt_iff_eventually_differentiableAt).2 ?_ + refine Filter.Eventually.of_forall ?_ + intro z + have : DifferentiableWithinAt ℂ F (Set.univ : Set ℂ) z := hdiff_univ z (by simp) + exact this.differentiableAt (by simp) + rcases + exists_ball_eq_divisorCanonicalProduct_div_pow_eq (m := m) (f := f) (h_sum := h_sum) + (z₀ := z₀) + with ⟨ε, hε, u, huA, hu0, hEq⟩ + let g : ℂ → ℂ := fun z => (divisorComplementCanonicalProduct m f z₀ z) * u z + have hcompDiff : DifferentiableOn ℂ (divisorComplementCanonicalProduct m f z₀) + (Set.univ : Set ℂ) := + differentiableOn_divisorComplementCanonicalProduct_univ (m := m) (f := f) (z₀ := z₀) h_sum + have hcompCont : ContinuousAt (divisorComplementCanonicalProduct m f z₀) z₀ := + (hcompDiff z₀ (by simp)).differentiableAt (by simp) |>.continuousAt + have hgCont : ContinuousAt g z₀ := (hcompCont.mul huA.continuousAt) + have hg0 : g z₀ ≠ 0 := by + have hcomp0 : divisorComplementCanonicalProduct m f z₀ z₀ ≠ 0 := + divisorComplementCanonicalProduct_ne_zero_at (m := m) (f := f) (z₀ := z₀) h_sum + exact mul_ne_zero hcomp0 hu0 + have hne_mem : ∀ᶠ z in 𝓝[≠] z₀, z ∈ (({z₀} : Set ℂ)ᶜ) := + Filter.eventually_of_mem + (self_mem_nhdsWithin : (({z₀} : Set ℂ)ᶜ) ∈ 𝓝[≠] z₀) (fun _ hz => hz) + have hne : ∀ᶠ z in 𝓝[≠] z₀, z ≠ z₀ := by + filter_upwards [hne_mem] with z hz + simpa [Set.mem_compl_singleton_iff] using hz + have ht_q0 : Tendsto q0 (𝓝[≠] z₀) (𝓝 (g z₀)) := by + have hball : ∀ᶠ z in 𝓝[≠] z₀, z ∈ Metric.ball z₀ ε := + Filter.eventually_of_mem + (mem_nhdsWithin_of_mem_nhds (Metric.ball_mem_nhds z₀ hε)) (fun _ hz => hz) + have heq : q0 =ᶠ[𝓝[≠] z₀] g := by + filter_upwards [hball, hne] with z hz hzne + have hq := hEq z hz hzne + simpa [q0, F, k, g, smul_eq_mul] using hq + exact (hgCont.continuousWithinAt.tendsto.congr' heq.symm) + have hlim : limUnder (𝓝[≠] z₀) q0 = g z₀ := ht_q0.limUnder_eq + have hq0 : q z₀ ≠ 0 := by + have hq_self' : q z₀ = limUnder (𝓝[≠] z₀) q0 := by + simpa [q0, F, k] using hq_self + have : q z₀ = g z₀ := hq_self'.trans hlim + exact this.symm ▸ hg0 + have heq_punct : (fun z : ℂ => F z) =ᶠ[𝓝[≠] z₀] fun z : ℂ => (z - z₀) ^ k • q z := by + filter_upwards [hne] with z hz + have hzpow : (z - z₀) ^ k ≠ 0 := pow_ne_zero _ (sub_ne_zero.mpr hz) + have hq : q z = q0 z := by simpa [q0, F, k] using hq_ne z hz + have hmul : (z - z₀) ^ k * q0 z = F z := by + calc + (z - z₀) ^ k * q0 z + = (((z - z₀) ^ k) * F z) / ((z - z₀) ^ k) := by + simp [q0, div_eq_mul_inv, mul_assoc] + _ = F z := by + simpa [mul_assoc] using (mul_div_cancel_left₀ (F z) hzpow) + have : F z = (z - z₀) ^ k * q z := by + calc + F z = (z - z₀) ^ k * q0 z := hmul.symm + _ = (z - z₀) ^ k * q z := by simp [hq] + simpa [smul_eq_mul] using this + have hcontF : ContinuousAt F z₀ := + (hdiff_univ z₀ (by simp)).differentiableAt (by simp) |>.continuousAt + have hcontq : ContinuousAt q z₀ := hqA.continuousAt + have h_at_z0 : F z₀ = (z₀ - z₀) ^ k • q z₀ := by + have ht1 : Tendsto F (𝓝[≠] z₀) (𝓝 (F z₀)) := hcontF.continuousWithinAt.tendsto + have hpow : + Tendsto (fun z : ℂ => (z - z₀) ^ k) (𝓝[≠] z₀) (𝓝 ((z₀ - z₀) ^ k)) := + ((continuousAt_id.sub continuousAt_const).pow k).continuousWithinAt.tendsto + have ht2 : + Tendsto (fun z : ℂ => (z - z₀) ^ k • q z) (𝓝[≠] z₀) + (𝓝 ((z₀ - z₀) ^ k • q z₀)) := + hpow.mul (hcontq.continuousWithinAt.tendsto) + have ht2' : Tendsto F (𝓝[≠] z₀) (𝓝 ((z₀ - z₀) ^ k • q z₀)) := + ht2.congr' heq_punct.symm + exact tendsto_nhds_unique ht1 ht2' + have hfac : ∀ᶠ z in 𝓝 z₀, F z = (z - z₀) ^ k • q z := by + have hball1 : Metric.ball z₀ 1 ∈ 𝓝 z₀ := Metric.ball_mem_nhds z₀ (by norm_num) + have hball1' : ∀ᶠ z in 𝓝 z₀, z ∈ Metric.ball z₀ 1 := + Filter.eventually_of_mem hball1 (fun _ hz => hz) + filter_upwards [hball1'] with z _hz + by_cases hz0 : z = z₀ + · subst hz0 + simpa using h_at_z0 + · have hzpow : (z - z₀) ^ k ≠ 0 := pow_ne_zero _ (sub_ne_zero.mpr hz0) + have hq : q z = q0 z := by simpa [q0, F, k] using hq_ne z hz0 + have hmul : (z - z₀) ^ k * q0 z = F z := by + calc + (z - z₀) ^ k * q0 z + = (((z - z₀) ^ k) * F z) / ((z - z₀) ^ k) := by + simp [q0, div_eq_mul_inv, mul_assoc] + _ = F z := by + simpa [mul_assoc] using (mul_div_cancel_left₀ (F z) hzpow) + have : F z = (z - z₀) ^ k * q z := by + calc + F z = (z - z₀) ^ k * q0 z := hmul.symm + _ = (z - z₀) ^ k * q z := by simp [hq] + simpa [smul_eq_mul] using this + have hk' : analyticOrderAt F z₀ = k := + (han.analyticOrderAt_eq_natCast (n := k)).2 ⟨q, hqA, hq0, hfac⟩ + have hkNat : analyticOrderNatAt F z₀ = k := by + simp [analyticOrderNatAt, hk'] + simpa [F, k] using hkNat + +theorem analyticOrderNatAt_divisorCanonicalProduct_eq_analyticOrderNatAt + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + {z₀ : ℂ} (hz₀ : z₀ ≠ 0) : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z₀ = + analyticOrderNatAt f z₀ := by + have hcp : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z₀ = + (divisorZeroIndex₀FiberFinset (f := f) z₀).card := + analyticOrderNatAt_divisorCanonicalProduct_eq_fiber_card (m := m) (f := f) (h_sum := h_sum) + (z₀ := z₀) + have hfib : + (divisorZeroIndex₀FiberFinset (f := f) z₀).card = analyticOrderNatAt f z₀ := + divisorZeroIndex₀FiberFinset_card_eq_analyticOrderNatAt (hf := hf) (z₀ := z₀) hz₀ + simpa [hfib] using hcp + +end Complex.Hadamard +end +section +namespace Complex.Hadamard + +open scoped Topology +open Set + +lemma analyticOrderAt_ne_top_of_exists_ne_zero {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (hnot : ∃ z : ℂ, f z ≠ 0) : + ∀ z : ℂ, analyticOrderAt f z ≠ ⊤ := by + rcases hnot with ⟨z1, hz1⟩ + have hf_an : AnalyticOnNhd ℂ f (Set.univ : Set ℂ) := by + intro z hz + exact (Differentiable.analyticAt (f := f) hf z) + have hz1_not_top : analyticOrderAt f z1 ≠ ⊤ := by + have : analyticOrderAt f z1 = 0 := + (hf.analyticAt z1).analyticOrderAt_eq_zero.2 hz1 + simp [this] + intro z + exact AnalyticOnNhd.analyticOrderAt_ne_top_of_isPreconnected (hf := hf_an) + (U := (Set.univ : Set ℂ)) (x := z1) (y := z) (by simpa using isPreconnected_univ) + (by simp) (by simp) hz1_not_top + +lemma no_zero_on_sphere_of_forall_val_norm_ne + {f : ℂ → ℂ} (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + {B r : ℝ} (hrpos : 0 < r) (hBr : r ≤ B) (hr_not : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖ ≤ B → r ≠ ‖divisorZeroIndex₀Val p‖) : + ∀ u : ℂ, ‖u‖ = r → f u ≠ 0 := by + intro u hur + have hu0 : u ≠ 0 := by + intro hu0 + subst hu0 + have : (0 : ℝ) = r := by simpa using hur + exact (ne_of_gt hrpos) this.symm + intro hfu0 + have hnotTop : analyticOrderAt f u ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (f := f) hf hnot u + have hord_ne0 : analyticOrderNatAt f u ≠ 0 := by + intro h0 + have hEN : (analyticOrderNatAt f u : ENat) = 0 := by simp [h0] + have hAt0 : analyticOrderAt f u = 0 := by + have hcast : (analyticOrderNatAt f u : ENat) = analyticOrderAt f u := + Nat.cast_analyticOrderNatAt (f := f) (z₀ := u) hnotTop + simpa [hcast] using hEN + have han : AnalyticAt ℂ f u := Differentiable.analyticAt (f := f) hf u + exact ((han.analyticOrderAt_eq_zero).1 hAt0) hfu0 + have hcard_pos : 0 < (divisorZeroIndex₀FiberFinset (f := f) u).card := by + have hcard := + divisorZeroIndex₀FiberFinset_card_eq_analyticOrderNatAt (hf := hf) (z₀ := u) hu0 + have : 0 < analyticOrderNatAt f u := Nat.pos_of_ne_zero hord_ne0 + simpa [hcard] using this + rcases Finset.card_pos.mp hcard_pos with ⟨p, hp⟩ + have hpval : divisorZeroIndex₀Val p = u := + (mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := u) p).1 hp + have hpB : ‖divisorZeroIndex₀Val p‖ ≤ B := by + have : ‖divisorZeroIndex₀Val p‖ = r := by simp [hpval, hur] + simpa [this] using hBr + have : r ≠ ‖divisorZeroIndex₀Val p‖ := hr_not p hpB + exact this (by simp [hpval, hur]) + +theorem analyticOrderAt_divisorCanonicalProduct_eq_fiber_card + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z₀ = + ((divisorZeroIndex₀FiberFinset (f := f) z₀).card : ℕ∞) := by + let F : ℂ → ℂ := divisorCanonicalProduct m f (Set.univ : Set ℂ) + have hNat : + analyticOrderNatAt F z₀ = (divisorZeroIndex₀FiberFinset (f := f) z₀).card := by + simpa [F] using + (analyticOrderNatAt_divisorCanonicalProduct_eq_fiber_card + (m := m) (f := f) (h_sum := h_sum) (z₀ := z₀)) + have hdiffOn : DifferentiableOn ℂ F (Set.univ : Set ℂ) := by + simpa [F] using differentiableOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + have hdiff : Differentiable ℂ F := by + intro z + exact (hdiffOn z (by simp)).differentiableAt (by simp) + have hnotTop : analyticOrderAt F z₀ ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (hf := hdiff) + ⟨0, by simp [F, divisorCanonicalProduct_zero]⟩ z₀ + have hcast : (analyticOrderNatAt F z₀ : ℕ∞) = analyticOrderAt F z₀ := + Nat.cast_analyticOrderNatAt (f := F) (z₀ := z₀) hnotTop + have hNatCast : + (analyticOrderNatAt F z₀ : ℕ∞) = + ((divisorZeroIndex₀FiberFinset (f := f) z₀).card : ℕ∞) := by + simp [hNat] + simpa [F, hcast] using hNatCast + +theorem divisorCanonicalProduct_ne_zero_of_forall_ne + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + {z : ℂ} (hz : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), z ≠ divisorZeroIndex₀Val p) : + divisorCanonicalProduct m f (Set.univ : Set ℂ) z ≠ 0 := by + let F : ℂ → ℂ := divisorCanonicalProduct m f (Set.univ : Set ℂ) + have hfiber_empty : divisorZeroIndex₀FiberFinset (f := f) z = ∅ := by + ext p + constructor + · intro hp + exact False.elim (hz p ((mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := z) p).1 hp).symm) + · intro hp + simp at hp + have horder : + analyticOrderAt F z = (0 : ℕ∞) := by + have h := + analyticOrderAt_divisorCanonicalProduct_eq_fiber_card + (m := m) (f := f) (h_sum := h_sum) (z₀ := z) + simpa [F, hfiber_empty] using h + have han : AnalyticAt ℂ F z := by + refine (Complex.analyticAt_iff_eventually_differentiableAt).2 ?_ + refine Filter.Eventually.of_forall ?_ + intro w + exact (((differentiableOn_divisorCanonicalProduct_univ m f h_sum) w + (by simp)).differentiableAt (by simp)) + exact (han.analyticOrderAt_eq_zero).1 horder + +theorem logDeriv_divisorCanonicalProduct_one_eq_tsum_of_forall_ne + {f : ℂ → ℂ} {z : ℂ} + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (2 : ℕ))) + (hz : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), z ≠ divisorZeroIndex₀Val p) : + logDeriv (divisorCanonicalProduct 1 f (Set.univ : Set ℂ)) z = + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (1 / (z - divisorZeroIndex₀Val p) + 1 / divisorZeroIndex₀Val p) := + logDeriv_divisorCanonicalProduct_one_eq_tsum h_sum hz + (divisorCanonicalProduct_ne_zero_of_forall_ne 1 f h_sum hz) + +end Hadamard +end Complex +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/DivisorProducts.lean b/PrimeNumberTheoremAnd/SiegelZeros/DivisorProducts.lean new file mode 100644 index 0000000..5ca9514 --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/DivisorProducts.lean @@ -0,0 +1,912 @@ +import Mathlib +import PrimeNumberTheoremAnd.SiegelZeros.DivisorBasics + +namespace SiegelZeros + +section +open Filter Function _root_.SiegelZeros.Complex _root_.Function.Complex Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +noncomputable def divisorComplementFactor + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) : ℂ := by + classical + exact if p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ then (1 : ℂ) + else weierstrassFactor m (z / divisorZeroIndex₀Val p) + +@[simp] +theorem divisorComplementFactor_eq_one_of_mem + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) + (hp : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀) : + divisorComplementFactor m f z₀ p z = 1 := by + classical + simp [divisorComplementFactor, hp] + +@[simp] +theorem divisorComplementFactor_eq_weierstrassFactor_of_not_mem + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) + (hp : p ∉ divisorZeroIndex₀FiberFinset (f := f) z₀) : + divisorComplementFactor m f z₀ p z = + weierstrassFactor m (z / divisorZeroIndex₀Val p) := by + classical + simp [divisorComplementFactor, hp] + +lemma divisorComplementFactor_def + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) : + divisorComplementFactor m f z₀ p z = + if divisorZeroIndex₀Val p = z₀ then (1 : ℂ) + else weierstrassFactor m (z / divisorZeroIndex₀Val p) := by + classical + by_cases h : divisorZeroIndex₀Val p = z₀ + · have hp : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ := by + simpa [mem_divisorZeroIndex₀FiberFinset] using h + simp [divisorComplementFactor_eq_one_of_mem, hp, h] + · have hp : p ∉ divisorZeroIndex₀FiberFinset (f := f) z₀ := by + intro hmem + exact h ((mem_divisorZeroIndex₀FiberFinset f z₀ p).1 hmem) + simp [divisorComplementFactor_eq_weierstrassFactor_of_not_mem, hp, h] + +noncomputable def divisorPartialProduct (m : ℕ) (f : ℂ → ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) : ℂ := + ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p) + +theorem differentiable_weierstrassFactor_divisorZeroIndex₀ (m : ℕ) {f : ℂ → ℂ} + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) : + Differentiable ℂ (fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p)) := by + have hdiv : Differentiable ℂ (fun z : ℂ => z / divisorZeroIndex₀Val p) := by + simp [div_eq_mul_inv] + exact (differentiable_weierstrassFactor m).comp hdiv + +theorem differentiable_divisorPartialProduct (m : ℕ) (f : ℂ → ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) : + Differentiable ℂ (divisorPartialProduct m f s) := by + let Φ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p z => weierstrassFactor m (z / divisorZeroIndex₀Val p) + have hΦ : ∀ p ∈ s, Differentiable ℂ (Φ p) := by + intro p _hp + exact differentiable_weierstrassFactor_divisorZeroIndex₀ m p + simpa [divisorPartialProduct, Φ] using! + (Differentiable.fun_finsetProd (𝕜 := ℂ) (f := Φ) (u := s) hΦ) + +theorem analyticAt_divisorPartialProduct (m : ℕ) (f : ℂ → ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z₀ : ℂ) : + AnalyticAt ℂ (divisorPartialProduct m f s) z₀ := + (differentiable_divisorPartialProduct m f s).analyticAt z₀ + +noncomputable def divisorComplementPartialProduct + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) : ℂ := + ∏ p ∈ s, divisorComplementFactor m f z₀ p z + +@[simp] +lemma divisorComplementPartialProduct_def + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) : + divisorComplementPartialProduct m f z₀ s z = + ∏ p ∈ s, if divisorZeroIndex₀Val p = z₀ then (1 : ℂ) + else weierstrassFactor m (z / divisorZeroIndex₀Val p) := by + simp [divisorComplementPartialProduct, divisorComplementFactor, + mem_divisorZeroIndex₀FiberFinset] + +theorem differentiable_divisorComplementPartialProduct + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) : + Differentiable ℂ (divisorComplementPartialProduct m f z₀ s) := by + let Φ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := + fun p z => divisorComplementFactor m f z₀ p z + have hΦ : ∀ p ∈ s, Differentiable ℂ (Φ p) := by + intro p _hp + by_cases hpF : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ + · have hΦp : Φ p = fun _ => (1 : ℂ) := by + ext z + simp only [Φ, divisorComplementFactor_eq_one_of_mem m f z₀ p z hpF] + rw [hΦp] + exact differentiable_const (1 : ℂ) + · have hΦp : Φ p = fun z => weierstrassFactor m (z / divisorZeroIndex₀Val p) := by + ext z + simp only [Φ, divisorComplementFactor_eq_weierstrassFactor_of_not_mem m f z₀ p z hpF] + rw [hΦp] + exact differentiable_weierstrassFactor_divisorZeroIndex₀ m p + have hEq : (fun z : ℂ => ∏ p ∈ s, Φ p z) = + divisorComplementPartialProduct m f z₀ s := by + ext z + simp [Φ, divisorComplementPartialProduct] + have : Differentiable ℂ (fun z : ℂ => ∏ p ∈ s, Φ p z) := by + simpa using (Differentiable.fun_finsetProd (𝕜 := ℂ) (f := Φ) (u := s) hΦ) + simpa [hEq] using this + +noncomputable def divisorComplementCanonicalProduct + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) (z : ℂ) : ℂ := + ∏' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), divisorComplementFactor m f z₀ p z + +theorem hasProdUniformlyOn_divisorComplementCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) {K : Set ℂ} (hK : IsCompact K) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + HasProdUniformlyOn (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + divisorComplementFactor m f z₀ p z) (divisorComplementCanonicalProduct m f z₀) + K := by + rcases (isBounded_iff_forall_norm_le.1 hK.isBounded) with ⟨R0, hR0⟩ + set R : ℝ := max R0 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + have hnormK : ∀ z ∈ K, ‖z‖ ≤ R := fun z hzK => le_trans (hR0 z hzK) (le_max_left _ _) + let term : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := fun p z => + divisorComplementFactor m f z₀ p z + let g : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ → ℂ := fun p z => term p z - 1 + let u : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (4 * R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) + have hu : Summable u := h_sum.mul_left (4 * R ^ (m + 1)) + have h_big : + ∀ᶠ p : divisorZeroIndex₀ f (Set.univ : Set ℂ) in Filter.cofinite, + (2 * R : ℝ) < ‖divisorZeroIndex₀Val p‖ := by + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ 2 * R} : + Set _).Finite := by + have : Metric.closedBall (0 : ℂ) (2 * R) ⊆ (Set.univ : Set ℂ) := by simp + exact divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) (B := 2 * R) this + have := hfin.eventually_cofinite_notMem + filter_upwards [this] with p hp + have : ¬ ‖divisorZeroIndex₀Val p‖ ≤ 2 * R := by simpa using hp + exact lt_of_not_ge this + have hBound : + ∀ᶠ p in Filter.cofinite, ∀ z ∈ K, ‖g p z‖ ≤ u p := by + filter_upwards [h_big] with p hp z hzK + by_cases hpF : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ + · have hval : divisorZeroIndex₀Val p = z₀ := + (mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := z₀) p).1 hpF + have hu0 : 0 ≤ u p := by + dsimp [u] + refine mul_nonneg ?_ ?_ + · nlinarith [pow_nonneg (show 0 ≤ R from le_of_lt hRpos) (m + 1)] + · exact pow_nonneg (inv_nonneg.2 (norm_nonneg _)) (m + 1) + simp [g, term, divisorComplementFactor, hval, hu0, sub_eq_add_neg] + · have hzle : ‖z‖ ≤ R := hnormK z hzK + have hz_div : ‖z / divisorZeroIndex₀Val p‖ ≤ (1 / 2 : ℝ) := by + have h2R_pos : 0 < (2 * R : ℝ) := by nlinarith [hRpos] + have hinv : ‖divisorZeroIndex₀Val p‖⁻¹ < (2 * R)⁻¹ := by + simpa [one_div] using (one_div_lt_one_div_of_lt h2R_pos hp) + have hmul_le : ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ ≤ R * ‖divisorZeroIndex₀Val p‖⁻¹ := by + refine mul_le_mul_of_nonneg_right hzle ?_ + exact inv_nonneg.2 (norm_nonneg _) + have hmul_lt : R * ‖divisorZeroIndex₀Val p‖⁻¹ < R * (2 * R)⁻¹ := + mul_lt_mul_of_pos_left hinv hRpos + have hlt : ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ < R * (2 * R)⁻¹ := + lt_of_le_of_lt hmul_le hmul_lt + have hRhalf : R * (2 * R)⁻¹ = (1 / 2 : ℝ) := by + have hRne : (R : ℝ) ≠ 0 := hRpos.ne' + have : R * (2 * R)⁻¹ = R / (2 * R) := by simp [div_eq_mul_inv] + rw [this] + field_simp [hRne] + have hnorm : ‖z / divisorZeroIndex₀Val p‖ = ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + have hzlt : ‖z / divisorZeroIndex₀Val p‖ < (1 / 2 : ℝ) := by + calc + ‖z / divisorZeroIndex₀Val p‖ = ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := hnorm + _ < R * (2 * R)⁻¹ := hlt + _ = (1 / 2 : ℝ) := hRhalf + exact le_of_lt hzlt + have hE : ‖weierstrassFactor m (z / divisorZeroIndex₀Val p) - 1‖ ≤ + 4 * ‖z / divisorZeroIndex₀Val p‖ ^ (m + 1) := + weierstrassFactor_sub_one_pow_bound (m := m) (z := z / divisorZeroIndex₀Val p) hz_div + have hz_pow : ‖z / divisorZeroIndex₀Val p‖ ^ (m + 1) ≤ + (R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + have : ‖z / divisorZeroIndex₀Val p‖ = ‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + rw [this] + have : (‖z‖ * ‖divisorZeroIndex₀Val p‖⁻¹) ^ (m + 1) = + ‖z‖ ^ (m + 1) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + simp [mul_pow] + rw [this] + have hzle_pow : ‖z‖ ^ (m + 1) ≤ R ^ (m + 1) := + pow_le_pow_left₀ (norm_nonneg z) hzle (m + 1) + gcongr + dsimp [g, term, u] + simp [divisorComplementFactor, hpF] at * + nlinarith [hE, hz_pow] + have hcts : ∀ p, ContinuousOn (g p) K := by + intro p + by_cases hpF : p ∈ divisorZeroIndex₀FiberFinset (f := f) z₀ + · have hval : divisorZeroIndex₀Val p = z₀ := + (mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := z₀) p).1 hpF + simpa [g, term, divisorComplementFactor, hval, sub_eq_add_neg, add_assoc, add_left_comm, + add_comm] using + (continuousOn_const : ContinuousOn (fun _ : ℂ => (0 : ℂ)) K) + · have hvalne : divisorZeroIndex₀Val p ≠ z₀ := + (not_mem_divisorZeroIndex₀FiberFinset_iff_val_ne (f := f) z₀ p).1 hpF + have hcontE : Continuous (fun z : ℂ => weierstrassFactor m z) := + (differentiable_weierstrassFactor m).continuous + have hdiv : Continuous fun z : ℂ => z / divisorZeroIndex₀Val p := by + simpa [div_eq_mul_inv] using! (continuous_id.mul continuous_const) + have hcont : Continuous fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) := + hcontE.comp hdiv + have : ContinuousOn (fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) - 1) K := + (hcont.continuousOn.sub continuous_const.continuousOn) + simpa [g, term, divisorComplementFactor, mem_divisorZeroIndex₀FiberFinset, hvalne] using this + have hprod : + HasProdUniformlyOn (fun p z ↦ 1 + g p z) (fun z ↦ ∏' p, (1 + g p z)) K := by + simpa using + Summable.hasProdUniformlyOn_one_add (f := g) (u := u) (K := K) hK hu hBound hcts + have hterm : + HasProdUniformlyOn (fun p z ↦ term p z) (fun z ↦ ∏' p, term p z) K := by + simpa [g, sub_eq_add_neg, add_assoc, add_left_comm, add_comm] using hprod + refine hterm.congr_right ?_ + intro z hz + simp [term, divisorComplementCanonicalProduct, divisorComplementFactor] + +theorem hasProdLocallyUniformlyOn_divisorComplementCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + divisorComplementFactor m f z₀ p z) + (divisorComplementCanonicalProduct m f z₀) + (Set.univ : Set ℂ) := by + refine hasProdLocallyUniformlyOn_of_forall_compact + (f := fun p z => divisorComplementFactor m f z₀ p z) + (g := divisorComplementCanonicalProduct m f z₀) (s := (Set.univ : Set ℂ)) + isOpen_univ ?_ + intro K hKU hK + simpa using + (hasProdUniformlyOn_divisorComplementCanonicalProduct_univ (m := m) (f := f) (z₀ := z₀) + (K := K) hK h_sum) + +theorem tendstoLocallyUniformlyOn_divisorComplementPartialProduct_univ + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + divisorComplementPartialProduct m f z₀ s) + (divisorComplementCanonicalProduct m f z₀) + Filter.atTop + (Set.univ : Set ℂ) := by + have hprod : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + divisorComplementFactor m f z₀ p z) + (divisorComplementCanonicalProduct m f z₀) + (Set.univ : Set ℂ) := + hasProdLocallyUniformlyOn_divisorComplementCanonicalProduct_univ (m := m) (f := f) + (z₀ := z₀) h_sum + have h : + TendstoLocallyUniformlyOn + (fun (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z : ℂ) => + ∏ p ∈ s, + if divisorZeroIndex₀Val p = z₀ then (1 : ℂ) + else weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorComplementCanonicalProduct m f z₀) + Filter.atTop + (Set.univ : Set ℂ) := by + simpa [HasProdLocallyUniformlyOn, divisorComplementFactor, mem_divisorZeroIndex₀FiberFinset] + using hprod + refine h.congr (G := fun s z => divisorComplementPartialProduct m f z₀ s z) ?_ + intro s z hz + simp [divisorComplementPartialProduct_def] + +theorem differentiableOn_divisorComplementCanonicalProduct_univ + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + DifferentiableOn ℂ (divisorComplementCanonicalProduct m f z₀) (Set.univ : Set ℂ) := by + have hloc : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + divisorComplementPartialProduct m f z₀ s) + (divisorComplementCanonicalProduct m f z₀) + Filter.atTop + (Set.univ : Set ℂ) := + tendstoLocallyUniformlyOn_divisorComplementPartialProduct_univ (m := m) (f := f) + (z₀ := z₀) h_sum + have hF : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in Filter.atTop, + DifferentiableOn ℂ (divisorComplementPartialProduct m f z₀ s) (Set.univ : Set ℂ) := by + refine Filter.Eventually.of_forall ?_ + intro s + exact (differentiable_divisorComplementPartialProduct m f z₀ s).differentiableOn + have : (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))).NeBot := + Filter.atTop_neBot + exact hloc.differentiableOn hF isOpen_univ + +lemma divisorPartialProduct_eq_fiber_mul_complement_of_subset + (m : ℕ) (f : ℂ → ℂ) (z₀ z : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hs : divisorZeroIndex₀FiberFinset (f := f) z₀ ⊆ s) : + divisorPartialProduct m f s z = + divisorPartialProduct m f (divisorZeroIndex₀FiberFinset (f := f) z₀) z * + divisorComplementPartialProduct m f z₀ s z := by + classical + let fiber : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + divisorZeroIndex₀FiberFinset (f := f) z₀ + let P : divisorZeroIndex₀ f (Set.univ : Set ℂ) → Prop := fun p => p ∈ fiber + let term : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ := + fun p => weierstrassFactor m (z / divisorZeroIndex₀Val p) + have hfilter : s.filter P = fiber := by + ext p + constructor + · intro hp + exact (Finset.mem_filter.mp hp).2 + · intro hp + exact Finset.mem_filter.mpr ⟨hs hp, hp⟩ + have hsplit : + (∏ p ∈ s with P p, term p) * (∏ p ∈ s with ¬ P p, term p) = ∏ p ∈ s, term p := by + simpa [term] using + (Finset.prod_filter_mul_prod_filter_not (s := s) (p := P) (f := term)) + have hP : (∏ p ∈ s with P p, term p) = divisorPartialProduct m f fiber z := by + have hg : ∀ x ∈ s \ fiber, (if x ∈ fiber then term x else (1 : ℂ)) = 1 := by + intro x hx + have hxnot : x ∉ fiber := (Finset.mem_sdiff.mp hx).2 + simp [hxnot] + have hfg : + ∀ x ∈ fiber, term x = (if x ∈ fiber then term x else (1 : ℂ)) := by + intro x hx + simp [hx] + have hsub := (Finset.prod_subset_one_on_sdiff (s₁ := fiber) (s₂ := s) + (f := term) (g := fun x => if x ∈ fiber then term x else (1 : ℂ)) hs hg hfg) + simpa [divisorPartialProduct, term, P, fiber, Finset.prod_filter] using hsub.symm + have hnotP : (∏ p ∈ s with ¬ P p, term p) = divisorComplementPartialProduct m f z₀ s z := by + simp [divisorComplementPartialProduct, divisorComplementFactor, term, P, fiber, + Finset.prod_filter, mem_divisorZeroIndex₀FiberFinset] + have hsplit' : ∏ p ∈ s, term p = (∏ p ∈ s with P p, term p) * (∏ p ∈ s with ¬ P p, term p) := + hsplit.symm + calc + divisorPartialProduct m f s z + = ∏ p ∈ s, term p := by simp [divisorPartialProduct, term] + _ = (∏ p ∈ s with P p, term p) * (∏ p ∈ s with ¬ P p, term p) := hsplit' + _ = divisorPartialProduct m f fiber z * divisorComplementPartialProduct m f z₀ s z := by + simp [hP, hnotP, fiber] + +end Complex.Hadamard +end +section +noncomputable section + +open _root_.SiegelZeros.Complex Filter Function Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +theorem analyticOrderAt_finset_prod_weierstrassFactor_divisorZeroIndex₀ + (m : ℕ) (f : ℂ → ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (z₀ : ℂ) : + analyticOrderAt (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + z₀ = ((s.filter (fun p => divisorZeroIndex₀Val p = z₀)).card : ℕ∞) := by + classical + refine Finset.induction_on s ?base ?step + · simp [analyticOrderAt_eq_zero] + · intro p s hp hs + by_cases hEq : divisorZeroIndex₀Val p = z₀ + · have hp0 : divisorZeroIndex₀Val p ≠ 0 := p.property + have han_fac : + AnalyticAt ℂ (fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p)) z₀ := by + exact (differentiable_weierstrassFactor_divisorZeroIndex₀ m p).analyticAt z₀ + have han_rest : AnalyticAt ℂ (fun z : ℂ => ∏ q ∈ s, weierstrassFactor m + (z / divisorZeroIndex₀Val q)) z₀ := by + simpa [divisorPartialProduct] using! analyticAt_divisorPartialProduct m f s z₀ + let fac : ℂ → ℂ := fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) + let rest : ℂ → ℂ := fun z : ℂ => ∏ q ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val q) + have hmul : + analyticOrderAt (fac * rest) z₀ = + analyticOrderAt fac z₀ + analyticOrderAt rest z₀ := by + simpa [fac, rest] using (analyticOrderAt_mul (z₀ := z₀) han_fac han_rest) + have hcard : + (Finset.filter (fun q => divisorZeroIndex₀Val q = z₀) (insert p s)).card = + (Finset.filter (fun q => divisorZeroIndex₀Val q = z₀) s).card + 1 := by + simp [hEq, hp, Finset.filter_insert] + have hfac : analyticOrderAt fac z₀ = (1 : ℕ∞) := by + simpa [fac, hEq] using + (analyticOrderAt_weierstrassFactor_div_self (m := m) (a := divisorZeroIndex₀Val p) hp0) + have hrest : analyticOrderAt rest z₀ = ((s.filter + (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simpa [rest] using hs + have hcongr : + (fun z : ℂ => ∏ q ∈ insert p s, weierstrassFactor m (z / divisorZeroIndex₀Val q)) + =ᶠ[𝓝 z₀] (fac * rest) := by + refine Filter.Eventually.of_forall ?_ + intro z + simp [fac, rest, Finset.prod_insert, hp, Pi.mul_apply] + calc + analyticOrderAt (fun z : ℂ => ∏ q ∈ insert p s, weierstrassFactor m + (z / divisorZeroIndex₀Val q)) z₀ = analyticOrderAt (fac * rest) z₀ := by + simpa using (analyticOrderAt_congr hcongr) + _ = analyticOrderAt fac z₀ + analyticOrderAt rest z₀ := hmul + _ = (1 : ℕ∞) + ((s.filter (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simp [hfac, hrest] + _ = (((insert p s).filter (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simp [hcard, Nat.add_comm] + · have han_fac : + AnalyticAt ℂ (fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p)) z₀ := by + exact (differentiable_weierstrassFactor_divisorZeroIndex₀ m p).analyticAt z₀ + have hfac0 : analyticOrderAt (fun z : ℂ => weierstrassFactor m + (z / divisorZeroIndex₀Val p)) z₀ = 0 := by + have hp0 : divisorZeroIndex₀Val p ≠ 0 := p.property + have hval : weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) ≠ 0 := by + have : (z₀ / divisorZeroIndex₀Val p) ≠ 1 := by + intro h1 + have : z₀ = divisorZeroIndex₀Val p := by + have : z₀ = (z₀ / divisorZeroIndex₀Val p) * (divisorZeroIndex₀Val p) := by + simp [div_eq_mul_inv] + simpa [h1, div_eq_mul_inv, hp0] using this + exact hEq (this.symm) + exact (weierstrassFactor_ne_zero_iff m (z₀ / divisorZeroIndex₀Val p)).2 this + simpa using (han_fac.analyticOrderAt_eq_zero).2 (by simpa using hval) + have hcard : + (Finset.filter (fun q => divisorZeroIndex₀Val q = z₀) (insert p s)).card = + (Finset.filter (fun q => divisorZeroIndex₀Val q = z₀) s).card := by + simp [hEq, Finset.filter_insert] + have han_rest : AnalyticAt ℂ (fun z : ℂ => ∏ q ∈ s, weierstrassFactor m + (z / divisorZeroIndex₀Val q)) z₀ := by + simpa [divisorPartialProduct] using! analyticAt_divisorPartialProduct m f s z₀ + let fac : ℂ → ℂ := fun z : ℂ => weierstrassFactor m (z / divisorZeroIndex₀Val p) + let rest : ℂ → ℂ := fun z : ℂ => ∏ q ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val q) + have hmul : + analyticOrderAt (fac * rest) z₀ = + analyticOrderAt fac z₀ + analyticOrderAt rest z₀ := by + simpa [fac, rest] using (analyticOrderAt_mul (z₀ := z₀) han_fac han_rest) + have hcongr : + (fun z : ℂ => ∏ q ∈ insert p s, weierstrassFactor m (z / divisorZeroIndex₀Val q)) + =ᶠ[𝓝 z₀] (fac * rest) := by + refine Filter.Eventually.of_forall ?_ + intro z + simp [fac, rest, Finset.prod_insert, hp, Pi.mul_apply] + calc + analyticOrderAt (fun z : ℂ => ∏ q ∈ insert p s, weierstrassFactor m + (z / divisorZeroIndex₀Val q)) z₀ + = analyticOrderAt (fac * rest) z₀ := by + simpa using (analyticOrderAt_congr hcongr) + _ = analyticOrderAt rest z₀ := by + calc + analyticOrderAt (fac * rest) z₀ = analyticOrderAt fac z₀ + + analyticOrderAt rest z₀ := hmul + _ = analyticOrderAt rest z₀ := by + have hfac0' : analyticOrderAt fac z₀ = 0 := by + simpa [fac] using hfac0 + simp [hfac0'] + _ = ((s.filter (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simpa [rest] using hs + _ = (((insert p s).filter (fun q => divisorZeroIndex₀Val q = z₀)).card : ℕ∞) := by + simpa using congrArg (fun n : ℕ => (n : ℕ∞)) hcard.symm + +theorem analyticOrderAt_partialProduct_eq_fiberCard_of_subset + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hs : divisorZeroIndex₀FiberFinset (f := f) z₀ ⊆ s) : + analyticOrderAt + (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + z₀ = ((divisorZeroIndex₀FiberFinset (f := f) z₀).card : ℕ∞) := by + have h := + analyticOrderAt_finset_prod_weierstrassFactor_divisorZeroIndex₀ + (m := m) (f := f) (s := s) (z₀ := z₀) + have hfilter : + s.filter (fun p => divisorZeroIndex₀Val p = z₀) = + divisorZeroIndex₀FiberFinset (f := f) z₀ := by + ext p + constructor + · intro hp' + have hpv : divisorZeroIndex₀Val p = z₀ := (Finset.mem_filter.mp hp').2 + simpa [mem_divisorZeroIndex₀FiberFinset] using hpv + · intro hp_fiber + have hpv : divisorZeroIndex₀Val p = z₀ := + (mem_divisorZeroIndex₀FiberFinset (f := f) (z₀ := z₀) p).1 hp_fiber + have hps : p ∈ s := hs (by simpa [mem_divisorZeroIndex₀FiberFinset] using hpv) + exact Finset.mem_filter.2 ⟨hps, hpv⟩ + simpa [hfilter] using h + +theorem exists_analyticAt_eq_pow_smul_of_partialProduct_contains_fiber + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hs : divisorZeroIndex₀FiberFinset (f := f) z₀ ⊆ s) : + ∃ g : ℂ → ℂ, + AnalyticAt ℂ g z₀ ∧ g z₀ ≠ 0 ∧ + (fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p)) + =ᶠ[𝓝 z₀] + fun z : ℂ => (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card • g z := by + let F : ℂ → ℂ := fun z : ℂ => ∏ p ∈ s, weierstrassFactor m (z / divisorZeroIndex₀Val p) + have hF_ana : AnalyticAt ℂ F z₀ := by + simpa [F, divisorPartialProduct] using! analyticAt_divisorPartialProduct m f s z₀ + have hOrder : + analyticOrderAt F z₀ = + ((divisorZeroIndex₀FiberFinset (f := f) z₀).card : ℕ∞) := by + simpa [F] using + (analyticOrderAt_partialProduct_eq_fiberCard_of_subset (m := m) + (f := f) (z₀ := z₀) (s := s) hs) + refine (hF_ana.analyticOrderAt_eq_natCast (n := (divisorZeroIndex₀FiberFinset + (f := f) z₀).card)).1 ?_ + simp [hOrder] + +end Complex.Hadamard +end +end +section +open Filter Function _root_.SiegelZeros.Complex _root_.Function.Complex Finset Topology +open scoped Topology BigOperators +open Set + +namespace Complex.Hadamard + +theorem tendstoLocallyUniformlyOn_divisorPartialProduct_univ + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => divisorPartialProduct m f s) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + Filter.atTop + (Set.univ : Set ℂ) := by + have hprod : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (z : ℂ) => + weierstrassFactor m (z / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + (Set.univ : Set ℂ) := + hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + simpa [HasProdLocallyUniformlyOn, divisorPartialProduct] using! hprod + +theorem tendstoUniformlyOn_divisorPartialProduct_div_pow_sub + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) (k : ℕ) {K : Set ℂ} (hK : IsCompact K) (hKz : ∀ z ∈ K, z ≠ z₀) : + TendstoUniformlyOn + (fun s z => (divisorPartialProduct m f s z) / (z - z₀) ^ k) + (fun z => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ k) + (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))) + K := by + have hloc : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => divisorPartialProduct m f s) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + Filter.atTop + K := + (tendstoLocallyUniformlyOn_divisorPartialProduct_univ (m := m) (f := f) h_sum).mono + (by intro z hz; simp) + have hunif : + TendstoUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => divisorPartialProduct m f s) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + Filter.atTop + K := + (tendstoLocallyUniformlyOn_iff_tendstoUniformlyOn_of_compact hK).1 hloc + let h : ℂ → ℂ := fun z => ((z - z₀) ^ k)⁻¹ + have hh : ∃ C, ∀ z ∈ K, ‖h z‖ ≤ C := by + have hcont : ContinuousOn h K := by + have hpow : ContinuousOn (fun z : ℂ => (z - z₀) ^ k) K := by + fun_prop + refine hpow.inv₀ ?_ + intro z hz + have hz0 : z - z₀ ≠ 0 := sub_ne_zero.mpr (hKz z hz) + exact pow_ne_zero k hz0 + have hKimg : IsCompact (h '' K) := hK.image_of_continuousOn hcont + rcases (isBounded_iff_forall_norm_le.1 hKimg.isBounded) with ⟨C, hC⟩ + refine ⟨C, ?_⟩ + intro z hz + exact hC (h z) ⟨z, hz, rfl⟩ + have hunif' := + (TendstoUniformlyOn.mul_left_bounded (p := (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f + (Set.univ : Set ℂ))))) + (K := K) + (F := fun s z => divisorPartialProduct m f s z) + (f := fun z => divisorCanonicalProduct m f (Set.univ : Set ℂ) z) + (h := h) + hunif hh) + simpa [h, div_eq_mul_inv, mul_comm, mul_left_comm, mul_assoc] using hunif' + +theorem tendstoLocallyUniformlyOn_divisorPartialProduct_div_pow_sub + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) (k : ℕ) : + TendstoLocallyUniformlyOn + (fun s z => (divisorPartialProduct m f s z) / (z - z₀) ^ k) + (fun z => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ k) + (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))) + ((Set.univ : Set ℂ) \ {z₀}) := by + have hopen : IsOpen ((Set.univ : Set ℂ) \ {z₀}) := by + have hset : ((Set.univ : Set ℂ) \ {z₀}) = ({z₀} : Set ℂ)ᶜ := by + ext z + simp + simp [hset] + refine (tendstoLocallyUniformlyOn_iff_forall_isCompact hopen).2 ?_ + intro K hKsub hK + have hKz : ∀ z ∈ K, z ≠ z₀ := by + intro z hzK + have : z ∈ (Set.univ : Set ℂ) \ {z₀} := hKsub hzK + exact by simpa [Set.mem_sdiff, Set.mem_singleton_iff] using this.2 + exact tendstoUniformlyOn_divisorPartialProduct_div_pow_sub + (m := m) (f := f) h_sum (z₀ := z₀) (k := k) (hK := hK) hKz + +open Filter + +theorem exists_ball_eq_divisorCanonicalProduct_div_pow_eq + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : + ∃ ε > 0, ∃ u : ℂ → ℂ, AnalyticAt ℂ u z₀ ∧ + u z₀ ≠ 0 ∧ + ∀ z : ℂ, z ∈ Metric.ball z₀ ε → z ≠ z₀ → + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card = + (divisorComplementCanonicalProduct m f z₀ z) * u z := by + let fiber : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + divisorZeroIndex₀FiberFinset (f := f) z₀ + have hfib : ∃ u : ℂ → ℂ, AnalyticAt ℂ u z₀ ∧ u z₀ ≠ 0 ∧ + (fun z : ℂ => divisorPartialProduct m f fiber z) =ᶠ[𝓝 z₀] + fun z : ℂ => (z - z₀) ^ fiber.card • u z := by + simpa [fiber, divisorPartialProduct] using + (exists_analyticAt_eq_pow_smul_of_partialProduct_contains_fiber (m := m) (f := f) (z₀ := z₀) + (s := fiber) (by rfl : fiber ⊆ fiber)) + rcases hfib with ⟨u, huA, hu0, huEq⟩ + have hmem : {z : ℂ | divisorPartialProduct m f fiber z = + (z - z₀) ^ fiber.card • u z} ∈ 𝓝 z₀ := huEq + rcases Metric.mem_nhds_iff.1 hmem with ⟨ε, hε, hball⟩ + refine ⟨ε, hε, u, huA, hu0, ?_⟩ + have hq : + TendstoLocallyUniformlyOn (fun s z => (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card) + (fun z => (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ fiber.card) + (Filter.atTop : Filter (Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)))) + ((Set.univ : Set ℂ) \ {z₀}) := + tendstoLocallyUniformlyOn_divisorPartialProduct_div_pow_sub + (m := m) (f := f) (h_sum := h_sum) (z₀ := z₀) (k := fiber.card) + have hcomp : + TendstoLocallyUniformlyOn + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + divisorComplementPartialProduct m f z₀ s) + (divisorComplementCanonicalProduct m f z₀) + Filter.atTop + (Set.univ : Set ℂ) := + tendstoLocallyUniformlyOn_divisorComplementPartialProduct_univ (m := m) (f := f) + (z₀ := z₀) h_sum + intro z hz hzne + have hz' : z ∈ ((Set.univ : Set ℂ) \ {z₀}) := by + refine ⟨by simp, ?_⟩ + simpa [Set.mem_singleton_iff] using hzne + have hF : Tendsto (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card) (Filter.atTop : Filter _) + (𝓝 ((divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / (z - z₀) ^ fiber.card)) := + hq.tendsto_at hz' + have hG0 : Tendsto (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + divisorComplementPartialProduct m f z₀ s z) (Filter.atTop : Filter _) + (𝓝 (divisorComplementCanonicalProduct m f z₀ z)) := + hcomp.tendsto_at (by simp : z ∈ (Set.univ : Set ℂ)) + have hG : Tendsto (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + (divisorComplementPartialProduct m f z₀ s z) * u z) (Filter.atTop : Filter _) + (𝓝 ((divisorComplementCanonicalProduct m f z₀ z) * u z)) := + (hG0.mul tendsto_const_nhds) + have hsub : ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in (Filter.atTop : Filter _), + fiber ⊆ s := eventually_atTop_subset_fiberFinset (f := f) z₀ + have heq_eventually : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in (Filter.atTop : Filter _), + (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card + = (divisorComplementPartialProduct m f z₀ s z) * u z := by + filter_upwards [hsub] with s hs + have hsplit : + divisorPartialProduct m f s z = + divisorPartialProduct m f fiber z * divisorComplementPartialProduct m f z₀ s z := by + simpa [fiber] using + (divisorPartialProduct_eq_fiber_mul_complement_of_subset (m := m) (f := f) (z₀ := z₀) + (z := z) (s := s) hs) + have hfibz : + divisorPartialProduct m f fiber z = (z - z₀) ^ fiber.card • u z := by + exact hball hz + have hzpow : (z - z₀) ^ fiber.card ≠ 0 := + pow_ne_zero _ (sub_ne_zero.mpr hzne) + set a : ℂ := (z - z₀) ^ fiber.card + have ha : a ≠ 0 := by simpa [a] using hzpow + set c : ℂ := divisorComplementPartialProduct m f z₀ s z with hc + rw [hsplit, hfibz, smul_eq_mul] + calc + ((a * u z) * c) / a + = (a * (u z * c)) / a := by simp [mul_assoc] + _ = u z * c := by + simpa [mul_assoc] using (mul_div_cancel_left₀ (u z * c) ha) + _ = c * u z := by ac_rfl + _ = (divisorComplementPartialProduct m f z₀ s z) * u z := by + simp [c] + have hG' : + Tendsto + (fun s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) => + (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card) + (Filter.atTop : Filter _) + (𝓝 ((divisorComplementCanonicalProduct m f z₀ z) * u z)) := by + have heq' : + ∀ᶠ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) in (Filter.atTop : Filter _), + (divisorComplementPartialProduct m f z₀ s z) * u z + = (divisorPartialProduct m f s z) / (z - z₀) ^ fiber.card := by + filter_upwards [heq_eventually] with s hs + exact hs.symm + exact (hG.congr' heq') + exact tendsto_nhds_unique hF hG' + +theorem bddAbove_norm_divisorCanonicalProduct_div_pow_puncturedBall + (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (z₀ : ℂ) : ∃ r > 0, BddAbove (norm ∘ (fun z : ℂ => + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card) '' + ((Metric.ball z₀ r) \ {z₀})) := by + rcases exists_ball_eq_divisorCanonicalProduct_div_pow_eq (m := m) (f := f) (h_sum := h_sum) + (z₀ := z₀) with ⟨ε, hε, u, huA, hu0, hEq⟩ + have huC : ContinuousAt u z₀ := huA.continuousAt + have hpre : {z : ℂ | ‖u z - u z₀‖ < 1} ∈ 𝓝 z₀ := by + have : u ⁻¹' Metric.ball (u z₀) (1 : ℝ) ∈ 𝓝 z₀ := + huC.preimage_mem_nhds (Metric.ball_mem_nhds (u z₀) (by norm_num)) + simpa [Metric.ball, dist_eq_norm, Set.preimage] using this + rcases Metric.mem_nhds_iff.1 hpre with ⟨r0, hr0pos, hr0sub⟩ + set r : ℝ := min (ε / 2) r0 + have hrpos : 0 < r := lt_min (by nlinarith [hε]) hr0pos + have hr_lt_ε : r < ε := lt_of_le_of_lt (min_le_left _ _) (by nlinarith [hε]) + have huBound : ∀ z ∈ Metric.ball z₀ r, ‖u z‖ ≤ ‖u z₀‖ + 1 := by + intro z hz + have hz0 : z ∈ Metric.ball z₀ r0 := by + have : r ≤ r0 := min_le_right _ _ + exact Metric.ball_subset_ball this hz + have hdiff : ‖u z - u z₀‖ < 1 := hr0sub hz0 + have htri : ‖u z‖ ≤ ‖u z - u z₀‖ + ‖u z₀‖ := by + simpa [sub_eq_add_neg, add_assoc] using + (norm_add_le (u z - u z₀) (u z₀)) + have : ‖u z‖ ≤ 1 + ‖u z₀‖ := le_trans htri (by nlinarith [le_of_lt hdiff]) + nlinarith [this] + have hdiffC : + DifferentiableOn ℂ (divisorComplementCanonicalProduct m f z₀) (Set.univ : Set ℂ) := + differentiableOn_divisorComplementCanonicalProduct_univ (m := m) (f := f) (z₀ := z₀) h_sum + have hcontC : ContinuousOn (divisorComplementCanonicalProduct m f z₀) (Metric.closedBall z₀ r) := + (hdiffC.continuousOn).mono (by intro z hz; simp) + have hK : IsCompact (Metric.closedBall z₀ r) := isCompact_closedBall _ _ + rcases (isBounded_iff_forall_norm_le.1 (hK.image_of_continuousOn hcontC).isBounded) with ⟨C, hC⟩ + refine ⟨r, hrpos, ⟨C * (‖u z₀‖ + 1), ?_⟩⟩ + rintro _ ⟨z, hzset, rfl⟩ + rcases hzset with ⟨hzr, hzne⟩ + have hz_in_ε : z ∈ Metric.ball z₀ ε := Metric.ball_subset_ball hr_lt_ε.le hzr + have hz_ne : z ≠ z₀ := by simpa [Set.mem_singleton_iff] using hzne + have hq : + (divisorCanonicalProduct m f (Set.univ : Set ℂ) z) / + (z - z₀) ^ (divisorZeroIndex₀FiberFinset (f := f) z₀).card + = divisorComplementCanonicalProduct m f z₀ z * u z := + hEq z hz_in_ε hz_ne + have hCz : ‖divisorComplementCanonicalProduct m f z₀ z‖ ≤ C := by + have hzK : z ∈ Metric.closedBall z₀ r := Metric.mem_closedBall.2 (le_of_lt hzr) + exact hC _ ⟨z, hzK, rfl⟩ + have huZ : ‖u z‖ ≤ ‖u z₀‖ + 1 := huBound z hzr + have hCnonneg : 0 ≤ C := le_trans (norm_nonneg _) hCz + have hmul : ‖divisorComplementCanonicalProduct m f z₀ z * u z‖ ≤ C * (‖u z₀‖ + 1) := by + calc + ‖divisorComplementCanonicalProduct m f z₀ z * u z‖ + = ‖divisorComplementCanonicalProduct m f z₀ z‖ * ‖u z‖ := by simp + _ ≤ C * (‖u z₀‖ + 1) := by + exact mul_le_mul hCz huZ (norm_nonneg _) hCnonneg + simpa [Function.comp, hq] using hmul + +theorem divisorComplementCanonicalProduct_ne_zero_at + (m : ℕ) (f : ℂ → ℂ) (z₀ : ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + divisorComplementCanonicalProduct m f z₀ z₀ ≠ 0 := by + let Φ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ := + fun p => if divisorZeroIndex₀Val p = z₀ then (1 : ℂ) + else weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ := fun p => Φ p - 1 + have hΦ_ne : ∀ p, Φ p ≠ 0 := by + intro p + by_cases hp : divisorZeroIndex₀Val p = z₀ + · simp [Φ, hp] + · have hval : divisorZeroIndex₀Val p ≠ z₀ := hp + have hz : z₀ / divisorZeroIndex₀Val p ≠ (1 : ℂ) := by + intro h + by_cases hp0 : divisorZeroIndex₀Val p = 0 + · have : z₀ / divisorZeroIndex₀Val p = (0 : ℂ) := by simp [hp0] + have h01 := h + rw [this] at h01 + exact (show False from (by simpa using (show (0 : ℂ) ≠ (1 : ℂ) from by simp) h01)) + · have : z₀ = divisorZeroIndex₀Val p := (div_eq_one_iff_eq hp0).1 h + exact hval this.symm + have hE : weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) ≠ 0 := by + intro h0 + have : z₀ / divisorZeroIndex₀Val p = (1 : ℂ) := + (weierstrassFactor_eq_zero_iff (m := m) (z := z₀ / divisorZeroIndex₀Val p)).1 h0 + exact hz this + simp [Φ, hp, hE] + have hz0_le : ‖z₀‖ ≤ max ‖z₀‖ 1 := le_max_left _ _ + set R : ℝ := max ‖z₀‖ 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) (le_max_right _ _) + let u : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (4 * R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) + have hu : Summable u := h_sum.mul_left (4 * R ^ (m + 1)) + have h_big : + ∀ᶠ p : divisorZeroIndex₀ f (Set.univ : Set ℂ) in Filter.cofinite, + (2 * R : ℝ) < ‖divisorZeroIndex₀Val p‖ := by + have hfin : ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ + 2 * R} : Set _).Finite := by + have : Metric.closedBall (0 : ℂ) (2 * R) ⊆ (Set.univ : Set ℂ) := by simp + exact divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) (B := 2 * R) this + have := hfin.eventually_cofinite_notMem + filter_upwards [this] with p hp + have : ¬ ‖divisorZeroIndex₀Val p‖ ≤ 2 * R := by simpa using hp + exact lt_of_not_ge this + have hBound : + ∀ᶠ p in Filter.cofinite, ‖a p‖ ≤ u p := by + filter_upwards [h_big] with p hp + have ha_pos : 0 < ‖divisorZeroIndex₀Val p‖ := lt_trans (by nlinarith [hRpos]) hp + have hz_div : ‖z₀ / divisorZeroIndex₀Val p‖ ≤ (1 / 2 : ℝ) := by + have h2R_pos : 0 < (2 * R : ℝ) := by nlinarith [hRpos] + have hinv : ‖divisorZeroIndex₀Val p‖⁻¹ < (2 * R)⁻¹ := by + simpa [one_div] using (one_div_lt_one_div_of_lt h2R_pos hp) + have hmul_le : ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ ≤ R * ‖divisorZeroIndex₀Val p‖⁻¹ := by + refine mul_le_mul_of_nonneg_right ?_ (inv_nonneg.2 (norm_nonneg _)) + exact hz0_le + have hmul_lt : R * ‖divisorZeroIndex₀Val p‖⁻¹ < R * (2 * R)⁻¹ := + mul_lt_mul_of_pos_left hinv hRpos + have hlt : ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ < R * (2 * R)⁻¹ := + lt_of_le_of_lt hmul_le hmul_lt + have hRhalf : R * (2 * R)⁻¹ = (1 / 2 : ℝ) := by + have hRne : (R : ℝ) ≠ 0 := hRpos.ne' + have : R * (2 * R)⁻¹ = R / (2 * R) := by simp [div_eq_mul_inv] + rw [this] + field_simp [hRne] + have hnorm : ‖z₀ / divisorZeroIndex₀Val p‖ = ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + have hzlt : ‖z₀ / divisorZeroIndex₀Val p‖ < (1 / 2 : ℝ) := by + calc + ‖z₀ / divisorZeroIndex₀Val p‖ = ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := hnorm + _ < R * (2 * R)⁻¹ := hlt + _ = (1 / 2 : ℝ) := hRhalf + exact le_of_lt hzlt + have hE : + ‖weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) - 1‖ ≤ + 4 * ‖z₀ / divisorZeroIndex₀Val p‖ ^ (m + 1) := + weierstrassFactor_sub_one_pow_bound (m := m) (z := z₀ / divisorZeroIndex₀Val p) hz_div + have hz_pow : + ‖z₀ / divisorZeroIndex₀Val p‖ ^ (m + 1) ≤ + (R ^ (m + 1)) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + have : ‖z₀ / divisorZeroIndex₀Val p‖ = ‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹ := by + simp [div_eq_mul_inv] + rw [this] + have : (‖z₀‖ * ‖divisorZeroIndex₀Val p‖⁻¹) ^ (m + 1) = + ‖z₀‖ ^ (m + 1) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + simp [mul_pow] + rw [this] + have hzle_pow : ‖z₀‖ ^ (m + 1) ≤ R ^ (m + 1) := + pow_le_pow_left₀ (norm_nonneg z₀) hz0_le (m + 1) + gcongr + have hp_ne : divisorZeroIndex₀Val p ≠ z₀ := by + intro h + have : ‖divisorZeroIndex₀Val p‖ ≤ R := by + simp [h, R] + exact (not_lt_of_ge this) (lt_trans (by nlinarith [hRpos]) hp) + have ha : ‖a p‖ = ‖weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) - 1‖ := by + simp [a, Φ, hp_ne, sub_eq_add_neg] + calc + ‖a p‖ = ‖weierstrassFactor m (z₀ / divisorZeroIndex₀Val p) - 1‖ := ha + _ ≤ 4 * ‖z₀ / divisorZeroIndex₀Val p‖ ^ (m + 1) := by + simpa [sub_eq_add_neg, add_comm] using hE + _ ≤ 4 * (R ^ (m + 1) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) := by + gcongr + _ = u p := by + simp [u, mul_assoc, mul_comm] + have hsum_norm : Summable (fun p => ‖a p‖) := by + refine (Summable.of_norm_bounded_eventually (E := ℝ) (f := fun p => ‖a p‖) (g := u) hu ?_) + filter_upwards [hBound] with p hp + simpa [Real.norm_eq_abs, abs_of_nonneg (norm_nonneg (a p))] using hp + have htprod_ne : + (∏' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (1 + a p)) ≠ 0 := + tprod_one_add_ne_zero_of_summable (R := ℂ) (f := a) (hf := fun p => by + simpa [a, Φ, add_sub_cancel] using hΦ_ne p) hsum_norm + have : (∏' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (1 + a p)) = + divisorComplementCanonicalProduct m f z₀ z₀ := by + simp [a, Φ, divisorComplementCanonicalProduct, divisorComplementFactor_def] + exact by + intro h0 + exact htprod_ne (by simpa [this] using h0) + +end Complex.Hadamard +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/Exponential.lean b/PrimeNumberTheoremAnd/SiegelZeros/Exponential.lean new file mode 100644 index 0000000..082148e --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/Exponential.lean @@ -0,0 +1,722 @@ +import Mathlib +import PrimeNumberTheoremAnd.SiegelZeros.ProductBounds + +namespace SiegelZeros + +section +noncomputable section + +namespace Complex +namespace Hadamard + +open _root_.SiegelZeros.Complex _root_.SiegelZeros.Real BigOperators + _root_.SiegelZeros.Finset Set Filter Topology Metric + +open scoped Topology + +theorem zero_free_polynomial_growth_is_exp_poly {H : ℂ → ℂ} {n : ℕ} + (hH : Differentiable ℂ H) + (h_nonzero : ∀ z, H z ≠ 0) + (h_bound : ∃ C > 0, ∀ z, ‖H z‖ ≤ Real.exp (C * (1 + ‖z‖) ^ n)) : + ∃ P : Polynomial ℂ, P.natDegree ≤ n ∧ ∀ z, H z = Complex.exp (Polynomial.eval z P) := by + classical + rcases h_bound with ⟨C, hCpos, hC⟩ + let L : ℂ → ℂ := fun z => deriv H z / H z + have hderivH : Differentiable ℂ (deriv H) := by + intro z + exact ((hH.analyticAt z).deriv).differentiableAt + have hL : Differentiable ℂ L := by + simpa [L] using! (hderivH.div hH h_nonzero) + let h : ℂ → ℂ := fun z => Complex.wedgeIntegral (0 : ℂ) z L + have hh_deriv : ∀ z, HasDerivAt h (L z) z := by + intro z + let r : ℝ := ‖z‖ + 1 + have hrpos : 0 < r := by + dsimp [r]; linarith [norm_nonneg z] + have hz_ball : z ∈ Metric.ball (0 : ℂ) r := by + have : dist z (0 : ℂ) < r := by simp [r, dist_zero_right] + simpa [Metric.mem_ball] using this + have hconserv : Complex.IsConservativeOn L (Metric.ball (0 : ℂ) r) := + (hL.differentiableOn).isConservativeOn + have hcont : ContinuousOn L (Metric.ball (0 : ℂ) r) := + hL.continuous.continuousOn + simpa [h, r] using hconserv.hasDerivAt_wedgeIntegral (f_cont := hcont) (hz := hz_ball) + have hh : Differentiable ℂ h := fun z => (hh_deriv z).differentiableAt + have hderiv_h : ∀ z, deriv h z = L z := fun z => (hh_deriv z).deriv + let k : ℂ → ℂ := fun z => h z + Complex.log (H 0) + have hk : Differentiable ℂ k := hh.add_const (Complex.log (H 0)) + have hk_exp : ∀ z, H z = Complex.exp (k z) := by + let F : ℂ → ℂ := fun z => Complex.exp (k z) / H z + have hF_deriv : ∀ z, deriv F z = 0 := by + intro z + have hH_has : HasDerivAt H (deriv H z) z := (hH z).hasDerivAt + have hk_has : HasDerivAt k (L z) z := by + have hh_has : HasDerivAt h (L z) z := hh_deriv z + simpa [k, L] using hh_has.add_const (Complex.log (H 0)) + have hExp : HasDerivAt (fun w => Complex.exp (k w)) (Complex.exp (k z) * L z) z := + (HasDerivAt.cexp hk_has) + have hDiv := (HasDerivAt.div hExp hH_has (h_nonzero z)) + have : + deriv F z = + ((Complex.exp (k z) * L z) * H z - Complex.exp (k z) * deriv H z) / (H z) ^ 2 := by + simpa [F] using! hDiv.deriv + rw [this] + have hnum : + (Complex.exp (k z) * L z) * H z - Complex.exp (k z) * deriv H z = 0 := by + dsimp [L] + field_simp [h_nonzero z] + ring + simp [hnum] + have hF_diff : Differentiable ℂ F := (hk.cexp).div hH h_nonzero + have hF_const : ∀ z, F z = F 0 := by + intro z + exact is_const_of_deriv_eq_zero hF_diff hF_deriv z 0 + have hF0 : F 0 = 1 := by + have hh0 : h 0 = 0 := by simp [h, Complex.wedgeIntegral] + have hk0 : k 0 = Complex.log (H 0) := by simp [k, hh0] + have hH0 : H 0 ≠ 0 := h_nonzero 0 + simp [F, hk0, Complex.exp_log hH0, hH0] + intro z + have : F z = 1 := by simpa [hF0] using (hF_const z) + have hHz : H z ≠ 0 := h_nonzero z + have : Complex.exp (k z) / H z = 1 := by simpa [F] using this + have : Complex.exp (k z) = H z := by + field_simp [hHz] at this + simpa using this + exact this.symm + have hk_re_bound : ∀ z, (k z).re ≤ C * (1 + ‖z‖) ^ n := by + intro z + have hHz : H z ≠ 0 := h_nonzero z + have hpos : 0 < ‖H z‖ := norm_pos_iff.mpr hHz + have hlog_le : Real.log ‖H z‖ ≤ C * (1 + ‖z‖) ^ n := by + have := Real.log_le_log hpos (hC z) + simpa [Real.log_exp] using this + have hlog_eq : Real.log ‖H z‖ = (k z).re := by + have : ‖H z‖ = Real.exp (k z).re := by + simpa [hk_exp z] using (Complex.norm_exp (k z)) + calc + Real.log ‖H z‖ = Real.log (Real.exp (k z).re) := by simp [this] + _ = (k z).re := by simp + simpa [hlog_eq] using hlog_le + have hk_iteratedDeriv_eq_zero : ∀ m : ℕ, n < m → iteratedDeriv m k 0 = 0 := by + intro m hm + have hm' : 0 < (m - n : ℕ) := Nat.sub_pos_of_lt hm + have hmne : m - n ≠ 0 := (Nat.pos_iff_ne_zero.1 hm') + let f : ℂ → ℂ := fun z => k z - k 0 + have hf : Differentiable ℂ f := hk.sub_const (k 0) + have hf0 : f 0 = 0 := by simp [f] + have hf_re_bound : ∀ R : ℝ, 0 < R → + ∀ z, ‖z‖ ≤ R → (f z).re ≤ C * (1 + R) ^ n + ‖k 0‖ := by + intro R hRpos z hzR + have hkz : (k z).re ≤ C * (1 + ‖z‖) ^ n := hk_re_bound z + have hkz' : (k z).re ≤ C * (1 + R) ^ n := by + have h1 : (1 + ‖z‖ : ℝ) ≤ 1 + R := by linarith + have hpow : (1 + ‖z‖ : ℝ) ^ n ≤ (1 + R) ^ n := + pow_le_pow_left₀ (by linarith [norm_nonneg z]) h1 n + exact hkz.trans (mul_le_mul_of_nonneg_left hpow (le_of_lt hCpos)) + have hRe0 : -(k 0).re ≤ ‖k 0‖ := by + have habs : |(k 0).re| ≤ ‖k 0‖ := Complex.abs_re_le_norm (k 0) + have hneg : -(k 0).re ≤ |(k 0).re| := by simpa using (neg_le_abs (k 0).re) + exact hneg.trans habs + have : (f z).re ≤ C * (1 + R) ^ n + ‖k 0‖ := by + have : (f z).re = (k z).re - (k 0).re := by simp [f, sub_eq_add_neg] + nlinarith [this, hkz', hRe0] + exact this + have hf_bound_on_ball : ∀ R : ℝ, 0 < R → + ∀ z, ‖z‖ ≤ R / 2 → ‖f z‖ ≤ 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + intro R hRpos z hz + have hR2pos : 0 < R / 2 := by nlinarith + have hlt : R / 2 < R := by nlinarith + have hMpos : 0 < (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + have : 0 ≤ C * (1 + R) ^ n := by + refine mul_nonneg (le_of_lt hCpos) ?_ + exact pow_nonneg (by linarith) _ + nlinarith [this, norm_nonneg (k 0)] + have hf_anal : AnalyticOnNhd ℂ f (Metric.closedBall 0 R) := by + intro w _hw + exact (hf.analyticAt w) + have hf_re : ∀ w, ‖w‖ ≤ R → (f w).re ≤ (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + intro w hw + have := hf_re_bound R hRpos w hw + linarith + have hf_bc := + borelCaratheodory_zero_closedBall (f := f) (r := R / 2) (R := R) + (M := (C * (1 + R) ^ n + ‖k 0‖ + 1)) + hf_anal hR2pos hlt hMpos hf0 hf_re (z := z) hz + have hconst : + 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1) * (R / 2) / (R - R / 2) + = 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + field_simp [hRpos.ne'] ; ring + simpa [hconst] using hf_bc + have hCauchy : ∀ R : ℝ, 0 < R → + ‖iteratedDeriv m f 0‖ ≤ + (m.factorial : ℝ) * (2 * (C * (1 + R) ^ n + ‖k 0‖ + 1)) / (R / 2) ^ m := by + intro R hRpos + have hR2pos : 0 < R / 2 := by nlinarith + have hf_diffCont : DiffContOnCl ℂ f (Metric.ball (0 : ℂ) (R / 2)) := hf.diffContOnCl + have hbound_sphere : + ∀ z ∈ Metric.sphere (0 : ℂ) (R / 2), + ‖f z‖ ≤ 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1) := by + intro z hz + have hz' : ‖z‖ ≤ R / 2 := by + simpa [Metric.mem_sphere, dist_zero_right] using (le_of_eq hz) + exact hf_bound_on_ball R hRpos z hz' + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using + (Complex.norm_iteratedDeriv_le_of_forall_mem_sphere_norm_le (n := m) (c := (0 : ℂ)) + (R := R / 2) (C := 2 * (C * (1 + R) ^ n + ‖k 0‖ + 1)) + (hR := hR2pos) hf_diffCont hbound_sphere) + have hf_iter_eq : iteratedDeriv m f 0 = 0 := by + by_contra hne + have ha : 0 < ‖iteratedDeriv m f 0‖ := norm_pos_iff.2 hne + let RHS : ℝ → ℝ := fun R => + (m.factorial : ℝ) * (2 * (C * (1 + R) ^ n + ‖k 0‖ + 1)) / (R / 2) ^ m + have hle_RHS : ∀ R : ℝ, 0 < R → ‖iteratedDeriv m f 0‖ ≤ RHS R := by + intro R hRpos + simpa [RHS] using hCauchy R hRpos + have hRHS_tendsto : Tendsto RHS atTop (𝓝 0) := by + let K : ℝ := ‖k 0‖ + 1 + have hmpos : 0 < m := lt_of_le_of_lt (Nat.zero_le n) hm + have hm0 : m ≠ 0 := ne_of_gt hmpos + have hratio : Tendsto (fun R : ℝ => R ^ n / (R / 2) ^ m) atTop (𝓝 0) := by + have hident : + (fun R : ℝ => R ^ n / (R / 2) ^ m) = fun R : ℝ => (2 : ℝ) ^ m * (R ^ n / R ^ m) := by + funext R + simp [div_eq_mul_inv, mul_pow, mul_assoc, mul_comm] + have hmain : Tendsto (fun R : ℝ => R ^ n / R ^ m) atTop (𝓝 0) := by + have hp : m - n ≠ 0 := (Nat.pos_iff_ne_zero.1 (Nat.sub_pos_of_lt hm)) + have hmain' : Tendsto (fun R : ℝ => (R ^ (m - n))⁻¹) atTop (𝓝 0) := by + simpa using (tendsto_pow_neg_atTop (𝕜 := ℝ) (n := m - n) hp) + have hEq : (fun R : ℝ => (R ^ (m - n))⁻¹) =ᶠ[atTop] fun R : ℝ => R ^ n / R ^ m := by + have hEq' : (fun R : ℝ => R ^ n / R ^ m) =ᶠ[atTop] fun R : ℝ => (R ^ (m - n))⁻¹ := by + filter_upwards [eventually_ne_atTop (0 : ℝ)] with R hR + have hle : n ≤ m := le_of_lt hm + have hm_eq : n + (m - n) = m := Nat.add_sub_of_le hle + have hn0 : R ^ n ≠ 0 := pow_ne_zero n hR + calc + R ^ n / R ^ m = R ^ n / R ^ (n + (m - n)) := by simp [hm_eq] + _ = R ^ n * ((R ^ (m - n))⁻¹ * (R ^ n)⁻¹) := by + simp [pow_add, div_eq_mul_inv, mul_comm] + _ = (R ^ (m - n))⁻¹ := by + ring_nf + simp [hn0] + exact hEq'.symm + exact Filter.Tendsto.congr' hEq hmain' + have : Tendsto (fun R : ℝ => (2 : ℝ) ^ m * (R ^ n / R ^ m)) atTop (𝓝 ((2 : ℝ) ^ m * 0)) := + tendsto_const_nhds.mul hmain + simpa [hident] using this + have hinv : Tendsto (fun R : ℝ => ((R / 2) ^ m)⁻¹) atTop (𝓝 0) := by + have hdiv : Tendsto (fun R : ℝ => R / 2) atTop atTop := + (tendsto_id.atTop_div_const (r := (2 : ℝ)) (by norm_num : (0 : ℝ) < 2)) + have hpow : Tendsto (fun R : ℝ => (R / 2) ^ m) atTop atTop := + (Filter.tendsto_pow_atTop (α := ℝ) (n := m) hm0).comp hdiv + simpa using! hpow.inv_tendsto_atTop + have hdiv : Tendsto (fun R : ℝ => (1 + R) / R) atTop (𝓝 (1 : ℝ)) := by + have hinv' : Tendsto (fun R : ℝ => (R : ℝ)⁻¹) atTop (𝓝 (0 : ℝ)) := tendsto_inv_atTop_zero + have hadd : Tendsto (fun R : ℝ => (1 : ℝ) + (R : ℝ)⁻¹) atTop (𝓝 (1 : ℝ)) := by + simpa using (tendsto_const_nhds.add hinv') + have hEq : (fun R : ℝ => (1 + R) / R) =ᶠ[atTop] fun R : ℝ => (1 : ℝ) + (R : ℝ)⁻¹ := by + filter_upwards [eventually_ne_atTop (0 : ℝ)] with R hR + field_simp [hR]; ring + exact Filter.Tendsto.congr' hEq.symm hadd + have hdiv_pow : Tendsto (fun R : ℝ => ((1 + R) / R) ^ n) atTop (𝓝 (1 : ℝ)) := by + simpa using (hdiv.pow n) + have hone_add_ratio : + Tendsto (fun R : ℝ => (1 + R) ^ n / (R / 2) ^ m) atTop (𝓝 (0 : ℝ)) := by + have hEq : + (fun R : ℝ => (1 + R) ^ n / (R / 2) ^ m) + =ᶠ[atTop] fun R : ℝ => ((1 + R) / R) ^ n * (R ^ n / (R / 2) ^ m) := by + filter_upwards [eventually_ne_atTop (0 : ℝ)] with R hR + have hRpow : (R ^ n : ℝ) ≠ 0 := pow_ne_zero n hR + have hident : + ((1 + R) / R) ^ n * (R ^ n / (R / 2) ^ m) = (1 + R) ^ n / (R / 2) ^ m := by + calc + ((1 + R) / R) ^ n * (R ^ n / (R / 2) ^ m) + = ((1 + R) ^ n / R ^ n) * (R ^ n / (R / 2) ^ m) := by + simp [div_pow] + _ = ((1 + R) ^ n * R ^ n) / (R ^ n * (R / 2) ^ m) := by + simp [div_mul_div_comm, mul_comm] + _ = ((1 + R) ^ n * R ^ n) / ((R / 2) ^ m * R ^ n) := by + simp [mul_comm] + _ = (1 + R) ^ n / (R / 2) ^ m := by + simpa [mul_assoc, mul_comm, mul_left_comm] using + (mul_div_mul_right (a := (1 + R) ^ n) (b := (R / 2) ^ m) hRpow) + exact hident.symm + have hmul : + Tendsto + (fun R : ℝ => ((1 + R) / R) ^ n * (R ^ n / (R / 2) ^ m)) + atTop (𝓝 (0 : ℝ)) := by + simpa [mul_zero] using (hdiv_pow.mul hratio) + exact Filter.Tendsto.congr' hEq.symm hmul + have h1 : Tendsto (fun R : ℝ => C * ((1 + R) ^ n / (R / 2) ^ m)) atTop (𝓝 0) := by + simpa using (tendsto_const_nhds.mul hone_add_ratio) + have h2 : Tendsto (fun R : ℝ => K * ((R / 2) ^ m)⁻¹) atTop (𝓝 0) := by + simpa using (tendsto_const_nhds.mul hinv) + have hsum : + Tendsto + (fun R : ℝ => C * ((1 + R) ^ n / (R / 2) ^ m) + K * ((R / 2) ^ m)⁻¹) + atTop (𝓝 0) := by + simpa using (h1.add h2) + have hrew : + (fun R : ℝ => (C * (1 + R) ^ n + K) / (R / 2) ^ m) + = fun R : ℝ => C * ((1 + R) ^ n / (R / 2) ^ m) + K * ((R / 2) ^ m)⁻¹ := by + funext R + simp [div_eq_mul_inv, mul_add, mul_assoc, mul_comm] + have hbase : Tendsto (fun R : ℝ => (C * (1 + R) ^ n + K) / (R / 2) ^ m) atTop (𝓝 0) := by + simpa [hrew] using hsum + have hconst : + Tendsto (fun _ : ℝ => (m.factorial : ℝ) * (2 : ℝ)) atTop + (𝓝 ((m.factorial : ℝ) * (2 : ℝ))) := tendsto_const_nhds + have hmul : Tendsto (fun R : ℝ => ((m.factorial : ℝ) * (2 : ℝ)) * + ((C * (1 + R) ^ n + K) / (R / 2) ^ m)) atTop (𝓝 0) := by + simpa [mul_assoc, mul_left_comm, mul_comm] using (hconst.mul hbase) + have hRHS_rw : RHS = fun R : ℝ => ((m.factorial : ℝ) * (2 : ℝ)) * + ((C * (1 + R) ^ n + K) / (R / 2) ^ m) := by + funext R + dsimp [RHS, K] + ring_nf + simpa [hRHS_rw] using hmul + have hsmall : ∀ᶠ R in atTop, RHS R < ‖iteratedDeriv m f 0‖ / 2 := + (tendsto_order.1 hRHS_tendsto).2 _ (half_pos ha) + have hle_eventually : ∀ᶠ R in atTop, ‖iteratedDeriv m f 0‖ ≤ RHS R := by + filter_upwards [eventually_gt_atTop (0 : ℝ)] with R hRpos + exact hle_RHS R hRpos + rcases (hle_eventually.and hsmall).exists with ⟨R, hle, hlt⟩ + have : ‖iteratedDeriv m f 0‖ < ‖iteratedDeriv m f 0‖ := + (lt_of_le_of_lt hle hlt).trans (half_lt_self ha) + exact lt_irrefl _ this + have hmpos : 0 < m := lt_of_le_of_lt (Nat.zero_le n) hm + have hm0 : m ≠ 0 := ne_of_gt hmpos + have hkcd : ContDiffAt ℂ (↑m) k (0 : ℂ) := (hk.analyticAt 0).contDiffAt + have hccd : ContDiffAt ℂ (↑m) (fun _ : ℂ => k 0) (0 : ℂ) := contDiffAt_const + have hsub : + iteratedDeriv m f 0 = + iteratedDeriv m k 0 - iteratedDeriv m (fun _ : ℂ => k 0) 0 := by + simpa [f] using! (iteratedDeriv_sub (n := m) (x := (0 : ℂ)) hkcd hccd) + have hconst0 : iteratedDeriv m (fun _ : ℂ => k 0) 0 = 0 := by + simp [iteratedDeriv_const, hm0] + have hf_eq : iteratedDeriv m f 0 = iteratedDeriv m k 0 := by + simp [hsub, hconst0] + simpa [hf_eq] using hf_iter_eq + let P : Polynomial ℂ := + ∑ m ∈ Finset.range (n + 1), Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0) + have hPdeg : P.natDegree ≤ n := by + have hnat : + P.natDegree ≤ + Finset.fold max 0 + (fun m : ℕ => + (Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0)).natDegree) + (Finset.range (n + 1)) := by + simpa [P, Function.comp] using + (Polynomial.natDegree_sum_le (s := Finset.range (n + 1)) + (f := fun m : ℕ => + Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0))) + have hfold : + Finset.fold max 0 + (fun m : ℕ => + (Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0)).natDegree) + (Finset.range (n + 1)) ≤ n := by + refine (Finset.fold_max_le (f := fun m : ℕ => + (Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0)).natDegree) + (b := 0) (s := Finset.range (n + 1)) (c := n)).2 ?_ + refine ⟨Nat.zero_le n, ?_⟩ + intro m hm + have hmon : + (Polynomial.monomial m ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0)).natDegree ≤ m := + Polynomial.natDegree_monomial_le _ + have hm_le : m ≤ n := Nat.le_of_lt_succ (Finset.mem_range.1 hm) + exact hmon.trans hm_le + exact hnat.trans hfold + have hk_poly : ∀ z, k z = Polynomial.eval z P := by + intro z + have htaylor := Complex.taylorSeries_eq_of_entire' (c := (0 : ℂ)) (z := z) hk + have htail : ∀ m : ℕ, m ∉ Finset.range (n + 1) → + ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * (z - 0) ^ m) = 0 := by + intro m hm' + have hmgt : n < m := by + have : n + 1 ≤ m := Nat.le_of_not_lt (by simpa [Finset.mem_range] using hm') + exact Nat.lt_of_lt_of_le (Nat.lt_succ_self n) this + have hz : iteratedDeriv m k 0 = 0 := hk_iteratedDeriv_eq_zero m hmgt + simp [hz] + have htsum : + (∑' m : ℕ, (m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * (z - 0) ^ m) + = ∑ m ∈ Finset.range (n + 1), (m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * z ^ m := by + simpa [sub_zero] using (tsum_eq_sum (s := Finset.range (n + 1)) htail) + have hfinite : + k z = ∑ m ∈ Finset.range (n + 1), (m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * z ^ m := by + calc + k z = ∑' m : ℕ, (m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0 * (z - 0) ^ m := by + simpa using htaylor.symm + _ = _ := htsum + have hEval : + Polynomial.eval z P = + ∑ m ∈ Finset.range (n + 1), z ^ m * ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0) := by + classical + change Polynomial.eval₂ (RingHom.id ℂ) z P = _ + let φ : Polynomial ℂ →+* ℂ := Polynomial.eval₂RingHom (RingHom.id ℂ) z + change φ P = _ + simp [P, φ, Polynomial.eval₂_monomial, mul_comm] + have hfinite' : + k z = ∑ m ∈ Finset.range (n + 1), z ^ m * ((m.factorial : ℂ)⁻¹ * iteratedDeriv m k 0) := by + simpa [mul_comm, mul_left_comm, mul_assoc] using hfinite + simpa [hEval] using hfinite' + refine ⟨P, hPdeg, ?_⟩ + intro z + have : H z = Complex.exp (k z) := by simp [hk_exp z] + simp [this, hk_poly z] + +end Hadamard +end Complex +end +end +section +noncomputable section + +namespace Complex +namespace Hadamard + +open _root_.SiegelZeros.Complex _root_.SiegelZeros.Real BigOperators + _root_.SiegelZeros.Finset Set Filter Topology Metric + +open scoped Topology + +open Polynomial + +private lemma exists_pow_eq_complex {n : ℕ} (hn : 0 < n) (w : ℂ) : ∃ z : ℂ, z ^ n = w := by + classical + by_cases hw : w = 0 + · subst hw + refine ⟨0, ?_⟩ + have hn0 : n ≠ 0 := Nat.ne_of_gt hn + simp [hn0] + · refine ⟨Complex.exp (Complex.log w / n), ?_⟩ + have hn0 : (n : ℂ) ≠ 0 := by + exact_mod_cast (Nat.ne_of_gt hn) + calc + (Complex.exp (Complex.log w / n)) ^ n + = Complex.exp ((n : ℂ) * (Complex.log w / n)) := by + simpa using (Complex.exp_nat_mul (Complex.log w / n) n).symm + _ = Complex.exp (Complex.log w) := by + have : (n : ℂ) * (Complex.log w / n) = Complex.log w := by + field_simp [hn0] + simp [this] + _ = w := by simpa using (Complex.exp_log hw) + +private lemma mul_conj_div_norm (a : ℂ) (ha : a ≠ 0) : + a * ((starRingEnd ℂ) a / (‖a‖ : ℂ)) = (‖a‖ : ℂ) := by + have hnorm_pos : 0 < ‖a‖ := norm_pos_iff.mpr ha + have hnorm_ne : (‖a‖ : ℂ) ≠ 0 := by + exact_mod_cast (ne_of_gt hnorm_pos) + have hmul : a * (starRingEnd ℂ) a = (Complex.normSq a : ℂ) := + Complex.mul_conj a + have hcast : (Complex.normSq a : ℂ) = ((‖a‖ ^ 2 : ℝ) : ℂ) := by + exact_mod_cast (Complex.normSq_eq_norm_sq a) + have hdiv : ((‖a‖ ^ 2 : ℝ) : ℂ) / (‖a‖ : ℂ) = (‖a‖ : ℂ) := by + have : ((‖a‖ ^ 2 : ℝ) : ℂ) = (‖a‖ : ℂ) * (‖a‖ : ℂ) := by + simp [pow_two] + calc + ((‖a‖ ^ 2 : ℝ) : ℂ) / (‖a‖ : ℂ) + = ((‖a‖ : ℂ) * (‖a‖ : ℂ)) / (‖a‖ : ℂ) := by simp [this] + _ = (‖a‖ : ℂ) := by + field_simp [hnorm_ne] + calc + a * ((starRingEnd ℂ) a / (‖a‖ : ℂ)) + = (a * (starRingEnd ℂ) a) / (‖a‖ : ℂ) := by + simp [div_eq_mul_inv, mul_assoc] + _ = (Complex.normSq a : ℂ) / (‖a‖ : ℂ) := by simp [hmul] + _ = ((‖a‖ ^ 2 : ℝ) : ℂ) / (‖a‖ : ℂ) := by simp [hcast] + _ = (‖a‖ : ℂ) := hdiv + +private lemma exists_z_norm_eq_re_eval_ge + (P : Polynomial ℂ) (hn : 0 < P.natDegree) : + ∃ R0 : ℝ, 0 < R0 ∧ + ∀ R : ℝ, R0 ≤ R → + ∃ z : ℂ, ‖z‖ = R ∧ + (‖P.leadingCoeff‖ / 2) * R ^ P.natDegree ≤ (P.eval z).re := by + classical + set n : ℕ := P.natDegree + have hn0 : 0 < n := hn + have hP0 : P ≠ 0 := by + intro h0 + simp [n, h0] at hn0 + have hLC : P.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr hP0 + set a : ℂ := P.leadingCoeff + have ha : a ≠ 0 := hLC + have hnorm_a_pos : 0 < ‖a‖ := norm_pos_iff.mpr ha + set wtarget : ℂ := (starRingEnd ℂ) a / (‖a‖ : ℂ) + have hwtarget_norm : ‖wtarget‖ = (1 : ℝ) := by + calc + ‖wtarget‖ = ‖(starRingEnd ℂ) a‖ / ‖(‖a‖ : ℂ)‖ := by + simp [wtarget] + _ = ‖a‖ / ‖a‖ := by simp + _ = (1 : ℝ) := by + field_simp [hnorm_a_pos.ne'] + rcases exists_pow_eq_complex (n := n) hn0 (w := wtarget) with ⟨w, hw⟩ + have hw_norm : ‖w‖ = (1 : ℝ) := by + have hpow : (‖w‖ : ℝ) ^ n = 1 := by + have := congrArg (fun z : ℂ => ‖z‖) hw + simpa [norm_pow, hwtarget_norm] using this + have hn0' : n ≠ 0 := Nat.ne_of_gt hn0 + exact (pow_eq_one_iff_of_nonneg (norm_nonneg w) hn0').1 hpow + set S : ℝ := ∑ i ∈ Finset.range n, ‖P.coeff i‖ + set R0 : ℝ := max 1 (2 * S / ‖a‖) + refine ⟨R0, ?_, ?_⟩ + · have : (0 : ℝ) < (1 : ℝ) := by norm_num + exact lt_of_lt_of_le this (le_max_left _ _) + · intro R hR + have hR_ge1 : (1 : ℝ) ≤ R := by + exact le_trans (le_max_left _ _) hR + have hR_nonneg : 0 ≤ R := le_trans (by norm_num) hR_ge1 + set z : ℂ := (R : ℂ) * w + have hz_norm : ‖z‖ = R := by + have : ‖z‖ = |R| * ‖w‖ := by + simp [z] + simp [this, hw_norm, abs_of_nonneg hR_nonneg] + have h_eval : P.eval z = + (∑ i ∈ Finset.range n, P.coeff i * z ^ i) + P.coeff n * z ^ n := by + have hsum : P.eval z = ∑ i ∈ Finset.range (n + 1), P.coeff i * z ^ i := by + have : P.natDegree + 1 = n + 1 := by simp [n] + simpa [this] using (Polynomial.eval_eq_sum_range (p := P) z) + have hsplit : + (∑ i ∈ Finset.range (n + 1), P.coeff i * z ^ i) + = (∑ i ∈ Finset.range n, P.coeff i * z ^ i) + P.coeff n * z ^ n := by + simpa using (Finset.sum_range_succ (f := fun i => P.coeff i * z ^ i) n) + exact hsum.trans hsplit + have h_lower_norm : + ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ ≤ S * R ^ (n - 1) := by + have h1 : + ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ + ≤ ∑ i ∈ Finset.range n, ‖P.coeff i * z ^ i‖ := by + simpa using (norm_sum_le (Finset.range n) (fun i => P.coeff i * z ^ i)) + have hterm : ∀ i ∈ Finset.range n, ‖P.coeff i * z ^ i‖ ≤ ‖P.coeff i‖ * R ^ (n - 1) := by + intro i hi + have hi_lt : i < n := Finset.mem_range.mp hi + have hi_le : i ≤ n - 1 := Nat.le_pred_of_lt hi_lt + have hzpow : ‖z‖ ^ i ≤ R ^ (n - 1) := by + have hmono : ‖z‖ ^ i ≤ ‖z‖ ^ (n - 1) := + pow_le_pow_right₀ (by simpa [hz_norm] using hR_ge1) hi_le + simpa [hz_norm] using hmono + calc + ‖P.coeff i * z ^ i‖ = ‖P.coeff i‖ * ‖z‖ ^ i := by + simp [norm_pow] + _ ≤ ‖P.coeff i‖ * R ^ (n - 1) := by + exact mul_le_mul_of_nonneg_left hzpow (norm_nonneg _) + have h2 : + ∑ i ∈ Finset.range n, ‖P.coeff i * z ^ i‖ + ≤ ∑ i ∈ Finset.range n, ‖P.coeff i‖ * R ^ (n - 1) := by + exact Finset.sum_le_sum (fun i hi => hterm i hi) + have h3 : + (∑ i ∈ Finset.range n, ‖P.coeff i‖ * R ^ (n - 1)) + = (∑ i ∈ Finset.range n, ‖P.coeff i‖) * R ^ (n - 1) := by + simp [Finset.sum_mul] + have hsum_le : (∑ i ∈ Finset.range n, ‖P.coeff i‖) ≤ S := by + simp [S] + calc + ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ + ≤ ∑ i ∈ Finset.range n, ‖P.coeff i * z ^ i‖ := h1 + _ ≤ ∑ i ∈ Finset.range n, ‖P.coeff i‖ * R ^ (n - 1) := h2 + _ = (∑ i ∈ Finset.range n, ‖P.coeff i‖) * R ^ (n - 1) := h3 + _ ≤ S * R ^ (n - 1) := by + exact mul_le_mul_of_nonneg_right hsum_le (pow_nonneg hR_nonneg _) + have h_lead_re : (P.coeff n * z ^ n).re = ‖a‖ * R ^ n := by + have hw_pow : w ^ n = wtarget := hw + have ha_mul : a * w ^ n = (‖a‖ : ℂ) := by + have : a * w ^ n = a * wtarget := by simp [hw_pow] + simpa [wtarget, a] using (this.trans (mul_conj_div_norm a ha)) + have hz_pow : z ^ n = ((R : ℂ) ^ n) * (w ^ n) := by + simp [z, mul_pow, mul_comm] + have hcoeffn : P.coeff n = a := by simp [a, n, Polynomial.coeff_natDegree] + have hreR : ∀ m : ℕ, (((R : ℂ) ^ m).re) = R ^ m := by + intro m + induction m with + | zero => simp + | succ m ih => + simp [pow_succ, ih, Complex.mul_re] + calc + (P.coeff n * z ^ n).re + = (a * z ^ n).re := by simp [hcoeffn] + _ = (a * (((R : ℂ) ^ n) * (w ^ n))).re := by simp [hz_pow] + _ = (((R : ℂ) ^ n) * (a * (w ^ n))).re := by + ring_nf + _ = (((R : ℂ) ^ n) * (‖a‖ : ℂ)).re := by simp [ha_mul] + _ = (((R : ℂ) ^ n).re) * ‖a‖ := by + simp [Complex.mul_re] + _ = (R ^ n) * ‖a‖ := by simp [hreR n] + _ = ‖a‖ * R ^ n := by ring + refine ⟨z, hz_norm, ?_⟩ + have hre_lower : (∑ i ∈ Finset.range n, P.coeff i * z ^ i).re + ≥ -‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ := by + have habs : |(∑ i ∈ Finset.range n, P.coeff i * z ^ i).re| + ≤ ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ := + Complex.abs_re_le_norm _ + have := neg_le_of_abs_le habs + simpa using this + have hre_main : + (P.eval z).re ≥ (P.coeff n * z ^ n).re - ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ := by + have : (P.eval z).re = + (∑ i ∈ Finset.range n, P.coeff i * z ^ i).re + (P.coeff n * z ^ n).re := by + simp [h_eval, add_comm] + linarith [this, hre_lower] + have hR_ge_R0 : R0 ≤ R := hR + have hR_ge : 2 * S / ‖a‖ ≤ R := le_trans (le_max_right _ _) hR_ge_R0 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hR_ge1 + have hR_nonneg' : 0 ≤ R := le_of_lt hRpos + have hn_ge1 : 1 ≤ n := Nat.succ_le_of_lt hn0 + have hlower_le : S * R ^ (n - 1) ≤ (‖a‖ / 2) * R ^ n := by + have ha_pos : 0 < ‖a‖ := hnorm_a_pos + have hS_le : S ≤ (‖a‖ / 2) * R := by + have : 2 * S ≤ ‖a‖ * R := by + have := (mul_le_mul_of_nonneg_left hR_ge (by linarith [ha_pos.le] : (0 : ℝ) ≤ ‖a‖)) + have hne : (‖a‖ : ℝ) ≠ 0 := ne_of_gt ha_pos + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm, hne] using this + have : S ≤ (‖a‖ * R) / 2 := by linarith + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using this + have : S * R ^ (n - 1) ≤ (‖a‖ / 2) * R * R ^ (n - 1) := by + have hpow_nonneg : 0 ≤ R ^ (n - 1) := pow_nonneg hR_nonneg' _ + exact mul_le_mul_of_nonneg_right hS_le hpow_nonneg + have hRR : R * R ^ (n - 1) = R ^ n := by + have : n = (n - 1) + 1 := by + exact (Nat.sub_add_cancel hn_ge1).symm + rw [this, pow_succ] + ring_nf; grind + simpa [mul_assoc, hRR] using this + have hfinal_re : + (‖a‖ / 2) * R ^ n ≤ (P.eval z).re := by + have hlower' : ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ ≤ (‖a‖ / 2) * R ^ n := by + exact h_lower_norm.trans hlower_le + have hlead : (P.coeff n * z ^ n).re = ‖a‖ * R ^ n := by simpa [a] using h_lead_re + have hre_main' : + (‖a‖ * R ^ n) - ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ ≤ (P.eval z).re := by + simpa [hlead] using hre_main + have hsub : + (‖a‖ * R ^ n) - (‖a‖ / 2) * R ^ n ≤ + (‖a‖ * R ^ n) - ‖∑ i ∈ Finset.range n, P.coeff i * z ^ i‖ := + sub_le_sub_left hlower' (‖a‖ * R ^ n) + have hsim : (‖a‖ * R ^ n) - (‖a‖ / 2) * R ^ n = (‖a‖ / 2) * R ^ n := by ring + have : (‖a‖ * R ^ n) - (‖a‖ / 2) * R ^ n ≤ (P.eval z).re := + hsub.trans hre_main' + simpa [hsim] using this + simpa [a, n] using hfinal_re + +theorem natDegree_le_floor_of_growth_exp_eval + {ρ : ℝ} (hρ : 0 ≤ ρ) (P : Polynomial ℂ) + (hgrowth : + ∃ C > 0, ∀ z : ℂ, + Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) ≤ C * (1 + ‖z‖) ^ ρ) : + P.natDegree ≤ Nat.floor ρ := by + classical + by_cases hdeg : P.natDegree = 0 + · simp [hdeg] + · have hnpos : 0 < P.natDegree := Nat.pos_of_ne_zero hdeg + rcases exists_z_norm_eq_re_eval_ge (P := P) hnpos with ⟨R0, hR0pos, hray⟩ + rcases hgrowth with ⟨C, hCpos, hC⟩ + have hLCpos : 0 < ‖P.leadingCoeff‖ := by + have hP0 : P ≠ 0 := by + intro h0 + simp [h0] at hdeg + have : P.leadingCoeff ≠ 0 := (Polynomial.leadingCoeff_ne_zero).2 hP0 + exact norm_pos_iff.2 this + let c : ℝ := ‖P.leadingCoeff‖ / 2 + have hcpos : 0 < c := by + have : (0 : ℝ) < (2 : ℝ) := by norm_num + exact (div_pos hLCpos this) + have hn_le_real : (P.natDegree : ℝ) ≤ ρ := by + by_contra hnlt + have hnlt' : ρ < (P.natDegree : ℝ) := lt_of_not_ge hnlt + let δ : ℝ := (P.natDegree : ℝ) - ρ + have hδ : 0 < δ := sub_pos.2 hnlt' + let K0 : ℝ := (C * (2 : ℝ) ^ ρ) / c + have hK0 : ∃ R1, ∀ R ≥ R1, K0 + 1 ≤ R ^ δ := by + have h : ∀ᶠ R in (atTop : Filter ℝ), K0 + 1 ≤ R ^ δ := + (tendsto_atTop.mp (tendsto_rpow_atTop hδ)) (K0 + 1) + rcases (eventually_atTop.1 h) with ⟨R1, hR1⟩ + exact ⟨R1, hR1⟩ + rcases hK0 with ⟨R1, hR1⟩ + set R : ℝ := max (max R0 1) R1 + have hR_ge_R0 : R0 ≤ R := le_trans (le_max_left _ _) (le_max_left _ _) + have hR_ge1 : (1 : ℝ) ≤ R := le_trans (le_max_right _ _) (le_max_left _ _) + have hR_ge_R1 : R1 ≤ R := le_max_right _ _ + have hR_pos : 0 < R := lt_of_lt_of_le (by norm_num : (0 : ℝ) < 1) hR_ge1 + have hRδ : K0 + 1 ≤ R ^ δ := hR1 R hR_ge_R1 + rcases hray R hR_ge_R0 with ⟨z, hz_norm, hz_re⟩ + have hlog_lower : + (P.eval z).re ≤ Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) := by + have hpos : 0 < ‖Complex.exp (Polynomial.eval z P)‖ := by + simp + have hle : + ‖Complex.exp (Polynomial.eval z P)‖ ≤ + 1 + ‖Complex.exp (Polynomial.eval z P)‖ := by + linarith [norm_nonneg (Complex.exp (Polynomial.eval z P))] + have hlog_le : Real.log ‖Complex.exp (Polynomial.eval z P)‖ + ≤ Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) := + Real.log_le_log hpos hle + have hlog_eq : Real.log ‖Complex.exp (Polynomial.eval z P)‖ = (P.eval z).re := by + simp [Complex.norm_exp] + simpa [hlog_eq] using hlog_le + have hlog_upper : + Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) ≤ C * (1 + ‖z‖) ^ ρ := + hC z + have hmain : c * R ^ (P.natDegree : ℝ) ≤ C * (1 + R) ^ ρ := by + have hz_re' : c * R ^ P.natDegree ≤ (P.eval z).re := by + simpa [c] using hz_re + have hz_re'' : c * R ^ (P.natDegree : ℝ) ≤ (P.eval z).re := by + simpa [Real.rpow_natCast, c] using hz_re' + have : c * R ^ (P.natDegree : ℝ) ≤ Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) := + hz_re''.trans hlog_lower + have : c * R ^ (P.natDegree : ℝ) ≤ C * (1 + ‖z‖) ^ ρ := + this.trans hlog_upper + simpa [hz_norm] using this + have h1R_le : (1 + R : ℝ) ≤ R * 2 := by linarith + have hpow1 : (1 + R : ℝ) ^ ρ ≤ (R * 2) ^ ρ := + Real.rpow_le_rpow (by linarith [hR_pos.le]) h1R_le hρ + have hR2 : (R * 2) ^ ρ = R ^ ρ * (2 : ℝ) ^ ρ := by + have hRnonneg : 0 ≤ R := le_of_lt hR_pos + have h2nonneg : 0 ≤ (2 : ℝ) := by norm_num + simpa [mul_assoc] using (Real.mul_rpow hRnonneg h2nonneg (z := ρ)) + have hmain' : c * R ^ (P.natDegree : ℝ) ≤ C * (R ^ ρ * (2 : ℝ) ^ ρ) := by + have := le_trans hmain (mul_le_mul_of_nonneg_left hpow1 (le_of_lt hCpos)) + simpa [hR2, mul_assoc, mul_left_comm, mul_comm] using this + have hRρ_pos : 0 < R ^ ρ := Real.rpow_pos_of_pos hR_pos _ + have hRρ_ne : (R ^ ρ : ℝ) ≠ 0 := ne_of_gt hRρ_pos + have hdiv : + (c * R ^ (P.natDegree : ℝ)) / (R ^ ρ) ≤ C * (2 : ℝ) ^ ρ := by + have h := + div_le_div_of_nonneg_right hmain' (le_of_lt hRρ_pos) + have hRhs : (C * (R ^ ρ * (2 : ℝ) ^ ρ)) / (R ^ ρ) = C * (2 : ℝ) ^ ρ := by + field_simp [hRρ_ne] + simpa [hRhs, mul_assoc, mul_left_comm, mul_comm] using h + have hRsub : R ^ δ = R ^ (P.natDegree : ℝ) / R ^ ρ := by + simpa [δ] using (Real.rpow_sub hR_pos (P.natDegree : ℝ) ρ) + have hRδ_le : c * (R ^ δ) ≤ C * (2 : ℝ) ^ ρ := by + have hLhs : c * (R ^ δ) = (c * R ^ (P.natDegree : ℝ)) / (R ^ ρ) := by + simp [hRsub, div_eq_mul_inv, mul_left_comm, mul_comm] + simpa [hLhs] using hdiv + have hRδ_le' : R ^ δ ≤ K0 := by + have : R ^ δ ≤ (C * (2 : ℝ) ^ ρ) / c := by + refine (le_div_iff₀ hcpos).2 ?_ + simpa [mul_assoc, mul_left_comm, mul_comm] using hRδ_le + simpa [K0] using this + have : K0 + 1 ≤ K0 := le_trans hRδ (le_trans hRδ_le' (le_rfl)) + exact (not_lt_of_ge this) (lt_add_of_pos_right _ (by norm_num : (0 : ℝ) < 1)) + exact (Nat.le_floor_iff hρ).2 hn_le_real + +theorem natDegree_le_floor_of_exp_eval_norm_bound {τ : ℝ} (hτ : 0 ≤ τ) (P : Polynomial ℂ) + (hbound : + ∃ C > 0, ∀ z : ℂ, + ‖Complex.exp (Polynomial.eval z P)‖ ≤ Real.exp (C * (1 + ‖z‖) ^ τ)) : + P.natDegree ≤ Nat.floor τ := by + rcases hbound with ⟨C, hCpos, hC⟩ + have hlog_growth : + ∃ C > 0, ∀ z : ℂ, + Real.log (1 + ‖Complex.exp (Polynomial.eval z P)‖) ≤ C * (1 + ‖z‖) ^ τ := + Real.log_growth_of_norm_le_exp_mul_rpow + (f := fun z : ℂ => Complex.exp (Polynomial.eval z P)) + (r := fun z : ℂ => 1 + ‖z‖) hCpos hτ + (fun z => by linarith [norm_nonneg z]) hC + exact natDegree_le_floor_of_growth_exp_eval (ρ := τ) hτ P hlog_growth + +end Hadamard +end Complex +end +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/Factorization.lean b/PrimeNumberTheoremAnd/SiegelZeros/Factorization.lean new file mode 100644 index 0000000..8fb7d8e --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/Factorization.lean @@ -0,0 +1,415 @@ +import Mathlib +import PrimeNumberTheoremAnd.SiegelZeros.DivisorLimits + +namespace SiegelZeros + +section +namespace Complex.Hadamard + +open Filter Topology Set _root_.SiegelZeros.Complex + +open scoped BigOperators Topology + +noncomputable def hadamardDenom (m : ℕ) (f : ℂ → ℂ) (z : ℂ) : ℂ := + z ^ (analyticOrderNatAt f 0) * divisorCanonicalProduct m f (Set.univ : Set ℂ) z + +theorem differentiable_divisorCanonicalProduct_univ (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + Differentiable ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) := by + intro z + have hdiffOn : + DifferentiableOn ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) (Set.univ : Set ℂ) := + differentiableOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + exact (hdiffOn z (by simp)).differentiableAt (by simp) + +theorem analyticAt_divisorCanonicalProduct_univ (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) (z : ℂ) : + AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := + (differentiable_divisorCanonicalProduct_univ m f h_sum).analyticAt z + +theorem differentiable_hadamardDenom (m : ℕ) (f : ℂ → ℂ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + Differentiable ℂ (hadamardDenom m f) := by + have hcprod : Differentiable ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) := by + exact differentiable_divisorCanonicalProduct_univ m f h_sum + simpa [hadamardDenom] using! (differentiable_id.pow (analyticOrderNatAt f 0)).mul hcprod + +theorem hadamardDenom_ne_zero_at {m : ℕ} {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (hnot : ∃ z : ℂ, f z ≠ 0) (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) {z : ℂ} (hz : f z ≠ 0) : hadamardDenom m f z ≠ 0 := by + have hf_not_top : ∀ w : ℂ, analyticOrderAt f w ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (hf := hf) hnot + have han_f : AnalyticAt ℂ f z := hf.analyticAt z + have horder_f : analyticOrderNatAt f z = 0 := by + have : analyticOrderAt f z = 0 := (han_f.analyticOrderAt_eq_zero).2 hz + have hcast : (analyticOrderNatAt f z : ℕ∞) = analyticOrderAt f z := + Nat.cast_analyticOrderNatAt (f := f) (z₀ := z) (hf_not_top z) + have : (analyticOrderNatAt f z : ℕ∞) = 0 := by simp [hcast, this] + exact_mod_cast this + have han_cprod : AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := by + exact analyticAt_divisorCanonicalProduct_univ m f h_sum z + by_cases hz0 : z = 0 + · subst hz0 + have hord0 : analyticOrderNatAt f 0 = 0 := by simpa using horder_f + simp [hadamardDenom, hord0, divisorCanonicalProduct_zero] + · have hp : z ^ (analyticOrderNatAt f 0) ≠ 0 := pow_ne_zero _ hz0 + have hcprod_order : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z = 0 := by + simpa [horder_f] using + (analyticOrderNatAt_divisorCanonicalProduct_eq_analyticOrderNatAt (m := m) (hf := hf) + (h_sum := h_sum) (z₀ := z) hz0) + have hcprod_ne : divisorCanonicalProduct m f (Set.univ : Set ℂ) z ≠ 0 := by + have hcprod_entire : + Differentiable ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) := by + exact differentiable_divisorCanonicalProduct_univ m f h_sum + have hcprod_not_top : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (hf := hcprod_entire) + ⟨0, by simp [divisorCanonicalProduct_zero]⟩ z + have hcprod_cast : + (analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z : ℕ∞) = + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := + Nat.cast_analyticOrderNatAt + (f := divisorCanonicalProduct m f (Set.univ : Set ℂ)) (z₀ := z) hcprod_not_top + have : analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z = 0 := by + have : + (analyticOrderNatAt + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z : ℕ∞) = 0 := by + exact_mod_cast hcprod_order + simp [hcprod_cast] at this + simpa using this + exact (han_cprod.analyticOrderAt_eq_zero).1 this + exact mul_ne_zero hp hcprod_ne + +lemma analyticOrderNatAt_divisorCanonicalProduct_zero + (m : ℕ) (f : ℂ → ℂ) (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 = 0 := by + have hcprod_entire : + Differentiable ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) := by + exact differentiable_divisorCanonicalProduct_univ m f h_sum + have hcprod_not_top : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (hf := hcprod_entire) + ⟨0, by simp [divisorCanonicalProduct_zero]⟩ 0 + have hcprodA : AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 := + hcprod_entire.analyticAt 0 + have hcprod0 : divisorCanonicalProduct m f (Set.univ : Set ℂ) 0 ≠ 0 := by + simp [divisorCanonicalProduct_zero] + have : analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 = 0 := + (hcprodA.analyticOrderAt_eq_zero).2 hcprod0 + have hcast : + (analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 : ℕ∞) = + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 := + Nat.cast_analyticOrderNatAt + (f := divisorCanonicalProduct m f (Set.univ : Set ℂ)) (z₀ := (0 : ℂ)) hcprod_not_top + have : + (analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 : ℕ∞) = + 0 := by + simp [hcast, this] + exact_mod_cast this + +theorem analyticOrderNatAt_hadamardDenom_eq + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) (z : ℂ) : + analyticOrderNatAt (hadamardDenom m f) z = analyticOrderNatAt f z := by + by_cases hz0 : z = 0 + · subst hz0 + have hpowA : AnalyticAt ℂ (fun z : ℂ => z ^ analyticOrderNatAt f 0) 0 := by + simpa using! (analyticAt_id.pow (analyticOrderNatAt f 0)) + have hpow_not_top : + analyticOrderAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) 0 ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero + (hf := (differentiable_id.pow (analyticOrderNatAt f 0))) + ⟨1, by simp⟩ 0 + have hcprodA : AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 := by + exact analyticAt_divisorCanonicalProduct_univ m f h_sum 0 + have hcprod0 : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 = 0 := + analyticOrderNatAt_divisorCanonicalProduct_zero (m := m) (f := f) h_sum + have hid0 : analyticOrderNatAt (fun z : ℂ => z) 0 = 1 := by + have hid_entire : Differentiable ℂ (fun z : ℂ => z) := differentiable_id + have hdiv : + (MeromorphicOn.divisor (fun z : ℂ => z) (Set.univ : Set ℂ)) 0 = + (analyticOrderNatAt (fun z : ℂ => z) 0 : ℤ) := by + simpa using + (divisor_univ_eq_analyticOrderNatAt_int + (f := fun z : ℂ => z) hid_entire 0) + have hdiv1 : (MeromorphicOn.divisor (fun z : ℂ => z) (Set.univ : Set ℂ)) 0 = 1 := by + simpa using + (MeromorphicOn.divisor_sub_const_self (z₀ := (0 : ℂ)) + (U := (Set.univ : Set ℂ)) (by simp)) + have : (analyticOrderNatAt (fun z : ℂ => z) 0 : ℤ) = 1 := by + simpa [hdiv] using hdiv1 + exact_mod_cast this + have hpow0 : + analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) 0 = + analyticOrderNatAt f 0 := by + have hidA : AnalyticAt ℂ (fun z : ℂ => z) 0 := by + simpa [id] using! (analyticAt_id : AnalyticAt ℂ (id : ℂ → ℂ) 0) + simpa [hid0] using! (analyticOrderNatAt_pow (hf := hidA) (n := analyticOrderNatAt f 0)) + have hmul : + analyticOrderNatAt (hadamardDenom m f) 0 = + analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) 0 + + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 := by + have hcprod_not_top' : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) 0 ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero + (hf := differentiable_divisorCanonicalProduct_univ m f h_sum) + ⟨0, by simp [divisorCanonicalProduct_zero]⟩ 0 + simpa [hadamardDenom] using! + analyticOrderNatAt_mul (hf := hpowA) (hg := hcprodA) + (hf' := hpow_not_top) (hg' := hcprod_not_top') + simp [hmul, hpow0, hcprod0] + · have hpowA : AnalyticAt ℂ (fun z : ℂ => z ^ analyticOrderNatAt f 0) z := by + simpa using! (analyticAt_id.pow (analyticOrderNatAt f 0)) + have hpow_not_top : + analyticOrderAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero + (hf := (differentiable_id.pow (analyticOrderNatAt f 0))) + ⟨1, by simp⟩ z + have hpow0 : analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z = 0 := by + have hz' : (fun z : ℂ => z ^ analyticOrderNatAt f 0) z ≠ 0 := by + simp [hz0] + have : analyticOrderAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z = 0 := + ((hpowA).analyticOrderAt_eq_zero).2 hz' + have hcast : (analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z : ℕ∞) = + analyticOrderAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z := + Nat.cast_analyticOrderNatAt + (f := fun z : ℂ => z ^ analyticOrderNatAt f 0) (z₀ := z) hpow_not_top + have : (analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z : ℕ∞) = 0 := by + simp [hcast, this] + exact_mod_cast this + have hcprod_eq : + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z = + analyticOrderNatAt f z := + analyticOrderNatAt_divisorCanonicalProduct_eq_analyticOrderNatAt + (m := m) (hf := hf) (h_sum := h_sum) (z₀ := z) hz0 + have hcprodA : AnalyticAt ℂ (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := by + exact analyticAt_divisorCanonicalProduct_univ m f h_sum z + have hcprod_not_top : + analyticOrderAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero + (hf := differentiable_divisorCanonicalProduct_univ m f h_sum) + ⟨0, by simp [divisorCanonicalProduct_zero]⟩ z + have hmul : + analyticOrderNatAt (hadamardDenom m f) z = + analyticOrderNatAt (fun z : ℂ => z ^ analyticOrderNatAt f 0) z + + analyticOrderNatAt (divisorCanonicalProduct m f (Set.univ : Set ℂ)) z := by + simpa [hadamardDenom] using! + analyticOrderNatAt_mul (hf := hpowA) (hg := hcprodA) + (hf' := hpow_not_top) (hg' := hcprod_not_top) + simp [hmul, hpow0, hcprod_eq] + +theorem divisor_hadamardDenom_eq + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + MeromorphicOn.divisor (hadamardDenom m f) (Set.univ : Set ℂ) = + MeromorphicOn.divisor f (Set.univ : Set ℂ) := by + ext z + have hden_entire : Differentiable ℂ (hadamardDenom m f) := + differentiable_hadamardDenom (m := m) f h_sum + have hf_entire : Differentiable ℂ f := hf + have hden : + (MeromorphicOn.divisor (hadamardDenom m f) (Set.univ : Set ℂ)) z = + (analyticOrderNatAt (hadamardDenom m f) z : ℤ) := by + simpa using (divisor_univ_eq_analyticOrderNatAt_int (f := hadamardDenom m f) hden_entire z) + have hfz : + (MeromorphicOn.divisor f (Set.univ : Set ℂ)) z = + (analyticOrderNatAt f z : ℤ) := by + simpa using (divisor_univ_eq_analyticOrderNatAt_int (f := f) hf_entire z) + simp [hden, hfz, analyticOrderNatAt_hadamardDenom_eq (m := m) (hf := hf) (h_sum := h_sum) z] + +theorem divisor_hadamardQuotient_eq_zero + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + MeromorphicOn.divisor (fun z : ℂ => f z / hadamardDenom m f z) (Set.univ : Set ℂ) = 0 := by + have hf_mero : MeromorphicOn f (Set.univ : Set ℂ) := by + intro z hz + exact (hf.analyticAt z).meromorphicAt + have hden_entire : Differentiable ℂ (hadamardDenom m f) := + differentiable_hadamardDenom (m := m) f h_sum + have hden_mero : MeromorphicOn (hadamardDenom m f) (Set.univ : Set ℂ) := by + intro z hz + exact (hden_entire.analyticAt z).meromorphicAt + rcases hnot with ⟨z1, hz1⟩ + have hden1 : hadamardDenom m f z1 ≠ 0 := + hadamardDenom_ne_zero_at (m := m) (f := f) hf ⟨z1, hz1⟩ h_sum hz1 + have hf_order_ne_top : ∀ z ∈ (Set.univ : Set ℂ), meromorphicOrderAt f z ≠ ⊤ := by + intro z hzU + have hz1_ne_top : meromorphicOrderAt f z1 ≠ ⊤ := by + have hfAt : MeromorphicAt f z1 := hf_mero z1 (by simp) + have hcont : ContinuousAt f z1 := (hf.differentiableAt).continuousAt + have hne_nhds : ∀ᶠ w in 𝓝 z1, f w ≠ 0 := + (hcont.ne_iff_eventually_ne continuousAt_const).1 hz1 + have hne_nhdsNE : ∀ᶠ w in 𝓝[≠] z1, f w ≠ 0 := + eventually_nhdsWithin_of_eventually_nhds hne_nhds + exact (meromorphicOrderAt_ne_top_iff_eventually_ne_zero (hf := hfAt)).2 hne_nhdsNE + exact MeromorphicOn.meromorphicOrderAt_ne_top_of_isPreconnected (hf := hf_mero) + (x := z1) (hU := isPreconnected_univ) (h₁x := by simp) (hy := by simp) hz1_ne_top + have hden_order_ne_top : + ∀ z ∈ (Set.univ : Set ℂ), meromorphicOrderAt (hadamardDenom m f) z ≠ ⊤ := by + intro z hzU + have hz1_ne_top : meromorphicOrderAt (hadamardDenom m f) z1 ≠ ⊤ := by + have hdenAt : MeromorphicAt (hadamardDenom m f) z1 := hden_mero z1 (by simp) + have hcont : ContinuousAt (hadamardDenom m f) z1 := + (hden_entire.differentiableAt).continuousAt + have hne_nhds : ∀ᶠ w in 𝓝 z1, hadamardDenom m f w ≠ 0 := + (hcont.ne_iff_eventually_ne continuousAt_const).1 hden1 + have hne_nhdsNE : ∀ᶠ w in 𝓝[≠] z1, hadamardDenom m f w ≠ 0 := + eventually_nhdsWithin_of_eventually_nhds hne_nhds + exact (meromorphicOrderAt_ne_top_iff_eventually_ne_zero (hf := hdenAt)).2 hne_nhdsNE + exact MeromorphicOn.meromorphicOrderAt_ne_top_of_isPreconnected (hf := hden_mero) + (x := z1) (hU := isPreconnected_univ) (h₁x := by simp) (hy := by simp) hz1_ne_top + have hinv_order_ne_top : + ∀ z ∈ (Set.univ : Set ℂ), + meromorphicOrderAt (fun z : ℂ => (hadamardDenom m f z)⁻¹) z ≠ ⊤ := by + intro z hzU + have hinv_mero : + MeromorphicOn (fun z : ℂ => (hadamardDenom m f z)⁻¹) (Set.univ : Set ℂ) := + hden_mero.inv + have hz1_ne_top : + meromorphicOrderAt (fun z : ℂ => (hadamardDenom m f z)⁻¹) z1 ≠ ⊤ := by + have hinvAt : MeromorphicAt (fun z : ℂ => (hadamardDenom m f z)⁻¹) z1 := + hinv_mero z1 (by simp) + have hcont_denom : ContinuousAt (hadamardDenom m f) z1 := + (hden_entire.differentiableAt).continuousAt + have hcont : ContinuousAt (fun z : ℂ => (hadamardDenom m f z)⁻¹) z1 := + hcont_denom.inv₀ hden1 + have hinv1 : (fun z : ℂ => (hadamardDenom m f z)⁻¹) z1 ≠ 0 := by + simpa using inv_ne_zero hden1 + have hne_nhds : + ∀ᶠ w in 𝓝 z1, (fun z : ℂ => (hadamardDenom m f z)⁻¹) w ≠ 0 := + (hcont.ne_iff_eventually_ne continuousAt_const).1 hinv1 + have hne_nhdsNE : + ∀ᶠ w in 𝓝[≠] z1, (fun z : ℂ => (hadamardDenom m f z)⁻¹) w ≠ 0 := + eventually_nhdsWithin_of_eventually_nhds hne_nhds + exact (meromorphicOrderAt_ne_top_iff_eventually_ne_zero (hf := hinvAt)).2 hne_nhdsNE + exact MeromorphicOn.meromorphicOrderAt_ne_top_of_isPreconnected (hf := hinv_mero) + (x := z1) (hU := isPreconnected_univ) (h₁x := by simp) (hy := by simp) hz1_ne_top + have hdiv_denom : MeromorphicOn.divisor (hadamardDenom m f) (Set.univ : Set ℂ) = + MeromorphicOn.divisor f (Set.univ : Set ℂ) := + divisor_hadamardDenom_eq (m := m) (hf := hf) (h_sum := h_sum) + calc + MeromorphicOn.divisor (fun z : ℂ => f z / hadamardDenom m f z) (Set.univ : Set ℂ) + = MeromorphicOn.divisor + (fun z : ℂ => f z * (hadamardDenom m f z)⁻¹) (Set.univ : Set ℂ) := by + simp [div_eq_mul_inv] + _ = MeromorphicOn.divisor f (Set.univ : Set ℂ) + + MeromorphicOn.divisor (fun z : ℂ => (hadamardDenom m f z)⁻¹) (Set.univ : Set ℂ) := by + simpa using (MeromorphicOn.divisor_fun_mul (U := (Set.univ : Set ℂ)) + (f₁ := f) (f₂ := fun z => (hadamardDenom m f z)⁻¹) hf_mero (hden_mero.inv) + hf_order_ne_top hinv_order_ne_top) + _ = MeromorphicOn.divisor f (Set.univ : Set ℂ) - + MeromorphicOn.divisor (hadamardDenom m f) (Set.univ : Set ℂ) := by + simp [sub_eq_add_neg] + _ = 0 := by + simp [hdiv_denom] + +theorem exists_entire_nonzero_hadamardQuotient + (m : ℕ) {f : ℂ → ℂ} (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) : + ∃ H : ℂ → ℂ, Differentiable ℂ H ∧ (∀ z, H z ≠ 0) ∧ ∀ z : ℂ, f z = + H z * z ^ (analyticOrderNatAt f 0) * divisorCanonicalProduct m f (Set.univ : Set ℂ) z := by + let denom : ℂ → ℂ := hadamardDenom m f + let q : ℂ → ℂ := fun z => f z / denom z + have hden_entire : Differentiable ℂ denom := + differentiable_hadamardDenom (m := m) f h_sum + have hq_mero : MeromorphicOn q (Set.univ : Set ℂ) := by + intro z hzU + have hf_m : MeromorphicAt f z := (hf.analyticAt z).meromorphicAt + have hden_m : MeromorphicAt denom z := (hden_entire.analyticAt z).meromorphicAt + simpa [q, denom, div_eq_mul_inv] using! (hf_m.mul hden_m.inv) + let H : ℂ → ℂ := toMeromorphicNFOn q (Set.univ : Set ℂ) + have hNF : MeromorphicNFOn H (Set.univ : Set ℂ) := + meromorphicNFOn_toMeromorphicNFOn q (Set.univ : Set ℂ) + have hdivH : MeromorphicOn.divisor H (Set.univ : Set ℂ) = 0 := by + have hdivq : MeromorphicOn.divisor q (Set.univ : Set ℂ) = 0 := + divisor_hadamardQuotient_eq_zero (m := m) (f := f) (hf := hf) + (hnot := hnot) (h_sum := h_sum) + simpa [H, hdivq] using + (MeromorphicOn.divisor_of_toMeromorphicNFOn + (f := q) (U := (Set.univ : Set ℂ)) hq_mero) + have hA : AnalyticOnNhd ℂ H (Set.univ : Set ℂ) := by + have : + (0 : Function.locallyFinsuppWithin (Set.univ : Set ℂ) ℤ) ≤ + MeromorphicOn.divisor H (Set.univ : Set ℂ) := by + simp [hdivH] + exact (MeromorphicNFOn.divisor_nonneg_iff_analyticOnNhd (h₁f := hNF)).1 (by simp [hdivH]) + have hH_entire : Differentiable ℂ H := by + intro z + exact (hA z (by simp)).differentiableAt + rcases hnot with ⟨z1, hz1⟩ + have hden1 : denom z1 ≠ 0 := + hadamardDenom_ne_zero_at (m := m) (f := f) hf ⟨z1, hz1⟩ h_sum hz1 + have hqA1 : AnalyticAt ℂ q z1 := by + have hdenA1 : AnalyticAt ℂ denom z1 := hden_entire.analyticAt z1 + exact (hf.analyticAt z1).div hdenA1 hden1 + have hqNF1 : MeromorphicNFAt q z1 := hqA1.meromorphicNFAt + have htoEq : toMeromorphicNFAt q z1 = q := (toMeromorphicNFAt_eq_self (f := q) (x := z1)).2 hqNF1 + have hH1 : H z1 = q z1 := by + have hx : z1 ∈ (Set.univ : Set ℂ) := by simp + have : toMeromorphicNFOn q (Set.univ : Set ℂ) z1 = toMeromorphicNFAt q z1 z1 := + (toMeromorphicNFOn_eq_toMeromorphicNFAt (f := q) (U := (Set.univ : Set ℂ)) hq_mero hx) + simpa [H, htoEq] using this + have hH1_ne : H z1 ≠ 0 := by + have : q z1 ≠ 0 := div_ne_zero hz1 hden1 + simpa [hH1] using this + have hH_not_top : ∀ z : ℂ, analyticOrderAt H z ≠ ⊤ := by + exact analyticOrderAt_ne_top_of_exists_ne_zero (hf := hH_entire) ⟨z1, hH1_ne⟩ + have hH_orderNat_zero : ∀ z : ℂ, analyticOrderNatAt H z = 0 := by + intro z + have hzdiv : + (MeromorphicOn.divisor H (Set.univ : Set ℂ)) z = (analyticOrderNatAt H z : ℤ) := by + simpa using (divisor_univ_eq_analyticOrderNatAt_int (f := H) hH_entire z) + have : (MeromorphicOn.divisor H (Set.univ : Set ℂ)) z = 0 := by + simp [hdivH] + have : (analyticOrderNatAt H z : ℤ) = 0 := by simpa [hzdiv] using this + exact_mod_cast this + have hH_ne : ∀ z : ℂ, H z ≠ 0 := by + intro z + have hcast : (analyticOrderNatAt H z : ℕ∞) = analyticOrderAt H z := + Nat.cast_analyticOrderNatAt (f := H) (z₀ := z) (hH_not_top z) + have : analyticOrderAt H z = 0 := by + have : (analyticOrderNatAt H z : ℕ∞) = 0 := by exact_mod_cast (hH_orderNat_zero z) + simpa [hcast] using this + exact ((hA z (by simp)).analyticOrderAt_eq_zero).1 this + have hfA : AnalyticOnNhd ℂ f (Set.univ : Set ℂ) := fun z hzU => hf.analyticAt z + have hdenA : AnalyticOnNhd ℂ denom (Set.univ : Set ℂ) := fun z hzU => hden_entire.analyticAt z + have hprodA : AnalyticOnNhd ℂ (fun z => H z * denom z) (Set.univ : Set ℂ) := + (hA.mul hdenA) + have hlocal : f =ᶠ[𝓝 z1] fun z => H z * denom z := by + have hden_ne : ∀ᶠ z in 𝓝 z1, denom z ≠ 0 := + (hden_entire.differentiableAt.continuousAt.ne_iff_eventually_ne continuousAt_const).1 hden1 + have hH_eq_q : H =ᶠ[𝓝 z1] q := by + have hx : z1 ∈ (Set.univ : Set ℂ) := by simp + have hloc : + toMeromorphicNFOn q (Set.univ : Set ℂ) =ᶠ[𝓝 z1] toMeromorphicNFAt q z1 := by + simpa [H] using (toMeromorphicNFOn_eq_toMeromorphicNFAt_on_nhds (f := q) + (U := (Set.univ : Set ℂ)) hq_mero hx) + simpa [H, htoEq] using hloc + filter_upwards [hden_ne, hH_eq_q] with z hzden hHz + have hcancel : q z * denom z = f z := by + dsimp [q] + field_simp [hzden] + calc + f z = q z * denom z := hcancel.symm + _ = H z * denom z := by simp [hHz] + have hglob : f = fun z => H z * denom z := + AnalyticOnNhd.eq_of_eventuallyEq (hf := hfA) (hg := hprodA) hlocal + refine ⟨H, hH_entire, hH_ne, ?_⟩ + intro z + have hglobz : f z = H z * denom z := congrArg (fun g => g z) hglob + simpa [denom, hadamardDenom, mul_assoc, mul_left_comm, mul_comm] using hglobz + +end Complex.Hadamard +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/Growth.lean b/PrimeNumberTheoremAnd/SiegelZeros/Growth.lean new file mode 100644 index 0000000..99df501 --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/Growth.lean @@ -0,0 +1,439 @@ +import Mathlib +import PrimeNumberTheoremAnd.SiegelZeros.Summability +import PrimeNumberTheoremAnd.SiegelZeros.Exponential + +namespace SiegelZeros + +section +noncomputable section + +open Set Filter Asymptotics +open scoped Topology BigOperators + +namespace Complex.Hadamard + +lemma no_zero_on_sphere_of_norm_image_avoid + {f : ℂ → ℂ} (hentire : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + {B r : ℝ} (hrpos : 0 < r) (hr_le_B : r ≤ B) + (smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))) (hsmall_fin : smallSet.Finite) + (hsmallSet : + smallSet = {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ B}) + (hr_not_bad : + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + r ∉ small.image a) : + ∀ u : ℂ, ‖u‖ = r → f u ≠ 0 := by + classical + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let bad : Finset ℝ := small.image a + have hr_not_bad' : r ∉ bad := by + simpa [bad, small, a] using hr_not_bad + have hr_not : + ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖ ≤ B → r ≠ ‖divisorZeroIndex₀Val p‖ := by + intro p hpB hEq + have hp_small : p ∈ small := by + have hp_mem : p ∈ smallSet := by + simpa [hsmallSet] using hpB + simpa [small] using (hsmall_fin.mem_toFinset.2 hp_mem) + have : r ∈ bad := Finset.mem_image.2 ⟨p, hp_small, by simpa [a] using hEq.symm⟩ + exact (hr_not_bad' this).elim + exact no_zero_on_sphere_of_forall_val_norm_ne (f := f) hentire hnot + (B := B) (r := r) hrpos hr_le_B hr_not + +theorem norm_inv_hadamardDenominator_le_exp_on_cartan_circle + {f : ℂ → ℂ} {ρ τ : ℝ} {m : ℕ} + (hmρ : (m : ℝ) ≤ ρ) (hτ : ρ < τ) (hτ_lt : τ < (m + 1 : ℝ)) + (hτ_nonneg : 0 ≤ τ) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (hsumτ : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) : + let Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + let Cprod : ℝ := cartanProductConstant m τ Sτ + ∀ {R r : ℝ}, 0 < R → 1 ≤ R → R ≤ r → r ≤ 2 * R → + ∀ (smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsmall_fin : smallSet.Finite), + smallSet = + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ‖divisorZeroIndex₀Val p‖ ≤ 4 * R} → + (let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => ‖divisorZeroIndex₀Val p‖ + r ∉ small.image a) → + (let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => ‖divisorZeroIndex₀Val p‖ + (∑ p ∈ small, (1 : ℝ) * CartanBound.φ (r / a p)) ≤ + CartanBound.Cφ * (small.card : ℝ)) → + ∀ u : ℂ, ‖u‖ = r → + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + ≤ Real.exp (Cprod * (1 + r) ^ τ) := by + classical + intro Sτ Cprod R r hRpos hRle hR_le_r hr_le_2R smallSet hsmall_fin + hsmallSet hr_not_bad hr_phi u hur + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let bad : Finset ℝ := small.image a + have hr_not_bad' : r ∉ bad := by + simpa [bad, small, a] using hr_not_bad + have hr1 : (1 : ℝ) ≤ r := le_trans hRle hR_le_r + have hpow_inv_le1 : ‖(u ^ analyticOrderNatAt f 0)⁻¹‖ ≤ 1 := + Complex.norm_inv_pow_le_one_of_one_le_norm u (analyticOrderNatAt f 0) (by simpa [hur] using hr1) + let fac : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℂ := + fun p => weierstrassFactor m (u / divisorZeroIndex₀Val p) + have hloc : + HasProdLocallyUniformlyOn + (fun (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) (w : ℂ) => + weierstrassFactor m (w / divisorZeroIndex₀Val p)) + (divisorCanonicalProduct m f (Set.univ : Set ℂ)) + (Set.univ : Set ℂ) := + hasProdLocallyUniformlyOn_divisorCanonicalProduct_univ (m := m) (f := f) h_sum + have hprod : + HasProd fac (divisorCanonicalProduct m f (Set.univ : Set ℂ) u) := + hloc.hasProd (by simp : u ∈ (Set.univ : Set ℂ)) + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + have : DecidablePred (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => p ∈ small) := + Classical.decPred _ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if hp : p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + have hterm : ∀ p, ‖(fac p)⁻¹‖ ≤ Real.exp (b p) := by + intro p + by_cases hp : p ∈ small + · have hval_ne : r ≠ ap p := by + intro hEq + have : r ∈ bad := by + refine Finset.mem_image.2 ⟨p, hp, ?_⟩ + simp [ap, a, hEq] + exact (hr_not_bad' this).elim + have hval0 : divisorZeroIndex₀Val p ≠ 0 := divisorZeroIndex₀Val_ne_zero p + have hmτ : (m : ℝ) ≤ τ := le_trans hmρ (le_of_lt hτ) + have hnear : + ‖(weierstrassFactor m (u / divisorZeroIndex₀Val p))⁻¹‖ + ≤ Real.exp (CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ)) := by + simpa [ap] using + (norm_inv_weierstrassFactor_le_exp_near (m := m) (τ := τ) (r := r) + (u := u) (a := divisorZeroIndex₀Val p) + (hur := hur) (ha := hval0) (hr := by simpa [ap] using hval_ne) hmτ) + simpa [fac, b, hp] using hnear + · have hlarge : (4 * R : ℝ) < ap p := by + have : ¬ap p ≤ 4 * R := by + intro hle + have : p ∈ small := by + have hp_mem : p ∈ smallSet := by + simpa [hsmallSet, ap] using hle + simpa [small] using (hsmall_fin.mem_toFinset.2 hp_mem) + exact hp this + exact lt_of_not_ge this + have hz' : ‖u / divisorZeroIndex₀Val p‖ ≤ (1 / 2 : ℝ) := + norm_div_le_half_of_norm_le_of_two_mul_lt (z := u) (a := divisorZeroIndex₀Val p) + (R := 2 * R) (by nlinarith [hRpos]) (by rw [hur]; exact hr_le_2R) + (by nlinarith [hlarge]) + have hτ_le : τ ≤ (m + 1 : ℝ) := le_of_lt hτ_lt + have hfar : + ‖(weierstrassFactor m (u / divisorZeroIndex₀Val p))⁻¹‖ ≤ + Real.exp ((2 : ℝ) * (r / ap p) ^ τ) := by + simpa [ap] using + (norm_inv_weierstrassFactor_le_exp_far (m := m) (τ := τ) (r := r) + (u := u) (a := divisorZeroIndex₀Val p) + (hur := hur) (ha := divisorZeroIndex₀Val_ne_zero p) (hz := hz') hτ_le) + simpa [fac, b, hp] using hfar + have hb_le : + ∀ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)), + (∑ p ∈ s, b p) ≤ Cprod * (1 + r) ^ τ := by + intro s + simpa [small, ap, b, Sτ, Cprod, a, hsmallSet] using + (Complex.Hadamard.cartan_sum_majorant_le (f := f) (m := m) (τ := τ) (R := R) (r := r) + (hRpos := hRpos) (hrpos := lt_of_lt_of_le hRpos hR_le_r) + (hR_le_r := hR_le_r) (hτ_nonneg := hτ_nonneg) + (smallSet := smallSet) (hsmall_fin := hsmall_fin) (hsmallSet := hsmallSet) + (hsumτ := hsumτ) + (hr_phi := by + simpa [small, a, one_mul] using hr_phi) + s) + have hcprod_inv : + ‖(divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ ≤ + Real.exp (Cprod * (1 + r) ^ τ) := by + refine hasProd_norm_inv_le_exp_of_pointwise_le_exp + (α := divisorZeroIndex₀ f (Set.univ : Set ℂ)) (fac := fac) + (F := divisorCanonicalProduct m f (Set.univ : Set ℂ) u) + hprod (b := b) (B := Cprod * (1 + r) ^ τ) ?_ ?_ + · exact hterm + · intro s + exact hb_le s + have hmul : + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + = + ‖(u ^ analyticOrderNatAt f 0)⁻¹‖ * + ‖(divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ := by + simp [mul_inv_rev, mul_comm] + rw [hmul] + have : + ‖(u ^ analyticOrderNatAt f 0)⁻¹‖ * + ‖(divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + ≤ 1 * Real.exp (Cprod * (1 + r) ^ τ) := + mul_le_mul hpow_inv_le1 hcprod_inv (by positivity) (by positivity) + simpa using this + +theorem hadamardQuotient_norm_le_exp_on_cartan_circle + {f H : ℂ → ℂ} {ρ τ : ℝ} {m : ℕ} {Cf : ℝ} + (hmρ : (m : ℝ) ≤ ρ) (hτ : ρ < τ) (hτ_lt : τ < (m + 1 : ℝ)) + (hτ_nonneg : 0 ≤ τ) (hentire : Differentiable ℂ f) + (hnot : ∃ z : ℂ, f z ≠ 0) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (hsumτ : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) + (hf_boundτ : ∀ z : ℂ, ‖f z‖ ≤ Real.exp (Cf * (1 + ‖z‖) ^ τ)) + (hfactor : ∀ z : ℂ, + f z = + H z * z ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) z) : + let Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + let Cprod : ℝ := cartanProductConstant m τ Sτ + ∀ {R r : ℝ}, 0 < R → 1 ≤ R → R ≤ r → r ≤ 2 * R → 0 < r → + ∀ (smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsmall_fin : smallSet.Finite), + smallSet = + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ‖divisorZeroIndex₀Val p‖ ≤ 4 * R} → + (let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => ‖divisorZeroIndex₀Val p‖ + r ∉ small.image a) → + (let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => ‖divisorZeroIndex₀Val p‖ + (∑ p ∈ small, (1 : ℝ) * CartanBound.φ (r / a p)) ≤ + CartanBound.Cφ * (small.card : ℝ)) → + ∀ u : ℂ, ‖u‖ = r → ‖H u‖ ≤ Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) := by + classical + intro Sτ Cprod R r hRpos hRle hR_le_r hr_le_2R hrpos smallSet hsmall_fin + hsmallSet hr_not_bad hr_phi u hur + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let bad : Finset ℝ := small.image a + have hr_not_bad' : r ∉ bad := by + simpa [bad, small, a] using hr_not_bad + have hden_eq : + f u = + H u * (u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u) := by + simpa [mul_assoc, mul_left_comm, mul_comm] using (hfactor u) + have hfu_ne : f u ≠ 0 := by + have hr_le_4R : r ≤ 4 * R := by nlinarith [hr_le_2R, hRpos] + exact no_zero_on_sphere_of_norm_image_avoid (f := f) hentire hnot + (B := 4 * R) (r := r) hrpos hr_le_4R smallSet hsmall_fin hsmallSet + (by simpa [small, a] using hr_not_bad) u hur + have hden_ne : + (u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u) ≠ 0 := by + intro hden0 + have : f u = 0 := by simpa [hden0] using hden_eq + exact hfu_ne this + have hHu : + H u = + f u / (u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u) := by + exact eq_div_of_mul_eq hden_ne (Eq.symm hden_eq) + have hf_u : ‖f u‖ ≤ Real.exp (Cf * (1 + r) ^ τ) := by + simpa [hur] using hf_boundτ u + have hden_inv : + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + ≤ Real.exp (Cprod * (1 + r) ^ τ) := by + simpa [Sτ, Cprod] using + (norm_inv_hadamardDenominator_le_exp_on_cartan_circle + (f := f) (ρ := ρ) (τ := τ) (m := m) + hmρ hτ hτ_lt hτ_nonneg h_sum hsumτ + (R := R) (r := r) hRpos hRle hR_le_r hr_le_2R + smallSet hsmall_fin hsmallSet + (by simpa [small, a] using hr_not_bad) + (by simpa [small, a, one_mul] using hr_phi) + u hur) + have : + ‖H u‖ ≤ + ‖f u‖ * + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ := by + have : + ‖H u‖ = + ‖f u / + (u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)‖ := by + simp [hHu] + simp [div_eq_mul_inv, norm_inv, this] + have hmul : + ‖f u‖ * + ‖(u ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) u)⁻¹‖ + ≤ Real.exp (Cf * (1 + r) ^ τ) * Real.exp (Cprod * (1 + r) ^ τ) := + mul_le_mul hf_u hden_inv (by positivity) (by positivity) + have hexp : + Real.exp (Cf * (1 + r) ^ τ) * Real.exp (Cprod * (1 + r) ^ τ) + = Real.exp ((Cf + Cprod) * (1 + r) ^ τ) := by + simp [Real.exp_add, add_mul, add_comm] + have : ‖H u‖ ≤ Real.exp ((Cf + Cprod) * (1 + r) ^ τ) := + (this.trans hmul).trans_eq hexp + have hslack : + Real.exp ((Cf + Cprod) * (1 + r) ^ τ) ≤ + Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) := by + refine Real.exp_le_exp.2 ?_ + have hnn : 0 ≤ (1 + r) ^ τ := by positivity + nlinarith + exact this.trans hslack + +theorem hadamardQuotient_norm_le_exp_rpow_of_growth {f H : ℂ → ℂ} {ρ τ : ℝ} {m : ℕ} + (hρ : 0 ≤ ρ) (hmρ : (m : ℝ) ≤ ρ) (hτ : ρ < τ) (hτ_lt : τ < (m + 1 : ℝ)) + (hτ_nonneg : 0 ≤ τ) (hentire : Differentiable ℂ f) (hH_entire : Differentiable ℂ H) + (hnot : ∃ z : ℂ, f z ≠ 0) + (h_sum : Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1))) + (hgrowth : ∃ C > 0, ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) + (hfactor : ∀ z : ℂ, + f z = + H z * z ^ analyticOrderNatAt f 0 * + divisorCanonicalProduct m f (Set.univ : Set ℂ) z) : + ∃ C > 0, ∀ z : ℂ, ‖H z‖ ≤ Real.exp (C * (1 + ‖z‖) ^ τ) := by + rcases hgrowth with ⟨Cf, hCfpos, hCf⟩ + have hsumτ : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := + summable_norm_inv_rpow_divisorZeroIndex₀_of_growth (f := f) (ρ := ρ) (τ := τ) + hρ hτ hentire hnot ⟨Cf, hCfpos, hCf⟩ + let Sτ : ℝ := ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + have hSτ_nonneg : 0 ≤ Sτ := tsum_nonneg fun _ => + Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _ + let Cprod : ℝ := cartanProductConstant m τ Sτ + have hCprod_nonneg : 0 ≤ Cprod := by + simpa [Cprod] using cartanProductConstant_nonneg (m := m) (τ := τ) hSτ_nonneg + have hf_boundτ : ∀ z : ℂ, ‖f z‖ ≤ Real.exp (Cf * (1 + ‖z‖) ^ τ) := + Real.norm_le_exp_mul_rpow_of_log_growth + (f := f) (r := fun z : ℂ => 1 + ‖z‖) (C := Cf) (ρ := ρ) (τ := τ) + hCfpos.le (fun z => by linarith [norm_nonneg z]) (le_of_lt hτ) hCf + refine ⟨(Cf + Cprod + 10) * (3 : ℝ) ^ τ, by + have h3τ : 0 < (3 : ℝ) ^ τ := by positivity + nlinarith [hCfpos, hCprod_nonneg, h3τ], ?_⟩ + intro z + let R : ℝ := max ‖z‖ 1 + have hRpos : 0 < R := lt_of_lt_of_le (by norm_num) (le_max_right _ _) + have hRle : (1 : ℝ) ≤ R := le_max_right _ _ + let smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + {p | ‖divisorZeroIndex₀Val p‖ ≤ 4 * R} + have hsmall_fin : smallSet.Finite := by + have : Metric.closedBall (0 : ℂ) (4 * R) ⊆ (Set.univ : Set ℂ) := by simp + simpa [smallSet] using + (divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) + (B := 4 * R) this) + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + have ha_pos : ∀ p ∈ small, 0 < a p := by + intro p hp + exact norm_pos_iff.2 (divisorZeroIndex₀Val_ne_zero p) + let bad : Finset ℝ := small.image a + rcases CartanBound.exists_radius_Ioc_sum_mul_phi_div_le_Cφ_mul_sum_avoid + (s := small) (w := fun _ => (1 : ℝ)) (a := a) + (hw := by intro _ _; norm_num) (ha := ha_pos) (bad := bad) (R := R) hRpos with + ⟨r, hr_mem, hr_not_bad, hr_phi⟩ + have hR_le_r : R ≤ r := le_of_lt hr_mem.1 + have hr_le_2R : r ≤ 2 * R := hr_mem.2 + have hrpos : 0 < r := lt_of_lt_of_le hRpos hR_le_r + have hcircle : + ∀ u : ℂ, ‖u‖ = r → ‖H u‖ ≤ Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) := by + simpa [Sτ, Cprod] using + (hadamardQuotient_norm_le_exp_on_cartan_circle + (f := f) (H := H) (ρ := ρ) (τ := τ) (m := m) (Cf := Cf) + hmρ hτ hτ_lt hτ_nonneg hentire hnot h_sum hsumτ hf_boundτ hfactor + (R := R) (r := r) hRpos hRle hR_le_r hr_le_2R hrpos + smallSet hsmall_fin (by rfl) + (by simpa [small, a, bad] using hr_not_bad) + (by simpa [small, a, one_mul, Finset.sum_const, nsmul_eq_mul] using hr_phi)) + have hz_ball : z ∈ Metric.ball (0 : ℂ) r := by + rw [Metric.mem_ball, dist_zero_right] + exact lt_of_le_of_lt (le_max_left _ _) hr_mem.1 + have hball : + ‖H z‖ ≤ Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) := by + exact Complex.norm_le_of_mem_ball_of_forall_sphere_norm_le hH_entire hrpos hz_ball hcircle + have hr_le_3 : 1 + r ≤ 3 * (1 + ‖z‖) := by + exact Real.one_add_le_three_mul_one_add_of_le_two_mul_max (norm_nonneg z) + (by simpa [R] using hr_le_2R) + have hmain : + Real.exp ((Cf + Cprod + 10) * (1 + r) ^ τ) + ≤ Real.exp (((Cf + Cprod + 10) * (3 : ℝ) ^ τ) * (1 + ‖z‖) ^ τ) := by + have hnn : 0 ≤ (Cf + Cprod + 10) := by nlinarith [le_of_lt hCfpos, hCprod_nonneg] + exact Real.exp_mul_rpow_le_exp_mul_rpow_of_le_mul hnn (by norm_num) + (by linarith [le_of_lt hrpos]) (by positivity) hτ_nonneg hr_le_3 + simpa [mul_assoc] using hball.trans hmain + +theorem hadamard_factorization_of_growth {f : ℂ → ℂ} {ρ : ℝ} (hρ : 0 ≤ ρ) + (hentire : Differentiable ℂ f) + (hnot : ∃ z : ℂ, f z ≠ 0) + (hgrowth : ∃ C > 0, ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) : + ∃ (P : Polynomial ℂ), + P.degree ≤ Nat.floor ρ ∧ + ∀ z : ℂ, + f z = + Complex.exp (Polynomial.eval z P) * + z ^ (analyticOrderNatAt f 0) * + divisorCanonicalProduct (Nat.floor ρ) f (Set.univ : Set ℂ) z := by + set m : ℕ := Nat.floor ρ + have h_sum : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (m + 1)) := by + simpa [m] using + (summable_norm_inv_pow_divisorZeroIndex₀_of_growth (f := f) (ρ := ρ) + hρ hentire hnot hgrowth) + rcases exists_entire_nonzero_hadamardQuotient (m := m) (f := f) hentire hnot h_sum with + ⟨H, hH_entire, hH_ne, hfactor⟩ + rcases Real.exists_between_self_and_floor_add_one_same_floor hρ with + ⟨τ, hτ, hτ_lt, hτ_nonneg, hfloorτ'⟩ + have hfloorτ : Nat.floor τ = m := by + simpa [m] using hfloorτ' + have hτ_lt_m : τ < (m + 1 : ℝ) := by + simpa [m] using hτ_lt + have hτ_lt_nat : τ < ((m + 1 : ℕ) : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one] using hτ_lt_m + have hmρ : (m : ℝ) ≤ ρ := by + have := Nat.floor_le hρ + simpa [m] using this + have hH_bound_rpow : + ∃ C > 0, ∀ z : ℂ, ‖H z‖ ≤ Real.exp (C * (1 + ‖z‖) ^ τ) := + hadamardQuotient_norm_le_exp_rpow_of_growth (f := f) (H := H) (ρ := ρ) (τ := τ) + (m := m) hρ hmρ hτ hτ_lt hτ_nonneg hentire hH_entire hnot h_sum hgrowth hfactor + have hH_growth_nat : + ∃ C > 0, ∀ z : ℂ, ‖H z‖ ≤ Real.exp (C * (1 + ‖z‖) ^ (m + 1)) := by + exact Real.exists_norm_le_exp_mul_pow_of_rpow_bound + (f := H) (r := fun z : ℂ => 1 + ‖z‖) + (fun z => by linarith [norm_nonneg z]) hτ_lt_nat hH_bound_rpow + rcases zero_free_polynomial_growth_is_exp_poly (H := H) (n := m + 1) + hH_entire hH_ne hH_growth_nat with + ⟨P, hPn, hHP⟩ + have hPnat : P.natDegree ≤ m := by + have hbound : + ∃ C > 0, ∀ z : ℂ, + ‖Complex.exp (Polynomial.eval z P)‖ ≤ Real.exp (C * (1 + ‖z‖) ^ τ) := by + rcases hH_bound_rpow with ⟨C, hCpos, hC⟩ + exact ⟨C, hCpos, fun z => by simpa [hHP z] using (hC z)⟩ + have := natDegree_le_floor_of_exp_eval_norm_bound hτ_nonneg P hbound + simpa [hfloorτ] using this + refine ⟨P, ?_, ?_⟩ + · have : P.degree ≤ m := Polynomial.degree_le_of_natDegree_le hPnat + simpa [m] using this + · intro z + have hH' : H z = Complex.exp (Polynomial.eval z P) := by simpa using (hHP z) + simpa [hH', mul_assoc, mul_left_comm, mul_comm, m] using (hfactor z) + +end Complex.Hadamard +end +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/HadamardSupport.lean b/PrimeNumberTheoremAnd/SiegelZeros/HadamardSupport.lean new file mode 100644 index 0000000..7ec52e3 --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/HadamardSupport.lean @@ -0,0 +1 @@ +import PrimeNumberTheoremAnd.SiegelZeros.Growth diff --git a/PrimeNumberTheoremAnd/SiegelZeros/NOTICE.md b/PrimeNumberTheoremAnd/SiegelZeros/NOTICE.md new file mode 100644 index 0000000..a3e10f6 --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/NOTICE.md @@ -0,0 +1,15 @@ +# Captured support notices + +The mathematical support is derived from PrimeNumberTheoremAnd. Its existing repository license remains applicable. Original retained notices follow. + +/- +Copyright (c) 2026 Matteo Cipollina. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Matteo Cipollina +-/ + +/- +Copyright (c) 2025 Stefan Kebekus. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Stefan Kebekus, Matteo Cipollina +-/ diff --git a/PrimeNumberTheoremAnd/SiegelZeros/ProductBounds.lean b/PrimeNumberTheoremAnd/SiegelZeros/ProductBounds.lean new file mode 100644 index 0000000..6a2985a --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/ProductBounds.lean @@ -0,0 +1,724 @@ +import Mathlib +import PrimeNumberTheoremAnd.SiegelZeros.DivisorLimits +import PrimeNumberTheoremAnd.SiegelZeros.CartanBounds + +namespace SiegelZeros + +section +noncomputable section + +namespace Complex.Hadamard + +open scoped BigOperators +open Filter Finset _root_.Real _root_.SiegelZeros.Real Topology + +section CartanFiniteSum + +variable {α : Type*} + +private lemma summable_ite_mem_finset [DecidableEq α] (s : Finset α) (u : α → ℝ) : + Summable (fun a => if a ∈ s then u a else 0) := + summable_of_ne_finset_zero (s := s) fun a ha => by simp [ite_eq_right ha] + +private lemma tsum_ite_mem_finset [DecidableEq α] (s : Finset α) (u : α → ℝ) : + (∑' a, if a ∈ s then u a else 0) = ∑ a ∈ s, u a := by + classical + simpa [Finset.sum_ite] using + (hasSum_sum_of_ne_finset_zero (s := s) (f := fun a => if a ∈ s then u a else 0) + fun a ha => by simp [ite_eq_right ha]).tsum_eq + +private lemma tsum_add_four (u₁ u₂ u₃ u₄ : α → ℝ) + (h₁ : Summable u₁) (h₂ : Summable u₂) (h₃ : Summable u₃) (h₄ : Summable u₄) : + tsum (fun a => ((u₁ a + u₂ a) + u₃ a) + u₄ a) + = tsum u₁ + tsum u₂ + tsum u₃ + tsum u₄ := by + calc + tsum (fun a => ((u₁ a + u₂ a) + u₃ a) + u₄ a) + = tsum (fun a => (u₁ a + u₂ a) + (u₃ a + u₄ a)) := by + simp [add_comm, add_left_comm] + _ = tsum (fun a => u₁ a + u₂ a) + tsum (fun a => u₃ a + u₄ a) := + Summable.tsum_add (h₁.add h₂) (h₃.add h₄) + _ = tsum u₁ + tsum u₂ + tsum u₃ + tsum u₄ := by + rw [Summable.tsum_add h₁ h₂, Summable.tsum_add h₃ h₄] + ring + +end CartanFiniteSum + +noncomputable def cartanProductConstant (m : ℕ) (τ Sτ : ℝ) : ℝ := + ((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 3) * (Sτ + 1) + +lemma cartanProductConstant_nonneg {m : ℕ} {τ Sτ : ℝ} (hSτ : 0 ≤ Sτ) : + 0 ≤ cartanProductConstant m τ Sτ := by + have hS : 0 ≤ Sτ + 1 := by linarith + have hA : 0 ≤ (CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 3 := by + have hCφ : 0 ≤ CartanBound.Cφ := le_of_lt CartanBound.Cφ_pos + have hm0 : 0 ≤ (m : ℝ) := by exact_mod_cast (Nat.zero_le m) + have h4τ : 0 ≤ (4 : ℝ) ^ τ := by positivity + nlinarith [hCφ, hm0, h4τ] + simpa [cartanProductConstant] using mul_nonneg hA hS + +lemma rpow_div_norm_divisorZeroIndex₀_eq + {f : ℂ → ℂ} {r τ : ℝ} (hr : 0 ≤ r) + (p : divisorZeroIndex₀ f (Set.univ : Set ℂ)) : + (r / ‖divisorZeroIndex₀Val p‖) ^ τ = + (r ^ τ) * ((‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) := by + have hp : 0 ≤ (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) := by positivity + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using + (Real.mul_rpow (x := r) (y := (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ)) (z := τ) hr hp) + +lemma tsum_rpow_div_norm_divisorZeroIndex₀_eq + {f : ℂ → ℂ} {r τ : ℝ} (hr : 0 ≤ r) : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + = (r ^ τ) * ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + calc + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + = ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ := by + refine tsum_congr ?_ + intro p + exact rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr p + _ = (r ^ τ) * ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + simp [tsum_mul_left] + +lemma tsum_two_mul_rpow_div_norm_divisorZeroIndex₀_le + {f : ℂ → ℂ} {r τ : ℝ} (hr : 0 ≤ r) (hτ_nonneg : 0 ≤ τ) : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (2 : ℝ) * (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + ≤ (2 : ℝ) * ((∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) + 1) * (1 + r) ^ τ := by + set Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + have htsum : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (2 : ℝ) * (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + = (2 : ℝ) * (r ^ τ) * Sτ := by + calc + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (2 : ℝ) * (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + = (2 : ℝ) * ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + (r / ‖divisorZeroIndex₀Val p‖) ^ τ := by + simp [tsum_mul_left] + _ = (2 : ℝ) * ((r ^ τ) * Sτ) := by + rw [tsum_rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr] + _ = (2 : ℝ) * (r ^ τ) * Sτ := by ring + have hSτ_nonneg : 0 ≤ Sτ := + tsum_nonneg (fun _ => Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _) + have h1r : r ^ τ ≤ (1 + r) ^ τ := + Real.rpow_le_rpow (by positivity) (by linarith) hτ_nonneg + have hS : Sτ ≤ Sτ + 1 := by linarith + have hle : (r ^ τ) * Sτ ≤ (1 + r) ^ τ * (Sτ + 1) := + mul_le_mul h1r hS (by linarith) (by positivity) + rw [htsum] + have : (2 : ℝ) * (r ^ τ) * Sτ ≤ (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ := by + nlinarith [hle] + simpa [Sτ, mul_assoc, mul_left_comm, mul_comm] using this + +lemma sum_rpow_div_norm_divisorZeroIndex₀_le + {f : ℂ → ℂ} {r τ : ℝ} (small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hr : 0 ≤ r) (hτ_nonneg : 0 ≤ τ) + (hsumτ : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) : + (∑ p ∈ small, (r / ‖divisorZeroIndex₀Val p‖) ^ τ) + ≤ ((∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) + 1) * (1 + r) ^ τ := by + set Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + have hsum_inv : + (∑ p ∈ small, (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) ≤ Sτ := by + have hnn : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + 0 ≤ (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ := by + intro p + positivity + simpa [Sτ] using + (Summable.sum_le_tsum (s := small) + (f := fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) + (fun p _ => hnn p) hsumτ) + have hsum_eq : + ∑ p ∈ small, (r / ‖divisorZeroIndex₀Val p‖) ^ τ = + (r ^ τ) * ∑ p ∈ small, (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ := by + simp [rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr, Finset.mul_sum] + have h1r : r ^ τ ≤ (1 + r) ^ τ := + Real.rpow_le_rpow (by positivity) (by linarith) hτ_nonneg + have hS : (∑ p ∈ small, (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) ≤ Sτ + 1 := by + linarith [hsum_inv] + have hle : + (r ^ τ) * (∑ p ∈ small, (‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ) + ≤ (1 + r) ^ τ * (Sτ + 1) := + mul_le_mul h1r hS (by positivity) (by positivity) + simpa [Sτ, hsum_eq, mul_assoc, mul_left_comm, mul_comm] using hle + +lemma add_four_le_add_two_mul_of_le {x₁ x₂ x₃ x₄ A B C : ℝ} + (h₁ : x₁ ≤ A) (h₂ : x₂ ≤ B) (h₃ : x₃ ≤ B) (h₄ : x₄ ≤ C) : + x₁ + x₂ + x₃ + x₄ ≤ A + 2 * B + C := by + nlinarith + +lemma cartan_majorant_four_term_bound + {xφ x0 xm xt Cφ m q Y T : ℝ} + (hφ : xφ ≤ Cφ * q * Y * T) + (h0 : x0 ≤ m * q * Y * T) + (hm : xm ≤ m * q * Y * T) + (ht : xt ≤ (2 : ℝ) * Y * T) : + xφ + x0 + xm + xt ≤ (Cφ + (2 : ℝ) * m) * q * Y * T + (2 : ℝ) * Y * T := by + have h := + add_four_le_add_two_mul_of_le hφ h0 hm ht + have hring : + Cφ * (q * (Y * T)) + 2 * (m * (q * (Y * T))) + 2 * (Y * T) + = (Cφ + (2 : ℝ) * m) * (q * (Y * T)) + (2 : ℝ) * (Y * T) := by + ring + simpa [mul_assoc, hring] using h + +lemma cartan_majorant_add_two_factor (A Y T : ℝ) : + A * Y * T + (2 : ℝ) * Y * T = ((A + 2) * Y) * T := by + ring + +lemma cartan_majorant_pad_two_to_three {A S T : ℝ} (hS : 0 ≤ S + 1) (hT : 0 ≤ T) : + ((A + 2) * (S + 1)) * T ≤ ((A + 3) * (S + 1)) * T := by + have h : (A + 2) * (S + 1) ≤ (A + 3) * (S + 1) := by + nlinarith + exact mul_le_mul_of_nonneg_right h hT + +lemma cartan_majorant_nonneg + {f : ℂ → ℂ} {m : ℕ} {τ r : ℝ} (hr : 0 ≤ r) + (small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) : + letI : DecidableEq (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := Classical.decEq _ + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + ∀ p, 0 ≤ b p := by + classical + dsimp + intro p + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun q => ‖divisorZeroIndex₀Val q‖ + have hap : ap p = ‖divisorZeroIndex₀Val p‖ := rfl + by_cases hp : p ∈ small + · have hφ : 0 ≤ CartanBound.φ (r / ap p) := CartanBound.φ_nonneg (t := r / ap p) + have hm0 : 0 ≤ (m : ℝ) := by exact_mod_cast (Nat.zero_le m) + have h1 : 0 ≤ (1 + (r / ap p) ^ τ) := by positivity + have : 0 ≤ CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) := by + nlinarith [hφ, hm0, h1] + simpa [hap, hp, ap] using this + · have hbase : 0 ≤ r / ap p := div_nonneg hr (by positivity) + have hpow : 0 ≤ (r / ap p) ^ τ := Real.rpow_nonneg hbase τ + have : 0 ≤ (2 : ℝ) * (r / ap p) ^ τ := mul_nonneg (by norm_num) hpow + simpa [hap, hp, ap] using this + +lemma cartan_majorant_summable + {f : ℂ → ℂ} {m : ℕ} {τ r : ℝ} (hr : 0 ≤ r) + (small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsumτ : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) : + letI : DecidableEq (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := Classical.decEq _ + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + Summable b := by + classical + dsimp + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun q => ‖divisorZeroIndex₀Val q‖ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + have hb : Summable b := by + let b₁ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else 0 + let b₂ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => if p ∈ small then 0 else (2 : ℝ) * (r / ap p) ^ τ + have hb_decomp : b = fun p => b₁ p + b₂ p := by + funext p + by_cases hp : p ∈ small <;> simp [b, b₁, b₂, hp] + have hb₁ : Summable b₁ := by + simpa [b₁] using + summable_ite_mem_finset small + (fun p => CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ)) + have hb₂ : Summable b₂ := by + have hconst : + Summable (fun p => + (2 : ℝ) * (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) := + hsumτ.mul_left ((2 : ℝ) * (r ^ τ)) + refine Summable.of_nonneg_of_le + (fun p => by + by_cases hp : p ∈ small + · simp [b₂, hp] + · have : 0 ≤ (2 : ℝ) * (r / ap p) ^ τ := by positivity + simpa [b₂, hp] using this) + (fun p => ?_) hconst + by_cases hp : p ∈ small + · have : 0 ≤ (2 : ℝ) * (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := by positivity + simpa [b₂, hp] using this + · have hrpow : (r / ap p) ^ τ = (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := by + simpa [ap] using rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr p + simp [b₂, hp, hrpow, mul_assoc, mul_left_comm, mul_comm] + simpa [hb_decomp] using hb₁.add hb₂ + refine hb.congr ?_ + intro p + by_cases hp : p ∈ small <;> simp [b, ap, hp] + +lemma cartan_card_small_le + {f : ℂ → ℂ} {τ R : ℝ} (hRpos : 0 < R) (hτ_nonneg : 0 ≤ τ) + (small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsmall : ∀ p ∈ small, ‖divisorZeroIndex₀Val p‖ ≤ 4 * R) + (hsumτ : + Summable + (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) : + (small.card : ℝ) + ≤ (4 * R) ^ τ + * ((∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) + 1) := by + classical + set Sτ : ℝ := + ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + have hsum_le : (∑ p ∈ small, ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) ≤ Sτ := by + have hnn : + ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + 0 ≤ ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + intro p + exact Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _ + simpa [Sτ] using + (Summable.sum_le_tsum (s := small) + (f := fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) + (fun p _ => hnn p) hsumτ) + have hgeom_sum : + (small.card : ℝ) ≤ ∑ p ∈ small, (4 * R) ^ τ * ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + have hcard_eq : (small.card : ℝ) = ∑ p ∈ small, (1 : ℝ) := by simp + rw [hcard_eq] + refine Finset.sum_le_sum (fun p hp => ?_) + have hp_le : ‖divisorZeroIndex₀Val p‖ ≤ 4 * R := hsmall p hp + have hap : 0 < ‖divisorZeroIndex₀Val p‖ := + norm_pos_iff.2 (divisorZeroIndex₀Val_ne_zero p) + have hbase : (1 : ℝ) ≤ (4 * R) / ‖divisorZeroIndex₀Val p‖ := by + exact (le_div_iff₀ hap).2 (by simpa [mul_one] using hp_le) + have : (1 : ℝ) ≤ ((4 * R) / ‖divisorZeroIndex₀Val p‖) ^ τ := + Real.one_le_rpow hbase hτ_nonneg + have hdiv : + ((4 * R) / ‖divisorZeroIndex₀Val p‖) ^ τ = + (4 * R) ^ τ * (‖divisorZeroIndex₀Val p‖)⁻¹ ^ τ := by + have h4 : 0 ≤ (4 * R : ℝ) := by nlinarith [le_of_lt hRpos] + have ha : 0 ≤ (‖divisorZeroIndex₀Val p‖ : ℝ)⁻¹ := by positivity + simpa [div_eq_mul_inv, mul_assoc, mul_left_comm, mul_comm] using + (Real.mul_rpow (x := (4 * R : ℝ)) + (y := (‖divisorZeroIndex₀Val p‖ : ℝ)⁻¹) (z := τ) h4 ha) + have : (1 : ℝ) ≤ (4 * R) ^ τ * ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + simpa [hdiv] using this + exact this + have hgeom : + (small.card : ℝ) ≤ (4 * R) ^ τ * (∑ p ∈ small, ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := by + simpa [Finset.mul_sum] using hgeom_sum + have hsmall_le : (small.card : ℝ) ≤ (4 * R) ^ τ * Sτ := by + exact hgeom.trans (mul_le_mul_of_nonneg_left hsum_le (by positivity)) + have hS_le : (4 * R) ^ τ * Sτ ≤ (4 * R) ^ τ * (Sτ + 1) := by + refine mul_le_mul_of_nonneg_left ?_ (by positivity) + linarith + have : (small.card : ℝ) ≤ (4 * R) ^ τ * (Sτ + 1) := hsmall_le.trans hS_le + simpa [Sτ, add_comm, add_left_comm, add_assoc, mul_assoc] using this + +lemma cartan_rpow_mul_le + {τ R r : ℝ} (hRpos : 0 < R) (hrpos : 0 < r) (hR_le_r : R ≤ r) (hτ_nonneg : 0 ≤ τ) : + (4 * R) ^ τ ≤ (4 : ℝ) ^ τ * (1 + r) ^ τ := by + have hR_le_1r : R ≤ 1 + r := by linarith [hR_le_r, le_of_lt hrpos] + have hbase0 : 0 ≤ (4 * R : ℝ) := by nlinarith [le_of_lt hRpos] + have : (4 * R) ^ τ ≤ (4 * (1 + r)) ^ τ := by + refine Real.rpow_le_rpow hbase0 ?_ hτ_nonneg + nlinarith [hR_le_1r] + have hmul : (4 * (1 + r)) ^ τ = (4 : ℝ) ^ τ * (1 + r) ^ τ := by + have h4 : 0 ≤ (4 : ℝ) := by norm_num + have h1 : 0 ≤ (1 + r : ℝ) := by positivity + simpa [mul_assoc] using + (Real.mul_rpow (x := (4 : ℝ)) (y := (1 + r : ℝ)) (z := τ) h4 h1) + simpa [hmul] using this + +open Classical in +theorem cartan_sum_majorant_le + {f : ℂ → ℂ} {m : ℕ} {τ R r : ℝ} + (hRpos : 0 < R) + (hrpos : 0 < r) + (hR_le_r : R ≤ r) + (hτ_nonneg : 0 ≤ τ) + (smallSet : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))) + (hsmall_fin : smallSet.Finite) + (hsmallSet : + smallSet = {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | ‖divisorZeroIndex₀Val p‖ ≤ 4 * R}) + (hsumτ : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) + (hr_phi : + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + let a : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + (∑ p ∈ small, CartanBound.φ (r / a p)) ≤ CartanBound.Cφ * (small.card : ℝ)) : + let small : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := hsmall_fin.toFinset + letI : DecidableEq (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := Classical.decEq _ + let ap : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := fun p => ‖divisorZeroIndex₀Val p‖ + let b : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => + if p ∈ small then + CartanBound.φ (r / ap p) + (m : ℝ) * (1 + (r / ap p) ^ τ) + else + (2 : ℝ) * (r / ap p) ^ τ + let Sτ : ℝ := ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ + let Cprod : ℝ := cartanProductConstant m τ Sτ + ∀ s : Finset (divisorZeroIndex₀ f (Set.univ : Set ℂ)), + (∑ p ∈ s, b p) ≤ Cprod * (1 + r) ^ τ := by + classical + intro small ap b Sτ Cprod s + have hr : 0 ≤ r := le_of_lt hrpos + have hSτ_nonneg : 0 ≤ Sτ := + tsum_nonneg (fun _ => Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _) + have hsmall_mem : ∀ p, p ∈ small ↔ p ∈ smallSet := by + intro p + simp [small, hsmall_fin.mem_toFinset] + have hphi_sum : + (∑ p ∈ small, CartanBound.φ (r / ap p)) ≤ CartanBound.Cφ * (small.card : ℝ) := by + simpa [small, ap] using hr_phi + have hb_nonneg : ∀ p, 0 ≤ b p := by + simpa [ap, b] using (cartan_majorant_nonneg (f := f) (m := m) (τ := τ) (r := r) hr small) + have hb_summable : Summable b := by + simpa [ap, b] using + (cartan_majorant_summable (f := f) (m := m) (τ := τ) (r := r) hr small hsumτ) + have hsmall_norm : ∀ p ∈ small, ‖divisorZeroIndex₀Val p‖ ≤ 4 * R := by + intro p hp + have : p ∈ smallSet := (hsmall_mem p).1 hp + simpa [hsmallSet] using this + have hcard_le : (small.card : ℝ) ≤ (4 * R) ^ τ * (Sτ + 1) := by + simpa [Sτ, mul_assoc, add_assoc, add_left_comm, add_comm] using + (cartan_card_small_le (f := f) (τ := τ) (R := R) hRpos hτ_nonneg small hsmall_norm hsumτ) + have hpowR : (4 * R) ^ τ ≤ (4 : ℝ) ^ τ * (1 + r) ^ τ := + cartan_rpow_mul_le (τ := τ) (R := R) (r := r) hRpos hrpos hR_le_r hτ_nonneg + have hcard_le' : (small.card : ℝ) ≤ (4 : ℝ) ^ τ * (1 + r) ^ τ * (Sτ + 1) := by + have : (4 * R) ^ τ * (Sτ + 1) ≤ (4 : ℝ) ^ τ * (1 + r) ^ τ * (Sτ + 1) := by + exact mul_le_mul_of_nonneg_right hpowR (by linarith [hSτ_nonneg]) + exact le_trans hcard_le this + have hb_tsum_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b p) ≤ Cprod * (1 + r) ^ τ := by + let bφ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => if p ∈ small then CartanBound.φ (r / ap p) else 0 + let b0 : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => if p ∈ small then (m : ℝ) else 0 + let bmτ : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => if p ∈ small then (m : ℝ) * (r / ap p) ^ τ else 0 + let bt : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℝ := + fun p => (2 : ℝ) * (r / ap p) ^ τ + have hb_pointwise : ∀ p, b p ≤ bφ p + b0 p + bmτ p + bt p := by + intro p + by_cases hp : p ∈ small + · have hbase : 0 ≤ r / ap p := div_nonneg hr (by positivity) + have hx : 0 ≤ (r / ap p) ^ τ := Real.rpow_nonneg hbase τ + have hpos : 0 ≤ (2 : ℝ) * (r / ap p) ^ τ := mul_nonneg (by norm_num) hx + simp [b, bφ, b0, bmτ, bt, hp] + nlinarith + · simp [b, bφ, b0, bmτ, bt, hp] + have hmaj_summ : Summable (fun p => bφ p + b0 p + bmτ p + bt p) := by + have hbφ_summ : Summable bφ := by + simpa [bφ] using summable_ite_mem_finset small (fun p => CartanBound.φ (r / ap p)) + have hb0_summ : Summable b0 := by + simpa [b0] using summable_ite_mem_finset small (fun _ => (m : ℝ)) + have hbmτ_summ : Summable bmτ := by + simpa [bmτ] using summable_ite_mem_finset small (fun p => (m : ℝ) * (r / ap p) ^ τ) + have hbt_summ : Summable bt := by + have hconst : Summable (fun p => + (2 : ℝ) * (r ^ τ) * (‖divisorZeroIndex₀Val p‖⁻¹ ^ τ)) := + hsumτ.mul_left ((2 : ℝ) * (r ^ τ)) + refine hconst.congr ?_ + intro p + simp [bt, ap, rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr p, + mul_assoc, mul_left_comm, mul_comm] + have h' : Summable (fun p => bφ p + b0 p + (bmτ p + bt p)) := + (hbφ_summ.add hb0_summ).add (hbmτ_summ.add hbt_summ) + simpa [add_assoc] using h' + have htsum_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b p) + ≤ ∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (bφ p + b0 p + bmτ p + bt p) := + (hasSum_le hb_pointwise hb_summable.hasSum hmaj_summ.hasSum) + have htsum_bφ : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bφ p) + = ∑ p ∈ small, CartanBound.φ (r / ap p) := by + classical + simpa [bφ] using tsum_ite_mem_finset small (fun p => CartanBound.φ (r / ap p)) + have htsum_b0 : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) + = (m : ℝ) * (small.card : ℝ) := by + classical + have : (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) = ∑ p ∈ small, (m : ℝ) := by + simpa [b0] using tsum_ite_mem_finset small (fun _ => (m : ℝ)) + simp [this, Finset.sum_const, nsmul_eq_mul, mul_comm] + have htsum_bmτ : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) + = (m : ℝ) * ∑ p ∈ small, (r / ap p) ^ τ := by + classical + have : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) + = ∑ p ∈ small, (m : ℝ) * (r / ap p) ^ τ := by + simpa [bmτ] using tsum_ite_mem_finset small (fun p => (m : ℝ) * (r / ap p) ^ τ) + simp [this, Finset.mul_sum] + have htsum_bt : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bt p) + ≤ (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ := by + simpa [bt, ap, Sτ] using + tsum_two_mul_rpow_div_norm_divisorZeroIndex₀_le (f := f) (τ := τ) hr hτ_nonneg + have hsum_small_rpow_le : + (∑ p ∈ small, (r / ap p) ^ τ) ≤ (Sτ + 1) * (1 + r) ^ τ := by + simpa [ap, Sτ] using + sum_rpow_div_norm_divisorZeroIndex₀_le (f := f) (τ := τ) small hr hτ_nonneg hsumτ + have hm0 : 0 ≤ (m : ℝ) := by exact_mod_cast (Nat.zero_le m) + have hCφ : 0 ≤ CartanBound.Cφ := le_of_lt CartanBound.Cφ_pos + have hS : 0 ≤ Sτ + 1 := by linarith [hSτ_nonneg] + have htsum_majorant : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (bφ p + b0 p + bmτ p + bt p)) + ≤ (((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 2) * (Sτ + 1)) + * (1 + r) ^ τ := by + have hφ_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bφ p) + ≤ CartanBound.Cφ * (small.card : ℝ) := by + simpa [htsum_bφ] using hphi_sum + have hb0_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) + ≤ (m : ℝ) * (small.card : ℝ) := by + simp [htsum_b0] + have hbmτ_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) ≤ + (m : ℝ) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + have h0 : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) + ≤ (m : ℝ) * ((Sτ + 1) * (1 + r) ^ τ) := by + have hmul := mul_le_mul_of_nonneg_left hsum_small_rpow_le hm0 + + simpa [htsum_bmτ, mul_assoc, mul_left_comm, mul_comm] using hmul + have h1 : (1 : ℝ) ≤ (4 : ℝ) ^ τ := + Real.one_le_rpow (by norm_num) hτ_nonneg + have hscale : + (m : ℝ) * ((Sτ + 1) * (1 + r) ^ τ) + ≤ (m : ℝ) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + have hnonneg : 0 ≤ (m : ℝ) * ((Sτ + 1) * (1 + r) ^ τ) := by + have : 0 ≤ (Sτ + 1) * (1 + r) ^ τ := by positivity + exact mul_nonneg hm0 this + simpa [mul_assoc, mul_left_comm, mul_comm] using (mul_le_mul_of_nonneg_right h1 hnonneg) + exact h0.trans hscale + have hbt_le : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bt p) + ≤ (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ := by + simpa [mul_assoc, mul_left_comm, mul_comm] using htsum_bt + have hsplit : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (bφ p + b0 p + bmτ p + bt p)) + = (∑' p, bφ p) + (∑' p, b0 p) + (∑' p, bmτ p) + (∑' p, bt p) := by + classical + have hbφ_summ : Summable bφ := by + simpa [bφ] using summable_ite_mem_finset small (fun p => CartanBound.φ (r / ap p)) + have hb0_summ : Summable b0 := by + simpa [b0] using summable_ite_mem_finset small (fun _ => (m : ℝ)) + have hbmτ_summ : Summable bmτ := by + simpa [bmτ] using summable_ite_mem_finset small (fun p => (m : ℝ) * (r / ap p) ^ τ) + have hbt_summ : Summable bt := by + have hconst : + Summable + (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + (2 : ℝ) * (r ^ τ) * ((‖divisorZeroIndex₀Val p‖⁻¹ : ℝ) ^ τ)) := + hsumτ.mul_left ((2 : ℝ) * (r ^ τ)) + refine hconst.congr ?_ + intro p + simp [bt, ap, rpow_div_norm_divisorZeroIndex₀_eq (f := f) (τ := τ) hr p, + mul_assoc, mul_left_comm, mul_comm] + exact tsum_add_four bφ b0 bmτ bt hbφ_summ hb0_summ hbmτ_summ hbt_summ + have hcard_le'' : + (small.card : ℝ) ≤ (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + simpa [mul_assoc, mul_left_comm, mul_comm] using hcard_le' + have hφ_le' : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bφ p) ≤ + CartanBound.Cφ * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + have : CartanBound.Cφ * (small.card : ℝ) ≤ + CartanBound.Cφ * ((4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ) := + mul_le_mul_of_nonneg_left hcard_le'' hCφ + exact hφ_le.trans (by simpa [mul_assoc, mul_left_comm, mul_comm] using this) + have hb0_le' : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) ≤ + (m : ℝ) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ := by + have : (m : ℝ) * (small.card : ℝ) ≤ (m : ℝ) * ((4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ) := + mul_le_mul_of_nonneg_left hcard_le'' hm0 + exact hb0_le.trans (by simpa [mul_assoc, mul_left_comm, mul_comm] using this) + have htsum_majorant' : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), (bφ p + b0 p + bmτ p + bt p)) + ≤ (CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ + + (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ := by + rw [hsplit] + set Y : ℝ := Sτ + 1 with hY + set T : ℝ := (1 + r) ^ τ with hT + have hφ_leY : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bφ p) + ≤ CartanBound.Cφ * (4 : ℝ) ^ τ * Y * T := by + simpa [hY, hT, mul_assoc] using hφ_le' + have hb0_leY : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b0 p) + ≤ (m : ℝ) * (4 : ℝ) ^ τ * Y * T := by + simpa [hY, hT, mul_assoc] using hb0_le' + have hbmτ_leY : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bmτ p) + ≤ (m : ℝ) * (4 : ℝ) ^ τ * Y * T := by + simpa [hY, hT, mul_assoc] using hbmτ_le + have hbt_leY : + (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), bt p) ≤ (2 : ℝ) * Y * T := by + simpa [hY, hT, mul_assoc] using hbt_le + have hmain := + cartan_majorant_four_term_bound + (q := (4 : ℝ) ^ τ) hφ_leY hb0_leY hbmτ_leY hbt_leY + simpa [Y, T, add_assoc] using hmain + have hring : + (CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ * (Sτ + 1) * (1 + r) ^ τ + + (2 : ℝ) * (Sτ + 1) * (1 + r) ^ τ + = (((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 2) * (Sτ + 1)) * (1 + r) ^ τ := by + exact cartan_majorant_add_two_factor + ((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ) (Sτ + 1) ((1 + r) ^ τ) + rw [← hring] + exact htsum_majorant' + have hCprod' : + (((CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ + 2) * (Sτ + 1)) * (1 + r) ^ τ + ≤ Cprod * (1 + r) ^ τ := by + simpa [Cprod, cartanProductConstant, mul_assoc, mul_left_comm, mul_comm] using + cartan_majorant_pad_two_to_three + (A := (CartanBound.Cφ + (2 : ℝ) * m) * (4 : ℝ) ^ τ) + (S := Sτ) (T := (1 + r) ^ τ) hS (by positivity) + exact (le_trans (le_trans htsum_le htsum_majorant) hCprod') + have hsum_fin_le : + (∑ p ∈ s, b p) ≤ (∑' p : divisorZeroIndex₀ f (Set.univ : Set ℂ), b p) := by + simpa using + (Summable.sum_le_tsum (s := s) (f := b) (fun p _ => hb_nonneg p) hb_summable) + exact hsum_fin_le.trans hb_tsum_le + +end Complex.Hadamard +end +end +section +noncomputable section + +open scoped BigOperators +open Filter Finset _root_.Real _root_.SiegelZeros.Real Topology + +lemma Finset.prod_le_exp_sum {α : Type} (s : Finset α) (a : α → ℝ) (b : α → ℝ) + (ha : ∀ x ∈ s, 0 ≤ a x) (hab : ∀ x ∈ s, a x ≤ Real.exp (b x)) : + (∏ x ∈ s, a x) ≤ Real.exp (∑ x ∈ s, b x) := by + calc + (∏ x ∈ s, a x) ≤ ∏ x ∈ s, Real.exp (b x) := Finset.prod_le_prod₀ ha hab + _ = Real.exp (∑ x ∈ s, b x) := by + simpa using (Real.exp_sum (s := s) (f := b)).symm + +lemma hasProd_le_of_prod_le_exp {α : Type} {f : α → ℝ} {a : ℝ} + (hf : HasProd f a (SummationFilter.unconditional α)) + {B : ℝ} (hB : ∀ s : Finset α, (∏ x ∈ s, f x) ≤ Real.exp B) : + a ≤ Real.exp B := + hasProd_le_of_prod_le (L := (SummationFilter.unconditional α)) hf hB + +lemma hasProd_inv_unconditional {α : Type} {fac : α → ℂ} {F : ℂ} + (hfac : HasProd fac F (SummationFilter.unconditional α)) (hF : F ≠ 0) : + HasProd (fun x => (fac x)⁻¹) (F⁻¹) (SummationFilter.unconditional α) := by + change + Tendsto (fun s : Finset α => ∏ x ∈ s, (fac x)⁻¹) + (SummationFilter.unconditional α).filter (𝓝 (F⁻¹)) + have hprod : + Tendsto (fun s : Finset α => ∏ x ∈ s, fac x) + (SummationFilter.unconditional α).filter (𝓝 F) := by + simpa [HasProd] using hfac + have hinv : + Tendsto (fun s : Finset α => (∏ x ∈ s, fac x)⁻¹) + (SummationFilter.unconditional α).filter (𝓝 (F⁻¹)) := + hprod.inv₀ hF + refine hinv.congr' (Filter.Eventually.of_forall ?_) + intro s + simp [Finset.prod_inv_distrib] + +lemma hasProd_norm_inv_unconditional {α : Type} {fac : α → ℂ} {F : ℂ} + (hfac : HasProd fac F (SummationFilter.unconditional α)) (hF : F ≠ 0) : + HasProd (fun x => ‖(fac x)⁻¹‖) ‖F⁻¹‖ (SummationFilter.unconditional α) := by + change + Tendsto (fun s : Finset α => ∏ x ∈ s, ‖(fac x)⁻¹‖) + (SummationFilter.unconditional α).filter (𝓝 ‖F⁻¹‖) + have hnorm := (hasProd_inv_unconditional hfac hF).norm + refine hnorm.congr' (Filter.Eventually.of_forall ?_) + intro s + simp [norm_inv, Finset.prod_inv_distrib] + +lemma hasProd_norm_inv_le_exp_of_pointwise_le_exp {α : Type} {fac : α → ℂ} {F : ℂ} + (hfac : HasProd fac F (SummationFilter.unconditional α)) + (b : α → ℝ) (B : ℝ) + (hterm : ∀ x, ‖(fac x)⁻¹‖ ≤ Real.exp (b x)) + (hsum : ∀ s : Finset α, (∑ x ∈ s, b x) ≤ B) : + ‖F⁻¹‖ ≤ Real.exp B := by + by_cases hF : F = 0 + · subst hF + simpa using exp_nonneg B + have hnorm : + HasProd (fun x => ‖(fac x)⁻¹‖) ‖F⁻¹‖ (SummationFilter.unconditional α) := + hasProd_norm_inv_unconditional hfac hF + have hprod : ∀ s : Finset α, (∏ x ∈ s, ‖(fac x)⁻¹‖) ≤ Real.exp B := by + intro s + have h0 : ∀ x ∈ s, 0 ≤ ‖(fac x)⁻¹‖ := by intro _ _; positivity + have h1 : (∏ x ∈ s, ‖(fac x)⁻¹‖) ≤ Real.exp (∑ x ∈ s, b x) := by + refine Finset.prod_le_exp_sum s (a := fun x => ‖(fac x)⁻¹‖) (b := b) h0 ?_ + intro x hx + simpa using hterm x + have h2 : Real.exp (∑ x ∈ s, b x) ≤ Real.exp B := + Real.exp_le_exp.2 (hsum s) + exact h1.trans h2 + exact hasProd_le_of_prod_le_exp hnorm hprod +end +end +section +open Metric + +namespace Complex + +theorem borelCaratheodory_zero_closedBall {f : ℂ → ℂ} {M r R : ℝ} + (hf : AnalyticOnNhd ℂ f (Metric.closedBall (0 : ℂ) R)) + (hr : 0 < r) (hlt : r < R) (hM : 0 < M) (hf0 : f 0 = 0) + (hf_re : ∀ w, ‖w‖ ≤ R → (f w).re ≤ M) {z : ℂ} (hz : ‖z‖ ≤ r) : + ‖f z‖ ≤ 2 * M * r / (R - r) := by + have hR : 0 < R := lt_trans hr hlt + have hz_ball : z ∈ Metric.ball (0 : ℂ) R := by + rw [Metric.mem_ball, dist_zero_right] + exact hz.trans_lt hlt + have hf_diff : DifferentiableOn ℂ f (Metric.ball (0 : ℂ) R) := by + intro w hw + have hw' : w ∈ Metric.closedBall (0 : ℂ) R := ball_subset_closedBall hw + exact (hf w hw').differentiableAt.differentiableWithinAt + have hf_map : Set.MapsTo f (Metric.ball (0 : ℂ) R) {w | w.re ≤ M} := by + intro w hw + simp only [Set.mem_ofPred_eq] + have hw' : ‖w‖ < R := by simpa [Metric.mem_ball, dist_zero_right] using hw + exact hf_re w hw'.le + have hbc := + _root_.Complex.borelCaratheodory_zero hM hf_diff hf_map hR hz_ball hf0 + have hzR : ‖z‖ < R := by + rw [Metric.mem_ball, dist_zero_right] at hz_ball + exact hz_ball + have hmono : ‖z‖ / (R - ‖z‖) ≤ r / (R - r) := by + have hrden : 0 < R - r := sub_pos.mpr hlt + have hden : 0 < R - ‖z‖ := sub_pos.mpr hzR + rw [div_le_div_iff₀ hden hrden] + nlinarith [hz, norm_nonneg z] + have hM' : 0 ≤ 2 * M := mul_nonneg (by norm_num) (le_of_lt hM) + calc ‖f z‖ + ≤ 2 * M * ‖z‖ / (R - ‖z‖) := hbc + _ ≤ 2 * M * (r / (R - r)) := by + simpa [mul_div_assoc] using mul_le_mul_of_nonneg_left hmono hM' + _ = 2 * M * r / (R - r) := by ring + +end Complex +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/Products.lean b/PrimeNumberTheoremAnd/SiegelZeros/Products.lean new file mode 100644 index 0000000..db0daa8 --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/Products.lean @@ -0,0 +1,496 @@ +import Mathlib + +namespace SiegelZeros + +open _root_.Complex + +section +open scoped BigOperators + +namespace Real + +lemma pow_div_one_sub_le_two_mul {r : ℝ} (hr : 0 ≤ r) (hrhalf : r ≤ 1 / 2) (m : ℕ) : + r ^ (m + 1) / (1 - r) ≤ 2 * r ^ (m + 1) := by + have hpow : 0 ≤ r ^ (m + 1) := pow_nonneg hr _ + have hhalf' : (1 / 2 : ℝ) ≤ 1 - r := by linarith + calc + r ^ (m + 1) / (1 - r) ≤ r ^ (m + 1) / (1 / 2 : ℝ) := by + exact div_le_div_of_nonneg_left hpow (by positivity) hhalf' + _ = 2 * r ^ (m + 1) := by ring + +end Real + +namespace Complex + +open scoped BigOperators in + +lemma neg_log_one_sub_eq_tsum {z : ℂ} (hz : ‖z‖ < 1) : + -log (1 - z) = ∑' n : ℕ, z ^ (n + 1) / (n + 1) := by + have h := hasSum_taylorSeries_neg_log hz + rw [← h.tsum_eq, h.summable.tsum_eq_zero_add] + simp only [pow_zero, Nat.cast_zero, div_zero, zero_add, Nat.cast_add, Nat.cast_one] + +noncomputable +def partialLogSum (m : ℕ) (z : ℂ) : ℂ := + -logTaylor (m + 1) (-z) + +@[simp] +lemma partialLogSum_zero (z : ℂ) : partialLogSum 0 z = 0 := by + simp [partialLogSum, logTaylor_succ, logTaylor_zero] + +@[simp] +lemma partialLogSum_at_zero (m : ℕ) : partialLogSum m 0 = 0 := by + simp [partialLogSum, logTaylor_at_zero] + +lemma logTaylor_succ_neg (n : ℕ) (z : ℂ) : + logTaylor (n + 1) (-z) = logTaylor n (-z) - z ^ n / n := by + rw [logTaylor_succ, Pi.add_apply] + have hsign : (-1 : ℂ) ^ (n + 1) * (-z) ^ n = -z ^ n := by + have hzpow : (-z) ^ n = (((-1 : ℂ) * z) ^ n) := by simp + rw [hzpow, mul_pow, ← mul_assoc, ← pow_add] + have hpow : (-1 : ℂ) ^ (n + 1 + n) = (-1 : ℂ) := by + rw [show n + 1 + n = 2 * n + 1 by omega, pow_add, pow_mul] + norm_num + rw [hpow] + ring + rw [show (-1 : ℂ) ^ (n + 1) * (-z) ^ n / n = -(z ^ n / n) by + rw [hsign] + ring] + abel + +lemma logTaylor_neg_eq_neg_sum (m : ℕ) (z : ℂ) : + logTaylor (m + 1) (-z) = -∑ k ∈ Finset.range m, z ^ (k + 1) / (k + 1) := by + induction m with + | zero => + simp [logTaylor_succ, logTaylor_zero] + | succ m hm => + rw [logTaylor_succ_neg, hm, Finset.sum_range_succ] + have hcast : ((m + 1 : ℕ) : ℂ) = (1 + (m : ℂ)) := by + simp [Nat.cast_add, Nat.cast_one, add_comm] + rw [hcast] + ring_nf + +lemma partialLogSum_eq_sum (m : ℕ) (z : ℂ) : + partialLogSum m z = ∑ k ∈ Finset.range m, z ^ (k + 1) / (k + 1) := by + simpa [partialLogSum] using congrArg Neg.neg (logTaylor_neg_eq_neg_sum m z) + +lemma hasDerivAt_partialLogSum (m : ℕ) (z : ℂ) : + HasDerivAt (partialLogSum m) (∑ j ∈ Finset.range m, z ^ j) z := by + cases m with + | zero => + have hzero : partialLogSum 0 = fun _ : ℂ ↦ (0 : ℂ) := by + funext w + exact partialLogSum_zero w + simpa [hzero] using (hasDerivAt_const z (c := (0 : ℂ))) + | succ m => + have hsum : + (∑ j ∈ Finset.range (m + 1), z ^ j) = + ∑ j ∈ Finset.range (m + 1), (-1) ^ j * (-z) ^ j := by + refine Finset.sum_congr rfl ?_ + intro j hj + symm + calc + (-1 : ℂ) ^ j * (-z) ^ j = (-1 : ℂ) ^ j * (((-1 : ℂ) * z) ^ j) := by simp + _ = ((-1 : ℂ) ^ j * (-1 : ℂ) ^ j) * z ^ j := by rw [mul_pow]; ring + _ = z ^ j := by + rw [← pow_add, show j + j = 2 * j by omega, pow_mul] + norm_num + rw [hsum] + simpa [partialLogSum] using! + (((hasDerivAt_logTaylor (m + 1) (-z)).comp z (hasDerivAt_neg z)).neg) + +lemma differentiable_partialLogSum (m : ℕ) : + Differentiable ℂ (fun z : ℂ => partialLogSum m z) := by + intro z + exact (hasDerivAt_partialLogSum m z).differentiableAt + +noncomputable +def logTail (m : ℕ) (z : ℂ) : ℂ := + ∑' k, z ^ (m + 1 + k) / (m + 1 + k) + +lemma summable_logTail {z : ℂ} (hz : ‖z‖ < 1) (m : ℕ) : + Summable (fun k => z ^ (m + 1 + k) / ((m + 1 + k) : ℂ)) := by + have h_geom : Summable (fun k : ℕ => ‖z‖ ^ k) := + summable_geometric_of_lt_one (norm_nonneg z) hz + refine Summable.of_norm_bounded (g := fun k => ‖z‖ ^ k) h_geom ?_ + intro k + rw [norm_div, norm_pow] + have h1 : (1 : ℝ) ≤ (m + 1 + k : ℝ) := by + have : (0 : ℝ) ≤ (m + k : ℝ) := by positivity + nlinarith + have hnorm : ‖(↑m + 1 + ↑k : ℂ)‖ = (m + 1 + k : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (Complex.norm_natCast (m + 1 + k)) + rw [hnorm] + calc + ‖z‖ ^ (m + 1 + k) / (m + 1 + k : ℝ) ≤ ‖z‖ ^ (m + 1 + k) := by + exact div_le_self (pow_nonneg (norm_nonneg z) _) h1 + _ = ‖z‖ ^ (m + 1) * ‖z‖ ^ k := by rw [pow_add] + _ ≤ 1 * ‖z‖ ^ k := by + refine mul_le_mul_of_nonneg_right ?_ (pow_nonneg (norm_nonneg z) k) + exact pow_le_one₀ (norm_nonneg z) (le_of_lt hz) + _ = ‖z‖ ^ k := one_mul _ + +lemma norm_logTail_le {z : ℂ} (hz : ‖z‖ < 1) (m : ℕ) : + ‖logTail m z‖ ≤ ‖z‖ ^ (m + 1) / (1 - ‖z‖) := by + dsimp only [logTail] + have h_rhs_summable : Summable (fun k => ‖z‖ ^ (m + 1 + k)) := by + simpa [pow_add] using + (summable_geometric_of_lt_one (norm_nonneg z) hz).mul_left (‖z‖ ^ (m + 1)) + have h_norm_summable : Summable (fun k => ‖z ^ (m + 1 + k) / ((m + 1 + k) : ℂ)‖) := by + refine Summable.of_nonneg_of_le (fun _ => norm_nonneg _) ?_ h_rhs_summable + intro k + rw [norm_div, norm_pow] + have hnorm : ‖(↑m + 1 + ↑k : ℂ)‖ = (m + 1 + k : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (Complex.norm_natCast (m + 1 + k)) + rw [hnorm] + have hm : 1 ≤ (m + 1 + k : ℝ) := by + have : (0 : ℝ) ≤ (m + k : ℝ) := by positivity + nlinarith + exact div_le_self (pow_nonneg (norm_nonneg z) _) hm + calc + ‖∑' k, z ^ (m + 1 + k) / ((m + 1 + k) : ℂ)‖ + ≤ ∑' k, ‖z ^ (m + 1 + k) / ((m + 1 + k) : ℂ)‖ := + norm_tsum_le_tsum_norm h_norm_summable + _ ≤ ∑' k, ‖z‖ ^ (m + 1 + k) := by + refine h_norm_summable.tsum_le_tsum ?_ h_rhs_summable + intro k + rw [norm_div, norm_pow] + have hm : 1 ≤ (m + 1 + k : ℝ) := by + have : (0 : ℝ) ≤ (m + k : ℝ) := by positivity + nlinarith + have hnorm : ‖(↑m + 1 + ↑k : ℂ)‖ = (m + 1 + k : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (Complex.norm_natCast (m + 1 + k)) + rw [hnorm] + exact div_le_self (pow_nonneg (norm_nonneg z) _) hm + _ = ‖z‖ ^ (m + 1) / (1 - ‖z‖) := by + have h_eq : + (fun k => ‖z‖ ^ (m + 1 + k)) = fun k => ‖z‖ ^ (m + 1) * ‖z‖ ^ k := by + ext k + rw [pow_add] + rw [h_eq, tsum_mul_left] + have h_geom := hasSum_geometric_of_lt_one (norm_nonneg z) hz + rw [h_geom.tsum_eq, div_eq_mul_inv] + +lemma norm_logTail_le_two_mul_norm_pow {z : ℂ} (hz : ‖z‖ < 1) (hzhalf : ‖z‖ ≤ 1 / 2) (m : ℕ) : + ‖logTail m z‖ ≤ 2 * ‖z‖ ^ (m + 1) := + (norm_logTail_le hz m).trans (Real.pow_div_one_sub_le_two_mul (norm_nonneg z) hzhalf m) + +lemma norm_partialLogSum_le_nat_mul_max_one_norm_pow (m : ℕ) (z : ℂ) : + ‖partialLogSum m z‖ ≤ (m : ℝ) * max 1 (‖z‖ ^ m) := by + have hsum : + ‖partialLogSum m z‖ ≤ ∑ k ∈ Finset.range m, ‖z ^ (k + 1) / (k + 1)‖ := by + rw [partialLogSum_eq_sum] + exact norm_sum_le _ _ + have hterm : ∀ k ∈ Finset.range m, ‖z ^ (k + 1) / (k + 1)‖ ≤ max 1 (‖z‖ ^ m) := by + intro k hk + rw [norm_div, norm_pow] + have hk1 : (1 : ℝ) ≤ (k : ℝ) + 1 := by + have hk1_nat : (1 : ℕ) ≤ k + 1 := Nat.succ_le_succ (Nat.zero_le k) + exact_mod_cast hk1_nat + have hdenom : ‖((k : ℂ) + 1)‖ = (k : ℝ) + 1 := by + simpa [Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (Complex.norm_natCast (k + 1)) + have hk_le : k + 1 ≤ m := Nat.succ_le_iff.2 (Finset.mem_range.1 hk) + have hpow_le : ‖z‖ ^ (k + 1) ≤ max 1 (‖z‖ ^ m) := by + have hz0 : 0 ≤ ‖z‖ := norm_nonneg z + by_cases hz1 : ‖z‖ ≤ (1 : ℝ) + · have : ‖z‖ ^ (k + 1) ≤ 1 := by exact pow_le_one₀ hz0 hz1 + exact this.trans (le_max_left _ _) + · have hz1' : (1 : ℝ) ≤ ‖z‖ := le_of_lt (lt_of_not_ge hz1) + have : ‖z‖ ^ (k + 1) ≤ ‖z‖ ^ m := pow_le_pow_right₀ hz1' hk_le + exact this.trans (le_max_right _ _) + calc + ‖z‖ ^ (k + 1) / ‖((k : ℂ) + 1)‖ = ‖z‖ ^ (k + 1) / ((k : ℝ) + 1) := by simp [hdenom] + _ ≤ ‖z‖ ^ (k + 1) := by + exact div_le_self (pow_nonneg (norm_nonneg z) _) hk1 + _ ≤ max 1 (‖z‖ ^ m) := hpow_le + have hsum_le : + (∑ k ∈ Finset.range m, ‖z ^ (k + 1) / (k + 1)‖) ≤ + ∑ _k ∈ Finset.range m, max 1 (‖z‖ ^ m) := + Finset.sum_le_sum (fun k hk => hterm k hk) + have hcard : ∑ _k ∈ Finset.range m, max 1 (‖z‖ ^ m) = (m : ℝ) * max 1 (‖z‖ ^ m) := by + simp [Finset.sum_const] + exact hsum.trans (hsum_le.trans_eq hcard) + +lemma neg_log_one_sub_eq_partialLogSum_add_logTail {z : ℂ} (hz : ‖z‖ < 1) (m : ℕ) : + -log (1 - z) = partialLogSum m z + logTail m z := by + let f : ℕ → ℂ := fun k ↦ z ^ (k + 1) / ((k : ℂ) + 1) + have h_summable : Summable f := by + simpa [f, Nat.cast_add, Nat.cast_one, add_assoc, add_comm, add_left_comm] using + (summable_logTail hz 0) + have h_decomp := h_summable.sum_add_tsum_nat_add m + rw [neg_log_one_sub_eq_tsum hz, partialLogSum_eq_sum, ← h_decomp] + congr 1 + dsimp only [logTail] + refine tsum_congr fun k ↦ ?_ + simp only [f, Nat.cast_add] + ring_nf + +end Complex +end +section +noncomputable section + +namespace Complex + +variable {z : ℂ} + +@[bound] +theorem neg_norm_le_re (z : ℂ) : -‖z‖ ≤ z.re := + neg_le_of_abs_le (abs_re_le_norm z) + +lemma norm_inv_pow_le_one_of_one_le_norm (u : ℂ) (n : ℕ) (hu : (1 : ℝ) ≤ ‖u‖) : + ‖(u ^ n)⁻¹‖ ≤ 1 := by + have hge : (1 : ℝ) ≤ ‖u ^ n‖ := by + rw [Complex.norm_pow] + exact one_le_pow₀ hu + calc ‖(u ^ n)⁻¹‖ = ‖(1 : ℂ) / u ^ n‖ := by rw [inv_eq_one_div] + _ = 1 / ‖u ^ n‖ := by + have hone : ‖(1 : ℂ)‖ = (1 : ℝ) := by simp + rw [Complex.norm_div, hone] + _ ≤ 1 := by simpa [one_div] using inv_le_one_of_one_le₀ hge + +end Complex +end +end +section +noncomputable section + +open scoped BigOperators +open Set + +namespace Complex + +def weierstrassFactor (m : ℕ) (z : ℂ) : ℂ := + (1 - z) * exp (partialLogSum m z) + +lemma weierstrassFactor_def (m : ℕ) (z : ℂ) : + weierstrassFactor m z = (1 - z) * exp (partialLogSum m z) := by + simp [weierstrassFactor] + +@[simp] +lemma weierstrassFactor_at_zero (m : ℕ) : weierstrassFactor m 0 = 1 := by + simp [weierstrassFactor, partialLogSum_at_zero] + +lemma weierstrassFactor_eq_zero_iff (m : ℕ) (z : ℂ) : + weierstrassFactor m z = 0 ↔ z = 1 := by + constructor + · intro hz + rw [weierstrassFactor] at hz + rcases mul_eq_zero.mp hz with h1 | h2 + · exact (sub_eq_zero.mp h1).symm + · exact absurd h2 (exp_ne_zero _) + · rintro rfl + simp [weierstrassFactor] + +lemma weierstrassFactor_ne_zero_iff (m : ℕ) (z : ℂ) : + weierstrassFactor m z ≠ 0 ↔ z ≠ 1 := by + simpa [ne_eq] using (not_congr (weierstrassFactor_eq_zero_iff (m := m) (z := z))) + +lemma weierstrassFactor_ne_zero_of_ne_one (m : ℕ) {z : ℂ} (hz : z ≠ 1) : + weierstrassFactor m z ≠ 0 := + (weierstrassFactor_ne_zero_iff (m := m) (z := z)).2 hz + +lemma differentiable_weierstrassFactor (m : ℕ) : + Differentiable ℂ (fun z : ℂ => weierstrassFactor m z) := by + simpa [weierstrassFactor] using! + ((differentiable_const (c := (1 : ℂ))).sub differentiable_id).mul + (differentiable_exp.comp (differentiable_partialLogSum m)) + +theorem analyticOrderAt_weierstrassFactor_div_self (m : ℕ) {a : ℂ} (ha : a ≠ 0) : + analyticOrderAt (fun z : ℂ => weierstrassFactor m (z / a)) a = (1 : ℕ∞) := by + set F : ℂ → ℂ := fun z => weierstrassFactor m (z / a) + have hF : AnalyticAt ℂ F a := by + have hdiv : Differentiable ℂ (fun z : ℂ => z / a) := by + simp [div_eq_mul_inv] + have hdiff : Differentiable ℂ F := (differentiable_weierstrassFactor m).comp hdiv + exact Differentiable.analyticAt (f := F) hdiff a + let g : ℂ → ℂ := fun z => (-a⁻¹) * Complex.exp (partialLogSum m (z / a)) + have hg : AnalyticAt ℂ g a := by + have hdiv : Differentiable ℂ (fun z : ℂ => z / a) := by + simp [div_eq_mul_inv] + have hpls : Differentiable ℂ (fun z : ℂ => partialLogSum m (z / a)) := + (differentiable_partialLogSum m).comp hdiv + have hexp : Differentiable ℂ (fun z : ℂ => Complex.exp (partialLogSum m (z / a))) := + (Complex.differentiable_exp).comp hpls + have hdiffg : Differentiable ℂ g := by + simpa [g] using hexp.const_mul (-a⁻¹ : ℂ) + exact Differentiable.analyticAt (f := g) hdiffg a + have hg0 : g a ≠ 0 := by + have hconst : (-a⁻¹ : ℂ) ≠ 0 := by simp [ha] + have hexp0 : Complex.exp (partialLogSum m (a / a)) ≠ 0 := + Complex.exp_ne_zero (partialLogSum m (a / a)) + simpa [g] using mul_ne_zero hconst hexp0 + refine (hF.analyticOrderAt_eq_natCast (n := 1)).2 ?_ + refine ⟨g, hg, hg0, ?_⟩ + refine Filter.Eventually.of_forall ?_ + intro z + have hlin : (1 - z / a) = (z - a) * (-a⁻¹) := by + have h1 : (1 : ℂ) = a * a⁻¹ := by simp [ha] + simp [div_eq_mul_inv, h1] + ring + simp only [F, g, pow_one, smul_eq_mul] + rw [weierstrassFactor_def] + simp [hlin, mul_assoc] + +lemma weierstrassFactor_eq_exp_neg_tail (m : ℕ) {z : ℂ} (hz : ‖z‖ < 1) (hz1 : z ≠ 1) : + weierstrassFactor m z = exp (-logTail m z) := by + unfold weierstrassFactor + have hz_ne_1 : 1 - z ≠ 0 := sub_ne_zero.mpr hz1.symm + rw [← exp_log hz_ne_1, ← Complex.exp_add] + have hsum : log (1 - z) + partialLogSum m z = -logTail m z := by + have hdecomp := neg_log_one_sub_eq_partialLogSum_add_logTail hz m + calc + log (1 - z) + partialLogSum m z + = log (1 - z) + (partialLogSum m z + logTail m z) - logTail m z := by ring + _ = log (1 - z) + (-log (1 - z)) - logTail m z := by rw [hdecomp] + _ = -logTail m z := by ring + simp [hsum] + +theorem weierstrassFactor_sub_one_pow_bound {m : ℕ} {z : ℂ} (hz : ‖z‖ ≤ 1 / 2) : + ‖weierstrassFactor m z - 1‖ ≤ 4 * ‖z‖ ^ (m + 1) := by + by_cases hm : m = 0 + · subst hm + have hmain : ‖(1 - z) - 1‖ ≤ 4 * ‖z‖ ^ 1 := by + have h : (1 - z) - 1 = -z := by ring + calc + ‖(1 - z) - 1‖ = ‖-z‖ := by simp [h] + _ = ‖z‖ := norm_neg z + _ = ‖z‖ ^ 1 := by simp + _ ≤ 4 * ‖z‖ ^ 1 := by nlinarith [pow_nonneg (norm_nonneg z) 1] + simpa [weierstrassFactor] using hmain + · have hz_lt : ‖z‖ < 1 := lt_of_le_of_lt hz (by norm_num) + by_cases hz1 : z = 1 + · exfalso; rw [hz1] at hz; norm_num at hz + have h_eq : weierstrassFactor m z = exp (-logTail m z) := + weierstrassFactor_eq_exp_neg_tail m hz_lt hz1 + rw [h_eq] + have h_tail_bound := norm_logTail_le_two_mul_norm_pow hz_lt hz m + have hw_le_one : ‖-logTail m z‖ ≤ 1 := by + simp only [norm_neg] + have : ‖logTail m z‖ ≤ 1 := by + have hm_pos : 0 < m := Nat.pos_of_ne_zero hm + have h2 : 2 ≤ m + 1 := by + exact Nat.succ_le_succ (Nat.succ_le_iff.2 hm_pos) + have hpow : (‖z‖ ^ (m + 1)) ≤ (‖z‖ ^ 2) := by + have hz1' : ‖z‖ ≤ 1 := by nlinarith [hz] + have hz0' : 0 ≤ ‖z‖ := norm_nonneg z + exact pow_le_pow_of_le_one hz0' hz1' h2 + have hmul : 2 * ‖z‖ ^ (m + 1) ≤ 2 * ‖z‖ ^ 2 := by gcongr + have hsq : 2 * ‖z‖ ^ 2 ≤ 1 := by + have hz0 : 0 ≤ ‖z‖ := norm_nonneg z + have hz_sq : ‖z‖ ^ 2 ≤ (1 / 2 : ℝ) ^ 2 := pow_le_pow_left₀ hz0 hz 2 + nlinarith + exact (h_tail_bound.trans hmul).trans hsq + linarith + have h_exp_sub_one : ‖exp (-logTail m z) - 1‖ ≤ 2 * ‖-logTail m z‖ := + Complex.norm_exp_sub_one_le hw_le_one + simp only [norm_neg] at h_exp_sub_one + calc + ‖exp (-logTail m z) - 1‖ ≤ 2 * ‖logTail m z‖ := h_exp_sub_one + _ ≤ 2 * (2 * ‖z‖ ^ (m + 1)) := by gcongr + _ = 4 * ‖z‖ ^ (m + 1) := by ring + +lemma log_norm_weierstrassFactor_ge_log_norm_one_sub_sub (m : ℕ) (z : ℂ) : + Real.log ‖1 - z‖ - ‖partialLogSum m z‖ ≤ Real.log ‖weierstrassFactor m z‖ := by + by_cases hz1 : z = (1 : ℂ) + · subst hz1 + simp [weierstrassFactor] + set S : ℂ := partialLogSum m z + have hS : weierstrassFactor m z = (1 - z) * Complex.exp S := by + simp [weierstrassFactor, S] + have hnorm_pos : 0 < ‖(1 : ℂ) - z‖ := + norm_pos_iff.mpr (sub_ne_zero.mpr (Ne.symm hz1)) + have hlog : + Real.log ‖weierstrassFactor m z‖ = Real.log ‖1 - z‖ + S.re := by + have hne : ‖(1 : ℂ) - z‖ ≠ 0 := ne_of_gt hnorm_pos + calc + Real.log ‖weierstrassFactor m z‖ + = Real.log (‖(1 : ℂ) - z‖ * ‖Complex.exp S‖) := by + simp [hS] + _ = Real.log ‖(1 : ℂ) - z‖ + Real.log ‖Complex.exp S‖ := by + simpa using (Real.log_mul hne (ne_of_gt (by simp))) + _ = Real.log ‖(1 : ℂ) - z‖ + S.re := by + simp [Complex.norm_exp, Real.log_exp] + _ = Real.log ‖1 - z‖ + S.re := by simp [sub_eq_add_neg, add_comm] + have hre : S.re ≥ -‖S‖ := Complex.neg_norm_le_re S + have : Real.log ‖weierstrassFactor m z‖ ≥ Real.log ‖1 - z‖ - ‖S‖ := by + linarith [hlog, hre] + simpa [S] using this + +lemma log_norm_weierstrassFactor_ge_neg_two_pow {m : ℕ} {z : ℂ} (hz : ‖z‖ ≤ (1 / 2 : ℝ)) : + (-2 : ℝ) * ‖z‖ ^ (m + 1) ≤ Real.log ‖weierstrassFactor m z‖ := by + have hz_lt : ‖z‖ < (1 : ℝ) := lt_of_le_of_lt hz (by norm_num) + have hz1 : z ≠ (1 : ℂ) := by + intro h + have : (1 : ℝ) ≤ (1 / 2 : ℝ) := by + simpa [h] using hz + norm_num at this + have hEq : weierstrassFactor m z = Complex.exp (-logTail m z) := + weierstrassFactor_eq_exp_neg_tail m hz_lt hz1 + have hlog : + Real.log ‖weierstrassFactor m z‖ = (-logTail m z).re := by + simp [hEq, Complex.norm_exp, Real.log_exp] + have hre : (-logTail m z).re ≥ -‖logTail m z‖ := by + simpa [norm_neg] using Complex.neg_norm_le_re (-logTail m z) + have htail := norm_logTail_le_two_mul_norm_pow hz_lt hz m + have : (-logTail m z).re ≥ (-2 : ℝ) * ‖z‖ ^ (m + 1) := by + calc + (-logTail m z).re ≥ -‖logTail m z‖ := hre + _ ≥ (-2 : ℝ) * ‖z‖ ^ (m + 1) := by + nlinarith [htail] + simpa [hlog, mul_assoc, mul_left_comm, mul_comm] using this + +end Complex +end +end +section +noncomputable section + +open Filter Topology + +namespace Complex + +theorem logDeriv_weierstrassFactor_one_div {a z : ℂ} (ha : a ≠ 0) (hz : z ≠ a) : + logDeriv (fun w : ℂ => weierstrassFactor 1 (w / a)) z = + 1 / (z - a) + 1 / a := by + have hE : + (fun w : ℂ => weierstrassFactor 1 (w / a)) = + fun w : ℂ => (1 - w / a) * exp (w / a) := by + ext w + simp [weierstrassFactor_def, partialLogSum_eq_sum] + have hf : (1 - z / a) ≠ 0 := by + intro hzero + have hdiv : z / a = 1 := by + exact (sub_eq_zero.mp hzero).symm + exact hz ((div_eq_one_iff_eq ha).1 hdiv) + rw [hE, logDeriv_fun_mul z hf (exp_ne_zero (z / a)) (by fun_prop) (by fun_prop)] + have hleft : logDeriv (fun w : ℂ => 1 - w / a) z = 1 / (z - a) := by + rw [logDeriv_apply] + have hderiv : deriv (fun w : ℂ => 1 - w / a) z = -(1 / a) := by + simp [one_div] + rw [hderiv] + have haz : -z + a ≠ 0 := by + simpa [sub_eq_add_neg, add_comm] using sub_ne_zero.mpr (Ne.symm hz) + field_simp [ha, sub_ne_zero.mpr hz, haz] + have haz' : a - z ≠ 0 := sub_ne_zero.mpr (Ne.symm hz) + have hza : z - a = -(a - z) := by ring + rw [hza] + field_simp [haz'] + have hright : logDeriv (fun w : ℂ => exp (w / a)) z = 1 / a := by + rw [logDeriv_apply] + have hderiv : deriv (fun w : ℂ => exp (w / a)) z = + exp (z / a) * (1 / a) := by + simp [one_div] + rw [hderiv] + field_simp [exp_ne_zero (z / a)] + rw [hleft, hright] + +end Complex +end +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SiegelZeros/Summability.lean b/PrimeNumberTheoremAnd/SiegelZeros/Summability.lean new file mode 100644 index 0000000..0a11558 --- /dev/null +++ b/PrimeNumberTheoremAnd/SiegelZeros/Summability.lean @@ -0,0 +1,501 @@ +import Mathlib +import PrimeNumberTheoremAnd.SiegelZeros.Factorization +import PrimeNumberTheoremAnd.SiegelZeros.Counting + +namespace SiegelZeros + +section +noncomputable section + +open Filter Topology Set _root_.SiegelZeros.Complex +open scoped BigOperators Topology + +namespace Complex.Hadamard + +open scoped _root_.Real + +noncomputable def divisorMassClosedBall₀ (f : ℂ → ℂ) (R : ℝ) : ℝ := + Function.locallyFinsuppWithin.massClosedBall₀ (MeromorphicOn.divisor f (Set.univ : Set ℂ)) R + +lemma divisorMassClosedBall₀_le_of_growth {f : ℂ → ℂ} {ρ C : ℝ} + (hf : Differentiable ℂ f) + (hC : ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) + {R : ℝ} (hR : 1 ≤ R) : + divisorMassClosedBall₀ f R + ≤ (C * (1 + |2 * R|) ^ ρ + |Real.log ‖meromorphicTrailingCoeffAt f 0‖|) / + Real.log 2 := by + simpa [divisorMassClosedBall₀] using + (Function.locallyFinsuppWithin.massClosedBall₀_divisor_le_of_log_growth + (f := f) (ρ := ρ) (C := C) hf hC hR) + +lemma exists_r0_le_norm_divisorZeroIndex₀Val {f : ℂ → ℂ} + (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) : + ∃ r0 : ℝ, 0 < r0 ∧ + ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), r0 ≤ ‖divisorZeroIndex₀Val p‖ := by + classical + set U : Set ℂ := (Set.univ : Set ℂ) + set D : Function.locallyFinsuppWithin U ℤ := MeromorphicOn.divisor f U + have hDnonneg : 0 ≤ D := by + simpa [D, U] using (Differentiable.divisor_nonneg (f := f) hf) + have hzero : ∀ p : divisorZeroIndex₀ f U, f (divisorZeroIndex₀Val p) = 0 := by + intro p + set z : ℂ := divisorZeroIndex₀Val p + have hneTop : meromorphicOrderAt f z ≠ ⊤ := by + have hzAnal : AnalyticAt ℂ f z := hf.analyticAt z + have hzA : analyticOrderAt f z ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (f := f) (hf := hf) hnot (z := z) + intro htop + have hm : meromorphicOrderAt f z = (analyticOrderAt f z).map (↑) := + hzAnal.meromorphicOrderAt_eq (𝕜 := ℂ) + cases h : analyticOrderAt f z with + | top => + exact hzA (by simp [h]) + | coe n => + have : (analyticOrderAt f z).map (↑) ≠ (⊤ : WithTop ℤ) := by + simp [h] + exact this (by simpa [hm] using htop) + have hmon : MeromorphicOn f U := by + intro w hw; exact (hf.analyticAt w).meromorphicAt + have hdiv : MeromorphicOn.divisor f U z = (meromorphicOrderAt f z).untop₀ := by + simpa [U] using (MeromorphicOn.divisor_apply (f := f) (U := U) (z := z) hmon (by aesop)) + have hDz : MeromorphicOn.divisor f U z ≠ 0 := by + have hzsup : z ∈ (MeromorphicOn.divisor f U).support := by + simp [z] + simpa [Function.mem_support] using hzsup + have hposZ : (0 : ℤ) < (meromorphicOrderAt f z).untop₀ := by + have hge0 : 0 ≤ (meromorphicOrderAt f z).untop₀ := by + have : 0 ≤ MeromorphicOn.divisor f U z := by + simpa [D, U, z] using hDnonneg z + simpa [hdiv] using this + have hne0 : (meromorphicOrderAt f z).untop₀ ≠ 0 := by + simpa [hdiv] using hDz + exact lt_of_le_of_ne hge0 (by simpa [eq_comm] using hne0) + have hpos : (0 : WithTop ℤ) < meromorphicOrderAt f z := by + have : (0 : WithTop ℤ) < ((meromorphicOrderAt f z).untop₀ : WithTop ℤ) := + WithTop.coe_lt_coe.2 hposZ + simpa [WithTop.coe_untop₀_of_ne_top hneTop] using this + have htend0 : Tendsto f (𝓝[≠] z) (𝓝 (0 : ℂ)) := + tendsto_zero_of_meromorphicOrderAt_pos (f := f) (x := z) hpos + have hcontz : ContinuousAt f z := (hf z).continuousAt + have htendz : Tendsto f (𝓝[≠] z) (𝓝 (f z)) := + (hcontz.tendsto.mono_left (nhdsWithin_le_nhds : 𝓝[≠] z ≤ 𝓝 z)) + exact tendsto_nhds_unique htendz htend0 + by_cases h0 : f 0 = 0 + · have hD0 : D 0 ≠ 0 := by + have hmero0 : MeromorphicAt f (0 : ℂ) := (hf.analyticAt 0).meromorphicAt + have hneTop0 : meromorphicOrderAt f (0 : ℂ) ≠ ⊤ := by + have hA0 : analyticOrderAt f (0 : ℂ) ≠ ⊤ := + analyticOrderAt_ne_top_of_exists_ne_zero (f := f) (hf := hf) hnot (z := 0) + intro htop + have hm : meromorphicOrderAt f (0 : ℂ) = (analyticOrderAt f (0 : ℂ)).map (↑) := + (hf.analyticAt 0).meromorphicOrderAt_eq (𝕜 := ℂ) + cases h : analyticOrderAt f (0 : ℂ) with + | top => exact (hA0 h).elim + | coe n => + have : (analyticOrderAt f (0 : ℂ)).map (↑) ≠ (⊤ : WithTop ℤ) := by + simp [h] + exact this (by simpa [hm] using htop) + have htend0 : Tendsto f (𝓝[≠] (0 : ℂ)) (𝓝 (0 : ℂ)) := by + have hcont0 : ContinuousAt f (0 : ℂ) := (hf 0).continuousAt + have : Tendsto f (𝓝 (0 : ℂ)) (𝓝 (0 : ℂ)) := by simpa [h0] using hcont0.tendsto + exact this.mono_left (nhdsWithin_le_nhds : 𝓝[≠] (0 : ℂ) ≤ 𝓝 (0 : ℂ)) + have hpos0 : (0 : WithTop ℤ) < meromorphicOrderAt f (0 : ℂ) := + (tendsto_zero_iff_meromorphicOrderAt_pos hmero0).1 htend0 + have hpos0' : (0 : ℤ) < (meromorphicOrderAt f (0 : ℂ)).untop₀ := by + have : (0 : WithTop ℤ) < ((meromorphicOrderAt f (0 : ℂ)).untop₀ : WithTop ℤ) := by + simpa [WithTop.coe_untop₀_of_ne_top hneTop0] using hpos0 + simpa using (WithTop.coe_lt_coe.1 this) + have hdiv0 : D 0 = (meromorphicOrderAt f (0 : ℂ)).untop₀ := by + have hmon : MeromorphicOn f U := by + intro w hw; exact (hf.analyticAt w).meromorphicAt + simpa [D, U] using + (MeromorphicOn.divisor_apply (f := f) (U := U) (z := (0 : ℂ)) + hmon (by aesop)) + exact by + have : (meromorphicOrderAt f (0 : ℂ)).untop₀ ≠ 0 := ne_of_gt hpos0' + simpa [hdiv0] using this + have hmem0 : (0 : ℂ) ∈ D.support := by + simp [Function.mem_support, hD0] + have hdisc : IsDiscrete D.support := by + simpa [D] using (D.discreteSupport) + rcases Metric.exists_ball_inter_eq_singleton_of_mem_discrete hdisc hmem0 with ⟨r0, hr0pos, hr0⟩ + refine ⟨r0, hr0pos, ?_⟩ + intro p + have hp : divisorZeroIndex₀Val p ∈ D.support := by + simp [D, divisorZeroIndex₀Val_mem_divisor_support (f := f) (U := U) p] + have hnotBall : divisorZeroIndex₀Val p ∉ Metric.ball (0 : ℂ) r0 := by + intro hball + have : divisorZeroIndex₀Val p ∈ Metric.ball (0 : ℂ) r0 ∩ D.support := ⟨hball, hp⟩ + have : divisorZeroIndex₀Val p ∈ ({(0 : ℂ)} : Set ℂ) := by simp [hr0] at this + have : divisorZeroIndex₀Val p = 0 := by simp [Set.mem_singleton_iff] at this + exact (divisorZeroIndex₀Val_ne_zero p) this + have : r0 ≤ ‖divisorZeroIndex₀Val p‖ := by + have : ¬ ‖divisorZeroIndex₀Val p‖ < r0 := by + intro hlt + exact hnotBall (by simpa [Metric.mem_ball, dist_zero_right] using hlt) + exact le_of_not_gt this + exact this + · have hcont0 : ContinuousAt f (0 : ℂ) := (hf 0).continuousAt + have hne : ∀ᶠ z in 𝓝 (0 : ℂ), f z ≠ 0 := hcont0.eventually_ne h0 + rcases Metric.mem_nhds_iff.1 hne with ⟨r0, hr0pos, hr0⟩ + refine ⟨r0, hr0pos, ?_⟩ + intro p + have : ¬ ‖divisorZeroIndex₀Val p‖ < r0 := by + intro hlt + have hzball : divisorZeroIndex₀Val p ∈ Metric.ball (0 : ℂ) r0 := by + simpa [Metric.mem_ball, dist_zero_right] using hlt + have : f (divisorZeroIndex₀Val p) ≠ 0 := hr0 hzball + exact this (hzero p) + exact le_of_not_gt this + +open scoped BigOperators + +lemma card_ball_le_divisorMassClosedBall₀ + {f : ℂ → ℂ} (hf : Differentiable ℂ f) {R : ℝ} (hR : 0 < R) : + (Nat.card {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) // ‖divisorZeroIndex₀Val p‖ ≤ R} : ℝ) + ≤ divisorMassClosedBall₀ f R := by + set U : Set ℂ := (Set.univ : Set ℂ) + set D : Function.locallyFinsuppWithin U ℤ := MeromorphicOn.divisor f U + have : + Fintype {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} := by + have : Finite {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} := by + have : Metric.closedBall (0 : ℂ) R ⊆ U := by simp [U] + simpa using (finite_divisorZeroIndex₀_subtype_norm_le (f := f) (U := U) (B := R) this) + exact Fintype.ofFinite _ + have hDnonneg : 0 ≤ D := by + simpa [D, U] using (Differentiable.divisor_nonneg (f := f) hf) + let SR : Finset ℂ := + (Function.locallyFinsuppWithin.finiteSupport (Function.locallyFinsuppWithin.toClosedBall R D) + (isCompact_closedBall (0 : ℂ) |R|)).toFinset + let S : Finset ℂ := SR.filter fun z : ℂ => z ≠ 0 + let T : Type := + Σ z : S, Fin (Int.toNat (D z.1)) + let φ : + {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} → T := fun p => + let z0 : ℂ := divisorZeroIndex₀Val p.1 + have hz0_memSR : z0 ∈ SR := by + have hz0_norm : ‖z0‖ ≤ |R| := by + have : ‖z0‖ ≤ R := p.2 + simpa [abs_of_pos hR] using this + have hz0_support : z0 ∈ (Function.locallyFinsuppWithin.toClosedBall R D).support := by + have hz0_suppD : z0 ∈ D.support := by + simp [z0, D] + exact Function.locallyFinsuppWithin.mem_toClosedBall_support_of_mem_support_of_norm_le_abs + hz0_suppD hz0_norm + exact (Set.Finite.mem_toFinset + (Function.locallyFinsuppWithin.finiteSupport + (Function.locallyFinsuppWithin.toClosedBall R D) + (isCompact_closedBall (0 : ℂ) |R|))).2 hz0_support + have hz0_ne0 : z0 ≠ 0 := divisorZeroIndex₀Val_ne_zero p.1 + have hz0_memS : z0 ∈ S := Finset.mem_filter.2 ⟨hz0_memSR, hz0_ne0⟩ + ⟨⟨z0, hz0_memS⟩, by + simpa [z0, divisorZeroIndex₀Val, D] using p.1.1.2⟩ + have hφ_inj : Function.Injective φ := by + intro p q hpq + have hσ := (Sigma.mk.inj_iff).1 hpq + have hzS : (φ p).1 = (φ q).1 := hσ.1 + have hz : divisorZeroIndex₀Val p.1 = divisorZeroIndex₀Val q.1 := by + simpa [φ] using congrArg Subtype.val hzS + apply Subtype.ext + apply Subtype.ext + apply Sigma.ext + · exact hz + · simpa [φ] using hσ.2 + have hcard_le : + Fintype.card {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} ≤ Fintype.card T := + Fintype.card_le_of_injective φ hφ_inj + have hT_card : + (Fintype.card T : ℝ) = + (S.sum fun z : ℂ => (Int.toNat (D z) : ℝ)) := by + have hNat : + Fintype.card T = ∑ z : S, Int.toNat (D z.1) := by + have h1 : + Fintype.card T = ∑ z : S, Fintype.card (Fin (Int.toNat (D z.1))) := by + change Fintype.card (Sigma (fun z : S => Fin (Int.toNat (D z.1)))) + = ∑ z : S, Fintype.card (Fin (Int.toNat (D z.1))) + exact (Fintype.card_sigma (ι := S) (α := fun z : S => Fin (Int.toNat (D z.1)))) + simpa using h1 + have hR : + (Fintype.card T : ℝ) = ∑ z : S, (Int.toNat (D z.1) : ℝ) := by + exact_mod_cast hNat + have hR' : + (Fintype.card T : ℝ) = S.attach.sum (fun z : S => (Int.toNat (D z.1) : ℝ)) := by + simpa [Finset.univ_eq_attach] using hR + calc + (Fintype.card T : ℝ) = S.attach.sum (fun z : S => (Int.toNat (D z.1) : ℝ)) := hR' + _ = S.sum (fun z : ℂ => (Int.toNat (D z) : ℝ)) := by + simpa using (Finset.sum_attach (s := S) (f := fun z : ℂ => (Int.toNat (D z) : ℝ))) + have htoNat_le : ∀ z ∈ S, (Int.toNat (D z) : ℝ) ≤ (D z : ℝ) := by + intro z hz + have hDz_nonneg : 0 ≤ D z := by simpa [D] using hDnonneg z + have hEqZ : ((Int.toNat (D z) : ℕ) : ℤ) = D z := by + simpa using (Int.toNat_of_nonneg hDz_nonneg) + have hEqR : (Int.toNat (D z) : ℝ) = (D z : ℝ) := by + exact_mod_cast hEqZ + exact le_of_eq hEqR + calc + (Nat.card {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} : ℝ) + = (Fintype.card {p : divisorZeroIndex₀ f U // ‖divisorZeroIndex₀Val p‖ ≤ R} : ℝ) := by + simp [Nat.card_eq_fintype_card] + _ ≤ (Fintype.card T : ℝ) := by exact_mod_cast hcard_le + _ = S.sum (fun z : ℂ => (Int.toNat (D z) : ℝ)) := hT_card + _ ≤ S.sum (fun z : ℂ => (D z : ℝ)) := by + refine Finset.sum_le_sum ?_ + intro z hz + exact htoNat_le z hz + _ = divisorMassClosedBall₀ f R := by + rfl + +lemma card_subtype_le_divisorMassClosedBall₀_of_norm_le + {f : ℂ → ℂ} (hf : Differentiable ℂ f) + {s : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ))} [Fintype s] + {R : ℝ} (hR : 0 < R) (hs : ∀ p : s, ‖divisorZeroIndex₀Val p.1‖ ≤ R) : + (Fintype.card s : ℝ) ≤ divisorMassClosedBall₀ f R := by + let Aball : Type := + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) // ‖divisorZeroIndex₀Val p‖ ≤ R} + have : Fintype Aball := by + have : Finite Aball := by + have : Metric.closedBall (0 : ℂ) R ⊆ (Set.univ : Set ℂ) := by simp + simpa [Aball] using + (finite_divisorZeroIndex₀_subtype_norm_le (f := f) (U := (Set.univ : Set ℂ)) + (B := R) this) + exact Fintype.ofFinite _ + have hinj : Function.Injective (fun p : s => (⟨p.1, hs p⟩ : Aball)) := by + intro p q hpq + apply Subtype.ext + exact congrArg (fun x : Aball => x.1) hpq + have hcard_le : Fintype.card s ≤ Fintype.card Aball := + Fintype.card_le_of_injective _ hinj + have hAball : (Nat.card Aball : ℝ) ≤ divisorMassClosedBall₀ f R := by + simpa [Aball] using card_ball_le_divisorMassClosedBall₀ (f := f) hf hR + calc + (Fintype.card s : ℝ) ≤ (Fintype.card Aball : ℝ) := by exact_mod_cast hcard_le + _ = (Nat.card Aball : ℝ) := by simp [Nat.card_eq_fintype_card] + _ ≤ divisorMassClosedBall₀ f R := hAball + +lemma divisorZeroIndex₀_dyadicShell_upper_bound + {f : ℂ → ℂ} {r0 : ℝ} + (hr0pos : 0 < r0) + (hr0 : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), r0 ≤ ‖divisorZeroIndex₀Val p‖) + {k : ℕ} {p : divisorZeroIndex₀ f (Set.univ : Set ℂ)} + (hp : ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ = k) : + ‖divisorZeroIndex₀Val p‖ ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1) := by + exact Real.dyadicShell_upper_bound (r0 := r0) (x := ‖divisorZeroIndex₀Val p‖) + hr0pos (hr0 p) hp + +lemma divisorZeroIndex₀_dyadicShell_lower_bound + {f : ℂ → ℂ} {r0 : ℝ} + (hr0pos : 0 < r0) + (hr0 : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), r0 ≤ ‖divisorZeroIndex₀Val p‖) + {k : ℕ} {p : divisorZeroIndex₀ f (Set.univ : Set ℂ)} + (hp : ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ = k) : + r0 * (2 : ℝ) ^ (k : ℝ) ≤ ‖divisorZeroIndex₀Val p‖ := by + exact Real.dyadicShell_lower_bound (r0 := r0) (x := ‖divisorZeroIndex₀Val p‖) + hr0pos (hr0 p) hp + +lemma finite_divisorZeroIndex₀_dyadicShell + {f : ℂ → ℂ} {r0 : ℝ} + (hr0pos : 0 < r0) + (hr0 : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), r0 ≤ ‖divisorZeroIndex₀Val p‖) + (k : ℕ) : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ = k} : Set _).Finite := by + have hsub : + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ = k} ⊆ + {p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ‖divisorZeroIndex₀Val p‖ ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1)} := by + intro p hp + exact divisorZeroIndex₀_dyadicShell_upper_bound hr0pos hr0 hp + have hfin : + ({p : divisorZeroIndex₀ f (Set.univ : Set ℂ) | + ‖divisorZeroIndex₀Val p‖ ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1)} : Set _).Finite := by + have : + Metric.closedBall (0 : ℂ) (r0 * (2 : ℝ) ^ ((k : ℝ) + 1)) ⊆ + (Set.univ : Set ℂ) := by + simp + simpa using + (divisorZeroIndex₀_norm_le_finite (f := f) (U := (Set.univ : Set ℂ)) + (B := r0 * (2 : ℝ) ^ ((k : ℝ) + 1)) this) + exact hfin.subset hsub + +lemma tsum_divisorZeroIndex₀_dyadicShell_inv_rpow_le_geometric_of_growth + {f : ℂ → ℂ} {ρ τ r0 Cgrow : ℝ} + (hρ : 0 ≤ ρ) (hτpos : 0 < τ) (hf : Differentiable ℂ f) + (hCgrow_pos : 0 < Cgrow) + (hCgrow : ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ Cgrow * (1 + ‖z‖) ^ ρ) + (hr0pos : 0 < r0) + (hr0 : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), + r0 ≤ ‖divisorZeroIndex₀Val p‖) + (k : ℕ) (hk_ge_one : 1 ≤ r0 * (2 : ℝ) ^ ((k : ℝ) + 1)) : + let kfun : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℕ := + fun p => ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ + let S : Set (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := {p | kfun p = k} + let Ctrail : ℝ := |Real.log ‖meromorphicTrailingCoeffAt f 0‖| + let A : ℝ := ((Cgrow / Real.log 2) * (1 + 4 * r0) ^ ρ) * (r0⁻¹) ^ τ + let B : ℝ := ((Ctrail / Real.log 2) + 1) * (r0⁻¹) ^ τ + let q : ℝ := (2 : ℝ) ^ (ρ - τ) + let qσ : ℝ := (2 : ℝ) ^ (-τ) + (∑' p : S, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) ≤ A * q ^ k + B * qσ ^ k := by + classical + intro kfun S Ctrail A B q qσ + let rk : ℝ := r0 * (2 : ℝ) ^ (k : ℝ) + let Rk : ℝ := r0 * (2 : ℝ) ^ ((k : ℝ) + 1) + have hrk_pos : 0 < rk := mul_pos hr0pos (Real.rpow_pos_of_pos (by norm_num) _) + have hrk0 : 0 ≤ rk := le_of_lt hrk_pos + have : Finite S := by + simpa [S, kfun] using (finite_divisorZeroIndex₀_dyadicShell + (f := f) hr0pos hr0 k).to_subtype + have : Fintype S := Fintype.ofFinite S + have hk_upper : ∀ p : S, ‖divisorZeroIndex₀Val p.1‖ ≤ Rk := by + intro p + have hk' : kfun p.1 = k := p.2 + simpa [Rk, kfun] using + divisorZeroIndex₀_dyadicShell_upper_bound (f := f) hr0pos hr0 hk' + have hk_lower : ∀ p : S, rk ≤ ‖divisorZeroIndex₀Val p.1‖ := by + intro p + have hk' : kfun p.1 = k := p.2 + simpa [rk, kfun] using + divisorZeroIndex₀_dyadicShell_lower_bound (f := f) hr0pos hr0 hk' + have htsum_le : + (∑' p : S, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) + ≤ (Fintype.card S : ℝ) * (rk⁻¹ ^ τ) := by + exact Real.tsum_inv_rpow_le_card_mul_of_lower_bound + (a := fun p : S => ‖divisorZeroIndex₀Val p.1‖) + hrk_pos hτpos (fun _ => norm_nonneg _) hk_lower + have hmass_le_growth : + divisorMassClosedBall₀ f Rk + ≤ (Cgrow * (1 + |2 * Rk|) ^ ρ + Ctrail) / (Real.log 2) := by + simpa [Ctrail, Rk] using + (divisorMassClosedBall₀_le_of_growth (f := f) (ρ := ρ) (C := Cgrow) hf hCgrow + (R := Rk) hk_ge_one) + have hcard_le_mass : + (Fintype.card S : ℝ) ≤ divisorMassClosedBall₀ f Rk := by + have hRk_pos : 0 < Rk := lt_of_lt_of_le (by norm_num) hk_ge_one + exact card_subtype_le_divisorMassClosedBall₀_of_norm_le (f := f) hf hRk_pos hk_upper + have htsum' : + (∑' p : S, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) + ≤ ((Cgrow * (1 + |2 * Rk|) ^ ρ + Ctrail) / (Real.log 2)) * (rk⁻¹ ^ τ) := by + have hcard_le_growth : + (Fintype.card S : ℝ) ≤ + (Cgrow * (1 + |2 * Rk|) ^ ρ + Ctrail) / (Real.log 2) := + le_trans hcard_le_mass hmass_le_growth + exact le_trans htsum_le <| + mul_le_mul_of_nonneg_right hcard_le_growth (Real.rpow_nonneg (inv_nonneg.2 hrk0) τ) + have hpow_bound : + (1 + |2 * Rk|) ^ ρ ≤ (1 + 4 * r0) ^ ρ * ((2 : ℝ) ^ ρ) ^ k := by + simpa [Rk] using + Real.one_add_abs_two_mul_dyadicRadius_rpow_le (r0 := r0) (ρ := ρ) k hr0pos hρ + have hlog2pos : 0 < Real.log 2 := Real.log_pos (by norm_num : (1 : ℝ) < 2) + simpa [A, B, q, qσ, rk, Ctrail, mul_assoc, mul_left_comm, mul_comm] using + Real.dyadic_growth_mass_mul_inv_le_geometric + (C := Cgrow) (L := Real.log 2) (M := (1 + 4 * r0) ^ ρ) + (X := (1 + |2 * Rk|) ^ ρ) + (T := ∑' p : S, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) + (Ctrail := Ctrail) (r0 := r0) (ρ := ρ) (τ := τ) (k := k) + hlog2pos hCgrow_pos.le hr0pos.le hpow_bound + (by simpa [rk] using htsum') + +theorem summable_norm_inv_rpow_divisorZeroIndex₀_of_growth {f : ℂ → ℂ} {ρ τ : ℝ} + (hρ : 0 ≤ ρ) (hτ : ρ < τ) (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + (hgrowth : ∃ C > 0, ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) := by + rcases hgrowth with ⟨Cgrow, hCgrow_pos, hCgrow⟩ + have hτpos : 0 < τ := lt_of_le_of_lt hρ hτ + rcases exists_r0_le_norm_divisorZeroIndex₀Val (f := f) hf hnot with ⟨r0, hr0pos, hr0⟩ + have hr0ne : (r0 : ℝ) ≠ 0 := ne_of_gt hr0pos + let kfun : divisorZeroIndex₀ f (Set.univ : Set ℂ) → ℕ := + fun p => ⌊Real.logb 2 (‖divisorZeroIndex₀Val p‖ / r0)⌋₊ + let S : ℕ → Set (divisorZeroIndex₀ f (Set.univ : Set ℂ)) := + fun k => {p | kfun p = k} + have hS : ∀ p : divisorZeroIndex₀ f (Set.univ : Set ℂ), ∃! k : ℕ, p ∈ S k := by + intro p + refine ⟨kfun p, ?_, ?_⟩ + · simp [S] + · intro k hk + simpa [S] using hk.symm + have hnonneg : 0 ≤ fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ := by + intro p + exact Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _ + have hSk_summable : ∀ k : ℕ, Summable fun p : S k => ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ := by + intro k + have : Finite (S k) := by + simpa [S, kfun] using (finite_divisorZeroIndex₀_dyadicShell + (f := f) hr0pos hr0 k).to_subtype + exact Summable.of_finite + have hshell_summable : + Summable fun k : ℕ => ∑' p : S k, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ := by + let q : ℝ := (2 : ℝ) ^ (ρ - τ) + let qσ : ℝ := (2 : ℝ) ^ (-τ) + have hq_nonneg : 0 ≤ q := le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) _) + have hq_lt_one : q < 1 := + Real.rpow_lt_one_of_one_lt_of_neg (x := (2 : ℝ)) (by norm_num : (1 : ℝ) < 2) + (sub_neg.2 hτ) + have hqσ_nonneg : 0 ≤ qσ := le_of_lt (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) _) + have hqσ_lt_one : qσ < 1 := + Real.rpow_lt_one_of_one_lt_of_neg (x := (2 : ℝ)) (by norm_num : (1 : ℝ) < 2) + (by simpa using (neg_neg_of_pos hτpos)) + have hgeom_q : Summable (fun k : ℕ => q ^ k) := + summable_geometric_of_lt_one hq_nonneg hq_lt_one + have hgeom_qσ : Summable (fun k : ℕ => qσ ^ k) := + summable_geometric_of_lt_one hqσ_nonneg hqσ_lt_one + let Ctrail : ℝ := |Real.log ‖meromorphicTrailingCoeffAt f 0‖| + let A : ℝ := ((Cgrow / Real.log 2) * (1 + 4 * r0) ^ ρ) * (r0⁻¹) ^ τ + let B : ℝ := ((Ctrail / Real.log 2) + 1) * (r0⁻¹) ^ τ + rcases Real.exists_nat_le_two_pow (1 / r0) with ⟨k0, hk0⟩ + let A0 : ℝ := A * q ^ k0 + let B0 : ℝ := B * qσ ^ k0 + have hmajor : Summable (fun k : ℕ => A0 * q ^ k + B0 * qσ ^ k) := + (hgeom_q.mul_left A0).add (hgeom_qσ.mul_left B0) + have hshell_summable_shift : + Summable fun k : ℕ => ∑' p : S (k + k0), ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ := by + refine hmajor.of_nonneg_of_le + (fun k => by + have : ∀ p : S (k + k0), 0 ≤ ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ := by + intro p; exact Real.rpow_nonneg (inv_nonneg.2 (norm_nonneg _)) _ + exact tsum_nonneg this) + (fun k => by + let kk : ℕ := k + k0 + let Rk : ℝ := r0 * (2 : ℝ) ^ ((kk : ℝ) + 1) + have hRk_ge_one : (1 : ℝ) ≤ Rk := by + have hkk : k0 ≤ kk + 1 := by + simp [kk, Nat.add_assoc, Nat.add_comm] + simpa [Rk] using + Real.one_le_dyadicRadius_succ_of_inv_le_two_pow hr0pos hk0 hkk + have hmain : + (∑' p : S kk, ‖divisorZeroIndex₀Val p.1‖⁻¹ ^ τ) ≤ A * q ^ kk + B * qσ ^ kk := by + simpa [S, kfun, Ctrail, A, B, q, qσ] using + tsum_divisorZeroIndex₀_dyadicShell_inv_rpow_le_geometric_of_growth + (f := f) (ρ := ρ) (τ := τ) hρ hτpos hf hCgrow_pos hCgrow hr0pos hr0 kk hRk_ge_one + have : A * q ^ kk + B * qσ ^ kk = A0 * q ^ k + B0 * qσ ^ k := by + simpa [A0, B0, kk] using Real.two_geometric_shift_add A B q qσ k k0 + simpa [kk] using (hmain.trans_eq this) + ) + exact (summable_nat_add_iff k0).1 hshell_summable_shift + have hpart := + (summable_partition (f := fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ τ) hnonneg (s := S) hS) + exact (hpart.2 ⟨hSk_summable, hshell_summable⟩) + +theorem summable_norm_inv_pow_divisorZeroIndex₀_of_growth {f : ℂ → ℂ} {ρ : ℝ} + (hρ : 0 ≤ ρ) (hf : Differentiable ℂ f) (hnot : ∃ z : ℂ, f z ≠ 0) + (hgrowth : ∃ C > 0, ∀ z : ℂ, Real.log (1 + ‖f z‖) ≤ C * (1 + ‖z‖) ^ ρ) : + Summable (fun p : divisorZeroIndex₀ f (Set.univ : Set ℂ) => + ‖divisorZeroIndex₀Val p‖⁻¹ ^ (Nat.floor ρ + 1)) := by + have hτ : ρ < (Nat.floor ρ + 1 : ℝ) := by + simpa [Nat.cast_add, Nat.cast_one] using (Nat.lt_floor_add_one (a := ρ)) + have hs := + summable_norm_inv_rpow_divisorZeroIndex₀_of_growth (f := f) (ρ := ρ) + (τ := (Nat.floor ρ + 1 : ℝ)) hρ hτ hf hnot hgrowth + exact hs.congr fun p => by + have hcast : ((Nat.floor ρ : ℝ) + 1) = ((Nat.floor ρ + 1 : ℕ) : ℝ) := by + norm_num + rw [hcast, Real.rpow_natCast] + +end Complex.Hadamard +end +end + +end SiegelZeros diff --git a/PrimeNumberTheoremAnd/SmoothExistence.lean b/PrimeNumberTheoremAnd/SmoothExistence.lean index b33edf8..2513738 100644 --- a/PrimeNumberTheoremAnd/SmoothExistence.lean +++ b/PrimeNumberTheoremAnd/SmoothExistence.lean @@ -1,20 +1,20 @@ -import Architect -import Batteries.Tactic.Lemma +/- +Adapted from PrimeNumberTheoremAnd by Alex Kontorovich and contributors. +Licensed under the Apache License, Version 2.0; see the upstream LICENSE. +This compatibility port retains the proven declarations used by this project. +-/ import Mathlib.Geometry.Manifold.PartitionOfUnity import Mathlib.Tactic.Bound -import PrimeNumberTheoremAnd.Mathlib.Algebra.Notation.Support - -set_option lang.lemmaCmd true open MeasureTheory Set Real open scoped ContDiff -lemma smooth_urysohn_support_Ioo {a b c d : ℝ} (h1 : a < b) (h3 : c < d) : +theorem smooth_urysohn_support_Ioo {a b c d : ℝ} (h1 : a < b) (h3 : c < d) : ∃ Ψ : ℝ → ℝ, (ContDiff ℝ ∞ Ψ) ∧ (HasCompactSupport Ψ) ∧ Set.indicator (Set.Icc b c) 1 ≤ Ψ ∧ Ψ ≤ Set.indicator (Set.Ioo a d) 1 ∧ (Function.support Ψ = Set.Ioo a d) := by - have := exists_contMDiff_zero_iff_one_iff_of_isClosed (n := ⊤) - (modelWithCornersSelf ℝ ℝ) (s := Set.Iic a ∪ Set.Ici d) (t := Set.Icc b c) + have := exists_contDiff_zero_iff_one_iff_of_isClosed (n := ⊤) + (s := Set.Iic a ∪ Set.Ici d) (t := Set.Icc b c) (IsClosed.union isClosed_Iic isClosed_Ici) isClosed_Icc (by simp_rw [Set.disjoint_union_left, Set.disjoint_iff, Set.subset_def, @@ -25,7 +25,7 @@ lemma smooth_urysohn_support_Ioo {a b c d : ℝ} (h1 : a < b) (h3 : c < d) : simp only [Set.mem_union, Set.mem_Iic, Set.mem_Ici, Set.mem_Icc] at * use Ψ simp only [range_subset_iff, mem_Icc] at hΨrange - refine ⟨ContMDiff.contDiff hΨSmooth, ?_, ?_, ?_, ?_⟩ + refine ⟨hΨSmooth, ?_, ?_, ?_, ?_⟩ · apply HasCompactSupport.of_support_subset_isCompact (K := Set.Icc a d) isCompact_Icc simp only [Function.support_subset_iff, ne_eq, mem_Icc, ← hΨ0, not_or] bound @@ -42,66 +42,3 @@ lemma smooth_urysohn_support_Ioo {a b c d : ℝ} (h1 : a < b) (h3 : c < d) : simpa [-not_and, mem_Ioo, not_and_or, not_lt] using hx · ext x simp only [Function.mem_support, ne_eq, mem_Ioo, ← hΨ0, not_or, not_le] - -blueprint_comment /-- -Let $\nu$ be a bumpfunction. --/ - -@[blueprint - (title := "SmoothExistence") - (statement := /-- - There exists a smooth (once differentiable would be enough), - nonnegative ``bumpfunction'' $\nu$, - supported in $[1/2,2]$ with total mass one: - $$ - \int_0^\infty \nu(x)\frac{dx}{x} = 1. - $$ - -/) - (proof := /-- Same idea as Urysohn-type argument. -/)] -lemma SmoothExistence : - ∃ (ν : ℝ → ℝ), (ContDiff ℝ ∞ ν) ∧ (∀ x, 0 ≤ ν x) ∧ - ν.support ⊆ Icc (1 / 2) 2 ∧ ∫ x in Ici 0, ν x / x = 1 := by - suffices h : ∃ (ν : ℝ → ℝ), (ContDiff ℝ ∞ ν) ∧ (∀ x, 0 ≤ ν x) ∧ - ν.support ⊆ Set.Icc (1 / 2) 2 ∧ 0 < ∫ x in Set.Ici 0, ν x / x by - obtain ⟨ν, hν, hνnonneg, hνsupp, hνpos⟩ := h - let c := (∫ x in Ici 0, ν x / x) - use fun y ↦ ν y / c - refine ⟨hν.div_const c, fun y ↦ div_nonneg (hνnonneg y) (le_of_lt hνpos), ?_, ?_⟩ - · rw [Function.support_div, Function.support_const (ne_of_lt hνpos).symm, inter_univ] - convert hνsupp - · simp only [div_right_comm _ c _, integral_div c, div_self <| ne_of_gt hνpos, c] - have := smooth_urysohn_support_Ioo (a := 1 / 2) (b := 1) (c := 3 / 2) (d := 2) - (by linarith) (by linarith) - obtain ⟨ν, hνContDiff, _, hν0, hν1, hνSupport⟩ := this - use ν, hνContDiff - unfold indicator at hν0 hν1 - simp only [mem_Icc, Pi.one_apply, Pi.le_def, mem_Ioo] at hν0 hν1 - simp only [hνSupport, subset_def, mem_Ioo, mem_Icc, and_imp] - split_ands - · exact fun x ↦ le_trans (by simp [apply_ite]) (hν0 x) - · exact fun y hy hy' ↦ ⟨by linarith, by linarith⟩ - · rw [integral_pos_iff_support_of_nonneg] - · simp only [Function.support_div, measurableSet_Ici, Measure.restrict_apply', - hνSupport, Function.support_id'] - have : (Ioo (1 / 2 : ℝ) 2 ∩ {0}ᶜ ∩ Ici 0) = Ioo (1 / 2) 2 := by - ext x - simp only [one_div, mem_inter_iff, mem_Ioo, mem_compl_iff, mem_singleton_iff, mem_Ici] - bound - simp only [this, volume_Ioo, ENNReal.ofReal_pos, sub_pos, gt_iff_lt] - linarith - · simp_rw [Pi.le_def, Pi.zero_apply] - intro y - by_cases h : y ∈ Function.support ν - · apply div_nonneg <| le_trans (by simp [apply_ite]) (hν0 y) - rw [hνSupport, mem_Ioo] at h - linarith [h.left] - · simp only [Function.mem_support, ne_eq, not_not] at h - simp [h] - · have : (fun x ↦ ν x / x).support ⊆ Icc (1 / 2) 2 := by - rw [Function.support_div, hνSupport] - exact (inter_subset_left).trans Ioo_subset_Icc_self - apply (integrableOn_iff_integrable_of_support_subset this).mp - apply ContinuousOn.integrableOn_compact isCompact_Icc - apply hνContDiff.continuous.continuousOn.div continuousOn_id ?_ - simp only [mem_Icc, ne_eq, and_imp, id_eq] - intros; linarith diff --git a/PrimeNumberTheoremAnd/Sobolev.lean b/PrimeNumberTheoremAnd/Sobolev.lean index 1f98bcb..c069633 100644 --- a/PrimeNumberTheoremAnd/Sobolev.lean +++ b/PrimeNumberTheoremAnd/Sobolev.lean @@ -1,4 +1,10 @@ +/- +Adapted from PrimeNumberTheoremAnd by Alex Kontorovich and contributors. +Licensed under the Apache License, Version 2.0; see the upstream LICENSE. +This compatibility port retains the proven declarations used by this project. +-/ import Mathlib.Analysis.Calculus.Deriv.Support +import Mathlib.Analysis.Calculus.IteratedDeriv.Lemmas import Mathlib.Analysis.Distribution.SchwartzSpace.Deriv import Mathlib.Order.Filter.ZeroAndBoundedAtFilter @@ -7,16 +13,26 @@ open scoped ContDiff variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {n : ℕ} -@[ext] structure CS (n : ℕ) (E : Type*) [NormedAddCommGroup E] [NormedSpace ℝ E] where +structure CS (n : ℕ) (E : Type*) [NormedAddCommGroup E] [NormedSpace ℝ E] where + toFun : ℝ → E h1 : ContDiff ℝ n toFun h2 : HasCompactSupport toFun +@[ext] protected theorem CS.ext {n : ℕ} {E : Type*} + [NormedAddCommGroup E] [NormedSpace ℝ E] {x y : CS n E} + (h : x.toFun = y.toFun) : x = y := by + cases x + cases y + cases h + rfl + structure trunc extends (CS 2 ℝ) where h3 : (Set.Icc (-1) (1)).indicator 1 ≤ toFun h4 : toFun ≤ Set.indicator (Set.Ioo (-2) (2)) 1 structure W1 (n : ℕ) (E : Type*) [NormedAddCommGroup E] [NormedSpace ℝ E] where + toFun : ℝ → E smooth : ContDiff ℝ n toFun integrable : ∀ ⦃k⦄, k ≤ n → Integrable (iteratedDeriv k toFun) @@ -27,14 +43,10 @@ section lemmas noncomputable def funscale {E : Type*} (g : ℝ → E) (R x : ℝ) : E := g (R⁻¹ • x) -lemma contDiff_ofReal : ContDiff ℝ ∞ ofReal := by - have key x : HasDerivAt ofReal 1 x := hasDerivAt_id x |>.ofReal_comp - have key' : deriv ofReal = fun _ => 1 := by ext x ; exact (key x).deriv - refine contDiff_infty_iff_deriv.mpr ⟨fun x => (key x).differentiableAt, ?_⟩ - simpa [key'] using contDiff_const +theorem contDiff_ofReal : ContDiff ℝ ∞ ofReal := Complex.ofRealCLM.contDiff omit [NormedSpace ℝ E] in -lemma tendsto_funscale {f : ℝ → E} (hf : ContinuousAt f 0) (x : ℝ) : +theorem tendsto_funscale {f : ℝ → E} (hf : ContinuousAt f 0) (x : ℝ) : Tendsto (fun R => funscale f R x) atTop (𝓝 (f 0)) := hf.tendsto.comp (by simpa using tendsto_inv_atTop_zero.mul_const x) @@ -52,31 +64,31 @@ instance : Coe (CS n ℝ) (CS n ℂ) where coe f := ⟨fun x => f x, def neg (f : CS n E) : CS n E where toFun := -f h1 := f.h1.neg - h2 := by simpa [HasCompactSupport, tsupport] using f.h2 + h2 := f.h2.neg instance : Neg (CS n E) where neg := neg -@[simp] lemma neg_apply {x : ℝ} : (-f) x = - (f x) := rfl +@[simp] theorem neg_apply {x : ℝ} : (-f) x = - (f x) := rfl def smul (R : ℝ) (f : CS n E) : CS n E := ⟨R • f, f.h1.const_smul R, f.h2.smul_left⟩ instance : HSMul ℝ (CS n E) (CS n E) where hSMul := smul -@[simp] lemma smul_apply : (R • f) x = R • f x := rfl +@[simp] theorem smul_apply : (R • f) x = R • f x := rfl -lemma continuous (f : CS n E) : Continuous f := f.h1.continuous +theorem continuous (f : CS n E) : Continuous f := f.h1.continuous noncomputable def deriv (f : CS (n + 1) E) : CS n E where toFun := _root_.deriv f h1 := (contDiff_succ_iff_deriv.mp f.h1).2.2 h2 := f.h2.deriv -lemma hasDerivAt (f : CS (n + 1) E) (x : ℝ) : HasDerivAt f (f.deriv x) x := +theorem hasDerivAt (f : CS (n + 1) E) (x : ℝ) : HasDerivAt f (f.deriv x) x := (f.h1.differentiable (by simp)).differentiableAt.hasDerivAt -lemma deriv_apply {f : CS (n + 1) E} {x : ℝ} : f.deriv x = _root_.deriv f x := rfl +theorem deriv_apply {f : CS (n + 1) E} {x : ℝ} : f.deriv x = _root_.deriv f x := rfl -lemma deriv_smul {f : CS (n + 1) E} : (R • f).deriv = R • f.deriv := by +theorem deriv_smul {f : CS (n + 1) E} : (R • f).deriv = R • f.deriv := by ext x ; exact (f.hasDerivAt x |>.const_smul R).deriv noncomputable def scale (g : CS n E) (R : ℝ) : CS n E := by @@ -86,27 +98,27 @@ noncomputable def scale (g : CS n E) (R : ℝ) : CS n E := by · exact g.h1.comp (contDiff_const_smul R⁻¹) · exact g.h2.comp_smul (inv_ne_zero h) -lemma deriv_scale {f : CS (n + 1) E} : (f.scale R).deriv = R⁻¹ • f.deriv.scale R := by +theorem deriv_scale {f : CS (n + 1) E} : (f.scale R).deriv = R⁻¹ • f.deriv.scale R := by ext v ; by_cases hR : R = 0 · simp [hR, scale, deriv] · simp only [scale, hR, ↓reduceDIte, smul_apply] exact ((f.hasDerivAt (R⁻¹ • v)).scomp v - (by simpa using! (hasDerivAt_id v).const_smul R⁻¹)).deriv + (by convert (hasDerivAt_const_mul (x := v) R⁻¹) using 1)).deriv -lemma deriv_scale' {f : CS (n + 1) E} : +theorem deriv_scale' {f : CS (n + 1) E} : (f.scale R).deriv v = R⁻¹ • f.deriv (R⁻¹ • v) := by rw [deriv_scale, smul_apply] by_cases hR : R = 0 <;> simp [hR, scale, funscale] -lemma hasDerivAt_scale (f : CS (n + 1) E) (R x : ℝ) : +theorem hasDerivAt_scale (f : CS (n + 1) E) (R x : ℝ) : HasDerivAt (f.scale R) (R⁻¹ • _root_.deriv f (R⁻¹ • x)) x := by convert hasDerivAt (f.scale R) x ; rw [deriv_scale'] ; rfl -lemma tendsto_scale (f : CS n E) (x : ℝ) : Tendsto (fun R => f.scale R x) atTop (𝓝 (f 0)) := by +theorem tendsto_scale (f : CS n E) (x : ℝ) : Tendsto (fun R => f.scale R x) atTop (𝓝 (f 0)) := by apply (tendsto_funscale f.continuous.continuousAt x).congr' filter_upwards [eventually_ne_atTop 0] with R hR ; simp [scale, hR] -lemma bounded : ∃ C, ∀ v, ‖f v‖ ≤ C := by +theorem bounded : ∃ C, ∀ v, ‖f v‖ ≤ C := by obtain ⟨x, hx⟩ := (continuous_norm.comp f.continuous).exists_forall_ge_of_hasCompactSupport f.h2.norm exact ⟨_, hx⟩ @@ -119,16 +131,16 @@ instance : CoeFun trunc (fun _ => ℝ → ℝ) where coe f := f.toFun instance : Coe trunc (CS 2 ℝ) where coe := trunc.toCS -lemma nonneg (g : trunc) (x : ℝ) : 0 ≤ g x := (Set.indicator_nonneg (by simp) x).trans (g.h3 x) +theorem nonneg (g : trunc) (x : ℝ) : 0 ≤ g x := (Set.indicator_nonneg (by simp) x).trans (g.h3 x) -lemma le_one (g : trunc) (x : ℝ) : g x ≤ 1 := +theorem le_one (g : trunc) (x : ℝ) : g x ≤ 1 := (g.h4 x).trans <| Set.indicator_le_self' (by simp) x -lemma zero (g : trunc) : g =ᶠ[𝓝 0] 1 := by +theorem zero (g : trunc) : g =ᶠ[𝓝 0] 1 := by have : Set.Icc (-1) 1 ∈ 𝓝 (0 : ℝ) := by apply Icc_mem_nhds <;> linarith exact eventually_of_mem this (fun x hx => le_antisymm (g.le_one x) (by simpa [hx] using g.h3 x)) -@[simp] lemma zero_at {g : trunc} : g 0 = 1 := g.zero.eq_of_nhds +@[simp] theorem zero_at {g : trunc} : g 0 = 1 := g.zero.eq_of_nhds end trunc @@ -136,23 +148,15 @@ namespace W1 instance : CoeFun (W1 n E) (fun _ => ℝ → E) where coe := W1.toFun -lemma continuous (f : W1 n E) : Continuous f := f.smooth.continuous +theorem continuous (f : W1 n E) : Continuous f := f.smooth.continuous -lemma differentiable (f : W1 (n + 1) E) : Differentiable ℝ f := +theorem differentiable (f : W1 (n + 1) E) : Differentiable ℝ f := f.smooth.differentiable (by simp) -lemma iteratedDeriv_sub {f g : ℝ → E} (hf : ContDiff ℝ n f) (hg : ContDiff ℝ n g) : +theorem iteratedDeriv_sub {f g : ℝ → E} (hf : ContDiff ℝ n f) (hg : ContDiff ℝ n g) : iteratedDeriv n (f - g) = iteratedDeriv n f - iteratedDeriv n g := by - induction n generalizing f g with - | zero => rfl - | succ n ih => - have hf' : ContDiff ℝ n (deriv f) := hf.iterate_deriv' n 1 - have hg' : ContDiff ℝ n (deriv g) := hg.iterate_deriv' n 1 - have hfg : deriv (f - g) = deriv f - deriv g := by - ext x ; apply deriv_sub - · exact (hf.differentiable (by simp)).differentiableAt - · exact (hg.differentiable (by simp)).differentiableAt - simp_rw [iteratedDeriv_succ', ← ih hf' hg', hfg] + funext x + exact _root_.iteratedDeriv_sub hf.contDiffAt hg.contDiffAt noncomputable def deriv (f : W1 (n + 1) E) : W1 n E where toFun := _root_.deriv f @@ -160,7 +164,7 @@ noncomputable def deriv (f : W1 (n + 1) E) : W1 n E where integrable k hk := by simpa [iteratedDeriv_succ'] using f.integrable (Nat.succ_le_succ hk) -lemma hasDerivAt (f : W1 (n + 1) E) (x : ℝ) : HasDerivAt f (f.deriv x) x := +theorem hasDerivAt (f : W1 (n + 1) E) (x : ℝ) : HasDerivAt f (f.deriv x) x := f.differentiable.differentiableAt.hasDerivAt def sub (f g : W1 n E) : W1 n E where @@ -173,12 +177,18 @@ def sub (f g : W1 n E) : W1 n E where instance : Sub (W1 n E) where sub := sub -lemma integrable_iteratedDeriv_Schwarz {f : 𝓢(ℝ, ℂ)} : Integrable (iteratedDeriv n f) := by +theorem integrable_iteratedDeriv_Schwarz {f : 𝓢(ℝ, ℂ)} : Integrable (iteratedDeriv n f) := by induction n generalizing f with | zero => exact f.integrable - | succ n ih => simpa [iteratedDeriv_succ'] using! ih (f := SchwartzMap.derivCLM ℝ ℂ f) - -noncomputable def of_Schwartz (f : 𝓢(ℝ, ℂ)) : W1 n ℂ where + | succ n ih => + rw [iteratedDeriv_succ'] + have hd : (SchwartzMap.derivCLM ℝ ℂ f : ℝ → ℂ) = _root_.deriv f := by + funext x + exact SchwartzMap.derivCLM_apply ℝ f x + rw [← hd] + exact ih (f := SchwartzMap.derivCLM ℝ ℂ f) + +noncomputable def ofSchwartz (f : 𝓢(ℝ, ℂ)) : W1 n ℂ where toFun := f smooth := f.smooth n integrable _ _ := integrable_iteratedDeriv_Schwarz @@ -192,20 +202,29 @@ variable {f : W21} noncomputable def norm (f : ℝ → ℂ) : ℝ := (∫ v, ‖f v‖) + (4 * π ^ 2)⁻¹ * (∫ v, ‖deriv (deriv f) v‖) -lemma norm_nonneg {f : ℝ → ℂ} : 0 ≤ norm f := +theorem norm_nonneg {f : ℝ → ℂ} : 0 ≤ norm f := add_nonneg (integral_nonneg (fun t => by simp)) (mul_nonneg (by positivity) (integral_nonneg (fun t => by simp))) noncomputable instance : Norm W21 where norm := norm ∘ W1.toFun -noncomputable instance : Coe 𝓢(ℝ, ℂ) W21 where coe := W1.of_Schwartz +noncomputable instance : Coe 𝓢(ℝ, ℂ) W21 where coe := W1.ofSchwartz def ofCS2 (f : CS 2 ℂ) : W21 := by - refine ⟨f, f.h1, fun k hk => ?_⟩ ; match k with - | 0 => exact f.h1.continuous.integrable_of_hasCompactSupport f.h2 - | 1 => simpa using (f.h1.continuous_deriv one_le_two).integrable_of_hasCompactSupport f.h2.deriv - | 2 => simpa [iteratedDeriv_succ] using - (f.h1.iterate_deriv' 0 2).continuous.integrable_of_hasCompactSupport f.h2.deriv.deriv + refine ⟨f, f.h1, ?_⟩ + intro k hk + cases k with + | zero => exact f.h1.continuous.integrable_of_hasCompactSupport f.h2 + | succ k => + cases k with + | zero => + simpa using (f.h1.continuous_deriv one_le_two).integrable_of_hasCompactSupport f.h2.deriv + | succ k => + have hk0 : k = 0 := + Nat.eq_zero_of_le_zero (Nat.le_of_succ_le_succ (Nat.le_of_succ_le_succ hk)) + subst k + simpa [iteratedDeriv_succ] using + (f.h1.iterate_deriv' 0 2).continuous.integrable_of_hasCompactSupport f.h2.deriv.deriv instance : Coe (CS 2 ℂ) W21 where coe := ofCS2 @@ -214,12 +233,12 @@ instance : HMul (CS 2 ℂ) W21 (CS 2 ℂ) where instance : HMul (CS 2 ℝ) W21 (CS 2 ℂ) where hMul g f := (g : CS 2 ℂ) * f -lemma hf (f : W21) : Integrable f := f.integrable zero_le_two +theorem hf (f : W21) : Integrable f := f.integrable zero_le_two -lemma hf' (f : W21) : Integrable (deriv f) := by +theorem hf' (f : W21) : Integrable (deriv f) := by simpa [iteratedDeriv_succ] using f.integrable one_le_two -lemma hf'' (f : W21) : Integrable (deriv (deriv f)) := by +theorem hf'' (f : W21) : Integrable (deriv (deriv f)) := by simpa [iteratedDeriv_succ] using f.integrable le_rfl end W21 @@ -227,7 +246,6 @@ end W21 theorem W21_approximation (f : W21) (g : trunc) : Tendsto (fun R => ‖f - (g.scale R * f : W21)‖) atTop (𝓝 0) := by - -- Definitions let f' := f.deriv let f'' := f'.deriv let g' := (g : CS 2 ℝ).deriv @@ -236,13 +254,12 @@ theorem W21_approximation (f : W21) (g : trunc) : let h' R := - (g.scale R).deriv let h'' R := - (g.scale R).deriv.deriv - -- Properties of h have ch {R} : Continuous (fun v => (h R v : ℂ)) := continuous_ofReal.comp <| continuous_const.sub (CS.continuous _) have ch' {R} : Continuous (fun v => (h' R v : ℂ)) := continuous_ofReal.comp (CS.continuous _) have ch'' {R} : Continuous (fun v => (h'' R v : ℂ)) := continuous_ofReal.comp (CS.continuous _) have dh R v : HasDerivAt (h R) (h' R v) v := by - convert! CS.hasDerivAt_scale (g : CS 2 ℝ) R v |>.const_sub 1 using 1 + convert CS.hasDerivAt_scale (g : CS 2 ℝ) R v |>.const_sub 1 using 1 simp [h', CS.deriv_scale', show g.deriv.toFun = deriv g.toFun from rfl] have dh' R v : HasDerivAt (h' R) (h'' R v) v := ((g.scale R).deriv.hasDerivAt v).neg have hh1 R v : |h R v| ≤ 1 := by @@ -254,12 +271,10 @@ theorem W21_approximation (f : W21) (g : trunc) : have vR v : Tendsto (fun R : ℝ => v * R⁻¹) atTop (𝓝 0) := by simpa using tendsto_inv_atTop_zero.const_mul v - -- Proof convert_to Tendsto (fun R => W21.norm (fun v => h R v * f v)) atTop (𝓝 0) · ext R ; change W21.norm _ = _ ; congr ; ext v ; simp [h, sub_mul] ; rfl rw [show (0 : ℝ) = 0 + ((4 * π ^ 2)⁻¹ : ℝ) * 0 by simp] refine Tendsto.add ?_ (Tendsto.const_mul _ ?_) - · let F R v := ‖h R v * f v‖ have eh v : ∀ᶠ R in atTop, h R v = 0 := by filter_upwards [(vR v).eventually g.zero, eventually_ne_atTop 0] with R hR hR' @@ -275,7 +290,6 @@ theorem W21_approximation (f : W21) (g : trunc) : apply Eventually.of_forall ; intro v apply tendsto_nhds_of_eventually_eq ; filter_upwards [eh v] with R hR ; simp [F, hR] simpa [F] using tendsto_integral_filter_of_dominated_convergence _ e1 e2 f.hf.norm e4 - · let F R v := ‖h'' R v * f v + 2 * h' R v * f' v + h R v * f'' v‖ convert_to Tendsto (fun R ↦ ∫ (v : ℝ), F R v) atTop (𝓝 0) · have this R v : @@ -291,9 +305,8 @@ theorem W21_approximation (f : W21) (g : trunc) : (dh R v).ofReal_comp.mul (df' v) have d1 : deriv (fun v => h R v * f v) = fun v => h' R v * f v + h R v * f' v := funext (fun v => (l3 v).deriv) - rw [d1] ; convert! (l5.add l7).deriv using 1 ; ring + rw [d1] ; convert (l5.add l7).deriv using 1 ; ring simp_rw [this, F] - obtain ⟨c1, mg'⟩ := g'.bounded obtain ⟨c2, mg''⟩ := g''.bounded let bound v := c2 * ‖f v‖ + 2 * c1 * ‖f' v‖ + ‖f'' v‖ @@ -338,8 +351,13 @@ theorem W21_approximation (f : W21) (g : trunc) : (((f.hf.norm).const_mul _).add ((f.hf'.norm).const_mul _)).add f.hf''.norm have e4 : ∀ᵐ (a : ℝ), Tendsto (fun n ↦ F n a) atTop (𝓝 0) := by apply Eventually.of_forall ; intro v - have evg' : g' =ᶠ[𝓝 0] 0 := by convert! ← g.zero.deriv ; exact deriv_const' _ - have evg'' : g'' =ᶠ[𝓝 0] 0 := by convert! ← evg'.deriv ; exact deriv_const' _ + have evg' : (g' : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 0) := by + have hzero : (g : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 1) := g.zero + change _root_.deriv (g : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 0) + simpa only [deriv_const'] using hzero.deriv + have evg'' : (g'' : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 0) := by + change _root_.deriv (g' : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 0) + simpa only [deriv_const'] using evg'.deriv refine tendsto_norm_zero.comp <| (ZeroAtFilter.add ?_ ?_).add ?_ · have eh'' v : ∀ᶠ R in atTop, h'' R v = 0 := by filter_upwards [(vR v).eventually evg'', eventually_ne_atTop 0] with R hR hR' @@ -355,5 +373,6 @@ theorem W21_approximation (f : W21) (g : trunc) : simp [h', CS.deriv_scale', mul_comm R⁻¹, hR] apply tendsto_nhds_of_eventually_eq filter_upwards [eh' v] with R hR ; simp [hR] - · simpa [h] using! ((g.tendsto_scale v).const_sub 1).ofReal.mul tendsto_const_nhds + · simpa [h, Filter.ZeroAtFilter] using + ((g.tendsto_scale v).const_sub 1).ofReal.mul tendsto_const_nhds simpa [F] using tendsto_integral_filter_of_dominated_convergence bound e1 e2 e3 e4 diff --git a/PrimeNumberTheoremAnd/Wiener.lean b/PrimeNumberTheoremAnd/Wiener.lean index 59fd506..d69b893 100644 --- a/PrimeNumberTheoremAnd/Wiener.lean +++ b/PrimeNumberTheoremAnd/Wiener.lean @@ -1,22 +1,18 @@ -import Architect +/- +Adapted from PrimeNumberTheoremAnd by Alex Kontorovich and contributors. +Licensed under the Apache License, Version 2.0; see the upstream LICENSE. +This compatibility port retains the proven declarations used by this project. +-/ import Mathlib.Analysis.Fourier.RiemannLebesgueLemma import Mathlib.Analysis.Normed.Group.Tannery import Mathlib.Analysis.SumIntegralComparisons import Mathlib.NumberTheory.Chebyshev import Mathlib.NumberTheory.LSeries.PrimesInAP import Mathlib.NumberTheory.MulChar.Lemmas -import Mathlib.Topology.EMetricSpace.BoundedVariation -import PrimeNumberTheoremAnd.Mathlib.Analysis.Asymptotics.Asymptotics import PrimeNumberTheoremAnd.Fourier import PrimeNumberTheoremAnd.SmoothExistence import Mathlib.Analysis.Convolution - -set_option lang.lemmaCmd true -set_option linter.style.header false - --- note: the opening of ArithmeticFunction introduces a notation σ that seems --- impossible to hide, and hence parameters that are traditionally called σ will --- have to be called σ' instead in this file. +import Mathlib.MeasureTheory.Group.Circle open Real BigOperators ArithmeticFunction MeasureTheory Filter Set FourierTransform LSeries Asymptotics SchwartzMap @@ -28,31 +24,17 @@ open scoped ComplexConjugate variable {n : ℕ} {A a b c d u x y t σ' : ℝ} {ψ Ψ : ℝ → ℂ} {F G : ℂ → ℂ} {f : ℕ → ℂ} {𝕜 : Type} [RCLike 𝕜] -blueprint_comment /-- -The Fourier transform of an absolutely integrable function $\psi: \R \to \C$ is defined by the -formula $$ \hat \psi(u) := \int_\R e(-tu) \psi(t)\ dt$$ where $e(\theta) := e^{2\pi i \theta}$. - -Let $f: \N \to \C$ be an arithmetic function such that $\sum_{n=1}^\infty \frac{|f(n)|}{n^\sigma} < -\infty$ for all $\sigma>1$. Then the Dirichlet series -$$ F(s) := \sum_{n=1}^\infty \frac{f(n)}{n^s}$$ -is absolutely convergent for $\sigma>1$. --/ - noncomputable def nterm (f : ℕ → ℂ) (σ' : ℝ) (n : ℕ) : ℝ := if n = 0 then 0 else ‖f n‖ / n ^ σ' -lemma nterm_eq_norm_term {f : ℕ → ℂ} : nterm f σ' n = ‖term f σ' n‖ := by +theorem nterm_eq_norm_term {f : ℕ → ℂ} : nterm f σ' n = ‖term f σ' n‖ := by by_cases h : n = 0 <;> simp [nterm, term, h] theorem norm_term_eq_nterm_re (s : ℂ) : ‖term f s n‖ = nterm f (s.re) n := by - simp only [nterm, term, apply_ite (‖·‖), norm_zero, norm_div] - apply ite_congr rfl (fun _ ↦ rfl) - intro h - congr - refine norm_natCast_cpow_of_pos (by omega) s + simpa only [nterm] using LSeries.norm_term_eq f s n -lemma hf_coe1 (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hσ : 1 < σ') : +theorem hf_coe1 (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hσ : 1 < σ') : ∑' i, (‖term f σ' i‖₊ : ENNReal) ≠ ⊤ := by simp_rw [ENNReal.tsum_coe_ne_top_iff_summable_coe, ← norm_toNNReal] norm_cast @@ -60,25 +42,19 @@ lemma hf_coe1 (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hσ : convert hf σ' hσ with i simp [nterm_eq_norm_term] -instance instMeasurableSpace : MeasurableSpace Circle := - inferInstanceAs <| MeasurableSpace <| Subtype _ -instance instBorelSpace : BorelSpace Circle := - inferInstanceAs <| BorelSpace <| Subtype (· ∈ Metric.sphere (0 : ℂ) 1) - --- TODO - add to mathlib attribute [fun_prop] Real.continuous_fourierChar -lemma first_fourier_aux1 (hψ : AEMeasurable ψ) {x : ℝ} (n : ℕ) : AEMeasurable fun (u : ℝ) ↦ +theorem first_fourier_aux1 (hψ : AEMeasurable ψ) {x : ℝ} (n : ℕ) : AEMeasurable fun (u : ℝ) ↦ (‖fourierChar (-(u * ((1 : ℝ) / ((2 : ℝ) * π) * (n / x).log))) • ψ u‖ₑ : ENNReal) := by fun_prop -lemma first_fourier_aux2a : +theorem first_fourier_aux2a : (2 : ℂ) * π * -(y * (1 / (2 * π) * Real.log ((n) / x))) = -(y * ((n) / x).log) := by calc _ = -(y * (((2 : ℂ) * π) / (2 * π) * Real.log ((n) / x))) := by ring _ = _ := by rw [div_self (by norm_num), one_mul] -lemma first_fourier_aux2 (hx : 0 < x) (n : ℕ) : +theorem first_fourier_aux2 (hx : 0 < x) (n : ℕ) : term f σ' n * 𝐞 (-(y * (1 / (2 * π) * Real.log (n / x)))) • ψ y = term f (σ' + y * I) n • (ψ y * x ^ (y * I)) := by by_cases hn : n = 0 @@ -106,31 +82,10 @@ lemma first_fourier_aux2 (hx : 0 < x) (n : ℕ) : ring _ = _ := by simp ; group -set_option backward.isDefEq.respectTransparency false in -@[blueprint "first-fourier" - (title := "first-fourier") - (statement := /-- - If $\psi: \R \to \C$ is integrable and $x > 0$, then for any $\sigma>1$ - $$ \sum_{n=1}^\infty \frac{f(n)}{n^\sigma} \hat \psi( \frac{1}{2\pi} \log \frac{n}{x} ) = - \int_\R F(\sigma + it) \psi(t) x^{it}\ dt.$$ - -/) - (proof := /-- - By the definition of the Fourier transform, the left-hand side expands as - $$ \sum_{n=1}^\infty \int_\R \frac{f(n)}{n^\sigma} \psi(t) e( - \frac{1}{2\pi} t \log - \frac{n}{x})\ dt$$ - while the right-hand side expands as - $$ \int_\R \sum_{n=1}^\infty \frac{f(n)}{n^{\sigma+it}} \psi(t) x^{it}\ dt.$$ - Since - $$\frac{f(n)}{n^\sigma} \psi(t) e( - \frac{1}{2\pi} t \log \frac{n}{x}) = - \frac{f(n)}{n^{\sigma+it}} \psi(t) x^{it}$$ - the claim then follows from Fubini's theorem. - -/) - (latexEnv := "lemma")] -lemma first_fourier (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) +theorem first_fourier (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hsupp : Integrable ψ) (hx : 0 < x) (hσ : 1 < σ') : ∑' n : ℕ, term f σ' n * (𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))) = ∫ t : ℝ, LSeries f (σ' + t * I) * ψ t * x ^ (t * I) := by - calc _ = ∑' n, term f σ' n * ∫ (v : ℝ), 𝐞 (-(v * ((1 : ℝ) / ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by @@ -162,14 +117,12 @@ lemma first_fourier (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) rw [norm_term_eq_nterm_re] simp - - @[continuity] -lemma continuous_multiplicative_ofAdd : Continuous (⇑Multiplicative.ofAdd : ℝ → ℝ) := ⟨fun _ ↦ id⟩ +theorem continuous_multiplicative_ofAdd : Continuous (⇑Multiplicative.ofAdd : ℝ → ℝ) := ⟨fun _ ↦ id⟩ attribute [fun_prop] measurable_coe_nnreal_ennreal -lemma second_fourier_integrable_aux1a (hσ : 1 < σ') : +theorem second_fourier_integrable_aux1a (hσ : 1 < σ') : IntegrableOn (fun (x : ℝ) ↦ cexp (-((x : ℂ) * ((σ' : ℂ) - 1)))) (Ici (-Real.log x)) := by norm_cast suffices IntegrableOn (fun (x : ℝ) ↦ (rexp (-(x * (σ' - 1))))) (Ici (-x.log)) _ from this.ofReal @@ -178,18 +131,16 @@ lemma second_fourier_integrable_aux1a (hσ : 1 < σ') : apply exp_neg_integrableOn_Ioi linarith -lemma second_fourier_integrable_aux1 (hcont : Measurable ψ) (hsupp : Integrable ψ) (hσ : 1 < σ') : +theorem second_fourier_integrable_aux1 (hcont : Measurable ψ) (hsupp : Integrable ψ) (hσ : 1 < σ') : let ν : Measure (ℝ × ℝ) := (volume.restrict (Ici (-Real.log x))).prod volume Integrable (Function.uncurry fun (u : ℝ) (a : ℝ) ↦ ((rexp (-u * (σ' - 1))) : ℂ) • (𝐞 (Multiplicative.ofAdd (-(a * (u / (2 * π))))) : ℂ) • ψ a) ν := by intro ν constructor · apply Measurable.aestronglyMeasurable - -- `Multiplicative.ofAdd x` is definitionally `x`; unfold it by `change` since `fun_prop` - -- does not see through it. - change Measurable (Function.uncurry fun (u : ℝ) (a : ℝ) ↦ ((rexp (-u * (σ' - 1))) : ℂ) • - (𝐞 (-(a * (u / (2 * π)))) : ℂ) • ψ a) - simp only [neg_mul, ofReal_exp, ofReal_neg, ofReal_mul, ofReal_sub, ofReal_one, smul_eq_mul] + change Measurable (fun p : ℝ × ℝ => + (rexp (-p.1 * (σ' - 1)) : ℂ) * + ((fourierChar (-(p.2 * (p.1 / (2 * π)))) : ℂ) * ψ p.2)) fun_prop · let f1 : ℝ → ENNReal := fun a1 ↦ ‖cexp (-(↑a1 * (↑σ' - 1)))‖ₑ let f2 : ℝ → ENNReal := fun a2 ↦ ‖ψ a2‖ₑ @@ -198,14 +149,14 @@ lemma second_fourier_integrable_aux1 (hcont : Measurable ψ) (hsupp : Integrable refine (lintegral_prod_mul ?_ ?_).trans_lt ?_ <;> try fun_prop exact ENNReal.mul_lt_top (second_fourier_integrable_aux1a hσ).2 hsupp.2 -lemma second_fourier_integrable_aux2 (hσ : 1 < σ') : +theorem second_fourier_integrable_aux2 (hσ : 1 < σ') : IntegrableOn (fun (u : ℝ) ↦ cexp ((1 - ↑σ' - ↑t * I) * ↑u)) (Ioi (-Real.log x)) := by refine (integrable_norm_iff (Measurable.aestronglyMeasurable <| by fun_prop)).mp ?_ suffices IntegrableOn (fun a ↦ rexp (-(σ' - 1) * a)) (Ioi (-x.log)) _ by simpa [Complex.norm_exp] apply exp_neg_integrableOn_Ioi linarith -lemma second_fourier_aux (hx : 0 < x) : +theorem second_fourier_aux (hx : 0 < x) : -(cexp (-((1 - ↑σ' - ↑t * I) * ↑(Real.log x))) / (1 - ↑σ' - ↑t * I)) = ↑(x ^ (σ' - 1)) * (↑σ' + ↑t * I - 1)⁻¹ * ↑x ^ (↑t * I) := by calc @@ -217,51 +168,24 @@ lemma second_fourier_aux (hx : 0 < x) : rw [Complex.cpow_add _ _ (ofReal_ne_zero.mpr (ne_of_gt hx))] _ = _ := by rw [ofReal_cpow hx.le]; push_cast; ring -set_option backward.isDefEq.respectTransparency false in -@[blueprint "second-fourier" - (title := "second-fourier") - (statement := /-- - If $\psi: \R \to \C$ is absolutely integrable and $x > 0$, then for any $\sigma>1$ - $$ \int_{-\log x}^\infty e^{-u(\sigma-1)} \hat \psi(\frac{u}{2\pi})\ du = - x^{\sigma - 1} \int_\R \frac{1}{\sigma+it-1} \psi(t) x^{it}\ dt.$$ - -/) - (proof := /-- - The left-hand side expands as - $$ \int_{-\log x}^\infty \int_\R e^{-u(\sigma-1)} \psi(t) e(-\frac{tu}{2\pi})\ dt\ du$$ - so by Fubini's theorem it suffices to verify the identity - \begin{align*} - \int_{-\log x}^\infty e^{-u(\sigma-1)} e(-\frac{tu}{2\pi})\ du - &= \int_{-\log x}^\infty e^{(it - \sigma + 1)u}\ du \\ - &= \frac{1}{it - \sigma + 1} e^{(it - \sigma + 1)u}\ \Big|_{-\log x}^\infty \\ - &= x^{\sigma - 1} \frac{1}{\sigma+it-1} x^{it} - \end{align*} - -/) - (latexEnv := "lemma")] -lemma second_fourier (hcont : Measurable ψ) (hsupp : Integrable ψ) +theorem second_fourier (hcont : Measurable ψ) (hsupp : Integrable ψ) {x σ' : ℝ} (hx : 0 < x) (hσ : 1 < σ') : ∫ u in Ici (-log x), Real.exp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = (x^(σ' - 1) : ℝ) * ∫ t, (1 / (σ' + t * I - 1)) * ψ t * x^(t * I) ∂ volume := by - conv in ↑(rexp _) * _ => { rw [Real.fourier_real_eq, ← smul_eq_mul, ← integral_smul] } rw [MeasureTheory.integral_integral_swap] swap · exact second_fourier_integrable_aux1 hcont hsupp hσ rw [← integral_const_mul] congr 1; ext t - dsimp [Real.fourierChar, Circle.exp] - - simp_rw [mul_smul_comm, ← smul_mul_assoc, integral_mul_const] - rw [fun (a b d : ℂ) ↦ show a * (b * (ψ t) * d) = (a * b * d) * ψ t by ring] + simp_rw [Circle.smul_def, smul_eq_mul, Real.fourierChar_apply, + ← mul_assoc, integral_mul_const] + rw [mul_right_comm _ (ψ t) _] congr 1 - conv => - lhs - enter [2] - ext a - rw [AddChar.coe_mk, Submonoid.mk_smul, smul_eq_mul] push_cast simp_rw [← Complex.exp_add] have (u : ℝ) : - 2 * ↑π * -(↑t * (↑u / (2 * ↑π))) * I + -↑u * (↑σ' - 1) = (1 - σ' - t * I) * u := calc + -↑u * (↑σ' - 1) + 2 * ↑π * -(↑t * (↑u / (2 * ↑π))) * I = (1 - σ' - t * I) * u := calc _ = -↑u * (↑σ' - 1) + (2 * ↑π) / (2 * ↑π) * -(↑t * ↑u) * I := by ring _ = -↑u * (↑σ' - 1) + 1 * -(↑t * ↑u) * I := by rw [div_self (by norm_num)] _ = _ := by ring @@ -285,107 +209,12 @@ lemma second_fourier (hcont : Measurable ψ) (hsupp : Integrable ψ) integral_Ioi_of_hasDerivAt_of_tendsto' hderiv (second_fourier_integrable_aux2 hσ) hf] simpa [f, f'] using second_fourier_aux hx -blueprint_comment /-- -Now let $A \in \C$, and suppose that there is a continuous function $G(s)$ defined on -$\mathrm{Re} s \geq 1$ such that $G(s) = F(s) - \frac{A}{s-1}$ whenever $\mathrm{Re} s > 1$. -We also make the Chebyshev-type hypothesis -\begin{equation}\label{cheby} -\sum_{n \leq x} |f(n)| \ll x -\end{equation} -for all $x \geq 1$ (this hypothesis is not strictly necessary, but simplifies the arguments and -can be obtained fairly easily in applications). --/ +theorem one_add_sq_pos (u : ℝ) : 0 < 1 + u ^ 2 := zero_lt_one.trans_le (by simpa using sq_nonneg u) -lemma one_add_sq_pos (u : ℝ) : 0 < 1 + u ^ 2 := zero_lt_one.trans_le (by simpa using sq_nonneg u) - -@[blueprint "prelim-decay" - (title := "Preliminary decay bound I") - (statement := /-- - If $\psi:\R \to \C$ is absolutely integrable then $$ |\hat \psi(u)| \leq \| \psi \|_1 $$ - for all $u \in \R$. where $C$ is an absolute constant. - -/) - (proof := /-- Immediate from the triangle inequality. -/) - (latexEnv := "lemma") - (discussion := 561)] theorem prelim_decay (ψ : ℝ → ℂ) (u : ℝ) : ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ ∫ t, ‖ψ t‖ := VectorFourier.norm_fourierIntegral_le_integral_norm .. -@[blueprint "prelim-decay-2" - (title := "Preliminary decay bound II") - (statement := /-- -If $\psi:\R \to \C$ is absolutely integrable and of bounded variation, then -$$ |\hat \psi(u)| \leq \| \psi \|_{TV} / 2\pi |u| $$ -for all non-zero $u \in \R$. - -/) - (proof := /-- By Lebesgue--Stiejtes integration by parts we have -$$ 2\pi i u \hat \psi(u) = \int _\R e(-tu) d\psi(t)$$ -and the claim then follows from the triangle inequality. -/) - (latexEnv := "lemma") - (discussion := 562)] -theorem prelim_decay_2 (ψ : ℝ → ℂ) (hψ : Integrable ψ) (hvar : BoundedVariationOn ψ Set.univ) - (u : ℝ) (hu : u ≠ 0) : - ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ (eVariationOn ψ Set.univ).toReal / (2 * π * ‖u‖) := by sorry - -noncomputable def AbsolutelyContinuous (f : ℝ → ℂ) : Prop := (∀ᵐ x, DifferentiableAt ℝ f x) ∧ - ∀ a b : ℝ, f b - f a = ∫ t in a..b, deriv f t - -@[blueprint "prelim-decay-3" - (title := "Preliminary decay bound III") - (statement := /-- -If $\psi:\R \to \C$ is absolutely integrable, absolutely continuous, and $\psi'$ is of bounded -variation, then -$$ |\hat \psi(u)| \leq \| \psi' \|_{TV} / (2\pi |u|)^2$$ -for all non-zero $u \in \R$. - -/) - (proof := /-- Should follow from previous lemma. -/) - (proofUses := ["prelim-decay-2"]) - (latexEnv := "lemma") - (discussion := 563)] -theorem prelim_decay_3 (ψ : ℝ → ℂ) (hψ : Integrable ψ) - (habscont : AbsolutelyContinuous ψ) - (hvar : BoundedVariationOn (deriv ψ) Set.univ) (u : ℝ) (hu : u ≠ 0) : - ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ (eVariationOn (deriv ψ) Set.univ).toReal / (2 * π * ‖u‖) ^ 2 := by sorry - -@[blueprint "decay-alt" - (title := "Decay bound, alternate form") - (statement := /-- -If $\psi:\R \to \C$ is absolutely -integrable, absolutely continuous, and $\psi'$ is of bounded variation, then -$$ |\hat \psi(u)| \leq ( \|\psi\|_1 + \| \psi' \|_{TV} / (2\pi)^2) / (1+|u|^2)$$ -for all $u \in \R$. -/) - (proof := /-- Should follow from previous lemmas. -/) - (proofUses := ["prelim-decay", "prelim-decay-3", "decay"]) - (latexEnv := "lemma") - (discussion := 564)] -theorem decay_alt (ψ : ℝ → ℂ) (hψ : Integrable ψ) (habscont : AbsolutelyContinuous ψ) - (hvar : BoundedVariationOn (deriv ψ) Set.univ) (u : ℝ) : - ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ - ((∫ t, ‖ψ t‖) + (eVariationOn (deriv ψ) Set.univ).toReal / (2 * π) ^ 2) / - (1 + ‖u‖ ^ 2) := by - rw [le_div_iff₀' <| one_add_sq_pos ‖u‖] - by_cases hu : u = 0 - · subst hu - simp only [norm_zero, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, zero_pow, add_zero, - one_mul] - calc ‖𝓕 ψ 0‖ ≤ ∫ t, ‖ψ t‖ := prelim_decay ψ 0 - _ ≤ (∫ t, ‖ψ t‖) + (eVariationOn (deriv ψ) Set.univ).toReal / (2 * π) ^ 2 := by - have : 0 ≤ (eVariationOn (deriv ψ) Set.univ).toReal / (2 * π) ^ 2 := by positivity - linarith - · have bound1 : ‖𝓕 ψ u‖ ≤ ∫ t, ‖ψ t‖ := prelim_decay ψ u - have bound2 : ‖𝓕 ψ u‖ ≤ (eVariationOn (deriv ψ) Set.univ).toReal / (2 * π * ‖u‖) ^ 2 := - prelim_decay_3 ψ hψ habscont hvar u hu - have : (2 * π * ‖u‖) ^ 2 = (2 * π) ^ 2 * ‖u‖ ^ 2 := by ring - calc (1 + ‖u‖ ^ 2) * ‖𝓕 ψ u‖ - = ‖𝓕 ψ u‖ * 1 + ‖𝓕 ψ u‖ * ‖u‖ ^ 2 := by ring - _ ≤ (∫ t, ‖ψ t‖) * 1 + - (eVariationOn (deriv ψ) Set.univ).toReal / (2 * π * ‖u‖) ^ 2 * ‖u‖ ^ 2 := by - gcongr - _ = (∫ t, ‖ψ t‖) + (eVariationOn (deriv ψ) Set.univ).toReal / (2 * π) ^ 2 := by - rw [mul_one, this, div_mul_eq_div_div] - congr 1 - rw [div_mul_eq_mul_div, div_eq_iff (pow_ne_zero 2 <| norm_ne_zero_iff.mpr hu)] - -lemma decay_bounds_key (f : W21) (u : ℝ) : ‖𝓕 (f : ℝ → ℂ) u‖ ≤ ‖f‖ * (1 + u ^ 2)⁻¹ := by +theorem decay_bounds_key (f : W21) (u : ℝ) : ‖𝓕 (f : ℝ → ℂ) u‖ ≤ ‖f‖ * (1 + u ^ 2)⁻¹ := by have l1 : 0 < 1 + u ^ 2 := one_add_sq_pos _ have l2 : 1 + u ^ 2 = ‖(1 : ℂ) + u ^ 2‖ := by norm_cast ; simp only [Real.norm_eq_abs, abs_eq_self.2 l1.le] @@ -399,7 +228,7 @@ lemma decay_bounds_key (f : W21) (u : ℝ) : ‖𝓕 (f : ℝ → ℂ) u‖ ≤ rw [norm_neg, F_mul, norm_mul, W21.norm] gcongr <;> apply VectorFourier.norm_fourierIntegral_le_integral_norm -lemma decay_bounds_aux {f : ℝ → ℂ} (hf : AEStronglyMeasurable f volume) +theorem decay_bounds_aux {f : ℝ → ℂ} (hf : AEStronglyMeasurable f volume) (h : ∀ t, ‖f t‖ ≤ A * (1 + t ^ 2)⁻¹) : ∫ t, ‖f t‖ ≤ π * A := by have l1 : Integrable (fun x ↦ A * (1 + x ^ 2)⁻¹) := integrable_inv_one_add_sq.const_mul A @@ -420,29 +249,12 @@ theorem decay_bounds_W21 (f : W21) (hA : ∀ t, ‖f t‖ ≤ A / (1 + t ^ 2)) change W21.norm _ * _ ≤ _ simp_rw [W21.norm, div_eq_mul_inv, add_mul, l0] ; gcongr -@[blueprint - "decay" - (title := "Decay bounds") - (statement := /-- - If $\psi:\R \to \C$ is $C^2$ and obeys the bounds - $$ |\psi(t)|, |\psi''(t)| \leq A / (1 + |t|^2)$$ - for all $t \in \R$, then - $$ |\hat \psi(u)| \leq C A / (1+|u|^2)$$ - for all $u \in \R$, where $C$ is an absolute constant. - -/) - (proof := /-- - From two integration by parts we obtain the identity - $$ (1+u^2) \hat \psi(u) = \int_{\bf R} (\psi(t) - \frac{u}{4\pi^2} \psi''(t)) e(-tu)\ dt.$$ - Now apply the triangle inequality and the identity $\int_{\bf R} \frac{dt}{1+t^2}\ dt = \pi$ to - obtain the claim with $C = \pi + 1 / 4 \pi$. - -/) - (latexEnv := "lemma")] -lemma decay_bounds (ψ : CS 2 ℂ) (hA : ∀ t, ‖ψ t‖ ≤ A / (1 + t ^ 2)) +theorem decay_bounds (ψ : CS 2 ℂ) (hA : ∀ t, ‖ψ t‖ ≤ A / (1 + t ^ 2)) (hA' : ∀ t, ‖deriv^[2] ψ t‖ ≤ A / (1 + t ^ 2)) : ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ (π + 1 / (4 * π)) * A / (1 + u ^ 2) := by exact decay_bounds_W21 ψ hA hA' u -lemma decay_bounds_cor_aux (ψ : CS 2 ℂ) : ∃ C : ℝ, ∀ u, ‖ψ u‖ ≤ C / (1 + u ^ 2) := by +theorem decay_bounds_cor_aux (ψ : CS 2 ℂ) : ∃ C : ℝ, ∀ u, ‖ψ u‖ ≤ C / (1 + u ^ 2) := by have l1 : HasCompactSupport (fun u : ℝ => ((1 + u ^ 2) : ℝ) * ψ u) := by exact ψ.h2.mul_left have := ψ.h1.continuous obtain ⟨C, hC⟩ := l1.exists_bound_of_continuous (by fun_prop) @@ -451,48 +263,37 @@ lemma decay_bounds_cor_aux (ψ : CS 2 ℂ) : ∃ C : ℝ, ∀ u, ‖ψ u‖ ≤ simp only [norm_mul, Complex.norm_real, norm_of_nonneg (one_add_sq_pos u).le] at hC rwa [le_div_iff₀' (one_add_sq_pos _)] -lemma decay_bounds_cor (ψ : W21) : +theorem decay_bounds_cor (ψ : W21) : ∃ C : ℝ, ∀ u, ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ C / (1 + u ^ 2) := by simpa only [div_eq_mul_inv] using ⟨_, decay_bounds_key ψ⟩ -set_option backward.isDefEq.respectTransparency false in -@[continuity, fun_prop] lemma continuous_FourierIntegral (ψ : W21) : Continuous (𝓕 (ψ : ℝ → ℂ)) := +@[continuity, fun_prop] theorem continuous_FourierIntegral (ψ : W21) : Continuous (𝓕 (ψ : ℝ → ℂ)) := VectorFourier.fourierIntegral_continuous continuous_fourierChar (by simp only [innerₗ_apply_apply, RCLike.inner_apply', conj_trivial, continuous_mul]) ψ.hf -lemma W21.integrable_fourier (ψ : W21) (hc : c ≠ 0) : +theorem W21.integrable_fourier (ψ : W21) (hc : c ≠ 0) : Integrable fun u ↦ 𝓕 (ψ : ℝ → ℂ) (u / c) := by have l1 (C) : Integrable (fun u ↦ C / (1 + (u / c) ^ 2)) volume := by - simpa using! (integrable_inv_one_add_sq.comp_div hc).const_mul C + simpa only [div_eq_mul_inv] using (integrable_inv_one_add_sq.comp_div hc).const_mul C have l2 : AEStronglyMeasurable (fun u ↦ 𝓕 (ψ : ℝ → ℂ) (u / c)) volume := by apply Continuous.aestronglyMeasurable ; fun_prop obtain ⟨C, h⟩ := decay_bounds_cor ψ apply @Integrable.mono' ℝ ℂ _ volume _ _ (fun u => C / (1 + (u / c) ^ 2)) (l1 C) l2 ?_ apply Eventually.of_forall (fun x => h _) - - - - -lemma continuous_LSeries_aux (hf : Summable (nterm f σ')) : +theorem continuous_LSeries_aux (hf : Summable (nterm f σ')) : Continuous fun x : ℝ => LSeries f (σ' + x * I) := by - have l1 i : Continuous fun x : ℝ ↦ term f (σ' + x * I) i := by by_cases h : i = 0 · simpa [h] using continuous_const - · simpa [h] using! continuous_const.div (continuous_const.cpow (by fun_prop) (by simp [h])) + · simpa [h] using continuous_const.div₀ (continuous_const.cpow (by fun_prop) (by simp [h])) (fun x => by simp [h]) have l2 n (x : ℝ) : ‖term f (σ' + x * I) n‖ = nterm f σ' n := by - by_cases h : n = 0 - · simp [h, nterm] - · simp [h, nterm, cpow_add _ _ (Nat.cast_ne_zero.mpr h), - Complex.norm_natCast_cpow_of_pos (Nat.pos_of_ne_zero h)] + simpa using norm_term_eq_nterm_re (f := f) (n := n) (σ' + x * I) exact continuous_tsum l1 hf (fun n x => le_of_eq (l2 n x)) --- Here compact support is used but perhaps it is not necessary -set_option backward.isDefEq.respectTransparency false in -lemma limiting_fourier_aux (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) +theorem limiting_fourier_aux (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 1 ≤ x) (σ' : ℝ) (hσ' : 1 < σ') : ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - @@ -519,7 +320,6 @@ lemma limiting_fourier_aux (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1 (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by apply l7.integrable_of_hasCompactSupport exact ψ.h2.mul_left.mul_right.mul_left.mul_left - simp_rw [l1 σ' hσ', l2 σ' hσ', ← integral_const_mul, ← integral_sub l4 l5] apply integral_congr_ae apply Eventually.of_forall @@ -541,61 +341,60 @@ def cumsum [AddCommMonoid E] (u : ℕ → E) (n : ℕ) : E := ∑ i ∈ Finset.r def nabla [Sub E] (u : α → E) (n : α) : E := u (n + 1) - u n -/- `nnabla` is the backward difference `u n - u (n+1)`; kept alongside `nabla` - for summation-by-parts identities that prefer that orientation. -/ def nnabla [Sub E] (u : α → E) (n : α) : E := u n - u (n + 1) def shift (u : α → E) (n : α) : E := u (n + 1) -@[simp] lemma cumsum_zero [AddCommMonoid E] {u : ℕ → E} : cumsum u 0 = 0 := by simp [cumsum] +@[simp] theorem cumsum_zero [AddCommMonoid E] {u : ℕ → E} : cumsum u 0 = 0 := by simp [cumsum] -lemma cumsum_succ [AddCommMonoid E] {u : ℕ → E} (n : ℕ) : +theorem cumsum_succ [AddCommMonoid E] {u : ℕ → E} (n : ℕ) : cumsum u (n + 1) = cumsum u n + u n := by simp [cumsum, Finset.sum_range_succ] -@[simp] lemma nabla_cumsum [AddCommGroup E] {u : ℕ → E} : nabla (cumsum u) = u := by +@[simp] theorem nabla_cumsum [AddCommGroup E] {u : ℕ → E} : nabla (cumsum u) = u := by ext n ; simp [nabla, cumsum, Finset.range_add_one] -lemma neg_cumsum [AddCommGroup E] {u : ℕ → E} : -(cumsum u) = cumsum (-u) := +theorem neg_cumsum [AddCommGroup E] {u : ℕ → E} : -(cumsum u) = cumsum (-u) := funext (fun n => by simp [cumsum]) -lemma cumsum_nonneg {u : ℕ → ℝ} (hu : 0 ≤ u) : 0 ≤ cumsum u := +theorem cumsum_nonneg {u : ℕ → ℝ} (hu : 0 ≤ u) : 0 ≤ cumsum u := fun _ => Finset.sum_nonneg (fun i _ => hu i) omit [Sub α] in -lemma neg_nabla [Ring E] {u : α → E} : -(nabla u) = nnabla u := by ext n ; simp [nabla, nnabla] +theorem neg_nabla [Ring E] {u : α → E} : -(nabla u) = nnabla u := by ext n ; simp [nabla, nnabla] omit [Sub α] in -@[simp] lemma nabla_mul [Ring E] {u : α → E} {c : E} : nabla (fun n => c * u n) = c • nabla u := by +@[simp] theorem nabla_mul [Ring E] {u : α → E} {c : E} : + nabla (fun n => c * u n) = c • nabla u := by ext n ; simp [nabla, mul_sub] omit [Sub α] in -@[simp] lemma nnabla_mul [Ring E] {u : α → E} {c : E} : +@[simp] theorem nnabla_mul [Ring E] {u : α → E} {c : E} : nnabla (fun n => c * u n) = c • nnabla u := by ext n ; simp [nnabla, mul_sub] -lemma nnabla_cast (u : ℝ → E) [Sub E] : nnabla u ∘ ((↑) : ℕ → ℝ) = nnabla (u ∘ (↑)) := by +theorem nnabla_cast (u : ℝ → E) [Sub E] : nnabla u ∘ ((↑) : ℕ → ℝ) = nnabla (u ∘ (↑)) := by ext n ; simp [nnabla] end nabla -lemma Finset.sum_shift_front {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : +theorem Finset.sum_shift_front {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : cumsum u (n + 1) = u 0 + cumsum (shift u) n := by simp_rw [add_comm n, cumsum, sum_range_add, sum_range_one, add_comm 1] ; rfl -lemma Finset.sum_shift_front' {E : Type*} [Ring E] {u : ℕ → E} : +theorem Finset.sum_shift_front' {E : Type*} [Ring E] {u : ℕ → E} : shift (cumsum u) = (fun _ => u 0) + cumsum (shift u) := by ext n ; apply Finset.sum_shift_front -lemma Finset.sum_shift_back {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : +theorem Finset.sum_shift_back {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : cumsum u (n + 1) = cumsum u n + u n := by simp [cumsum, Finset.range_add_one, add_comm] -lemma Finset.sum_shift_back' {E : Type*} [Ring E] {u : ℕ → E} : +theorem Finset.sum_shift_back' {E : Type*} [Ring E] {u : ℕ → E} : shift (cumsum u) = cumsum u + u := by ext n ; apply Finset.sum_shift_back -lemma summation_by_parts {E : Type*} [Ring E] {a A b : ℕ → E} (ha : a = nabla A) {n : ℕ} : +theorem summation_by_parts {E : Type*} [Ring E] {a A b : ℕ → E} (ha : a = nabla A) {n : ℕ} : cumsum (a * b) (n + 1) = A (n + 1) * b n - A 0 * b 0 - cumsum (shift A * fun i => (b (i + 1) - b i)) n := by have l1 : ∑ x ∈ Finset.range (n + 1), A (x + 1) * b x = ∑ x ∈ Finset.range n, @@ -608,31 +407,33 @@ lemma summation_by_parts {E : Type*} [Ring E] {a A b : ℕ → E} (ha : a = nabl mul_sub] abel -lemma summation_by_parts' {E : Type*} [Ring E] {a b : ℕ → E} {n : ℕ} : +theorem summation_by_parts' {E : Type*} [Ring E] {a b : ℕ → E} {n : ℕ} : cumsum (a * b) (n + 1) = cumsum a (n + 1) * b n - cumsum (shift (cumsum a) * nabla b) n := by - simpa using! summation_by_parts (a := a) (b := b) (A := cumsum a) (by simp) + change cumsum (a * b) (n + 1) = cumsum a (n + 1) * b n - + cumsum (shift (cumsum a) * (fun i : ℕ => b (i + 1) - b i)) n + simpa using summation_by_parts (a := a) (b := b) (A := cumsum a) (by simp) -lemma summation_by_parts'' {E : Type*} [Ring E] {a b : ℕ → E} : +theorem summation_by_parts'' {E : Type*} [Ring E] {a b : ℕ → E} : shift (cumsum (a * b)) = shift (cumsum a) * b - cumsum (shift (cumsum a) * nabla b) := by ext n ; apply summation_by_parts' -lemma summable_iff_bounded {u : ℕ → ℝ} (hu : 0 ≤ u) : +theorem summable_iff_bounded {u : ℕ → ℝ} (hu : 0 ≤ u) : Summable u ↔ BoundedAtFilter atTop (cumsum u) := by have l1 : (cumsum u =O[atTop] 1) ↔ _ := isBigO_one_nat_atTop_iff have l2 n : ‖cumsum u n‖ = cumsum u n := by simpa using cumsum_nonneg hu n simp only [BoundedAtFilter, l1, l2] - constructor <;> intro ⟨C, h1⟩ + constructor <;> intro h <;> rcases h with ⟨C, h1⟩ · exact ⟨C, fun n => sum_le_hasSum _ (fun i _ => hu i) h1⟩ · exact summable_of_sum_range_le hu h1 -lemma Filter.EventuallyEq.summable {u v : ℕ → ℝ} (h : u =ᶠ[atTop] v) (hu : Summable v) : +theorem Filter.EventuallyEq.summable {u v : ℕ → ℝ} (h : u =ᶠ[atTop] v) (hu : Summable v) : Summable u := summable_of_isBigO_nat hu h.isBigO -lemma summable_congr_ae {u v : ℕ → ℝ} (huv : u =ᶠ[atTop] v) : Summable u ↔ Summable v := by +theorem summable_congr_ae {u v : ℕ → ℝ} (huv : u =ᶠ[atTop] v) : Summable u ↔ Summable v := by constructor <;> intro h <;> simp [huv.summable, huv.symm.summable, h] -lemma BoundedAtFilter.add_const {u : ℕ → ℝ} {c : ℝ} : +theorem BoundedAtFilter.add_const {u : ℕ → ℝ} {c : ℝ} : BoundedAtFilter atTop (fun n => u n + c) ↔ BoundedAtFilter atTop u := by have : u = fun n => (u n + c) + (-c) := by ext n ; ring simp only [BoundedAtFilter] @@ -640,17 +441,17 @@ lemma BoundedAtFilter.add_const {u : ℕ → ℝ} {c : ℝ} : on_goal 1 => rw [this] all_goals { exact h.add (const_boundedAtFilter _ _) } -lemma BoundedAtFilter.comp_add {u : ℕ → ℝ} {N : ℕ} : +theorem BoundedAtFilter.comp_add {u : ℕ → ℝ} {N : ℕ} : BoundedAtFilter atTop (fun n => u (n + N)) ↔ BoundedAtFilter atTop u := by - simp only [BoundedAtFilter, isBigO_iff, norm_eq_abs, Pi.one_apply, - eventually_atTop] - constructor <;> intro ⟨C, n₀, h⟩ <;> use C + simp only [BoundedAtFilter, isBigO_iff, norm_eq_abs, Pi.one_apply, one_mem, + CStarRing.norm_of_mem_unitary, mul_one, eventually_atTop] + constructor <;> intro hbound <;> rcases hbound with ⟨C, n₀, h⟩ <;> use C · refine ⟨n₀ + N, fun n hn => ?_⟩ obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le' (m := N) (n := n) (by grind) exact h _ <| Nat.add_le_add_iff_right.mp hn · exact ⟨n₀, fun n hn => h _ (by grind)⟩ -lemma summable_iff_bounded' {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, 0 ≤ u n) : +theorem summable_iff_bounded' {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, 0 ≤ u n) : Summable u ↔ BoundedAtFilter atTop (cumsum u) := by obtain ⟨N, hu⟩ := eventually_atTop.mp hu have e2 : cumsum (fun i ↦ u (i + N)) = fun n => cumsum u (n + N) - cumsum u N := by @@ -658,7 +459,7 @@ lemma summable_iff_bounded' {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, 0 ≤ u n rw [← summable_nat_add_iff N, summable_iff_bounded (fun n => hu _ <| Nat.le_add_left N n), e2] simp_rw [sub_eq_add_neg, BoundedAtFilter.add_const, BoundedAtFilter.comp_add] -lemma bounded_of_shift {u : ℕ → ℝ} (h : BoundedAtFilter atTop (shift u)) : +theorem bounded_of_shift {u : ℕ → ℝ} (h : BoundedAtFilter atTop (shift u)) : BoundedAtFilter atTop u := by simp only [BoundedAtFilter, isBigO_iff, eventually_atTop] at h ⊢ obtain ⟨C, N, hC⟩ := h @@ -668,24 +469,26 @@ lemma bounded_of_shift {u : ℕ → ℝ} (h : BoundedAtFilter atTop (shift u)) : have r2 : n - 1 + 1 = n := Nat.sub_add_cancel (by omega) simpa [r2] using hC (n - 1) r1 -lemma dirichlet_test' {a b : ℕ → ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) +theorem dirichlet_test' {a b : ℕ → ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) (hAb : BoundedAtFilter atTop (shift (cumsum a) * b)) (hbb : ∀ᶠ n in atTop, b (n + 1) ≤ b n) (h : Summable (shift (cumsum a) * nnabla b)) : Summable (a * b) := by have l1 : ∀ᶠ n in atTop, 0 ≤ (shift (cumsum a) * nnabla b) n := by filter_upwards [hbb] with n hb - exact mul_nonneg (by simpa [shift] using! Finset.sum_nonneg (fun n _ ↦ ha n)) (sub_nonneg.mpr hb) + exact mul_nonneg (by simpa [shift] using cumsum_nonneg ha (n + 1)) (sub_nonneg.mpr hb) rw [summable_iff_bounded (mul_nonneg ha hb)] rw [summable_iff_bounded' l1] at h apply bounded_of_shift simpa only [summation_by_parts'', sub_eq_add_neg, neg_cumsum, ← mul_neg, neg_nabla] using hAb.add h -lemma exists_antitone_of_eventually {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, u (n + 1) ≤ u n) : +theorem exists_antitone_of_eventually {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, u (n + 1) ≤ u n) : ∃ v : ℕ → ℝ, range v ⊆ range u ∧ Antitone v ∧ v =ᶠ[atTop] u := by obtain ⟨N, hN⟩ := eventually_atTop.mp hu let v (n : ℕ) := u (if n < N then N else n) refine ⟨v, ?_, ?_, ?_⟩ - · exact fun x ⟨n, hn⟩ => ⟨if n < N then N else n, hn⟩ + · intro x hx + rcases hx with ⟨n, hn⟩ + exact ⟨if n < N then N else n, hn⟩ · refine antitone_nat_of_succ_le (fun n => ?_) by_cases h : n < N · by_cases h' : n + 1 < N <;> simp [v, h, h'] @@ -696,7 +499,7 @@ lemma exists_antitone_of_eventually {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, u · have : ∀ᶠ n in atTop, ¬(n < N) := by simpa using ⟨N, fun b hb => by linarith⟩ filter_upwards [this] with n hn ; simp [v, hn] -lemma summable_inv_mul_log_sq : Summable (fun n : ℕ => (n * (Real.log n) ^ 2)⁻¹) := by +theorem summable_inv_mul_log_sq : Summable (fun n : ℕ => (n * (Real.log n) ^ 2)⁻¹) := by let u (n : ℕ) := (n * (Real.log n) ^ 2)⁻¹ have l7 : ∀ᶠ n : ℕ in atTop, 1 ≤ Real.log n := tendsto_atTop.mp (tendsto_log_atTop.comp tendsto_natCast_atTop_atTop) 1 @@ -715,26 +518,26 @@ lemma summable_inv_mul_log_sq : Summable (fun n : ℕ => (n * (Real.log n) ^ 2) simp only [l5, mul_inv_rev, Nat.cast_pow, Nat.cast_ofNat, log_pow, u] field_simp -lemma tendsto_mul_add_atTop {a : ℝ} (ha : 0 < a) (b : ℝ) : +theorem tendsto_mul_add_atTop {a : ℝ} (ha : 0 < a) (b : ℝ) : Tendsto (fun x => a * x + b) atTop atTop := tendsto_atTop_add_const_right _ b (tendsto_id.const_mul_atTop ha) -lemma isLittleO_const_of_tendsto_atTop {α : Type*} [Preorder α] (a : ℝ) {f : α → ℝ} +theorem isLittleO_const_of_tendsto_atTop {α : Type*} [Preorder α] (a : ℝ) {f : α → ℝ} (hf : Tendsto f atTop atTop) : (fun _ => a) =o[atTop] f := by simp [tendsto_norm_atTop_atTop.comp hf] -lemma isBigO_pow_pow_of_le {m n : ℕ} (h : m ≤ n) : +theorem isBigO_pow_pow_of_le {m n : ℕ} (h : m ≤ n) : (fun x : ℝ => x ^ m) =O[atTop] (fun x : ℝ => x ^ n) := by apply IsBigO.of_bound 1 filter_upwards [eventually_ge_atTop 1] with x l1 simpa [abs_eq_self.mpr (zero_le_one.trans l1)] using pow_le_pow_right₀ l1 h -lemma isLittleO_mul_add_sq (a b : ℝ) : (fun x => a * x + b) =o[atTop] (fun x => x ^ 2) := by +theorem isLittleO_mul_add_sq (a b : ℝ) : (fun x => a * x + b) =o[atTop] (fun x => x ^ 2) := by apply IsLittleO.add · apply IsLittleO.const_mul_left ; simpa using isLittleO_pow_pow_atTop_of_lt (𝕜 := ℝ) one_lt_two · apply isLittleO_const_of_tendsto_atTop _ <| tendsto_pow_atTop (by linarith) -lemma log_mul_add_isBigO_log {a : ℝ} (ha : 0 < a) (b : ℝ) : +theorem log_mul_add_isBigO_log {a : ℝ} (ha : 0 < a) (b : ℝ) : (fun x => Real.log (a * x + b)) =O[atTop] Real.log := by apply IsBigO.of_bound (2 : ℕ) have l2 : ∀ᶠ x : ℝ in atTop, 0 ≤ log x := tendsto_atTop.mp tendsto_log_atTop 0 @@ -748,21 +551,22 @@ lemma log_mul_add_isBigO_log {a : ℝ} (ha : 0 < a) (b : ℝ) : simpa [abs_eq_self.mpr l2, abs_eq_self.mpr l3, Real.log_pow] using Real.log_le_log (by linarith) l1 -lemma isBigO_log_mul_add {a : ℝ} (ha : 0 < a) (b : ℝ) : +theorem isBigO_log_mul_add {a : ℝ} (ha : 0 < a) (b : ℝ) : Real.log =O[atTop] (fun x => Real.log (a * x + b)) := by - convert! (log_mul_add_isBigO_log (b := -b / a) (inv_pos.mpr ha)).comp_tendsto + convert (log_mul_add_isBigO_log (b := -b / a) (inv_pos.mpr ha)).comp_tendsto (tendsto_mul_add_atTop (b := b) ha) using 1 - ext x - simp only [Function.comp_apply] - congr - field_simp - simp + · ext x + simp only [Function.comp_apply] + congr + field_simp + simp + · rfl -lemma log_isbigo_log_div {d : ℝ} (hb : 0 < d) : +theorem log_isbigo_log_div {d : ℝ} (hb : 0 < d) : (fun n ↦ Real.log n) =O[atTop] (fun n ↦ Real.log (n / d)) := by convert isBigO_log_mul_add (inv_pos.mpr hb) 0 using 1; simp only [add_zero]; field_simp -lemma Asymptotics.IsBigO.add_isLittleO_right {f g : ℝ → ℝ} (h : g =o[atTop] f) : +theorem Asymptotics.IsBigO.add_isLittleO_right {f g : ℝ → ℝ} (h : g =o[atTop] f) : f =O[atTop] (f + g) := by rw [isLittleO_iff] at h ; specialize h (c := 2⁻¹) (by norm_num) rw [isBigO_iff''] @@ -774,11 +578,11 @@ lemma Asymptotics.IsBigO.add_isLittleO_right {f g : ℝ → ℝ} (h : g =o[atTop _ ≤ |(|f x| - |g x|)| := le_abs_self _ _ ≤ _ := by rw [← sub_neg_eq_add, ← abs_neg (g x)] ; exact abs_abs_sub_abs_le (f x) (-g x) -lemma Asymptotics.IsBigO.sq {α : Type*} [Preorder α] {f g : α → ℝ} (h : f =O[atTop] g) : - (fun n ↦ f n ^ 2) =O[atTop] (fun n => g n ^ 2) := by - simpa [pow_two] using h.mul h +theorem Asymptotics.IsBigO.sq {α : Type*} [Preorder α] {f g : α → ℝ} (h : f =O[atTop] g) : + (fun n ↦ f n ^ 2) =O[atTop] (fun n => g n ^ 2) := + h.pow 2 -lemma log_sq_isbigo_mul {a b : ℝ} (hb : 0 < b) : +theorem log_sq_isbigo_mul {a b : ℝ} (hb : 0 < b) : (fun x ↦ Real.log x ^ 2) =O[atTop] (fun x ↦ a + Real.log (x / b) ^ 2) := by apply (log_isbigo_log_div hb).sq.trans ; simp_rw [add_comm a] refine IsBigO.add_isLittleO_right <| isLittleO_const_of_tendsto_atTop _ ?_ @@ -789,9 +593,13 @@ theorem log_add_div_isBigO_log (a : ℝ) {b : ℝ} (hb : 0 < b) : (fun x ↦ Real.log ((x + a) / b)) =O[atTop] fun x ↦ Real.log x := by convert log_mul_add_isBigO_log (inv_pos.mpr hb) (a / b) using 3 ; ring -lemma log_add_one_sub_log_le {x : ℝ} (hx : 0 < x) : nabla Real.log x ≤ x⁻¹ := by +theorem log_add_one_sub_log_le {x : ℝ} (hx : 0 < x) : nabla Real.log x ≤ x⁻¹ := by have l1 : ContinuousOn Real.log (Icc x (x + 1)) := by - apply continuousOn_log.mono ; intro t ⟨h1, _⟩ ; simp ; linarith + apply continuousOn_log.mono + intro t ht + have h1 := ht.1 + simp + linarith have l2 t (ht : t ∈ Ioo x (x + 1)) : HasDerivAt Real.log t⁻¹ t := Real.hasDerivAt_log (by linarith [ht.1]) obtain ⟨t, ⟨ht1, _⟩, htx⟩ := exists_hasDerivAt_eq_slope Real.log (·⁻¹) (by linarith) l1 l2 @@ -799,22 +607,21 @@ lemma log_add_one_sub_log_le {x : ℝ} (hx : 0 < x) : nabla Real.log x ≤ x⁻ rw [nabla, ← htx, inv_le_inv₀ (by linarith) hx] exact ht1.le -lemma nabla_log_main : nabla Real.log =O[atTop] fun x ↦ 1 / x := by +theorem nabla_log_main : nabla Real.log =O[atTop] fun x ↦ 1 / x := by apply IsBigO.of_bound 1 filter_upwards [eventually_gt_atTop 0] with x l1 have l2 : log x ≤ log (x + 1) := log_le_log l1 (by linarith) simpa [nabla, abs_eq_self.mpr l1.le, abs_eq_self.mpr (sub_nonneg.mpr l2)] using log_add_one_sub_log_le l1 -lemma nabla_log {b : ℝ} (hb : 0 < b) : +theorem nabla_log {b : ℝ} (hb : 0 < b) : nabla (fun x => Real.log (x / b)) =O[atTop] (fun x => 1 / x) := by refine EventuallyEq.trans_isBigO ?_ nabla_log_main filter_upwards [eventually_gt_atTop 0] with x l2 rw [nabla, log_div (by linarith) (by linarith), log_div l2.ne.symm (by linarith), nabla] ; ring -lemma nnabla_mul_log_sq (a : ℝ) {b : ℝ} (hb : 0 < b) : +theorem nnabla_mul_log_sq (a : ℝ) {b : ℝ} (hb : 0 < b) : nabla (fun x => x * (a + Real.log (x / b) ^ 2)) =O[atTop] (fun x => Real.log x ^ 2) := by - have l1 : nabla (fun n => n * (a + Real.log (n / b) ^ 2)) = fun n => a + Real.log ((n + 1) / b) ^ 2 + (n * (Real.log ((n + 1) / b) ^ 2 - Real.log (n / b) ^ 2)) := by @@ -828,25 +635,24 @@ lemma nnabla_mul_log_sq (a : ℝ) {b : ℝ} (hb : 0 < b) : filter_upwards [eventually_ge_atTop 1] with x hx using by field_simp have l5 : (fun n ↦ n * (Real.log n * (1 / n))) =O[atTop] (fun n ↦ (Real.log n) ^ 2) := e2.trans_isBigO - (by simpa using! (isLittleO_mul_add_sq 1 0).isBigO.comp_tendsto Real.tendsto_log_atTop) - + (by simpa [Function.comp_def] using + (isLittleO_mul_add_sq 1 0).isBigO.comp_tendsto Real.tendsto_log_atTop) simp_rw [l1, _root_.sq_sub_sq] exact ((l2.add l3).add (isBigO_refl (·) atTop |>.mul (l4.mul (nabla_log hb)) |>.trans l5)) -lemma nnabla_bound_aux1 (a : ℝ) {b : ℝ} (hb : 0 < b) : +theorem nnabla_bound_aux1 (a : ℝ) {b : ℝ} (hb : 0 < b) : Tendsto (fun x => x * (a + Real.log (x / b) ^ 2)) atTop atTop := tendsto_id.atTop_mul_atTop₀ <| tendsto_atTop_add_const_left _ _ <| (tendsto_pow_atTop two_ne_zero).comp <| tendsto_log_atTop.comp <| tendsto_id.atTop_div_const hb -lemma nnabla_bound_aux2 (a : ℝ) {b : ℝ} (hb : 0 < b) : +theorem nnabla_bound_aux2 (a : ℝ) {b : ℝ} (hb : 0 < b) : ∀ᶠ x in atTop, 0 < x * (a + Real.log (x / b) ^ 2) := (nnabla_bound_aux1 a hb).eventually (eventually_gt_atTop 0) -lemma Real.log_eventually_gt_atTop (a : ℝ) : +theorem Real.log_eventually_gt_atTop (a : ℝ) : ∀ᶠ x in atTop, a < Real.log x := Real.tendsto_log_atTop.eventually (eventually_gt_atTop a) -/-- Should this be a gcongr lemma? -/ @[local gcongr] theorem norm_lt_norm_of_nonneg (x y : ℝ) (hx : 0 ≤ x) (hxy : x ≤ y) : ‖x‖ ≤ ‖y‖ := by @@ -854,13 +660,11 @@ theorem norm_lt_norm_of_nonneg (x y : ℝ) (hx : 0 ≤ x) (hxy : x ≤ y) : apply abs_le_abs hxy linarith -lemma nnabla_bound_aux {x : ℝ} (hx : 0 < x) : +theorem nnabla_bound_aux {x : ℝ} (hx : 0 < x) : nnabla (fun n ↦ 1 / (n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2))) =O[atTop] (fun n ↦ 1 / (Real.log n ^ 2 * n ^ 2)) := by - let d n : ℝ := n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2) change (fun x_1 ↦ nnabla (fun n ↦ 1 / d n) x_1) =O[atTop] _ - have l2 : ∀ᶠ n in atTop, 0 < d n := (nnabla_bound_aux2 ((2 * π) ^ 2) hx) have l3 : ∀ᶠ n in atTop, 0 < d (n + 1) := (tendsto_atTop_add_const_right atTop (1 : ℝ) tendsto_id).eventually l2 @@ -869,7 +673,6 @@ lemma nnabla_bound_aux {x : ℝ} (hx : 0 < x) : filter_upwards [l2, l3] with n l2 l3 rw [nnabla, one_div, one_div, inv_sub_inv l2.ne.symm l3.ne.symm, div_eq_mul_inv, mul_inv, mul_assoc] - have l4 : (fun n => (d n)⁻¹) =O[atTop] (fun n => (n * (Real.log n) ^ 2)⁻¹) := by apply IsBigO.inv_rev · refine (isBigO_refl _ _).mul <| (log_sq_isbigo_mul hx) @@ -889,17 +692,16 @@ lemma nnabla_bound_aux {x : ℝ} (hx : 0 < x) : filter_upwards [l2, l3, e3] with n e1 e2 e3 simp_rw [one_mul] gcongr - have l6 : (fun n => d (n + 1) - d n) =O[atTop] (fun n => (Real.log n) ^ 2) := by - simpa [d, nabla] using! (nnabla_mul_log_sq ((2 * π) ^ 2) hx) - + change nabla (fun n : ℝ => n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2)) + =O[atTop] (fun n => (Real.log n) ^ 2) + exact nnabla_mul_log_sq ((2 * π) ^ 2) hx apply EventuallyEq.trans_isBigO l1 - apply ((l6.mul l4).mul l5).trans_eventuallyEq filter_upwards [eventually_ge_atTop 2, Real.log_eventually_gt_atTop 0] with n hn hn' field_simp -lemma nnabla_bound (C : ℝ) {x : ℝ} (hx : 0 < x) : +theorem nnabla_bound (C : ℝ) {x : ℝ} (hx : 0 < x) : nnabla (fun n => C / (1 + (Real.log (n / x) / (2 * π)) ^ 2) / n) =O[atTop] (fun n => (n ^ 2 * (Real.log n) ^ 2)⁻¹) := by field_simp @@ -907,11 +709,8 @@ lemma nnabla_bound (C : ℝ) {x : ℝ} (hx : 0 < x) : apply IsBigO.const_mul_left simpa [div_eq_mul_inv, mul_pow, mul_comm] using nnabla_bound_aux hx -def chebyWith (C : ℝ) (f : ℕ → ℂ) : Prop := ∀ n, cumsum (‖f ·‖) n ≤ C * n - -def cheby (f : ℕ → ℂ) : Prop := ∃ C, chebyWith C f - -lemma cheby.bigO (h : cheby f) : cumsum (‖f ·‖) =O[atTop] ((↑) : ℕ → ℝ) := by +theorem cheby.bigO (h : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + cumsum (‖f ·‖) =O[atTop] ((↑) : ℕ → ℝ) := by have l1 : 0 ≤ cumsum (‖f ·‖) := cumsum_nonneg (fun _ => norm_nonneg _) obtain ⟨C, hC⟩ := h apply isBigO_of_le' (c := C) atTop @@ -919,12 +718,12 @@ lemma cheby.bigO (h : cheby f) : cumsum (‖f ·‖) =O[atTop] ((↑) : ℕ → rw [Real.norm_eq_abs, abs_eq_self.mpr (l1 n)] simpa using hC n -lemma limiting_fourier_lim1_aux (hcheby : cheby f) (hx : 0 < x) (C : ℝ) (hC : 0 ≤ C) : +theorem limiting_fourier_lim1_aux + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hx : 0 < x) (C : ℝ) (hC : 0 ≤ C) : Summable fun n ↦ ‖f n‖ / ↑n * (C / (1 + (1 / (2 * π) * Real.log (↑n / x)) ^ 2)) := by - let a (n : ℕ) := (C / (1 + (Real.log (↑n / x) / (2 * π)) ^ 2) / ↑n) - replace hcheby := hcheby.bigO - + replace hcheby := cheby.bigO hcheby have l1 : shift (cumsum (‖f ·‖)) =O[atTop] (fun n : ℕ => (↑(n + 1) : ℝ)) := hcheby.comp_tendsto <| tendsto_add_atTop_nat 1 have l2 : shift (cumsum (‖f ·‖)) =O[atTop] (fun n => (n : ℝ)) := @@ -943,10 +742,13 @@ lemma limiting_fourier_lim1_aux (hcheby : cheby f) (hx : 0 < x) (C : ℝ) (hC : apply le_add_of_le_of_nonneg le_rfl positivity have l3 : a =O[atTop] (fun n => 1 / (n : ℝ)) := by - simpa [a] using! IsBigO.mul l5 (isBigO_refl (fun n : ℕ => 1 / (n : ℝ)) _) + convert IsBigO.mul l5 (isBigO_refl (fun n : ℕ => 1 / (n : ℝ)) _) using 1 + · ext n + simp [a, div_eq_mul_inv] + · ext n + simp have l4 : nnabla a =O[atTop] (fun n : ℕ => (n ^ 2 * (Real.log n) ^ 2)⁻¹) := by - convert (nnabla_bound C hx).natCast ; simp [nnabla, a] - + convert (nnabla_bound C hx).natCast_atTop ; simp [nnabla, a] simp_rw [div_mul_eq_mul_div, mul_div_assoc, one_mul] apply dirichlet_test' · intro n ; exact norm_nonneg _ @@ -974,11 +776,12 @@ lemma limiting_fourier_lim1_aux (hcheby : cheby f) (hx : 0 < x) (C : ℝ) (hC : grind field_simp -theorem limiting_fourier_lim1 (hcheby : cheby f) (ψ : W21) (hx : 0 < x) : +theorem limiting_fourier_lim1 + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (ψ : W21) (hx : 0 < x) : Tendsto (fun σ' : ℝ ↦ ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (n / x))) (𝓝[>] 1) (𝓝 (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (n / x)))) := by - obtain ⟨C, hC⟩ := decay_bounds_cor ψ have : 0 ≤ C := by simpa using (norm_nonneg _).trans (hC 0) refine tendsto_tsum_of_dominated_convergence @@ -994,7 +797,7 @@ theorem limiting_fourier_lim1 (hcheby : cheby f) (ψ : W21) (hx : 0 < x) : rw [norm_mul, ← nterm_eq_norm_term] refine mul_le_mul ?_ (hC _) (norm_nonneg _) (div_nonneg (norm_nonneg _) (Nat.cast_nonneg _)) by_cases h : n = 0 <;> simp only [nterm, h, ↓reduceIte, CharP.cast_eq_zero, div_zero, le_refl] - have : 1 ≤ (n : ℝ) := by simpa using! Nat.pos_iff_ne_zero.mpr h + have : 1 ≤ (n : ℝ) := by exact_mod_cast (show 1 ≤ n by omega) refine div_le_div₀ (norm_nonneg _) le_rfl (by simpa [Nat.pos_iff_ne_zero]) ?_ simpa using Real.rpow_le_rpow_of_exponent_le this hσ'.le @@ -1009,7 +812,6 @@ theorem limiting_fourier_lim2 (A : ℝ) (ψ : W21) (hx : 1 ≤ x) : Tendsto (fun σ' ↦ A * ↑(x ^ (1 - σ')) * ∫ u in Ici (-Real.log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) (𝓝[>] 1) (𝓝 (A * ∫ u in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)))) := by - obtain ⟨C, hC⟩ := decay_bounds_cor ψ apply Tendsto.mul · suffices h : Tendsto (fun σ' : ℝ ↦ ofReal (x ^ (1 - σ'))) (𝓝[>] 1) (𝓝 1) by @@ -1028,7 +830,9 @@ theorem limiting_fourier_lim2 (A : ℝ) (ψ : W21) (hx : 1 ≤ x) : continuity · apply eventually_of_mem (U := Ioo 1 2) · apply Ioo_mem_nhdsGT_of_mem ; simp - · intro σ' ⟨h1, h2⟩ + · intro σ' hσ + have h1 := hσ.1 + have h2 := hσ.2 rw [ae_restrict_iff' measurableSet_Ici] apply Eventually.of_forall intro t (ht : - Real.log x ≤ t) @@ -1063,11 +867,9 @@ theorem limiting_fourier_lim2 (A : ℝ) (ψ : W21) (hx : 1 ≤ x) : theorem limiting_fourier_lim3 (hG : ContinuousOn G {s | 1 ≤ s.re}) (ψ : CS 2 ℂ) (hx : 1 ≤ x) : Tendsto (fun σ' : ℝ ↦ ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I)) (𝓝[>] 1) (𝓝 (∫ t : ℝ, G (1 + t * I) * ψ t * x ^ (t * I))) := by - by_cases hh : tsupport ψ = ∅ · simp [tsupport_eq_empty_iff.mp hh] obtain ⟨a₀, ha₀⟩ := Set.nonempty_iff_ne_empty.mpr hh - let S : Set ℂ := reProdIm (Icc 1 2) (tsupport ψ) have l1 : IsCompact S := by refine Metric.isCompact_iff_isClosed_bounded.mpr ⟨?_, ?_⟩ @@ -1079,7 +881,6 @@ theorem limiting_fourier_lim3 (hG : ContinuousOn G {s | 1 ≤ s.re}) (ψ : CS 2 obtain ⟨z, -, hmax⟩ := l1.exists_isMaxOn l4 l3 let MG := ‖G z‖ let bound (a : ℝ) : ℝ := MG * ‖ψ a‖ - apply tendsto_integral_filter_of_dominated_convergence (bound := bound) · apply eventually_of_mem (U := Icc 1 2) (Icc_mem_nhdsGT_of_mem (by simp)) ; intro u hu apply Continuous.aestronglyMeasurable @@ -1099,7 +900,6 @@ theorem limiting_fourier_lim3 (hG : ContinuousOn G {s | 1 ≤ s.re}) (ψ : CS 2 exact mul_le_mul_of_nonneg_right r2 (norm_nonneg _) · have : v ∉ Function.support ψ := fun a ↦ h (subset_tsupport ψ a) simp at this ; simp [this, bound] - · suffices h : Continuous bound by exact h.integrable_of_hasCompactSupport ψ.h2.norm.mul_left have := ψ.h1.continuous ; fun_prop · apply Eventually.of_forall ; intro t @@ -1109,125 +909,70 @@ theorem limiting_fourier_lim3 (hG : ContinuousOn G {s | 1 ≤ s.re}) (ψ : CS 2 · exact ((continuous_ofReal.tendsto _).add tendsto_const_nhds).mono_left nhdsWithin_le_nhds · exact eventually_nhdsWithin_of_forall (fun x (hx : 1 < x) => by simp [hx.le]) -@[blueprint - "limiting" - (title := "Limiting Fourier identity") - (statement := /-- - If $\psi: \R \to \C$ is $C^2$ and compactly supported and $x \geq 1$, then - $$ \sum_{n=1}^\infty \frac{f(n)}{n} \hat \psi( \frac{1}{2\pi} \log \frac{n}{x} ) - - A \int_{-\log x}^\infty \hat \psi(\frac{u}{2\pi})\ du - = \int_\R G(1+it) \psi(t) x^{it}\ dt.$$ - -/) - (proof := /-- - By Lemma \ref{first-fourier} and Lemma \ref{second-fourier}, we know that for any $\sigma>1$, - we have - $$ \sum_{n=1}^\infty \frac{f(n)}{n^\sigma} \hat \psi( \frac{1}{2\pi} \log \frac{n}{x} ) - - A x^{1-\sigma} \int_{-\log x}^\infty e^{-u(\sigma-1)} \hat \psi(\frac{u}{2\pi})\ du - = \int_\R G(\sigma+it) \psi(t) x^{it}\ dt.$$ - Now take limits as $\sigma \to 1$ using dominated convergence together with \eqref{cheby} - and Lemma \ref{decay} to obtain the result. - -/) - (latexEnv := "lemma")] -lemma limiting_fourier (hcheby : cheby f) +theorem limiting_fourier (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 1 ≤ x) : ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = ∫ (t : ℝ), (G (1 + t * I)) * (ψ t) * x ^ (t * I) := by - have l1 := limiting_fourier_lim1 hcheby ψ (by linarith) have l2 := limiting_fourier_lim2 A ψ hx have l3 := limiting_fourier_lim3 hG ψ hx apply tendsto_nhds_unique_of_eventuallyEq (l1.sub l2) l3 - simpa [eventuallyEq_nhdsWithin_iff] using! Eventually.of_forall (limiting_fourier_aux hG' hf ψ hx) - - - - -set_option backward.isDefEq.respectTransparency false in -lemma limiting_cor_aux {f : ℝ → ℂ} : Tendsto (fun x : ℝ ↦ ∫ t, f t * x ^ (t * I)) atTop (𝓝 0) := by + simpa [eventuallyEq_nhdsWithin_iff, W21.ofCS2] using + Eventually.of_forall (limiting_fourier_aux hG' hf ψ hx) +theorem limiting_cor_aux {f : ℝ → ℂ} : + Tendsto (fun x : ℝ ↦ ∫ t, f t * x ^ (t * I)) atTop (𝓝 0) := by have l1 : ∀ᶠ x : ℝ in atTop, ∀ t : ℝ, x ^ (t * I) = exp (log x * t * I) := by filter_upwards [eventually_ne_atTop 0, eventually_ge_atTop 0] with x hx hx' t rw [Complex.cpow_def_of_ne_zero (ofReal_ne_zero.mpr hx), ofReal_log hx'] ; ring_nf - have l2 : ∀ᶠ x : ℝ in atTop, ∫ t, f t * x ^ (t * I) = ∫ t, f t * exp (log x * t * I) := by filter_upwards [l1] with x hx refine integral_congr_ae (Eventually.of_forall (fun x => by simp [hx])) - simp_rw [tendsto_congr' l2] convert_to Tendsto (fun x => 𝓕 f (-Real.log x / (2 * π))) atTop (𝓝 0) - · ext ; congr ; ext - simp only [← ofReal_mul, mul_comm (f _), fourierChar, Circle.exp, ContinuousMap.coe_mk, - innerₗ_apply_apply, RCLike.inner_apply, conj_trivial, AddChar.coe_mk, mul_neg, ofReal_neg, - neg_mul] - congr - rw [← neg_mul] ; congr ; norm_cast ; field_simp + · funext x + rw [Real.fourier_real_eq_integral_exp_smul] + apply integral_congr_ae + filter_upwards [] with t + have hphase : -2 * π * t * (-Real.log x / (2 * π)) = Real.log x * t := by + field_simp + rw [hphase, ofReal_mul, smul_eq_mul] + exact mul_comm _ _ refine (Real.zero_at_infty_fourier f).comp <| Tendsto.mono_right ?_ _root_.atBot_le_cocompact exact (tendsto_neg_atBot_iff.mpr tendsto_log_atTop).atBot_mul_const (inv_pos.mpr two_pi_pos) -@[blueprint - "limiting-cor" - (title := "Corollary of limiting identity") - (statement := /-- - With the hypotheses as above, we have - $$ \sum_{n=1}^\infty \frac{f(n)}{n} \hat \psi( \frac{1}{2\pi} \log \frac{n}{x} ) - = A \int_{-\infty}^\infty \hat \psi(\frac{u}{2\pi})\ du + o(1)$$ - as $x \to \infty$. - -/) - (proof := /-- - Immediate from the Riemann-Lebesgue lemma, and also noting that - $\int_{-\infty}^{-\log x} \hat \psi(\frac{u}{2\pi})\ du = o(1)$. - -/) - (latexEnv := "corollary")] -lemma limiting_cor (ψ : CS 2 ℂ) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hcheby : cheby f) +theorem limiting_cor (ψ : CS 2 ℂ) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := by - apply limiting_cor_aux.congr' filter_upwards [eventually_ge_atTop 1] with x hx using limiting_fourier hcheby hG hG' hf ψ hx |>.symm - - - - -@[blueprint - "smooth-ury" - (title := "Smooth Urysohn lemma") - (statement := /-- - If $I$ is a closed interval contained in an open interval $J$, then there exists a smooth - function $\Psi: \R \to \R$ with $1_I \leq \Psi \leq 1_J$. - -/) - (proof := /-- - A standard analysis lemma, which can be proven by convolving $1_K$ with a smooth approximation - to the identity for some interval $K$ between $I$ and $J$. Note that we have - ``SmoothBumpFunction''s on smooth manifolds in Mathlib, so this shouldn't be too hard... - -/) - (latexEnv := "lemma")] -lemma smooth_urysohn (a b c d : ℝ) (h1 : a < b) (h3 : c < d) : ∃ Ψ : ℝ → ℝ, +theorem smooth_urysohn (a b c d : ℝ) (h1 : a < b) (h3 : c < d) : ∃ Ψ : ℝ → ℝ, (ContDiff ℝ ∞ Ψ) ∧ (HasCompactSupport Ψ) ∧ Set.indicator (Set.Icc b c) 1 ≤ Ψ ∧ Ψ ≤ Set.indicator (Set.Ioo a d) 1 := by - obtain ⟨ψ, l1, l2, l3, l4, -⟩ := smooth_urysohn_support_Ioo h1 h3 refine ⟨ψ, l1, l2, l3, l4⟩ - - noncomputable def exists_trunc : trunc := by choose ψ h1 h2 h3 h4 using smooth_urysohn (-2) (-1) (1) (2) (by linarith) (by linarith) exact ⟨⟨ψ, h1.of_le (by norm_cast), h2⟩, h3, h4⟩ -lemma one_div_sub_one (n : ℕ) : 1 / (↑(n - 1) : ℝ) ≤ 2 / n := by - match n with - | 0 => simp - | 1 => simp - | n + 2 => { norm_cast ; rw [div_le_div_iff₀] <;> simp [mul_add] <;> linarith } +theorem one_div_sub_one (n : ℕ) : 1 / (↑(n - 1) : ℝ) ≤ 2 / n := by + cases n with + | zero => simp + | succ n => + cases n with + | zero => simp + | succ n => norm_cast ; rw [div_le_div_iff₀] <;> simp [mul_add] <;> linarith -lemma quadratic_pos (a b c x : ℝ) (ha : 0 < a) (hΔ : discrim a b c < 0) : +theorem quadratic_pos (a b c x : ℝ) (ha : 0 < a) (hΔ : discrim a b c < 0) : 0 < a * x ^ 2 + b * x + c := by have l1 : a * x ^ 2 + b * x + c = a * (x + b / (2 * a)) ^ 2 - discrim a b c / (4 * a) := by simp only [discrim]; field_simp; ring @@ -1238,66 +983,71 @@ noncomputable def pp (a x : ℝ) : ℝ := a ^ 2 * (x + 1) ^ 2 + (1 - a) * (1 + a noncomputable def pp' (a x : ℝ) : ℝ := a ^ 2 * (2 * (x + 1)) -lemma pp_pos {a : ℝ} (ha : a ∈ Ioo (-1) 1) (x : ℝ) : 0 < pp a x := by +theorem pp_pos {a : ℝ} (ha : a ∈ Ioo (-1) 1) (x : ℝ) : 0 < pp a x := by simp only [pp] have : 0 < 1 - a := by linarith [ha.2] have : 0 < 1 + a := by linarith [ha.1] positivity -lemma pp_deriv (a x : ℝ) : HasDerivAt (pp a) (pp' a x) x := by +theorem pp_deriv (a x : ℝ) : HasDerivAt (pp a) (pp' a x) x := by unfold pp pp' simpa using hasDerivAt_id x |>.add_const 1 |>.pow 2 |>.const_mul _ -lemma pp_deriv_eq (a : ℝ) : deriv (pp a) = pp' a := by +theorem pp_deriv_eq (a : ℝ) : deriv (pp a) = pp' a := by ext x ; exact pp_deriv a x |>.deriv -lemma pp'_deriv (a x : ℝ) : HasDerivAt (pp' a) (a ^ 2 * 2) x := by - simpa using! hasDerivAt_id x |>.add_const 1 |>.const_mul 2 |>.const_mul (a ^ 2) +theorem pp'_deriv (a x : ℝ) : HasDerivAt (pp' a) (a ^ 2 * 2) x := by + change HasDerivAt (fun y : ℝ => a ^ 2 * (2 * (y + 1))) (a ^ 2 * 2) x + convert hasDerivAt_id x |>.add_const 1 |>.const_mul 2 |>.const_mul (a ^ 2) + using 1 <;> first | rfl | ring -lemma pp'_deriv_eq (a : ℝ) : deriv (pp' a) = fun _ => a ^ 2 * 2 := by +theorem pp'_deriv_eq (a : ℝ) : deriv (pp' a) = fun _ => a ^ 2 * 2 := by ext x ; exact pp'_deriv a x |>.deriv noncomputable def hh (a t : ℝ) : ℝ := (t * (1 + (a * log t) ^ 2))⁻¹ noncomputable def hh' (a t : ℝ) : ℝ := - pp a (log t) * hh a t ^ 2 -lemma hh_nonneg (a : ℝ) {t : ℝ} (ht : 0 ≤ t) : 0 ≤ hh a t := by dsimp only [hh] ; positivity +theorem hh_nonneg (a : ℝ) {t : ℝ} (ht : 0 ≤ t) : 0 ≤ hh a t := by dsimp only [hh] ; positivity -lemma hh_le (a t : ℝ) (ht : 0 ≤ t) : |hh a t| ≤ t⁻¹ := by +theorem hh_le (a t : ℝ) (ht : 0 ≤ t) : |hh a t| ≤ t⁻¹ := by by_cases h0 : t = 0 · simp [hh, h0] replace ht : 0 < t := lt_of_le_of_ne ht (by tauto) unfold hh rw [abs_inv, inv_le_inv₀ (by positivity) ht, abs_mul, abs_eq_self.mpr ht.le] - convert_to! t * 1 ≤ _ + convert_to t * 1 ≤ _ · simp apply mul_le_mul le_rfl ?_ zero_le_one ht.le rw [abs_eq_self.mpr (by positivity)] simp only [le_add_iff_nonneg_right] positivity -lemma hh_deriv (a : ℝ) {t : ℝ} (ht : t ≠ 0) : HasDerivAt (hh a) (hh' a t) t := by +theorem hh_deriv (a : ℝ) {t : ℝ} (ht : t ≠ 0) : HasDerivAt (hh a) (hh' a t) t := by have e1 : t * (1 + (a * log t) ^ 2) ≠ 0 := mul_ne_zero ht (_root_.ne_of_lt (by positivity)).symm have l5 : HasDerivAt (fun t : ℝ => log t) t⁻¹ t := Real.hasDerivAt_log ht have l4 : HasDerivAt (fun t : ℝ => a * log t) (a * t⁻¹) t := l5.const_mul _ have l3 : HasDerivAt (fun t : ℝ => (a * log t) ^ 2) (2 * a ^ 2 * t⁻¹ * log t) t := by - convert! l4.pow 2 using 1 ; ring + convert l4.pow 2 using 1 ; ring have l2 : HasDerivAt (fun t : ℝ => 1 + (a * log t) ^ 2) (2 * a ^ 2 * t⁻¹ * log t) t := l3.const_add _ have l1 : HasDerivAt (fun t : ℝ => t * (1 + (a * log t) ^ 2)) (1 + 2 * a ^ 2 * log t + a ^ 2 * log t ^ 2) t := by - convert! (hasDerivAt_id' t).mul l2 using 1; field_simp; ring - convert! l1.inv e1 using 1; simp only [hh', pp, hh]; field_simp; ring + convert (hasDerivAt_id' t).mul l2 using 1; field_simp; ring + apply (l1.inv e1).congr_deriv + dsimp only [hh', pp, hh] + simp only [div_eq_mul_inv, inv_pow] + ring -lemma hh_continuous (a : ℝ) : ContinuousOn (hh a) (Ioi 0) := +theorem hh_continuous (a : ℝ) : ContinuousOn (hh a) (Ioi 0) := fun t (ht : 0 < t) => (hh_deriv a ht.ne.symm).continuousAt.continuousWithinAt -lemma hh'_nonpos {a x : ℝ} (ha : a ∈ Ioo (-1) 1) : hh' a x ≤ 0 := by +theorem hh'_nonpos {a x : ℝ} (ha : a ∈ Ioo (-1) 1) : hh' a x ≤ 0 := by have := pp_pos ha (log x) simp only [hh', neg_mul, Left.neg_nonpos_iff, ge_iff_le] positivity -lemma hh_antitone {a : ℝ} (ha : a ∈ Ioo (-1) 1) : AntitoneOn (hh a) (Ioi 0) := by +theorem hh_antitone {a : ℝ} (ha : a ∈ Ioo (-1) 1) : AntitoneOn (hh a) (Ioi 0) := by have l1 x (hx : x ∈ interior (Ioi 0)) : HasDerivWithinAt (hh a) (hh' a x) (interior (Ioi 0)) x := by have : x ≠ 0 := by contrapose! hx ; simp [hx] @@ -1307,17 +1057,17 @@ lemma hh_antitone {a : ℝ} (ha : a ∈ Ioo (-1) 1) : AntitoneOn (hh a) (Ioi 0) noncomputable def gg (x i : ℝ) : ℝ := 1 / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ -lemma gg_of_hh {x : ℝ} (hx : x ≠ 0) (i : ℝ) : gg x i = x⁻¹ * hh (1 / (2 * π)) (i / x) := by +theorem gg_of_hh {x : ℝ} (hx : x ≠ 0) (i : ℝ) : gg x i = x⁻¹ * hh (1 / (2 * π)) (i / x) := by simp only [gg, hh] field_simp -lemma gg_l1 {x : ℝ} (hx : 0 < x) (n : ℕ) : |gg x n| ≤ 1 / n := by +theorem gg_l1 {x : ℝ} (hx : 0 < x) (n : ℕ) : |gg x n| ≤ 1 / n := by simp only [gg_of_hh hx.ne.symm, one_div, mul_inv_rev, abs_mul] apply mul_le_mul le_rfl (hh_le _ _ (by positivity)) (by positivity) (by positivity) |>.trans (le_of_eq ?_) simp [abs_inv, abs_eq_self.mpr hx.le] ; field_simp -lemma gg_le_one (i : ℕ) : gg x i ≤ 1 := by +theorem gg_le_one (i : ℕ) : gg x i ≤ 1 := by by_cases hi : i = 0 <;> simp only [gg, hi, CharP.cast_eq_zero, div_zero, one_div, mul_inv_rev, zero_div, Real.log_zero, mul_zero, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, zero_pow, add_zero, inv_one, mul_one, zero_le_one] @@ -1326,13 +1076,13 @@ lemma gg_le_one (i : ℕ) : gg x i ≤ 1 := by simp only [le_add_iff_nonneg_right] ; positivity rw [← mul_inv] ; apply inv_le_one_of_one_le₀ ; simpa using mul_le_mul l1 l2 zero_le_one (by simp) -lemma one_div_two_pi_mem_Ioo : 1 / (2 * π) ∈ Ioo (-1) 1 := by +theorem one_div_two_pi_mem_Ioo : 1 / (2 * π) ∈ Ioo (-1) 1 := by constructor · trans 0 · linarith · positivity · rw [div_lt_iff₀ (by positivity)] - convert_to! 1 * 1 < 2 * π + convert_to 1 * 1 < 2 * π · simp · simp apply mul_lt_mul one_lt_two ?_ zero_lt_one zero_le_two @@ -1340,22 +1090,22 @@ lemma one_div_two_pi_mem_Ioo : 1 / (2 * π) ∈ Ioo (-1) 1 := by · exact one_le_two · exact two_le_pi -lemma sum_telescopic (a : ℕ → ℝ) (n : ℕ) : ∑ i ∈ Finset.range n, (a (i + 1) - a i) = a n - a 0 := by +theorem sum_telescopic (a : ℕ → ℝ) (n : ℕ) : + ∑ i ∈ Finset.range n, (a (i + 1) - a i) = a n - a 0 := by apply Finset.sum_range_sub -lemma cancel_aux {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) +theorem cancel_aux {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : ∑ i ∈ Finset.range n, f i * g i ≤ g (n - 1) * (C * n) + (C * (↑(n - 1 - 1) + 1) * g 0 - C * (↑(n - 1 - 1) + 1) * g (n - 1) - ((n - 1 - 1) • (C * g 0) - ∑ x ∈ Finset.range (n - 1 - 1), C * g (x + 1))) := by - have l1 (n : ℕ) : (g n - g (n + 1)) * ∑ i ∈ Finset.range (n + 1), f i ≤ (g n - g (n + 1)) * (C * (n + 1)) := by - apply mul_le_mul le_rfl (by simpa using! hf' (n + 1)) (Finset.sum_nonneg (fun n _ ↦ hf n)) ?_ + apply mul_le_mul le_rfl (by simpa only [cumsum, Nat.cast_add, Nat.cast_one] using hf' (n + 1)) + (Finset.sum_nonneg (fun i _ => hf i)) ?_ simp only [sub_nonneg] ; apply hg' ; simp have l2 (x : ℕ) : C * (↑(x + 1) + 1) - C * (↑x + 1) = C := by simp ; ring - have l3 (n : ℕ) : 0 ≤ cumsum f n := Finset.sum_nonneg (fun n _ ↦ hf n) - + have l3 (n : ℕ) : 0 ≤ cumsum f n := Finset.sum_nonneg (fun i _ => hf i) convert_to ∑ i ∈ Finset.range n, (g i) • (f i) ≤ _ · simp [mul_comm] rw [Finset.sum_range_by_parts, sub_eq_add_neg, ← Finset.sum_neg_distrib] @@ -1363,20 +1113,20 @@ lemma cancel_aux {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) apply _root_.add_le_add · exact mul_le_mul le_rfl (hf' n) (l3 n) (hg _) · apply Finset.sum_le_sum (fun n _ => l1 n) |>.trans - convert_to! ∑ i ∈ Finset.range (n - 1), (C * (↑i + 1)) • (g i - g (i + 1)) ≤ _ + convert_to ∑ i ∈ Finset.range (n - 1), (C * (↑i + 1)) • (g i - g (i + 1)) ≤ _ · congr ; ext i ; simp ; ring rw [Finset.sum_range_by_parts] simp_rw [Finset.sum_range_sub', l2, smul_sub, smul_eq_mul, Finset.sum_sub_distrib, Finset.sum_const, Finset.card_range] apply le_of_eq ; ring_nf -lemma sum_range_succ (a : ℕ → ℝ) (n : ℕ) : +theorem sum_range_succ (a : ℕ → ℝ) (n : ℕ) : ∑ i ∈ Finset.range n, a (i + 1) = (∑ i ∈ Finset.range (n + 1), a i) - a 0 := by have := Finset.sum_range_sub a n rw [Finset.sum_sub_distrib, sub_eq_iff_eq_add] at this rw [Finset.sum_range_succ, this] ; ring -lemma cancel_aux' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) +theorem cancel_aux' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : ∑ i ∈ Finset.range n, f i * g i ≤ C * n * g (n - 1) @@ -1387,27 +1137,37 @@ lemma cancel_aux' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) simp only [nsmul_eq_mul, ← Finset.mul_sum, sum_range_succ] at this convert this using 1 ; unfold cumsum ; ring -lemma cancel_main {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) +theorem cancel_main {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) (hn : 2 ≤ n) : cumsum (f * g) n ≤ C * cumsum g n := by - convert! cancel_aux' hf hg hf' hg' n using 1 - match n with - | n + 2 => simp only [cumsum_succ] ; push_cast ; ring - -lemma cancel_main' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hf0 : f 0 = 0) (hg : 0 ≤ g) + change (∑ i ∈ Finset.range n, f i * g i) ≤ C * cumsum g n + refine (cancel_aux' hf hg hf' hg' n).trans_eq ?_ + have hindex : n - 1 - 1 + 1 = n - 1 := by omega + have hcast : (n : ℝ) = ↑(n - 1) + 1 := by + exact_mod_cast (show n = (n - 1) + 1 by omega) + have hcast' : (↑(n - 1 - 1) : ℝ) + 1 = ↑(n - 1) := by + exact_mod_cast hindex + have hsum : cumsum g n = cumsum g (n - 1) + g (n - 1) := by + conv_lhs => rw [show n = (n - 1) + 1 by omega] + exact cumsum_succ (n - 1) + rw [hindex, hcast', hcast, hsum] + ring + +theorem cancel_main' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hf0 : f 0 = 0) (hg : 0 ≤ g) (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : cumsum (f * g) n ≤ C * cumsum g n := by - match n with - | 0 => simp [cumsum] - | 1 => specialize hg 0 ; specialize hf' 1 ; simp only [cumsum, Finset.range_one, - Finset.sum_singleton, hf0, Nat.cast_one, mul_one, Pi.zero_apply, Pi.mul_apply, zero_mul, - ge_iff_le] at hf' hg ⊢ ; positivity - | n + 2 => convert! cancel_aux' hf hg hf' hg' (n + 2) using 1 ; simp [cumsum_succ] ; ring + cases n with + | zero => simp [cumsum] + | succ n => + cases n with + | zero => + have hC : 0 ≤ C := by simpa [cumsum, hf0] using hf' 1 + simpa [cumsum, hf0] using mul_nonneg hC (hg 0) + | succ n => exact cancel_main hf hg hf' hg' (n + 2) (by omega) theorem sum_le_integral {x₀ : ℝ} {f : ℝ → ℝ} {n : ℕ} (hf : AntitoneOn f (Ioc x₀ (x₀ + n))) (hfi : IntegrableOn f (Icc x₀ (x₀ + n))) : (∑ i ∈ Finset.range n, f (x₀ + ↑(i + 1))) ≤ ∫ x in x₀..x₀ + n, f x := by - cases n with simp only [Nat.cast_add, Nat.cast_one, CharP.cast_eq_zero, add_zero, lt_self_iff_false, not_false_eq_true, Ioc_eq_empty, Finset.range_zero, Nat.cast_add, Nat.cast_one, Finset.sum_empty, @@ -1418,7 +1178,6 @@ theorem sum_le_integral {x₀ : ℝ} {f : ℝ → ℝ} {n : ℕ} (hf : AntitoneO simp only [this, Finset.singleton_union, Finset.mem_Ico, nonpos_iff_eq_zero, one_ne_zero, lt_add_iff_pos_left, add_pos_iff, zero_lt_one, or_true, and_true, not_false_eq_true, Finset.sum_insert, CharP.cast_eq_zero, zero_add, ge_iff_le] - have l4 : IntervalIntegrable f volume x₀ (x₀ + 1) := by apply IntegrableOn.intervalIntegrable simp only [le_add_iff_nonneg_right, zero_le_one, uIcc_of_le] @@ -1429,24 +1188,21 @@ theorem sum_le_integral {x₀ : ℝ} {f : ℝ → ℝ} {n : ℕ} (hf : AntitoneO rcases hx with ⟨hx1, hx2⟩ refine hf ⟨hx1, by linarith⟩ ⟨by linarith, by linarith⟩ hx2 have l6 : ∫ x in x₀..x₀ + 1, f (x₀ + 1) = f (x₀ + 1) := by simp - have l1 : f (x₀ + 1) ≤ ∫ x in x₀..x₀ + 1, f x := by - rw [← l6] ; apply intervalIntegral.integral_mono_ae_restrict (by linarith) (by simp) l4 - apply eventually_of_mem _ l5 - have : (Ioc x₀ (x₀ + 1))ᶜ ∩ Icc x₀ (x₀ + 1) = {x₀} := by simp [← sdiff_eq_compl_inter] - rw [mem_ae_iff, Measure.restrict_apply measurableSet_Ioc.compl, this] - simp - + rw [← l6] + apply intervalIntegral.integral_mono_on_of_le_Ioo (by linarith) (by simp) l4 + intro x hx + exact l5 x ⟨hx.1, hx.2.le⟩ have l2 : AntitoneOn (fun x ↦ f (x₀ + x)) (Icc 1 ↑(n + 1)) := by - intro u ⟨hu1, _⟩ v ⟨_, hv2⟩ huv ; push_cast at hv2 + intro u hu v hv huv + have hu1 := hu.1 + have hv2 := hv.2 + push_cast at hv2 refine hf ⟨?_, ?_⟩ ⟨?_, ?_⟩ ?_ <;> linarith - have l3 := @AntitoneOn.sum_le_integral_Ico 1 (n + 1) (fun x => f (x₀ + x)) (by simp) (by simpa using l2) - simp only [Nat.cast_add, Nat.cast_one, intervalIntegral.integral_comp_add_left] at l3 - convert! _root_.add_le_add l1 l3 - + convert _root_.add_le_add l1 l3 have := @intervalIntegral.integral_comp_mul_add ℝ _ _ 1 (n + 1) 1 f one_ne_zero x₀ rw [intervalIntegral.integral_add_adjacent_intervals] · exact l4 @@ -1457,26 +1213,25 @@ theorem sum_le_integral {x₀ : ℝ} {f : ℝ → ℝ} {n : ℕ} (hf : AntitoneO · linarith · simp -lemma hh_integrable_aux (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : +theorem hh_integrable_aux (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : (IntegrableOn (fun t ↦ a * hh b (t / c)) (Ici 0)) ∧ (∫ (t : ℝ) in Ioi 0, a * hh b (t / c) = a * c / b * π) := by - rw [integrableOn_Ici_iff_integrableOn_Ioi] simp only [hh] - let g (x : ℝ) := (a * c / b) * Real.arctan (b * log (x / c)) let g₀ (x : ℝ) := if x = 0 then ((a * c / b) * (- (π / 2))) else g x let g' (x : ℝ) := a * (x / c * (1 + (b * Real.log (x / c)) ^ 2))⁻¹ - have l3 (x) (hx : 0 < x) : HasDerivAt Real.log x⁻¹ x := by apply Real.hasDerivAt_log (by linarith) have l4 (x) : HasDerivAt (fun t => t / c) (1 / c) x := (hasDerivAt_id x).div_const c have l2 (x) (hx : 0 < x) : HasDerivAt (fun t => log (t / c)) x⁻¹ x := by - have := @HasDerivAt.comp _ _ _ _ _ _ (fun t => t / c) _ _ _ (l3 (x / c) (by positivity)) (l4 x) - convert! this using 1 ; field_simp + have hcomp := (l3 (x / c) (by positivity)).comp x (l4 x) + convert hcomp using 1 + · rfl + · field_simp [hc.ne', hx.ne'] have l5 (x) (hx : 0 < x) := (l2 x hx).const_mul b have l1 (x) (hx : 0 < x) := (l5 x hx).arctan have l6 (x) (hx : 0 < x) : HasDerivAt g (g' x) x := by - convert! (l1 x hx).const_mul (a * c / b) using 1 + convert (l1 x hx).const_mul (a * c / b) using 1 simp only [g'] field_simp have key (x) (hx : 0 < x) : HasDerivAt g₀ (g' x) x := by @@ -1484,7 +1239,6 @@ lemma hh_integrable_aux (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : apply eventually_of_mem <| Ioi_mem_nhds hx intro y (hy : 0 < y) simp [g₀, hy.ne.symm] - have k1 : Tendsto g₀ atTop (𝓝 ((a * c / b) * (π / 2))) := by have : g =ᶠ[atTop] g₀ := by apply eventually_of_mem (Ioi_mem_atTop 0) @@ -1497,7 +1251,6 @@ lemma hh_integrable_aux (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : apply tendsto_log_atTop.comp apply Tendsto.atTop_div_const hc apply tendsto_id - have k2 : Tendsto g₀ (𝓝[>] 0) (𝓝 (g₀ 0)) := by have : g =ᶠ[𝓝[>] 0] g₀ := by apply eventually_of_mem self_mem_nhdsWithin @@ -1514,20 +1267,20 @@ lemma hh_integrable_aux (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : · simp only [mem_Ioi] at hx1 ⊢ ; positivity · simp only [dist_zero_right, norm_eq_abs, norm_div, abs_eq_self.mpr hc.le] at hx2 ⊢ rwa [div_lt_iff₀ hc, mul_comm] - have k3 : ContinuousWithinAt g₀ (Ici 0) 0 := by rw [Metric.continuousWithinAt_iff] rw [Metric.tendsto_nhdsWithin_nhds] at k2 - gconvert k2 using 5 with ε hε δ hδ x h - intro (hx : 0 ≤ x) - have := le_iff_lt_or_eq.mp hx - cases this with - | inl hx => exact h hx - | inr hx => simp [g₀, hx.symm, hε] - + intro ε hε + obtain ⟨δ, hδ, hδx⟩ := k2 ε hε + refine ⟨δ, hδ, ?_⟩ + intro x hx hdist + change 0 ≤ x at hx + rcases lt_or_eq_of_le hx with hx | hx + · exact hδx hx hdist + · subst x + simpa only [dist_self] using hε have k4 : ∀ x ∈ Ioi 0, 0 ≤ g' x := by intro x (hx : 0 < x) ; simp only [mul_inv_rev, inv_div, g'] ; positivity - constructor · convert_to IntegrableOn g' _ exact integrableOn_Ioi_deriv_of_nonneg k3 key k4 k1 @@ -1535,25 +1288,25 @@ lemma hh_integrable_aux (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : simp only [mul_inv_rev, inv_div, mul_neg, ↓reduceIte, sub_neg_eq_add, g', g₀] at this ⊢ convert this using 1 ; field_simp ; ring -lemma hh_integrable (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : +theorem hh_integrable (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : IntegrableOn (fun t ↦ a * hh b (t / c)) (Ici 0) := hh_integrable_aux ha hb hc |>.1 -lemma hh_integral (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : +theorem hh_integral (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : ∫ (t : ℝ) in Ioi 0, a * hh b (t / c) = a * c / b * π := hh_integrable_aux ha hb hc |>.2 -lemma hh_integral' : ∫ t in Ioi 0, hh (1 / (2 * π)) t = 2 * π ^ 2 := by +theorem hh_integral' : ∫ t in Ioi 0, hh (1 / (2 * π)) t = 2 * π ^ 2 := by have := hh_integral (a := 1) (b := 1 / (2 * π)) (c := 1) (by positivity) (by positivity) (by positivity) convert this using 1 <;> simp ; ring -lemma bound_sum_log {C : ℝ} (hf0 : f 0 = 0) (hf : chebyWith C f) {x : ℝ} (hx : 1 ≤ x) : +theorem bound_sum_log {C : ℝ} (hf0 : f 0 = 0) + (hf : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + {x : ℝ} (hx : 1 ≤ x) : ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ C * (1 + ∫ t in Ioi 0, hh (1 / (2 * π)) t) := by - let ggg (i : ℕ) : ℝ := if i = 0 then 1 else gg x i - have l0 : x ≠ 0 := by linarith have l1 i : 0 ≤ ggg i := by by_cases hi : i = 0 <;> simp only [gg, one_div, mul_inv_rev, hi, ↓reduceIte, zero_le_one, ggg] ; positivity @@ -1569,33 +1322,29 @@ lemma bound_sum_log {C : ℝ} (hf0 : f 0 = 0) (hf : chebyWith C f) {x : ℝ} (hx · simp only [mem_Ioi] ; positivity · gcongr have l3 : 0 ≤ C := by simpa [cumsum, hf0] using hf 1 - have l4 : 0 ≤ ∫ (t : ℝ) in Ioi 0, hh (π⁻¹ * 2⁻¹) t := setIntegral_nonneg measurableSet_Ioi (fun x hx => hh_nonneg _ (LT.lt.le hx)) - have l5 {n : ℕ} : AntitoneOn (fun t ↦ x⁻¹ * hh (1 / (2 * π)) (t / x)) (Ioc 0 n) := by - intro u ⟨hu1, _⟩ v ⟨hv1, _⟩ huv + intro u hu v hv huv + have hu1 := hu.1 + have hv1 := hv.1 simp only apply mul_le_mul le_rfl ?_ (hh_nonneg _ (by positivity)) (by positivity) apply hh_antitone one_div_two_pi_mem_Ioo (by simp only [mem_Ioi] ; positivity) (by simp only [mem_Ioi] ; positivity) apply (div_le_div_iff_of_pos_right (by positivity)).mpr huv - have l6 {n : ℕ} : IntegrableOn (fun t ↦ x⁻¹ * hh (π⁻¹ * 2⁻¹) (t / x)) (Icc 0 n) volume := by apply IntegrableOn.mono_set (hh_integrable (by positivity) (by positivity) (by positivity)) Icc_subset_Ici_self - apply Real.tsum_le_of_sum_range_le (fun n => by positivity) ; intro n - convert_to! ∑ i ∈ Finset.range n, ‖f i‖ * ggg i ≤ _ + convert_to ∑ i ∈ Finset.range n, ‖f i‖ * ggg i ≤ _ · congr ; ext i by_cases hi : i = 0 · simp [hi, hf0] · simp only [gg, hi, ↓reduceIte, ggg] field_simp - apply cancel_main' (fun _ => norm_nonneg _) (by simp [hf0]) l1 hf l2 n |>.trans gcongr ; simp only [cumsum, gg_of_hh l0, one_div, mul_inv_rev, ggg] - by_cases hn : n = 0 · simp only [hn, Finset.range_zero, Finset.sum_empty] ; positivity replace hn : 0 < n := by omega @@ -1603,7 +1352,7 @@ lemma bound_sum_log {C : ℝ} (hf0 : f 0 = 0) (hf : chebyWith C f) {x : ℝ} (hx ext i ; simp ; by_cases hi : i = 0 <;> simp [hi, hn] ; omega simp only [this, Finset.singleton_union, Finset.mem_Ico, nonpos_iff_eq_zero, one_ne_zero, false_and, not_false_eq_true, Finset.sum_insert, ↓reduceIte, add_le_add_iff_left, ge_iff_le] - convert_to! ∑ x_1 ∈ Finset.Ico 1 n, x⁻¹ * hh (π⁻¹ * 2⁻¹) (↑x_1 / x) ≤ _ + convert_to ∑ x_1 ∈ Finset.Ico 1 n, x⁻¹ * hh (π⁻¹ * 2⁻¹) (↑x_1 / x) ≤ _ · apply Finset.sum_congr rfl (fun i hi => ?_) simp at hi have : i ≠ 0 := by omega @@ -1624,36 +1373,43 @@ lemma bound_sum_log {C : ℝ} (hf0 : f 0 = 0) (hf : chebyWith C f) {x : ℝ} (hx · apply eventually_of_mem (self_mem_ae_restrict measurableSet_Ioi) intro x (hx : 0 < x) apply hh_nonneg _ hx.le - · have := (@hh_integrable 1 (1 / (2 * π)) 1 (by positivity) (by positivity) (by positivity)) - simpa using! this.mono_set Ioi_subset_Ici_self - -lemma bound_sum_log0 {C : ℝ} (hf : chebyWith C f) {x : ℝ} (hx : 1 ≤ x) : + · have h := (@hh_integrable 1 (1 / (2 * π)) 1 (by positivity) (by positivity) (by positivity)) + have h' := h.mono_set Ioi_subset_Ici_self + unfold IntegrableOn at h' + apply h'.congr + exact Eventually.of_forall (fun t => by simp) + +theorem bound_sum_log0 {C : ℝ} + (hf : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + {x : ℝ} (hx : 1 ≤ x) : ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ C * (1 + ∫ t in Ioi 0, hh (1 / (2 * π)) t) := by - let f0 i := if i = 0 then 0 else f i - have l1 : chebyWith C f0 := by + have l1 : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f0 k : ℂ)‖) n ≤ C * n) := by intro n ; refine Finset.sum_le_sum (fun i _ => ?_) |>.trans (hf n) by_cases hi : i = 0 <;> simp [hi, f0] have l2 i : ‖f i‖ / i = ‖f0 i‖ / i := by by_cases hi : i = 0 <;> simp [hi, f0] simp_rw [l2] ; apply bound_sum_log rfl l1 hx -lemma bound_sum_log' {C : ℝ} (hf : chebyWith C f) {x : ℝ} (hx : 1 ≤ x) : +theorem bound_sum_log' {C : ℝ} + (hf : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + {x : ℝ} (hx : 1 ≤ x) : ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ C * (1 + 2 * π ^ 2) := by simpa only [hh_integral'] using bound_sum_log0 hf hx variable (f x) in -lemma summable_fourier_aux (ψ : W21) (i : ℕ) : +theorem summable_fourier_aux (ψ : W21) (i : ℕ) : ‖f i / i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (i / x))‖ ≤ W21.norm ψ * (‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹) := by - convert! mul_le_mul_of_nonneg_left (decay_bounds_key ψ (1 / (2 * π) * log (i / x))) + convert mul_le_mul_of_nonneg_left (decay_bounds_key ψ (1 / (2 * π) * log (i / x))) (norm_nonneg (f i / i)) using 1 · simp · change _ = _ * (W21.norm ψ * _) simp only [W21.norm, mul_inv_rev, one_div, Complex.norm_div, RCLike.norm_natCast] ring -lemma summable_fourier (x : ℝ) (hx : 0 < x) (ψ : W21) (hcheby : cheby f) : +theorem summable_fourier (x : ℝ) (hx : 0 < x) (ψ : W21) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : Summable fun i ↦ ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑i / x))‖ := by have l5 : Summable fun i ↦ ‖f i‖ / ↑i * ((1 + (1 / (2 * ↑π) * ↑(Real.log (↑i / x))) ^ 2)⁻¹) := by simpa using limiting_fourier_lim1_aux hcheby hx 1 (zero_le_one' ℝ) @@ -1661,31 +1417,32 @@ lemma summable_fourier (x : ℝ) (hx : 0 < x) (ψ : W21) (hcheby : cheby f) : exact Summable.of_nonneg_of_le (fun _ => norm_nonneg _) l6 (by simpa using l5.const_smul (W21.norm ψ)) -lemma bound_I1 (x : ℝ) (hx : 0 < x) (ψ : W21) (hcheby : cheby f) : +theorem bound_I1 (x : ℝ) (hx : 0 < x) (ψ : W21) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ W21.norm ψ • ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ := by - have l5 : Summable fun i ↦ ‖f i‖ / ↑i * ((1 + (1 / (2 * ↑π) * ↑(Real.log (↑i / x))) ^ 2)⁻¹) := by simpa using limiting_fourier_lim1_aux hcheby hx 1 (zero_le_one' ℝ) have l6 := summable_fourier_aux x f ψ have l1 : Summable fun i ↦ ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑i / x))‖ := by exact summable_fourier x hx ψ hcheby apply (norm_tsum_le_tsum_norm l1).trans - simpa only [← Summable.tsum_const_smul _ l5] using! - Summable.tsum_mono l1 (by simpa using l5.const_smul (W21.norm ψ)) l6 + change (∑' i, ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) + (1 / (2 * π) * Real.log (↑i / x))‖) ≤ W21.norm ψ * _ + rw [← tsum_mul_left] + exact Summable.tsum_mono l1 (l5.mul_left (W21.norm ψ)) l6 -lemma bound_I1' {C : ℝ} (x : ℝ) (hx : 1 ≤ x) (ψ : W21) (hcheby : chebyWith C f) : +theorem bound_I1' {C : ℝ} (x : ℝ) (hx : 1 ≤ x) (ψ : W21) + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ W21.norm ψ * C * (1 + 2 * π ^ 2) := by - apply bound_I1 x (by linarith) ψ ⟨_, hcheby⟩ |>.trans rw [smul_eq_mul, mul_assoc] apply mul_le_mul le_rfl (bound_sum_log' hcheby hx) ?_ W21.norm_nonneg apply tsum_nonneg (fun i => by positivity) -lemma bound_I2 (x : ℝ) (ψ : W21) : +theorem bound_I2 (x : ℝ) (ψ : W21) : ‖∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))‖ ≤ W21.norm ψ * (2 * π ^ 2) := by - have key a : ‖𝓕 (ψ : ℝ → ℂ) (a / (2 * π))‖ ≤ W21.norm ψ * (1 + (a / (2 * π)) ^ 2)⁻¹ := decay_bounds_key ψ _ have twopi : 0 ≤ 2 * π := by simp [pi_nonneg] @@ -1706,36 +1463,31 @@ lemma bound_I2 (x : ℝ) (ψ : W21) : rw [Measure.integral_comp_div (fun x => (1 + x ^ 2)⁻¹) (2 * π)] simp [abs_eq_self.mpr twopi] ; ring_nf ; rfl -lemma bound_main {C : ℝ} (A : ℂ) (x : ℝ) (hx : 1 ≤ x) (ψ : W21) - (hcheby : chebyWith C f) : +theorem bound_main {C : ℝ} (A : ℂ) (x : ℝ) (hx : 1 ≤ x) (ψ : W21) + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))‖ ≤ W21.norm ψ * (C * (1 + 2 * π ^ 2) + ‖A‖ * (2 * π ^ 2)) := by - have l1 := bound_I1' x hx ψ hcheby have l2 := mul_le_mul (le_refl ‖A‖) (bound_I2 x ψ) (by positivity) (by positivity) apply norm_sub_le _ _ |>.trans ; rw [norm_mul] convert _root_.add_le_add l1 l2 using 1 ; ring - -set_option backward.isDefEq.respectTransparency false in -lemma limiting_cor_W21 (ψ : W21) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) +theorem limiting_cor_W21 (ψ : W21) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := by - -- Shorter notation for clarity let S1 x (ψ : ℝ → ℂ) := ∑' (n : ℕ), f n / ↑n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑n / x)) let S2 x (ψ : ℝ → ℂ) := ↑A * ∫ (u : ℝ) in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) let S x ψ := S1 x ψ - S2 x ψ ; change Tendsto (fun x ↦ S x ψ) atTop (𝓝 0) - -- Build the truncation obtain g := exists_trunc let Ψ R := g.scale R * ψ have key R : Tendsto (fun x ↦ S x (Ψ R)) atTop (𝓝 0) := limiting_cor (Ψ R) hf hcheby hG hG' - -- Choose the truncation radius obtain ⟨C, hcheby⟩ := hcheby have hC : 0 ≤ C := by have : ‖f 0‖ ≤ C := by simpa [cumsum] using hcheby 1 @@ -1747,130 +1499,62 @@ lemma limiting_cor_W21 (ψ : W21) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (n obtain ⟨R, hRψ⟩ := (key2 ((ε / 2) / (1 + M)) (by positivity)).exists simp only [dist_zero_right, Real.norm_eq_abs, abs_eq_self.mpr W21.norm_nonneg] at hRψ key - -- Apply the compact support case filter_upwards [eventually_ge_atTop 1, key R (ε / 2) (by positivity)] with x hx key - -- Control the tail term have key3 : ‖S x (ψ - Ψ R)‖ < ε / 2 := by - have : ‖S x _‖ ≤ _ * M := @bound_main f C A x hx (ψ - Ψ R) hcheby - apply this.trans_lt - apply (mul_le_mul (d := 1 + M) le_rfl (by simp) (by positivity) W21.norm_nonneg).trans_lt - have : 0 < 1 + M := by positivity - convert! (mul_lt_mul_iff_left₀ this).mpr hRψ using 1 ; field_simp - - -- Conclude the proof - have S1_sub_1 x : 𝓕 (⇑ψ - ⇑(Ψ R)) x = 𝓕 (ψ : ℝ → ℂ) x - 𝓕 ⇑(Ψ R) x := by - have l1 : AEStronglyMeasurable (fun x_1 : ℝ ↦ cexp (-(2 * ↑π * (↑x_1 * ↑x) * I))) volume := by - refine (Continuous.mul ?_ continuous_const).neg.cexp.aestronglyMeasurable - apply continuous_const.mul <| contDiff_ofReal.continuous.mul continuous_const - simp only [Real.fourier_eq', neg_mul, RCLike.inner_apply', conj_trivial, ofReal_neg, - ofReal_mul, ofReal_ofNat, Pi.sub_apply, smul_eq_mul, mul_sub] - apply integral_sub - · apply ψ.hf.bdd_mul (c := 1) l1 ; simp [Complex.norm_exp] - · apply (Ψ R : W21) |>.hf |>.bdd_mul (c := 1) l1 - simp [Complex.norm_exp] + have hbound := @bound_main f C A x hx (ψ - Ψ R) hcheby + change ‖S x (⇑ψ - ⇑(Ψ R))‖ ≤ W21.norm (⇑ψ - ⇑(Ψ R)) * M at hbound + apply hbound.trans_lt + calc + W21.norm (⇑ψ - ⇑(Ψ R)) * M ≤ W21.norm (⇑ψ - ⇑(Ψ R)) * (1 + M) := + mul_le_mul_of_nonneg_left (by linarith) W21.norm_nonneg + _ < ε / 2 := (lt_div_iff₀ (show 0 < 1 + M by positivity)).mp hRψ + have S1_sub_1 x : 𝓕 (⇑ψ - ⇑(Ψ R)) x = 𝓕 (ψ : ℝ → ℂ) x - 𝓕 ⇑(Ψ R) x := + F_sub ψ.hf (Ψ R : W21).hf x have S1_sub : S1 x (ψ - Ψ R) = S1 x ψ - S1 x (Ψ R) := by simp only [one_div, mul_inv_rev, S1_sub_1, mul_sub, S1] ; apply Summable.tsum_sub · have := summable_fourier x (by positivity) ψ ⟨_, hcheby⟩ rw [summable_norm_iff] at this simpa using this - · have := summable_fourier x (by positivity) (Ψ R) ⟨_, hcheby⟩ - rw [summable_norm_iff] at this - simpa using! this - + · have hsum := summable_fourier x (by positivity) (Ψ R : W21) ⟨_, hcheby⟩ + rw [summable_norm_iff] at hsum + simpa only [W21.ofCS2, one_div, mul_inv_rev] using hsum have S2_sub : S2 x (ψ - Ψ R) = S2 x ψ - S2 x (Ψ R) := by simp only [S1_sub_1, S2] ; rw [integral_sub] · ring · exact ψ.integrable_fourier (by positivity) |>.restrict · exact (Ψ R : W21).integrable_fourier (by positivity) |>.restrict - have S_sub : S x (ψ - Ψ R) = S x ψ - S x (Ψ R) := by simp [S, S1_sub, S2_sub] ; ring simpa [S_sub, Ψ] using norm_add_le _ _ |>.trans_lt (_root_.add_lt_add key3 key) -@[blueprint - "schwarz-id" - (title := "Limiting identity for Schwartz functions") - (statement := /-- - The previous corollary also holds for functions $\psi$ that are assumed to be in the Schwartz - class, as opposed to being $C^2$ and compactly supported. - -/) - (proof := /-- - For any $R>1$, one can use a smooth cutoff function (provided by Lemma \ref{smooth-ury} to write - $\psi = \psi_{\leq R} + \psi_{>R}$, where $\psi_{\leq R}$ is $C^2$ (in fact smooth) and compactly - supported (on $[-R,R]$), and $\psi_{>R}$ obeys bounds of the form - $$ |\psi_{>R}(t)|, |\psi''_{>R}(t)| \ll R^{-1} / (1 + |t|^2) $$ - where the implied constants depend on $\psi$. By Lemma \ref{decay} we then have - $$ \hat \psi_{>R}(u) \ll R^{-1} / (1+|u|^2).$$ - Using this and \eqref{cheby} one can show that - $$ \sum_{n=1}^\infty \frac{f(n)}{n} \hat \psi_{>R}( \frac{1}{2\pi} \log \frac{n}{x} ), - A \int_{-\infty}^\infty \hat \psi_{>R} (\frac{u}{2\pi})\ du \ll R^{-1} $$ - (with implied constants also depending on $A$), while from Lemma \ref{limiting-cor} one has - $$ \sum_{n=1}^\infty \frac{f(n)}{n} \hat \psi_{\leq R}( \frac{1}{2\pi} \log \frac{n}{x} ) - = A \int_{-\infty}^\infty \hat \psi_{\leq R} (\frac{u}{2\pi})\ du + o(1).$$ - Combining the two estimates and letting $R$ be large, we obtain the claim. - -/) - (latexEnv := "lemma")] -lemma limiting_cor_schwartz (ψ : 𝓢(ℝ, ℂ)) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) +theorem limiting_cor_schwartz (ψ : 𝓢(ℝ, ℂ)) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := limiting_cor_W21 ψ hf hcheby hG hG' - - - - --- just the surjectivity is stated here, as this is all that is needed for the current --- application, but perhaps one should state and prove bijectivity instead - -@[blueprint - "bij" - (title := "Bijectivity of Fourier transform") - (statement := /-- - The Fourier transform is a bijection on the Schwartz class. [Note: only surjectivity is - actually used.] - -/) - (proof := /-- - This is a standard result in Fourier analysis. - It can be proved here by appealing to Mellin inversion, Theorem \ref{MellinInversion}. - In particular, given $f$ in the Schwartz class, let - $F : \R_+ \to \C : x \mapsto f(\log x)$ be a function in the ``Mellin space''; then the - Mellin transform of $F$ on the imaginary axis $s=it$ is the Fourier transform of $f$. - The Mellin inversion theorem gives Fourier inversion. - -/) - (latexEnv := "lemma")] -lemma fourier_surjection_on_schwartz (f : 𝓢(ℝ, ℂ)) : ∃ g : 𝓢(ℝ, ℂ), 𝓕 g = f := by +theorem fourier_surjection_on_schwartz (f : 𝓢(ℝ, ℂ)) : ∃ g : 𝓢(ℝ, ℂ), 𝓕 g = f := by refine ⟨𝓕⁻ f, ?_⟩ exact FourierTransform.fourier_fourierInv_eq f +noncomputable def toSchwartz (f : ℝ → ℂ) (h1 : ContDiff ℝ ∞ f) + (h2 : HasCompactSupport f) : 𝓢(ℝ, ℂ) := + h2.toSchwartzMap h1 +@[simp] theorem toSchwartz_apply (f : ℝ → ℂ) {h1 h2 x} : SchwartzMap.mk f h1 h2 x = f x := rfl - -noncomputable def toSchwartz (f : ℝ → ℂ) (h1 : ContDiff ℝ ∞ f) - (h2 : HasCompactSupport f) : 𝓢(ℝ, ℂ) where - toFun := f - smooth' := h1 - decay' k n := by - have l1 : Continuous (fun x => ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖) := by - have : ContDiff ℝ ∞ (iteratedFDeriv ℝ n f) := h1.iteratedFDeriv_right (mod_cast le_top) - exact Continuous.mul (by continuity) this.continuous.norm - have l2 : HasCompactSupport (fun x ↦ ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖) := - (h2.iteratedFDeriv _).norm.mul_left - simpa using l1.bounded_above_of_compact_support l2 - -@[simp] lemma toSchwartz_apply (f : ℝ → ℂ) {h1 h2 x} : SchwartzMap.mk f h1 h2 x = f x := rfl - -lemma comp_exp_support0 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : +theorem comp_exp_support0 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : ∀ᶠ x in 𝓝 0, Ψ x = 0 := notMem_tsupport_iff_eventuallyEq.mp (fun h => lt_irrefl 0 <| mem_Ioi.mp (hplus h)) -lemma comp_exp_support1 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : +theorem comp_exp_support1 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : ∀ᶠ x in atBot, Ψ (exp x) = 0 := Real.tendsto_exp_atBot <| comp_exp_support0 hplus -lemma comp_exp_support2 {Ψ : ℝ → ℂ} (hsupp : HasCompactSupport Ψ) : +theorem comp_exp_support2 {Ψ : ℝ → ℂ} (hsupp : HasCompactSupport Ψ) : ∀ᶠ (x : ℝ) in atTop, (Ψ ∘ rexp) x = 0 := by simp only [hasCompactSupport_iff_eventuallyEq, coclosedCompact_eq_cocompact, cocompact_eq_atBot_atTop] at hsupp @@ -1882,11 +1566,9 @@ theorem comp_exp_support {Ψ : ℝ → ℂ} (hsupp : HasCompactSupport Ψ) cocompact_eq_atBot_atTop] exact ⟨comp_exp_support1 hplus, comp_exp_support2 hsupp⟩ -set_option backward.isDefEq.respectTransparency false in -lemma wiener_ikehara_smooth_aux (l0 : Continuous Ψ) (hsupp : HasCompactSupport Ψ) +theorem wiener_ikehara_smooth_aux (l0 : Continuous Ψ) (hsupp : HasCompactSupport Ψ) (hplus : closure (Function.support Ψ) ⊆ Ioi 0) (x : ℝ) (hx : 0 < x) : ∫ (u : ℝ) in Ioi (-Real.log x), ↑(rexp u) * Ψ (rexp u) = ∫ (y : ℝ) in Ioi (1 / x), Ψ y := by - have l1 : ContinuousOn rexp (Ici (-Real.log x)) := by fun_prop have l2 : Tendsto rexp atTop atTop := Real.tendsto_exp_atTop have l3 t (_ : t ∈ Ioi (-log x)) : HasDerivWithinAt rexp (rexp t) (Ioi t) t := @@ -1905,13 +1587,10 @@ theorem wiener_ikehara_smooth_sub (h1 : Integrable Ψ) (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : Tendsto (fun x ↦ (↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y) - ↑A * ∫ (y : ℝ) in Ioi 0, Ψ y) atTop (𝓝 0) := by - obtain ⟨ε, hε, hh⟩ := Metric.eventually_nhds_iff.mp <| comp_exp_support0 hplus apply tendsto_nhds_of_eventually_eq ; filter_upwards [eventually_gt_atTop ε⁻¹] with x hxε - have l1 : Integrable (indicator (Ioi x⁻¹) (fun x : ℝ => Ψ x)) := h1.indicator measurableSet_Ioi have l2 : Integrable (indicator (Ioi 0) (fun x : ℝ => Ψ x)) := h1.indicator measurableSet_Ioi - simp_rw [← MeasureTheory.integral_indicator measurableSet_Ioi, ← mul_sub, ← integral_sub l1 l2] simp only [mul_eq_zero, ofReal_eq_zero] right @@ -1919,12 +1598,10 @@ theorem wiener_ikehara_smooth_sub (h1 : Integrable Ψ) apply Eventually.of_forall intro t simp only [Pi.zero_apply] - have hε' : 0 < ε⁻¹ := by positivity have hx : 0 < x := by linarith have hx' : 0 < x⁻¹ := by positivity have hεx : x⁻¹ < ε := (inv_lt_comm₀ hε hx).mp hxε - have l3 : Ioi 0 = Ioc 0 x⁻¹ ∪ Ioi x⁻¹ := by ext t ; simp only [mem_Ioi, mem_union, mem_Ioc] ; constructor <;> intro h · simp [h, le_or_gt] @@ -1943,52 +1620,35 @@ theorem wiener_ikehara_smooth_sub (h1 : Integrable Ψ) rw [abs_le] ; constructor <;> linarith simp [ht] - - -@[blueprint - "WienerIkeharaSmooth" - (title := "Smoothed Wiener-Ikehara") - (statement := /-- - If $\Psi: (0,\infty) \to \C$ is smooth and compactly supported away from the origin, then, - $$ \sum_{n=1}^\infty f(n) \Psi( \frac{n}{x} ) = A x \int_0^\infty \Psi(y)\ dy + o(x)$$ - as $x \to \infty$. - -/) - (proof := /-- - By Lemma \ref{bij}, we can write - $$ y \Psi(y) = \hat \psi( \frac{1}{2\pi} \log y )$$ - for all $y>0$ and some Schwartz function $\psi$. Making this substitution, the claim is then - equivalent after standard manipulations to - $$ \sum_{n=1}^\infty \frac{f(n)}{n} \hat \psi( \frac{1}{2\pi} \log \frac{n}{x} ) - = A \int_{-\infty}^\infty \hat \psi(\frac{u}{2\pi})\ du + o(1)$$ - and the claim follows from Lemma \ref{schwarz-id}. - -/) - (latexEnv := "corollary")] -lemma wiener_ikehara_smooth (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hcheby : cheby f) +theorem wiener_ikehara_smooth (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x - A * ∫ y in Set.Ioi 0, Ψ y) atTop (𝓝 0) := by - let h (x : ℝ) : ℂ := rexp (2 * π * x) * Ψ (exp (2 * π * x)) have h1 : ContDiff ℝ ∞ h := by have : ContDiff ℝ ∞ (fun x : ℝ => (rexp (2 * π * x))) := (contDiff_const.mul contDiff_id).exp exact (contDiff_ofReal.comp this).mul (hsmooth.comp this) have h2 : HasCompactSupport h := by - have : 2 * π ≠ 0 := by simp [pi_ne_zero] - simpa using! (comp_exp_support hsupp hplus).comp_smul this |>.mul_left + have hπ : 2 * π ≠ 0 := by simp [pi_ne_zero] + have hh : HasCompactSupport (fun x : ℝ => Ψ (rexp (2 * π * x))) := by + simpa only [Function.comp_def, smul_eq_mul] using + (comp_exp_support hsupp hplus).comp_smul hπ + change HasCompactSupport + ((fun x : ℝ => (rexp (2 * π * x) : ℂ)) * fun x : ℝ => Ψ (rexp (2 * π * x))) + exact hh.mul_left obtain ⟨g, hg⟩ := fourier_surjection_on_schwartz (toSchwartz h h1 h2) - have l1 {y} (hy : 0 < y) : y * Ψ y = 𝓕 g (1 / (2 * π) * Real.log y) := by - simp only [one_div, mul_inv_rev, hg, toSchwartz, ofReal_exp, ofReal_mul, ofReal_ofNat, - toSchwartz_apply, ofReal_inv, h] - field_simp - norm_cast - rw [Real.exp_log hy] - + rw [hg] + change (y : ℂ) * Ψ y = h (1 / (2 * π) * Real.log y) + have harg : 2 * π * (1 / (2 * π) * Real.log y) = Real.log y := by + rw [← mul_assoc, mul_one_div_cancel (mul_ne_zero (by norm_num) pi_ne_zero), one_mul] + dsimp only [h] + rw [harg, Real.exp_log hy] have key := limiting_cor_schwartz g hf hcheby hG hG' - have l2 : ∀ᶠ x in atTop, ∑' (n : ℕ), f n / ↑n * 𝓕 g (1 / (2 * π) * Real.log (↑n / x)) = ∑' (n : ℕ), f n * Ψ (↑n / x) / x := by filter_upwards [eventually_gt_atTop 0] with x hx @@ -2000,26 +1660,25 @@ lemma wiener_ikehara_smooth (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f have : (x : ℂ) ≠ 0 := by simpa using hx.ne.symm simp only [ofReal_div, ofReal_natCast] field_simp - have l3 : ∀ᶠ x in atTop, ↑A * ∫ (u : ℝ) in Ici (-Real.log x), 𝓕 g (u / (2 * π)) = ↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y := by filter_upwards [eventually_gt_atTop 0] with x hx congr 1 - simp only [hg, toSchwartz, ofReal_exp, ofReal_mul, ofReal_ofNat, toSchwartz_apply, - ofReal_div, h] - norm_cast ; field_simp; norm_cast + rw [hg] + change (∫ u in Ici (-Real.log x), h (u / (2 * π))) = ∫ y in Ioi x⁻¹, Ψ y + dsimp only [h] + have hscale : (2 : ℝ) * π ≠ 0 := mul_ne_zero (by norm_num) pi_ne_zero + have harg (u : ℝ) : 2 * π * (u / (2 * π)) = u := mul_div_cancel₀ u hscale + simp_rw [harg] rw [MeasureTheory.integral_Ici_eq_integral_Ioi] - exact wiener_ikehara_smooth_aux hsmooth.continuous hsupp hplus x hx - + simpa only [one_div] using wiener_ikehara_smooth_aux hsmooth.continuous hsupp hplus x hx have l4 : Tendsto (fun x => (↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y) - ↑A * ∫ (y : ℝ) in Ioi 0, Ψ y) atTop (𝓝 0) := by exact wiener_ikehara_smooth_sub (hsmooth.continuous.integrable_of_hasCompactSupport hsupp) hplus - simpa [tsum_div_const] using (key.congr' <| EventuallyEq.sub l2 l3) |>.add l4 - - -lemma wiener_ikehara_smooth' (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hcheby : cheby f) +theorem wiener_ikehara_smooth' (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) @@ -2033,14 +1692,14 @@ local instance {E : Type*} : Coe (E → ℝ) (E → ℂ) := ⟨fun f n => f n⟩ theorem set_integral_ofReal {f : ℝ → ℝ} {s : Set ℝ} : ∫ x in s, (f x : ℂ) = ∫ x in s, f x := integral_ofReal -lemma wiener_ikehara_smooth_real {f : ℕ → ℝ} {Ψ : ℝ → ℝ} +theorem wiener_ikehara_smooth_real {f : ℕ → ℝ} {Ψ : ℝ → ℝ} (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x) atTop (nhds (A * ∫ y in Set.Ioi 0, Ψ y)) := by - let Ψ' := ofReal ∘ Ψ have l1 : ContDiff ℝ ∞ Ψ' := contDiff_ofReal.comp hsmooth have l2 : HasCompactSupport Ψ' := hsupp.comp_left rfl @@ -2049,11 +1708,10 @@ lemma wiener_ikehara_smooth_real {f : ℕ → ℝ} {Ψ : ℝ → ℝ} (@wiener_ikehara_smooth' A Ψ G f hf hcheby hG hG' l1 l2 l3) simp at key ; norm_cast at key -lemma interval_approx_inf (ha : 0 < a) (hab : a < b) : +theorem interval_approx_inf (ha : 0 < a) (hab : a < b) : ∀ᶠ ε in 𝓝[>] 0, ∃ ψ : ℝ → ℝ, ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ closure (Function.support ψ) ⊆ Set.Ioi 0 ∧ ψ ≤ indicator (Ico a b) 1 ∧ b - a - ε ≤ ∫ y in Ioi 0, ψ y := by - have l1 : Iio ((b - a) / 3) ∈ 𝓝[>] 0 := nhdsWithin_le_nhds <| Iio_mem_nhds <| by rw [← sub_pos] at hab positivity @@ -2083,11 +1741,10 @@ lemma interval_approx_inf (ha : 0 < a) (hab : a < b) : apply integrableOn_const <;> simp -lemma interval_approx_sup (ha : 0 < a) (hab : a < b) : +theorem interval_approx_sup (ha : 0 < a) (hab : a < b) : ∀ᶠ ε in 𝓝[>] 0, ∃ ψ : ℝ → ℝ, ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ closure (Function.support ψ) ⊆ Set.Ioi 0 ∧ indicator (Ico a b) 1 ≤ ψ ∧ ∫ y in Ioi 0, ψ y ≤ b - a + ε := by - have l1 : Iio (a / 2) ∈ 𝓝[>] 0 := nhdsWithin_le_nhds <| Iio_mem_nhds (by linarith) filter_upwards [self_mem_nhdsWithin, l1] with ε (hε : 0 < ε) (hε' : ε < a / 2) have l2 : a - ε / 2 < a := by linarith @@ -2101,12 +1758,14 @@ lemma interval_approx_sup (ha : 0 < a) (hab : a < b) : apply indicator_le_indicator_of_subset Ico_subset_Icc_self (by simp) · have l4 : 0 ≤ b - a + ε := by linarith have l5 : Ioo (a - ε / 2) (b + ε / 2) ⊆ Ioi 0 := by intro t ht ; simp at ht ⊢ ; linarith - have l6 : Ioo (a - ε / 2) (b + ε / 2) ∩ Ioi 0 = Ioo (a - ε / 2) (b + ε / 2) := inter_eq_left.mpr l5 + have l6 : Ioo (a - ε / 2) (b + ε / 2) ∩ Ioi 0 = Ioo (a - ε / 2) (b + ε / 2) := + inter_eq_left.mpr l5 have l7 : ∫ y in Ioi 0, indicator (Ioo (a - ε / 2) (b + ε / 2)) 1 y = b - a + ε := by simp only [measurableSet_Ioo, integral_indicator_one, measureReal_restrict_apply, l6, volume_real_Ioo] convert max_eq_left l4 using 1 ; ring_nf - have l8 : IntegrableOn ψ (Ioi 0) volume := (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + have l8 : IntegrableOn ψ (Ioi 0) volume := + (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn rw [← l7] refine setIntegral_mono l8 ?_ h4 rw [IntegrableOn, integrable_indicator_iff measurableSet_Ioo] @@ -2114,7 +1773,7 @@ lemma interval_approx_sup (ha : 0 < a) (hab : a < b) : apply integrableOn_const <;> simp -lemma WI_summable {f : ℕ → ℝ} {g : ℝ → ℝ} (hg : HasCompactSupport g) (hx : 0 < x) : +theorem WI_summable {f : ℕ → ℝ} {g : ℝ → ℝ} (hg : HasCompactSupport g) (hx : 0 < x) : Summable (fun n => f n * g (n / x)) := by obtain ⟨M, hM⟩ := hg.bddAbove.mono subset_closure apply summable_of_hasFiniteSupport @@ -2122,21 +1781,24 @@ lemma WI_summable {f : ℕ → ℝ} {g : ℝ → ℝ} (hg : HasCompactSupport g) simp only [Function.support_mul] ; apply Finite.inter_of_right ; rw [finite_iff_bddAbove] exact ⟨Nat.ceil (M * x), fun i hi => by simpa using Nat.ceil_mono ((div_le_iff₀ hx).mp (hM hi))⟩ -lemma WI_sum_le {f : ℕ → ℝ} {g₁ g₂ : ℝ → ℝ} (hf : 0 ≤ f) (hg : g₁ ≤ g₂) (hx : 0 < x) +theorem WI_sum_le {f : ℕ → ℝ} {g₁ g₂ : ℝ → ℝ} (hf : 0 ≤ f) (hg : g₁ ≤ g₂) (hx : 0 < x) (hg₁ : HasCompactSupport g₁) (hg₂ : HasCompactSupport g₂) : (∑' n, f n * g₁ (n / x)) / x ≤ (∑' n, f n * g₂ (n / x)) / x := by apply div_le_div_of_nonneg_right ?_ hx.le exact Summable.tsum_le_tsum (fun n => mul_le_mul_of_nonneg_left (hg _) (hf _)) (WI_summable hg₁ hx) (WI_summable hg₂ hx) -lemma WI_sum_Iab_le {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} (hcheby : chebyWith C f) (hb : 0 < b) (hxb : 2 / b < x) : +theorem WI_sum_Iab_le {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hb : 0 < b) (hxb : 2 / b < x) : (∑' n, f n * indicator (Ico a b) 1 (n / x)) / x ≤ C * 2 * b := by have hb' : 0 < 2 / b := by positivity have hx : 0 < x := by linarith have hxb' : 2 < x * b := (div_lt_iff₀ hb).mp hxb have l1 (i : ℕ) (hi : i ∉ Finset.range ⌈b * x⌉₊) : f i * indicator (Ico a b) 1 (i / x) = 0 := by simp_all [le_div_iff₀ hx] - have l2 (i : ℕ) (_ : i ∈ Finset.range ⌈b * x⌉₊) : f i * indicator (Ico a b) 1 (i / x) ≤ |f i| := by + have l2 (i : ℕ) (_ : i ∈ Finset.range ⌈b * x⌉₊) : + f i * indicator (Ico a b) 1 (i / x) ≤ |f i| := by rw [abs_eq_self.mpr (hpos _)] convert_to _ ≤ f i * 1 · ring @@ -2151,29 +1813,21 @@ lemma WI_sum_Iab_le {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} (hcheby : cheby apply (Nat.ceil_lt_add_one (by positivity)).le.trans linarith -lemma WI_sum_Iab_le' {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} (hcheby : chebyWith C f) (hb : 0 < b) : +theorem WI_sum_Iab_le' {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hb : 0 < b) : ∀ᶠ x : ℝ in atTop, (∑' n, f n * indicator (Ico a b) 1 (n / x)) / x ≤ C * 2 * b := by filter_upwards [eventually_gt_atTop (2 / b)] with x hx using WI_sum_Iab_le hpos hcheby hb hx -lemma le_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[>] b, a ≤ c) : a ≤ b := by - apply le_of_forall_gt ; intro d hd - have key : ∀ᶠ c in 𝓝[>] b, c < d := by - apply eventually_of_mem (U := Iio d) ?_ (fun x hx => hx) - rw [mem_nhdsWithin] - refine ⟨Iio d, isOpen_Iio, hd, inter_subset_left⟩ - obtain ⟨x, h1, h2⟩ := (h.and key).exists - linarith +theorem le_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[>] b, a ≤ c) : a ≤ b := by + exact ge_of_tendsto + (show Tendsto (fun c : ℝ => c) (𝓝[>] b) (𝓝 b) from nhdsWithin_le_nhds) h -lemma ge_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[<] b, c ≤ a) : b ≤ a := by - apply le_of_forall_lt ; intro d hd - have key : ∀ᶠ c in 𝓝[<] b, c > d := by - apply eventually_of_mem (U := Ioi d) ?_ (fun x hx => hx) - rw [mem_nhdsWithin] - refine ⟨Ioi d, isOpen_Ioi, hd, inter_subset_left⟩ - obtain ⟨x, h1, h2⟩ := (h.and key).exists - linarith +theorem ge_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[<] b, c ≤ a) : b ≤ a := by + exact le_of_tendsto + (show Tendsto (fun c : ℝ => c) (𝓝[<] b) (𝓝 b) from nhdsWithin_le_nhds) h -lemma WI_tendsto_aux (a b : ℝ) {A : ℝ} (hA : 0 < A) : +theorem WI_tendsto_aux (a b : ℝ) {A : ℝ} (hA : 0 < A) : Tendsto (fun c => c / A - (b - a)) (𝓝[>] (A * (b - a))) (𝓝[>] 0) := by rw [Metric.tendsto_nhdsWithin_nhdsWithin] intro ε hε @@ -2186,7 +1840,7 @@ lemma WI_tendsto_aux (a b : ℝ) {A : ℝ} (hA : 0 < A) : rw [← abs_eq_self.mpr hA.le, ← abs_div, abs_eq_self.mpr hA.le] ; congr ; field_simp rwa [this, div_lt_iff₀' hA] -lemma WI_tendsto_aux' (a b : ℝ) {A : ℝ} (hA : 0 < A) : +theorem WI_tendsto_aux' (a b : ℝ) {A : ℝ} (hA : 0 < A) : Tendsto (fun c => (b - a) - c / A) (𝓝[<] (A * (b - a))) (𝓝[>] 0) := by rw [Metric.tendsto_nhdsWithin_nhdsWithin] intro ε hε @@ -2200,8 +1854,11 @@ lemma WI_tendsto_aux' (a b : ℝ) {A : ℝ} (hA : 0 < A) : rwa [this, div_lt_iff₀' hA, ← neg_sub, abs_neg] theorem residue_nonneg {f : ℕ → ℝ} (hpos : 0 ≤ f) - (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm (fun n ↦ ↑(f n)) σ')) (hcheby : cheby fun n ↦ ↑(f n)) - (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : EqOn G (fun s ↦ LSeries (fun n ↦ ↑(f n)) s - ↑A / (s - 1)) {s | 1 < s.re}) : 0 ≤ A := by + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm (fun n ↦ ↑(f n)) σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : EqOn G (fun s ↦ LSeries (fun n ↦ ↑(f n)) s - ↑A / (s - 1)) {s | 1 < s.re}) : + 0 ≤ A := by let S (g : ℝ → ℝ) (x : ℝ) := (∑' n, f n * g (n / x)) / x have hSnonneg {g : ℝ → ℝ} (hg : 0 ≤ g) : ∀ᶠ x : ℝ in atTop, 0 ≤ S g x := by filter_upwards [eventually_ge_atTop 0] with x hx @@ -2215,37 +1872,29 @@ theorem residue_nonneg {f : ℕ → ℝ} (hpos : 0 ≤ f) have r1 : 0 ≤ᵐ[Measure.restrict volume (Ioi 0)] ψ := Eventually.of_forall l2 have r2 : IntegrableOn (fun y ↦ ψ y) (Ioi 0) volume := (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn - have r3 : Ico 1 2 ⊆ Function.support ψ := by intro x hx ; have := h4 x ; simp [hx] at this ⊢ ; linarith + have r3 : Ico 1 2 ⊆ Function.support ψ := by + intro x hx ; have := h4 x ; simp [hx] at this ⊢ ; linarith have r4 : Ico 1 2 ⊆ Function.support ψ ∩ Ioi 0 := by - simp only [subset_inter_iff, r3, true_and] ; apply Ico_subset_Icc_self.trans ; rw [Icc_subset_Ioi_iff] <;> linarith - have r5 : 1 ≤ volume ((Function.support fun y ↦ ψ y) ∩ Ioi 0) := by convert! volume.mono r4 ; norm_num - simpa [setIntegral_pos_iff_support_of_nonneg_ae r1 r2] using! zero_lt_one.trans_le r5 + simp only [subset_inter_iff, r3, + true_and] ; apply Ico_subset_Icc_self.trans ; rw [Icc_subset_Ioi_iff] <;> linarith + have r5 : 1 ≤ volume ((Function.support fun y ↦ ψ y) ∩ Ioi 0) := by + convert volume.mono r4 ; norm_num + simpa [setIntegral_pos_iff_support_of_nonneg_ae r1 r2] using zero_lt_one.trans_le r5 have := div_nonneg l3 l4.le ; field_simp at this ; exact this -blueprint_comment /-- -Now we add the hypothesis that $f(n) \geq 0$ for all $n$. - --/ +theorem WienerIkeharaInterval {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * (indicator (Ico a b) 1 (n / x))) / x) + atTop (nhds (A * (b - a))) := by -@[blueprint - (title := "Wiener-Ikehara in an interval") - (statement := /-- - For any closed interval $I \subset (0,+\infty)$, we have - $$ \sum_{n=1}^\infty f(n) 1_I( \frac{n}{x} ) = A x |I| + o(x).$$ - -/) - (proof := /-- Use Lemma \ref{smooth-ury} to bound $1_I$ above and below by smooth compactly supported functions whose integral is close to the measure of $|I|$, and use the non-negativity of $f$. -/) - (latexEnv := "proposition")] -lemma WienerIkeharaInterval {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) - (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (ha : 0 < a) (hb : a ≤ b) : - Tendsto (fun x : ℝ ↦ (∑' n, f n * (indicator (Ico a b) 1 (n / x))) / x) atTop (nhds (A * (b - a))) := by - - -- Take care of the trivial case `a = b` by_cases hab : a = b · simp [hab] replace hb : a < b := lt_of_le_of_ne hb hab ; clear hab - -- Notation to make the proof more readable let S (g : ℝ → ℝ) (x : ℝ) := (∑' n, f n * g (n / x)) / x have hSnonneg {g : ℝ → ℝ} (hg : 0 ≤ g) : ∀ᶠ x : ℝ in atTop, 0 ≤ S g x := by filter_upwards [eventually_ge_atTop 0] with x hx @@ -2253,10 +1902,10 @@ lemma WienerIkeharaInterval {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : refine tsum_nonneg (fun i => mul_nonneg (hpos _) (hg _)) have hA : 0 ≤ A := residue_nonneg hpos hf hcheby hG hG' - -- A few facts about the indicator function of `Icc a b` let Iab : ℝ → ℝ := indicator (Ico a b) 1 change Tendsto (S Iab) atTop (𝓝 (A * (b - a))) - have hIab : HasCompactSupport Iab := by simpa [Iab, HasCompactSupport, tsupport, hb.ne] using isCompact_Icc + have hIab : HasCompactSupport Iab := by + simpa [Iab, HasCompactSupport, tsupport, hb.ne] using isCompact_Icc have Iab_nonneg : ∀ᶠ x : ℝ in atTop, 0 ≤ S Iab x := hSnonneg (indicator_nonneg (by simp)) have Iab2 : IsBoundedUnder (· ≤ ·) atTop (S Iab) := by obtain ⟨C, hC⟩ := hcheby ; exact ⟨C * 2 * b, WI_sum_Iab_le' hpos hC (by linarith)⟩ @@ -2264,10 +1913,10 @@ lemma WienerIkeharaInterval {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : have Iab0 : IsCoboundedUnder (· ≥ ·) atTop (S Iab) := Iab2.isCoboundedUnder_ge have Iab1 : IsCoboundedUnder (· ≤ ·) atTop (S Iab) := Iab3.isCoboundedUnder_le - -- Bound from above by a smooth function have sup_le : limsup (S Iab) atTop ≤ A * (b - a) := by have l_sup : ∀ᶠ ε in 𝓝[>] 0, limsup (S Iab) atTop ≤ A * (b - a + ε) := by - filter_upwards [interval_approx_sup ha hb] with ε ⟨ψ, h1, h2, h3, h4, h6⟩ + filter_upwards [interval_approx_sup ha hb] with ε happrox + rcases happrox with ⟨ψ, h1, h2, h3, h4, h6⟩ have l1 : Tendsto (S ψ) atTop _ := wiener_ikehara_smooth_real hf hcheby hG hG' h1 h2 h3 have l6 : S Iab ≤ᶠ[atTop] S ψ := by filter_upwards [eventually_gt_atTop 0] with x hx using WI_sum_le hpos h4 hx hIab h2 @@ -2281,10 +1930,10 @@ lemma WienerIkeharaInterval {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : filter_upwards [WI_tendsto_aux a b key l_sup] with x hx simpa [mul_div_cancel₀ _ h] using hx - -- Bound from below by a smooth function have le_inf : A * (b - a) ≤ liminf (S Iab) atTop := by have l_inf : ∀ᶠ ε in 𝓝[>] 0, A * (b - a - ε) ≤ liminf (S Iab) atTop := by - filter_upwards [interval_approx_inf ha hb] with ε ⟨ψ, h1, h2, h3, h5, h6⟩ + filter_upwards [interval_approx_inf ha hb] with ε happrox + rcases happrox with ⟨ψ, h1, h2, h3, h5, h6⟩ have l1 : Tendsto (S ψ) atTop _ := wiener_ikehara_smooth_real hf hcheby hG hG' h1 h2 h3 have l2 : S ψ ≤ᶠ[atTop] S Iab := by filter_upwards [eventually_gt_atTop 0] with x hx using WI_sum_le hpos h5 hx h2 hIab @@ -2298,63 +1947,66 @@ lemma WienerIkeharaInterval {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : filter_upwards [WI_tendsto_aux' a b key l_inf] with x hx simpa [mul_div_cancel₀ _ h] using hx - -- Combine the two bounds have : liminf (S Iab) atTop ≤ limsup (S Iab) atTop := liminf_le_limsup Iab2 Iab3 refine tendsto_of_liminf_eq_limsup ?_ ?_ Iab2 Iab3 <;> linarith - - -lemma le_floor_mul_iff (hb : 0 ≤ b) (hx : 0 < x) : n ≤ ⌊b * x⌋₊ ↔ n / x ≤ b := by +theorem le_floor_mul_iff (hb : 0 ≤ b) (hx : 0 < x) : n ≤ ⌊b * x⌋₊ ↔ n / x ≤ b := by rw [div_le_iff₀ hx, Nat.le_floor_iff] ; positivity -lemma lt_ceil_mul_iff (hx : 0 < x) : n < ⌈b * x⌉₊ ↔ n / x < b := by +theorem lt_ceil_mul_iff (hx : 0 < x) : n < ⌈b * x⌉₊ ↔ n / x < b := by rw [div_lt_iff₀ hx, Nat.lt_ceil] -lemma ceil_mul_le_iff (hx : 0 < x) : ⌈a * x⌉₊ ≤ n ↔ a ≤ n / x := by +theorem ceil_mul_le_iff (hx : 0 < x) : ⌈a * x⌉₊ ≤ n ↔ a ≤ n / x := by rw [le_div_iff₀ hx, Nat.ceil_le] -lemma mem_Icc_iff_div (hb : 0 ≤ b) (hx : 0 < x) : n ∈ Finset.Icc ⌈a * x⌉₊ ⌊b * x⌋₊ ↔ n / x ∈ Icc a b := by +theorem mem_Icc_iff_div (hb : 0 ≤ b) (hx : 0 < x) : + n ∈ Finset.Icc ⌈a * x⌉₊ ⌊b * x⌋₊ ↔ n / x ∈ Icc a b := by rw [Finset.mem_Icc, mem_Icc, ceil_mul_le_iff hx, le_floor_mul_iff hb hx] -lemma mem_Ico_iff_div (hx : 0 < x) : n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊ ↔ n / x ∈ Ico a b := by +theorem mem_Ico_iff_div (hx : 0 < x) : n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊ ↔ n / x ∈ Ico a b := by rw [Finset.mem_Ico, mem_Ico, ceil_mul_le_iff hx, lt_ceil_mul_iff hx] -lemma tsum_indicator {f : ℕ → ℝ} (hx : 0 < x) : +theorem tsum_indicator {f : ℕ → ℝ} (hx : 0 < x) : ∑' n, f n * (indicator (Ico a b) 1 (n / x)) = ∑ n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n := by have l1 : ∀ n ∉ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n * indicator (Ico a b) 1 (↑n / x) = 0 := by simp [mem_Ico_iff_div hx] ; tauto - rw [tsum_eq_sum l1] ; apply Finset.sum_congr rfl ; simp only [mem_Ico_iff_div hx] ; intro n hn ; simp [hn] + rw [tsum_eq_sum l1] ; apply Finset.sum_congr rfl ; simp only + [mem_Ico_iff_div hx] ; intro n hn ; simp [hn] -lemma WienerIkeharaInterval_discrete {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) - (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (ha : 0 < a) (hb : a ≤ b) : - Tendsto (fun x : ℝ ↦ (∑ n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n) / x) atTop (nhds (A * (b - a))) := by +theorem WienerIkeharaInterval_discrete {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun x : ℝ ↦ (∑ n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n) / x) + atTop (nhds (A * (b - a))) := by apply (WienerIkeharaInterval hpos hf hcheby hG hG' ha hb).congr' filter_upwards [eventually_gt_atTop 0] with x hx rw [tsum_indicator hx] -lemma WienerIkeharaInterval_discrete' {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) - (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) (ha : 0 < a) (hb : a ≤ b) : - Tendsto (fun N : ℕ ↦ (∑ n ∈ Finset.Ico ⌈a * N⌉₊ ⌈b * N⌉₊, f n) / N) atTop (nhds (A * (b - a))) := +theorem WienerIkeharaInterval_discrete' {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun N : ℕ ↦ (∑ n ∈ Finset.Ico ⌈a * N⌉₊ ⌈b * N⌉₊, f n) / N) + atTop (nhds (A * (b - a))) := WienerIkeharaInterval_discrete hpos hf hcheby hG hG' ha hb |>.comp tendsto_natCast_atTop_atTop --- TODO with `Ico` - - - -/-- A version of the *Wiener-Ikehara Tauberian Theorem*: If `f` is a nonnegative arithmetic -function whose L-series has a simple pole at `s = 1` with residue `A` and otherwise extends -continuously to the closed half-plane `re s ≥ 1`, then `∑ n < N, f n` is asymptotic to `A*N`. -/ - -lemma tendsto_mul_ceil_div : +theorem tendsto_mul_ceil_div : Tendsto (fun (p : ℝ × ℕ) => ⌈p.1 * p.2⌉₊ / (p.2 : ℝ)) (𝓝[>] 0 ×ˢ atTop) (𝓝 0) := by rw [Metric.tendsto_nhds] ; intro δ hδ - have l1 : ∀ᶠ ε : ℝ in 𝓝[>] 0, ε ∈ Ioo 0 (δ / 2) := inter_mem_nhdsWithin _ (Iio_mem_nhds (by positivity)) + have l1 : ∀ᶠ ε : ℝ in 𝓝[>] 0, ε ∈ Ioo 0 (δ / 2) := + inter_mem_nhdsWithin _ (Iio_mem_nhds (by positivity)) have l2 : ∀ᶠ N : ℕ in atTop, 1 ≤ δ / 2 * N := by apply Tendsto.eventually_ge_atTop exact tendsto_natCast_atTop_atTop.const_mul_atTop (by positivity) - filter_upwards [l1.prod_mk l2] with (ε, N) ⟨⟨hε, h1⟩, h2⟩ ; dsimp only at * + filter_upwards [l1.prod_mk l2] with p hp + rcases p with ⟨ε, N⟩ + rcases hp with ⟨⟨hε, h1⟩, h2⟩ + dsimp only at * have l3 : 0 < (N : ℝ) := by simp only [Nat.cast_pos, Nat.pos_iff_ne_zero] ; rintro rfl ; simp [zero_lt_one.not_ge] at h2 have l5 : 0 ≤ ε * ↑N := by positivity @@ -2364,19 +2016,20 @@ lemma tendsto_mul_ceil_div : noncomputable def S (f : ℕ → 𝕜) (ε : ℝ) (N : ℕ) : 𝕜 := (∑ n ∈ Finset.Ico ⌈ε * N⌉₊ N, f n) / N -lemma S_sub_S {f : ℕ → 𝕜} {ε : ℝ} {N : ℕ} (hε : ε ≤ 1) : S f 0 N - S f ε N = cumsum f ⌈ε * N⌉₊ / N := by - have hceilN : ⌈ε * N⌉₊ ≤ N := by +theorem S_sub_S {f : ℕ → 𝕜} {ε : ℝ} {N : ℕ} (hε : ε ≤ 1) : + S f 0 N - S f ε N = cumsum f ⌈ε * N⌉₊ / N := by + have r1 : Finset.range N = Finset.range ⌈ε * N⌉₊ ∪ Finset.Ico ⌈ε * N⌉₊ N := by + simp_rw [Finset.range_eq_Ico] + symm + apply Finset.Ico_union_Ico_eq_Ico (Nat.zero_le _) simp only [Nat.ceil_le] exact mul_le_of_le_one_left N.cast_nonneg hε - have r1 : Finset.range N = Finset.range ⌈ε * N⌉₊ ∪ Finset.Ico ⌈ε * N⌉₊ N := by - ext n - simp only [Finset.mem_range, Finset.mem_union, Finset.mem_Ico] - omega have r2 : Disjoint (Finset.range ⌈ε * N⌉₊) (Finset.Ico ⌈ε * N⌉₊ N) := by rw [Finset.range_eq_Ico] ; apply Finset.Ico_disjoint_Ico_consecutive simp [S, r1, Finset.sum_union r2, cumsum, add_div] -lemma tendsto_S_S_zero {f : ℕ → ℝ} (hpos : 0 ≤ f) (hcheby : cheby f) : +theorem tendsto_S_S_zero {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : TendstoUniformlyOnFilter (S f) (S f 0) (𝓝[>] 0) atTop := by rw [Metric.tendstoUniformlyOnFilter_iff] ; intro δ hδ obtain ⟨C, hC⟩ := hcheby @@ -2384,40 +2037,34 @@ lemma tendsto_S_S_zero {f : ℕ → ℝ} (hpos : 0 ≤ f) (hcheby : cheby f) : have r1 := tendsto_mul_ceil_div.const_mul C simp only [mul_div_assoc', mul_zero] at r1 ; exact r1 (Iio_mem_nhds hδ) have : Ioc 0 1 ∈ 𝓝[>] (0 : ℝ) := inter_mem_nhdsWithin _ (Iic_mem_nhds zero_lt_one) - filter_upwards [l1, Eventually.prod_inl this _] with (ε, N) h1 h2 + filter_upwards [l1, Eventually.prod_inl this _] with p h1 h2 + rcases p with ⟨ε, N⟩ have l2 : ‖cumsum f ⌈ε * ↑N⌉₊ / ↑N‖ ≤ C * ⌈ε * N⌉₊ / N := by have r1 := hC ⌈ε * N⌉₊ have r2 : 0 ≤ cumsum f ⌈ε * N⌉₊ := by apply cumsum_nonneg hpos simp only [norm_real, norm_of_nonneg (hpos _), norm_div, norm_of_nonneg r2, Real.norm_natCast] at r1 ⊢ apply div_le_div_of_nonneg_right r1 (by positivity) - simpa [← S_sub_S h2.2] using! l2.trans_lt h1 - -@[blueprint "WienerIkehara" - (title := "Wiener-Ikehara Theorem (1)") - (statement := /-- - We have - $$ \sum_{n\leq x} f(n) = A x + o(x).$$ - -/) - (proof := /-- Apply the preceding proposition with $I = [\varepsilon,1]$ and then send - $\varepsilon$ to zero (using \eqref{cheby} to control the error). -/) - (latexEnv := "corollary")] + simpa [dist_eq_norm, ← S_sub_S h2.2] using l2.trans_lt h1 + theorem WienerIkeharaTheorem' {f : ℕ → ℝ} (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hcheby : cheby f) (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : Tendsto (fun N => cumsum f N / N) atTop (𝓝 A) := by - convert_to Tendsto (S f 0) atTop (𝓝 A) ; · ext N ; simp [S, cumsum] apply (tendsto_S_S_zero hpos hcheby).tendsto_of_eventually_tendsto · have L0 : Ioc 0 1 ∈ 𝓝[>] (0 : ℝ) := inter_mem_nhdsWithin _ (Iic_mem_nhds zero_lt_one) apply eventually_of_mem L0 · intro ε hε - simpa using! WienerIkeharaInterval_discrete' hpos hf hcheby hG hG' hε.1 hε.2 + convert WienerIkeharaInterval_discrete' hpos hf hcheby hG hG' hε.1 hε.2 using 1 + funext N + simp only [S, one_mul, Nat.ceil_natCast] · have : Tendsto (fun ε : ℝ => ε) (𝓝[>] 0) (𝓝 0) := nhdsWithin_le_nhds simpa using (this.const_sub 1).const_mul A -theorem vonMangoldt_cheby : cheby Λ := by +theorem vonMangoldt_cheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(Λ k : ℂ)‖) n ≤ C * n) := by use Real.log 4 + 4 intro N by_cases! h : N = 0 @@ -2430,1956 +2077,20 @@ theorem vonMangoldt_cheby : cheby Λ := by gcongr linarith -blueprint_comment /-- -\section{Weak PNT} - --/ - --- Proof extracted from the `EulerProducts` project so we can adapt it to the --- version of the Wiener-Ikehara theorem proved above (with the `cheby` --- hypothesis) - -@[blueprint - (title := "WeakPNT") - (statement := /-- - We have - $$ \sum_{n \leq x} \Lambda(n) = x + o(x).$$ - -/) - (proof := /-- Already done by Stoll, assuming Wiener-Ikehara. -/)] theorem WeakPNT : Tendsto (fun N ↦ cumsum Λ N / N) atTop (𝓝 1) := by let F := vonMangoldt.LFunctionResidueClassAux (q := 1) 1 - have hnv := riemannZeta_ne_zero_of_one_le_re have l1 (n : ℕ) : 0 ≤ Λ n := vonMangoldt_nonneg have l2 s (hs : 1 < s.re) : F s = LSeries Λ s - 1 / (s - 1) := by have := vonMangoldt.eqOn_LFunctionResidueClassAux (q := 1) isUnit_one hs - simp only [F, this, vonMangoldt.residueClass, Nat.totient_one, Nat.cast_one, inv_one, one_div, sub_left_inj] + simp only [F, this, vonMangoldt.residueClass, Nat.totient_one, Nat.cast_one, + inv_one, one_div, sub_left_inj] apply LSeries_congr intro n _ - simp only [ofReal_inj, indicator_apply_eq_self, mem_ofPred_eq] + simp only [ofReal_inj, indicator_apply_eq_self, Set.mem_ofPred_eq] exact fun hn ↦ absurd (Subsingleton.eq_one _) hn have l3 : ContinuousOn F {s | 1 ≤ s.re} := vonMangoldt.continuousOn_LFunctionResidueClassAux 1 - have l4 : cheby Λ := vonMangoldt_cheby + have l4 : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(Λ k : ℂ)‖) n ≤ C * n) := vonMangoldt_cheby have l5 (σ' : ℝ) (hσ' : 1 < σ') : Summable (nterm Λ σ') := by - simpa only [← nterm_eq_norm_term] using (@ArithmeticFunction.LSeriesSummable_vonMangoldt σ' hσ').norm + simpa only [← nterm_eq_norm_term] + using (@ArithmeticFunction.LSeriesSummable_vonMangoldt σ' hσ').norm apply WienerIkeharaTheorem' l1 l5 l4 l3 l2 - --- #print axioms WeakPNT - -section auto_cheby - -variable {f : ℕ → ℝ} - -lemma norm_x_cpow_it (x t : ℝ) (hx : 0 < x) : ‖(x : ℂ) ^ (t * I)‖ = 1 := by - rw [cpow_def_of_ne_zero <| ofReal_ne_zero.mpr hx.ne', ← ofReal_log hx.le] - convert norm_exp_ofReal_mul_I (t * x.log) using 2 - push_cast; ring_nf - -set_option backward.isDefEq.respectTransparency false in -lemma limiting_fourier_aux_gt_zero (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) - (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 0 < x) (σ' : ℝ) (hσ' : 1 < σ') : - ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - - A * (x ^ (1 - σ') : ℝ) * ∫ u in Ici (- log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = - ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I) := by - have hint : Integrable ψ := ψ.h1.continuous.integrable_of_hasCompactSupport ψ.h2 - have l8 : Continuous fun t : ℝ ↦ (x : ℂ) ^ (t * I) := - continuous_const.cpow (continuous_ofReal.mul continuous_const) (by simp [hx]) - have l4 : Integrable fun t : ℝ ↦ LSeries f (↑σ' + ↑t * I) * ψ t * ↑x ^ (↑t * I) := - (((continuous_LSeries_aux (hf _ hσ')).mul ψ.h1.continuous).mul l8).integrable_of_hasCompactSupport - ψ.h2.mul_left.mul_right - have e2 (u : ℝ) : σ' + u * I - 1 ≠ 0 := fun h ↦ by - have := congrArg Complex.re (sub_eq_zero.mp h); simp at this; linarith - have l5 : Integrable fun a ↦ A * ↑(x ^ (1 - σ')) * - (↑(x ^ (σ' - 1)) * (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by - have : Continuous fun a ↦ A * ↑(x ^ (1 - σ')) * - (↑(x ^ (σ' - 1)) * (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by - simp only [one_div, ← mul_assoc] - exact ((continuous_const.mul (Continuous.inv₀ (by fun_prop) e2)).mul ψ.h1.continuous).mul l8 - exact this.integrable_of_hasCompactSupport ψ.h2.mul_left.mul_right.mul_left.mul_left - simp_rw [first_fourier hf hint hx hσ', second_fourier ψ.h1.continuous.measurable hint hx hσ', - ← integral_const_mul, ← integral_sub l4 l5] - refine integral_congr_ae (.of_forall fun u ↦ ?_) - have e1 : 1 < ((σ' : ℂ) + (u : ℂ) * I).re := by simp [hσ'] - simp_rw [hG' e1, sub_mul, ← mul_assoc] - simp only [one_div, sub_right_inj, mul_eq_mul_right_iff, cpow_eq_zero_iff, ofReal_eq_zero, ne_eq, - mul_eq_zero, I_ne_zero, or_false] - field_simp [e2]; norm_cast; simp [mul_assoc, ← rpow_add hx] - -theorem limiting_fourier_lim2_gt_zero (A : ℝ) (ψ : W21) (hx : 0 < x) : - Tendsto (fun σ' ↦ A * ↑(x ^ (1 - σ')) * - ∫ u in Ici (-Real.log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) - (𝓝[>] 1) (𝓝 (A * ∫ u in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)))) := by - obtain ⟨C, hC⟩ := decay_bounds_cor ψ - refine Tendsto.mul ?_ (tendsto_integral_filter_of_dominated_convergence _ - (.of_forall fun _ ↦ (by continuity : Continuous _).aestronglyMeasurable) ?_ - (limiting_fourier_lim2_aux x C) (.of_forall fun u ↦ ?_)) - · suffices Tendsto (fun σ' : ℝ ↦ x ^ (1 - σ')) (𝓝[>] 1) (𝓝 1) by - simpa using ((continuous_ofReal.tendsto 1).comp this).const_mul ↑A - have : Tendsto (fun σ' : ℝ ↦ 1 - σ') (𝓝[>] 1) (𝓝 0) := - tendsto_nhdsWithin_of_tendsto_nhds (by simpa using (continuous_id.tendsto (1 : ℝ)).const_sub 1) - simpa using tendsto_const_nhds.rpow this (Or.inl hx.ne') - · refine eventually_of_mem (Ioo_mem_nhdsGT_of_mem (by norm_num : (1 : ℝ) ∈ Set.Ico 1 2)) fun σ' hσ' ↦ ?_ - obtain ⟨h1, h2⟩ := hσ' - rw [ae_restrict_iff' measurableSet_Ici] - refine .of_forall fun t ht ↦ ?_ - simp only [norm_mul, neg_mul, ofReal_exp, ofReal_neg, ofReal_mul, ofReal_sub, ofReal_one, - norm_exp, neg_re, mul_re, ofReal_re, sub_re, one_re, ofReal_im, sub_im, one_im, - sub_self, mul_zero, sub_zero] - refine mul_le_mul ?_ (hC _) (norm_nonneg _) ((abs_nonneg x).trans (le_max_left _ _)) - have hα0 : 0 ≤ σ' - 1 := by linarith - have hα1 : σ' - 1 ≤ 1 := by linarith - have hmul1 : (-x.log) * (σ' - 1) ≤ t * (σ' - 1) := mul_le_mul_of_nonneg_right ht hα0 - calc Real.exp (-(t * (σ' - 1))) - ≤ Real.exp (x.log * (σ' - 1)) := Real.exp_monotone (by linarith) - _ ≤ max |x| 1 := by - by_cases hx1 : 1 ≤ x - · calc _ ≤ Real.exp x.log := - Real.exp_monotone (mul_le_of_le_one_right (Real.log_nonneg hx1) hα1) - _ = |x| := by rw [Real.exp_log hx, abs_of_pos hx] - _ ≤ _ := le_max_left _ _ - · calc _ ≤ 1 := (Real.exp_monotone (mul_nonpos_of_nonpos_of_nonneg - ((Real.log_neg_iff hx).2 (by linarith)).le hα0)).trans_eq Real.exp_zero - _ ≤ _ := le_max_right _ _ - · suffices Tendsto (fun n ↦ ((rexp (-u * (n - 1))) : ℂ)) (𝓝[>] 1) (𝓝 1) by simpa using this.mul_const _ - refine Tendsto.mono_left ?_ nhdsWithin_le_nhds - have : Continuous (fun n ↦ ((rexp (-u * (n - 1))) : ℂ)) := by continuity - simpa using this.tendsto 1 - -theorem limiting_fourier_lim3_gt_zero - (hG : ContinuousOn G {s | 1 ≤ s.re}) (ψ : CS 2 ℂ) (hx : 0 < x) : - Tendsto (fun σ' : ℝ ↦ ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I)) (𝓝[>] 1) - (𝓝 (∫ t : ℝ, G (1 + t * I) * ψ t * x ^ (t * I))) := by - by_cases hh : tsupport ψ = ∅ - · simp [tsupport_eq_empty_iff.mp hh] - obtain ⟨a₀, ha₀⟩ := Set.nonempty_iff_ne_empty.mpr hh - let S : Set ℂ := reProdIm (Icc 1 2) (tsupport ψ) - have l1 : IsCompact S := Metric.isCompact_iff_isClosed_bounded.mpr - ⟨isClosed_Icc.reProdIm (isClosed_tsupport ψ), (Metric.isBounded_Icc 1 2).reProdIm ψ.h2.isBounded⟩ - have l2 : S ⊆ {s : ℂ | 1 ≤ s.re} := fun z hz => (mem_reProdIm.mp hz).1.1 - obtain ⟨z, -, hmax⟩ := l1.exists_isMaxOn ⟨1 + a₀ * I, by simp [S, mem_reProdIm, ha₀]⟩ (hG.mono l2).norm - have hxC : (x : ℂ) ≠ 0 := ofReal_ne_zero.mpr hx.ne' - refine tendsto_integral_filter_of_dominated_convergence (bound := fun a ↦ ‖G z‖ * ‖ψ a‖) - (eventually_of_mem (Icc_mem_nhdsGT_of_mem (by norm_num : (1 : ℝ) ∈ Set.Ico 1 2)) fun u hu ↦ - ((hG.comp_continuous (by fun_prop) (by simp [hu.1])).mul ψ.h1.continuous).mul - (by simpa using Continuous.const_cpow (by fun_prop) (Or.inl hxC)) |>.aestronglyMeasurable) - (eventually_of_mem (Icc_mem_nhdsGT_of_mem (by norm_num : (1 : ℝ) ∈ Set.Ico 1 2)) fun u hu ↦ - .of_forall fun v ↦ ?_) - ((continuous_const.mul ψ.h1.continuous.norm).integrable_of_hasCompactSupport ψ.h2.norm.mul_left) - (.of_forall fun t ↦ ?_) - · by_cases h : v ∈ tsupport ψ - · simp_rw [norm_mul, norm_x_cpow_it x v hx, mul_one] - exact mul_le_mul_of_nonneg_right (isMaxOn_iff.mp hmax _ (by simp [S, mem_reProdIm, hu.1, hu.2, h])) (norm_nonneg _) - · have : v ∉ Function.support ψ := fun a ↦ h (subset_tsupport ψ a) - simp [Function.notMem_support.mp this] - · exact ((hG (1 + t * I) (by simp)).tendsto.comp <| tendsto_nhdsWithin_iff.mpr - ⟨((continuous_ofReal.tendsto _).add tendsto_const_nhds).mono_left nhdsWithin_le_nhds, - eventually_nhdsWithin_of_forall fun _ hx' ↦ by simp [(Set.mem_Ioi.mp hx').le]⟩).mul_const _ |>.mul_const _ - -lemma tendsto_tsum_of_monotone_convergence - {β : Type*} {f : ℕ → β → ENNReal} {g : β → ENNReal} - (hmono : ∀ k, Monotone (fun n => f n k)) - (hlim : ∀ k, Tendsto (fun n => f n k) atTop (𝓝 (g k))) : - Tendsto (fun n => ∑' k, f n k) atTop (𝓝 (∑' k, g k)) := by - let : MeasurableSpace β := ⊤ - let μ : Measure β := Measure.count - have hg_iSup (k : β) : (⨆ n : ℕ, f n k) = g k := iSup_eq_of_tendsto (hmono k) (hlim k) - have h_tend_lint : Tendsto (fun n => ∫⁻ k, f n k ∂μ) atTop (𝓝 (∫⁻ k, (⨆ n, f n k) ∂μ)) := by - have hmeas : ∀ n, Measurable fun k : β => f n k := fun _ _ _ ↦ trivial - have hmono_fn : Monotone (fun n => fun k : β => f n k) := fun _ _ hnm k ↦ hmono k hnm - simpa [lintegral_iSup hmeas hmono_fn] using - tendsto_atTop_iSup fun _ _ hmn ↦ lintegral_mono fun k ↦ hmono k hmn - simpa [μ, lintegral_count, hg_iSup] using h_tend_lint - -lemma tendsto_tsum_of_monotone_convergence_nhdsGT_one - {F : ℝ → ℕ → ℝ} - (hF_nonneg : ∀ σ n, 0 ≤ F σ n) - (hF_antitone : ∀ n, AntitoneOn (fun σ : ℝ => F σ n) (Set.Ioi (1 : ℝ))) - (hF_tend : ∀ n, Tendsto (fun σ : ℝ => F σ n) (𝓝[>] (1 : ℝ)) (𝓝 (F 1 n))) - (hSumm : ∀ σ, 1 < σ → Summable (fun n : ℕ => F σ n)) - (hbounded : - BoundedAtFilter (𝓝[>] (1 : ℝ)) (fun σ : ℝ => (∑' n : ℕ, F σ n))) : - Tendsto (fun σ : ℝ => ∑' n : ℕ, F σ n) (𝓝[>] (1 : ℝ)) (𝓝 (∑' n : ℕ, F 1 n)) := by - let T : ℝ → ℝ := fun σ => ∑' n : ℕ, F σ n - have hT_antitone : AntitoneOn T (Set.Ioi (1 : ℝ)) := fun a ha b hb hab ↦ - (hSumm b hb).tsum_le_tsum_of_inj (fun n ↦ n) (fun _ _ h ↦ h) (fun c hc ↦ (hc ⟨c, rfl⟩).elim) - (fun n ↦ hF_antitone n ha hb hab) (hSumm a ha) - have hT_bdd : BddAbove (T '' Set.Ioi (1 : ℝ)) := by - obtain ⟨C, hC⟩ := isBigO_iff.1 hbounded - have hC' : ∀ᶠ σ : ℝ in 𝓝[>] (1 : ℝ), T σ ≤ C := by - filter_upwards [hC] with σ hσ - calc T σ ≤ |T σ| := le_abs_self _ - _ = ‖T σ‖ := (Real.norm_eq_abs _).symm - _ ≤ C * ‖(1 : ℝ → ℝ) σ‖ := hσ - _ = C := by simp - obtain ⟨U, hU, V, hV, hUV⟩ := Filter.mem_inf_iff_superset.1 hC' - obtain ⟨ε, hε, hball⟩ := Metric.mem_nhds_iff.1 hU - have hIoi_sub : Set.Ioi (1 : ℝ) ⊆ V := Filter.mem_principal.mp hV - have hUsub : U ∩ Set.Ioi (1 : ℝ) ⊆ {σ : ℝ | T σ ≤ C} := fun σ hσ ↦ hUV ⟨hσ.1, hIoi_sub hσ.2⟩ - have hσ0_Ioi : 1 + ε / 2 ∈ Set.Ioi (1 : ℝ) := by simp [half_pos hε] - have hσ0_leC : T (1 + ε / 2) ≤ C := - hUsub ⟨hball (by simp only [Metric.mem_ball, Real.dist_eq, add_sub_cancel_left, - abs_of_pos (half_pos hε)]; exact half_lt_self hε), hσ0_Ioi⟩ - refine ⟨C, ?_⟩ - rintro _ ⟨σ, hσIoi, rfl⟩ - by_cases hσlt : σ < 1 + ε / 2 - · exact hUsub ⟨hball (by - simp only [Metric.mem_ball, Real.dist_eq] - rw [abs_of_pos (sub_pos.2 (Set.mem_Ioi.mp hσIoi))] - linarith [half_lt_self hε]), hσIoi⟩ - · exact (hT_antitone hσ0_Ioi hσIoi (le_of_not_gt hσlt)).trans hσ0_leC - have hT_tend_sup : Tendsto T (𝓝[>] (1 : ℝ)) (𝓝 (sSup (T '' Set.Ioi (1 : ℝ)))) := - hT_antitone.tendsto_nhdsGT hT_bdd - let σseq : ℕ → ℝ := fun k => 1 + 1 / (k + 1 : ℝ) - have hσseq_mem (k) : σseq k ∈ Set.Ioi (1 : ℝ) := by - simp only [σseq, Set.mem_Ioi, lt_add_iff_pos_right] - positivity - have hσseq_tend_nhds : Tendsto σseq atTop (𝓝 (1 : ℝ)) := by - have : Tendsto (fun k : ℕ => (1 : ℝ) + ((k + 1 : ℕ) : ℝ)⁻¹) atTop (𝓝 ((1 : ℝ) + 0)) := - tendsto_const_nhds.add (tendsto_inv_atTop_nhds_zero_nat.comp (tendsto_add_atTop_nat 1)) - simp only [add_zero] at this - convert this using 1; ext k; simp [σseq, one_div] - have hσseq_tend_nhdsWithin : Tendsto σseq atTop (𝓝[>] (1 : ℝ)) := - tendsto_nhdsWithin_of_tendsto_nhds_of_eventually_within _ hσseq_tend_nhds - (.of_forall hσseq_mem) - have hσseq_antitone : Antitone σseq := fun k₁ k₂ hk ↦ by simp only [σseq]; gcongr - have hmono_seq (n) : Monotone (fun k => F (σseq k) n) := fun k₁ k₂ hk ↦ - hF_antitone n (hσseq_mem k₂) (hσseq_mem k₁) (hσseq_antitone hk) - have htend_seq (n) : Tendsto (fun k => F (σseq k) n) atTop (𝓝 (F 1 n)) := - (hF_tend n).comp hσseq_tend_nhdsWithin - have hTseq : Tendsto (fun k : ℕ => T (σseq k)) atTop (𝓝 (T 1)) := by - have hsum1 : Summable (fun n : ℕ => F (1 : ℝ) n) := by - obtain ⟨C, hC⟩ := hT_bdd - refine summable_of_sum_range_le (hF_nonneg 1) fun m ↦ le_of_tendsto - (tendsto_finsetSum _ fun i _ ↦ hF_tend i) - (eventually_of_mem self_mem_nhdsWithin fun σ hσ ↦ - ((hSumm σ hσ).sum_le_tsum _ (fun n _ ↦ hF_nonneg σ n)).trans (hC ⟨σ, hσ, rfl⟩)) - have hg_ne_top : (∑' n : ℕ, ENNReal.ofReal (F 1 n)) ≠ ⊤ := hsum1.tsum_ofReal_ne_top - have hENN : Tendsto (fun k => ∑' n, ENNReal.ofReal (F (σseq k) n)) atTop - (𝓝 (∑' n, ENNReal.ofReal (F 1 n))) := - tendsto_tsum_of_monotone_convergence (fun n _ _ hk ↦ ENNReal.ofReal_le_ofReal (hmono_seq n hk)) - (fun n ↦ ENNReal.tendsto_ofReal (htend_seq n)) - have hrew (σ) : (∑' n, ENNReal.ofReal (F σ n)).toReal = ∑' n, F σ n := by - rw [ENNReal.tsum_toReal_eq (fun n ↦ by simp)] - exact tsum_congr fun n ↦ by simp [hF_nonneg σ n] - simp only [T, ← hrew]; exact (ENNReal.tendsto_toReal hg_ne_top).comp hENN - have hsSup_eq : sSup (T '' Set.Ioi (1 : ℝ)) = T 1 := - tendsto_nhds_unique (hT_tend_sup.comp hσseq_tend_nhdsWithin) hTseq - simpa [T, hsSup_eq] using hT_tend_sup - -lemma limiting_fourier_variant_lim1_aux - {f : ℕ → ℝ} {x : ℝ} (ψ : CS 2 ℂ) - (hpos : 0 ≤ f) - (hf : ∀ (σ : ℝ), 1 < σ → Summable (nterm f σ)) - (hψpos : ∀ y, 0 ≤ (𝓕 (ψ : ℝ → ℂ) y).re ∧ (𝓕 (ψ : ℝ → ℂ) y).im = 0) : - ∀ (σ : ℝ), 1 < σ → - Summable (fun n : ℕ => - (if n = 0 then 0 else f n / ((n : ℝ) ^ σ)) * - (𝓕 ψ.toFun (1 / (2 * π) * Real.log ((n : ℝ) / x))).re) := by - intro σ hσ - let y : ℕ → ℝ := fun n => (1 / (2 * π)) * Real.log ((n : ℝ) / x) - let W : ℕ → ℝ := fun n => (𝓕 ψ.toFun (y n)).re - let base : ℕ → ℝ := fun n => if n = 0 then 0 else f n / ((n : ℝ) ^ σ) - obtain ⟨C, hC⟩ := decay_bounds_cor (W21.ofCS2 ψ) - have hC_nonneg : 0 ≤ C := (norm_nonneg _).trans ((hC 0).trans (by simp)) - have hW_nonneg (n : ℕ) : 0 ≤ W n := (hψpos (y n)).1 - have hnorm_four (n : ℕ) : ‖𝓕 ψ.toFun (y n)‖ = W n := by - have him0 : (𝓕 ψ.toFun (y n)).im = 0 := (hψpos (y n)).2 - rw [show 𝓕 ψ.toFun (y n) = W n by exact Complex.ext rfl him0] - simp [abs_of_nonneg (hW_nonneg n)] - have hW_le_C (n : ℕ) : W n ≤ C := by - rw [← hnorm_four]; exact (hC (y n)).trans (div_le_self hC_nonneg (by nlinarith [sq_nonneg (y n)])) - have hbase_summ : Summable base := by - convert hf σ hσ using 1; ext n - by_cases hn : n = 0 <;> simp [nterm, base, hn, Real.norm_eq_abs, abs_of_nonneg (hpos n)] - refine (hbase_summ.mul_left C).of_norm_bounded fun n ↦ ?_ - by_cases hn : n = 0 - · simp [base, hn] - · have hnpos : 0 < (n : ℝ) := Nat.cast_pos.mpr (Nat.pos_of_ne_zero hn) - have hbase_nonneg : 0 ≤ base n := by - simp only [base, hn, ite_false] - exact div_nonneg (hpos n) (Real.rpow_pos_of_pos hnpos σ).le - calc |base n * W n| = base n * W n := abs_of_nonneg (mul_nonneg hbase_nonneg (hW_nonneg n)) - _ ≤ base n * C := mul_le_mul_of_nonneg_left (hW_le_C n) hbase_nonneg - _ = C * base n := mul_comm _ _ - - -theorem limiting_fourier_variant_lim1 - {f : ℕ → ℝ} {x : ℝ} {ψ : CS 2 ℂ} - (hpos : 0 ≤ f) - (hψpos : ∀ y, 0 ≤ (𝓕 (ψ : ℝ → ℂ) y).re ∧ (𝓕 (ψ : ℝ → ℂ) y).im = 0) - (S : ℝ → ℂ) - (hSdef : - ∀ σ' : ℝ, - S σ' = - ∑' n : ℕ, - term (fun n ↦ (f n : ℂ)) (σ' : ℝ) n * - 𝓕 ψ.toFun (π⁻¹ * 2⁻¹ * Real.log ((n : ℝ) / x))) - (hbounded : BoundedAtFilter (𝓝[>] (1 : ℝ)) (fun σ' : ℝ => ‖S σ'‖)) - (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) : - Tendsto - (fun σ' : ℝ => - ∑' n : ℕ, - term (fun n ↦ (f n : ℂ)) (σ' : ℝ) n * - 𝓕 ψ.toFun (π⁻¹ * 2⁻¹ * Real.log ((n : ℝ) / x))) - (𝓝[>] (1 : ℝ)) - (𝓝 - (∑' n : ℕ, - (f n : ℂ) / (n : ℂ) * - 𝓕 ψ.toFun (π⁻¹ * 2⁻¹ * Real.log ((n : ℝ) / x)))) := by - - let y : ℕ → ℝ := fun n => (π⁻¹ * 2⁻¹) * Real.log ((n : ℝ) / x) - let w : ℕ → ℝ := fun n => (𝓕 ψ.toFun (y n)).re - - have hw_nonneg : ∀ n, 0 ≤ w n := by - intro n - exact (hψpos (y n)).1 - - have hFour_eq_ofReal : ∀ n, 𝓕 ψ.toFun (y n) = Complex.ofReal (w n) := by - intro n - have h := hψpos (y n) - refine Complex.ext ?_ ?_ - · simp [w] - · simp [w, h.2] - - let rterm : ℝ → ℕ → ℝ := - fun σ n => - if h0 : n = 0 then 0 else (f n) / ((n : ℝ) ^ σ) * (w n) - - have summand_eq_ofReal : - ∀ (σ : ℝ) (n : ℕ), - term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n) - = Complex.ofReal (rterm σ n) := by - intro σ n - by_cases hn : n = 0 - · subst hn - simp [rterm, y] - · have hnpos : (0 : ℝ) < (n : ℝ) := by - exact_mod_cast (Nat.pos_of_ne_zero hn) - have hn0 : 0 ≤ (n : ℝ) := le_of_lt hnpos - have hcpow : - ( (n : ℂ) ^ ((σ : ℝ) : ℂ) ) = ( ( (n : ℝ) ^ σ : ℝ) : ℂ ) := by - simpa using (Complex.ofReal_cpow hn0 σ).symm - have hpow_ne : ((n : ℝ) ^ σ) ≠ 0 := by - exact (ne_of_gt (Real.rpow_pos_of_pos hnpos σ)) - calc - term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n) - = - ((f n : ℂ) / ((n : ℂ) ^ ((σ : ℝ) : ℂ))) * ( (w n : ℝ) : ℂ ) := by - simp [term, LSeries.term, hn, hFour_eq_ofReal] - _ = - ((f n : ℂ) / (((n : ℝ) ^ σ : ℝ) : ℂ)) * ((w n : ℝ) : ℂ) := by - simp [hcpow] - _ = - (( (f n : ℝ) : ℂ) / (((n : ℝ) ^ σ : ℝ) : ℂ)) * ((w n : ℝ) : ℂ) := by - simp - _ = - ( ( (f n : ℝ) / ((n : ℝ) ^ σ) : ℝ) : ℂ ) * ((w n : ℝ) : ℂ) := by - simp [Complex.ofReal_div] - _ = - ( ( (f n : ℝ) / ((n : ℝ) ^ σ) * (w n) : ℝ ) : ℂ ) := by - simp [Complex.ofReal_mul] - _ = - Complex.ofReal (rterm σ n) := by - simp [rterm, hn] - - let T : ℝ → ℝ := fun σ => ∑' n, rterm σ n - - have tsum_eq_ofReal_T : ∀ σ : ℝ, - (∑' n : ℕ, term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) - = Complex.ofReal (T σ) := by - intro σ - have hcongr : - (∑' n : ℕ, term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) - = ∑' n : ℕ, (Complex.ofReal (rterm σ n)) := by - refine tsum_congr ?_ - intro n - simpa using (summand_eq_ofReal σ n) - - calc - (∑' n : ℕ, term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) - = ∑' n : ℕ, (Complex.ofReal (rterm σ n)) := hcongr - _ = Complex.ofReal (∑' n : ℕ, rterm σ n) := by - simpa using (Complex.ofReal_tsum (fun n : ℕ => rterm σ n)).symm - _ = Complex.ofReal (T σ) := by rfl - - have hS_ofReal_T : ∀ σ : ℝ, S σ = Complex.ofReal (T σ) := by - intro σ - simpa [hSdef σ, y] using (tsum_eq_ofReal_T σ) - - have rterm_nonneg : ∀ σ n, 0 ≤ rterm σ n := by - intro σ n - by_cases hn : n = 0 - · subst hn; simp [rterm] - · have hf : 0 ≤ f n := hpos n - have hw : 0 ≤ w n := hw_nonneg n - have hnpos : 0 < (n : ℝ) := by - exact_mod_cast (Nat.pos_of_ne_zero hn) - have hden : 0 < (n : ℝ) ^ σ := Real.rpow_pos_of_pos hnpos σ - have : 0 ≤ (f n) / ((n : ℝ) ^ σ) := div_nonneg hf (le_of_lt hden) - simp [rterm, hn, mul_nonneg this hw] - - have T_nonneg : ∀ σ, 0 ≤ T σ := by - intro σ - exact tsum_nonneg (fun n => rterm_nonneg σ n) - - have hT_eq_normS : ∀ σ, T σ = ‖S σ‖ := by - intro σ - have := hS_ofReal_T σ - calc - T σ = ‖Complex.ofReal (T σ)‖ := by simp [abs_of_nonneg (T_nonneg σ)] - _ = ‖S σ‖ := by simp [this] - - have hboundedT : BoundedAtFilter (𝓝[>] (1 : ℝ)) (fun σ : ℝ => T σ) := by - have : (fun σ : ℝ => T σ) = (fun σ : ℝ => ‖S σ‖) := by - funext σ; exact hT_eq_normS σ - simpa [this] using hbounded - - have rterm_antitone : ∀ n, AntitoneOn (fun σ => rterm σ n) (Set.Ioi 1) := by - intro n σ₁ hσ₁ σ₂ hσ₂ hσ₁₂ - by_cases hn : n = 0 - · subst hn; simp [rterm] - · have hf : 0 ≤ f n := hpos n - have hw : 0 ≤ w n := hw_nonneg n - have hnpos : 0 < (n : ℝ) := by exact_mod_cast (Nat.pos_of_ne_zero hn) - have hn1 : (1 : ℝ) ≤ (n : ℝ) := by - exact_mod_cast (Nat.one_le_iff_ne_zero.mpr hn) - have hpow : (n : ℝ) ^ σ₁ ≤ (n : ℝ) ^ σ₂ := - Real.rpow_le_rpow_of_exponent_le hn1 hσ₁₂ - have hinv : - (1 / ((n : ℝ) ^ σ₂)) ≤ (1 / ((n : ℝ) ^ σ₁)) := by - have hpos1 : 0 < (n : ℝ) ^ σ₁ := Real.rpow_pos_of_pos hnpos σ₁ - exact one_div_le_one_div_of_le hpos1 hpow - have hinv_inv : ((n : ℝ) ^ σ₂)⁻¹ ≤ ((n : ℝ) ^ σ₁)⁻¹ := by - simpa [one_div] using hinv - have hmul1 : - (f n) * (((n : ℝ) ^ σ₂)⁻¹) ≤ (f n) * (((n : ℝ) ^ σ₁)⁻¹) := - mul_le_mul_of_nonneg_left hinv_inv hf - have hmul2 : - ((f n) * (((n : ℝ) ^ σ₂)⁻¹)) * (w n) - ≤ ((f n) * (((n : ℝ) ^ σ₁)⁻¹)) * (w n) := - mul_le_mul_of_nonneg_right hmul1 hw - simpa [rterm, hn, div_eq_mul_inv, mul_assoc] using hmul2 - - have rterm_tend : ∀ n, Tendsto (fun σ : ℝ => rterm σ n) (𝓝[>] (1 : ℝ)) (𝓝 (rterm 1 n)) := by - intro n - have hterm : - Tendsto (fun σ : ℝ => term (fun n ↦ (f n : ℂ)) (σ : ℝ) n) - (𝓝[>] (1 : ℝ)) (𝓝 ((f n : ℂ) / (n : ℂ))) := by - by_cases hn : n = 0 - · subst hn - simp [term, LSeries.term] - · have hden : - Tendsto (fun σ : ℝ => ((n : ℂ) ^ ((σ : ℝ) : ℂ))) (𝓝[>] (1 : ℝ)) (𝓝 ((n : ℂ) ^ (1 : ℂ))) := by - simpa using ((continuous_ofReal.tendsto (1 : ℝ)).mono_left nhdsWithin_le_nhds).const_cpow - - have hden' : - Tendsto (fun σ : ℝ => ((n : ℂ) ^ ((σ : ℝ) : ℂ))) (𝓝[>] (1 : ℝ)) (𝓝 (n : ℂ)) := by - simpa using hden - - have hnC : (n : ℂ) ≠ 0 := by - exact_mod_cast hn - - have hterm : - Tendsto (fun σ : ℝ => term (fun n ↦ (f n : ℂ)) (σ : ℝ) n) - (𝓝[>] (1 : ℝ)) (𝓝 ((f n : ℂ) / (n : ℂ))) := by - have hnC : (n : ℂ) ≠ 0 := by - exact_mod_cast hn - simpa [term, LSeries.term, hn] using! - (tendsto_const_nhds.div hden' hnC) - exact hterm - - have hsummand : - Tendsto - (fun σ : ℝ => - term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) - (𝓝[>] (1 : ℝ)) - (𝓝 (((f n : ℂ) / (n : ℂ)) * 𝓕 ψ.toFun (y n))) := by - simpa [mul_assoc, mul_left_comm, mul_comm] using (hterm.mul_const (𝓕 ψ.toFun (y n))) - - have hre : ∀ σ, rterm σ n = - (term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)).re := by - intro σ - have := congrArg Complex.re (summand_eq_ofReal σ n) - simpa [Complex.ofReal_re] using this.symm - - have hRe : Tendsto - (fun σ : ℝ => - (term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)).re) - (𝓝[>] (1 : ℝ)) - (𝓝 ((((f n : ℂ) / (n : ℂ)) * 𝓕 ψ.toFun (y n)).re)) := - (continuous_re.tendsto _).comp hsummand - - have hlimit_re : - (f n / (n : ℝ)) * (𝓕 ψ.toFun (y n)).re = rterm 1 n := by - have h0 : - (term (fun n ↦ (f n : ℂ)) (1 : ℝ) n * 𝓕 ψ.toFun (y n)).re = rterm 1 n := by - have := congrArg Complex.re (summand_eq_ofReal (σ := (1 : ℝ)) n) - simpa [Complex.ofReal_re] using this - - by_cases hn : n = 0 - · subst hn - simp [rterm, y] - · have h1 : - (term (fun n ↦ (f n : ℂ)) (1 : ℝ) n * 𝓕 ψ.toFun (y n)).re - = (f n / (n : ℝ)) * (𝓕 ψ.toFun (y n)).re := by - simp [Complex.mul_re, term, LSeries.term, hn, y, - (hψpos (y n)).2] - - exact (h1.symm.trans h0) - - simpa [hre, hlimit_re] using hRe - - have hSumm_rterm : ∀ σ : ℝ, 1 < σ → Summable (fun n : ℕ => rterm σ n) := by - simpa [rterm] using limiting_fourier_variant_lim1_aux (ψ := ψ) - (f := f) (x := x) hpos hf hψpos - - have hT_tend : - Tendsto T (𝓝[>] (1 : ℝ)) (𝓝 (T 1)) := by - have : - Tendsto (fun σ : ℝ => ∑' n : ℕ, rterm σ n) - (𝓝[>] (1 : ℝ)) - (𝓝 (∑' n : ℕ, rterm (1 : ℝ) n)) := by - refine tendsto_tsum_of_monotone_convergence_nhdsGT_one - (F := rterm) - (hF_nonneg := rterm_nonneg) - (hF_antitone := rterm_antitone) - (hF_tend := rterm_tend) - (hSumm := hSumm_rterm) - (hbounded := hboundedT) - - simpa [T] using this - - have hToReal : - Tendsto (fun σ => Complex.ofReal (T σ)) (𝓝[>] (1 : ℝ)) (𝓝 (Complex.ofReal (T 1))) := - (continuous_ofReal.tendsto _).comp hT_tend - - have hsource : - (fun σ : ℝ => - ∑' n : ℕ, - term (fun n ↦ (f n : ℂ)) (σ : ℝ) n * 𝓕 ψ.toFun (y n)) - = fun σ : ℝ => Complex.ofReal (T σ) := by - funext σ - exact (tsum_eq_ofReal_T σ) - - have hσ1 : - (∑' n : ℕ, term (fun n ↦ (f n : ℂ)) (↑(1:ℝ)) n * 𝓕 ψ.toFun (y n)) - = (↑(T 1) : ℂ) := - by simpa using (tsum_eq_ofReal_T (σ := (1:ℝ))) - have hterm1 : - ∀ n : ℕ, term (fun n ↦ (f n : ℂ)) (1 : ℂ) n = (f n : ℂ) / (n : ℂ) := by - intro n - by_cases hn : n = 0 - · subst hn - simp [term, LSeries.term] - · simp [term, LSeries.term, hn] - - have hrewrite : - (∑' n : ℕ, - term (fun n ↦ (f n : ℂ)) (1 : ℂ) n * 𝓕 ψ.toFun (y n)) - = - (∑' n : ℕ, - (f n : ℂ) / (n : ℂ) * 𝓕 ψ.toFun (y n)) := by - refine tsum_congr ?_ - intro n - simp [hterm1 n] - - have htarget : - (∑' n : ℕ, - (f n : ℂ) / (n : ℂ) * 𝓕 ψ.toFun (y n)) - = (↑(T 1) : ℂ) := by - exact (hrewrite.symm.trans hσ1) - - simpa [hsource, htarget, y] using hToReal - - - - -blueprint_comment /-- -\section{Removing the Chebyshev hypothesis} - -In this section we do *not* assume the bound \eqref{cheby}, but instead derive it from the other hypotheses. - --/ - -@[blueprint "limiting-fourier-variant" - (title := "limiting-fourier-variant") - (statement := /-- - If $\psi: \R \to \C$ is $C^2$ and compactly supported with $f$ and $\hat \psi$ non-negative, and $0 < x$, then - $$ \sum_{n=1}^\infty \frac{f(n)}{n} \hat \psi( \frac{1}{2\pi} \log \frac{n}{x} ) - A \int_{-\log x}^\infty \hat \psi(\frac{u}{2\pi})\ du = \int_\R G(1+it) \psi(t) x^{it}\ dt.$$ - -/) - (proof := /-- Repeat the proof of Lemma \ref{limiting-fourier-variant}, but use monotone convergence instead of dominated convergence. (The proof should be simpler, as one no longer needs to establish domination for the sum.) -/) - (proofUses := ["decay", "second-fourier", "first-fourier"]) - (latexEnv := "lemma")] -lemma limiting_fourier_variant - (hpos : 0 ≤ f) - (hG : ContinuousOn G {s | 1 ≤ s.re}) - (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) - (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (ψ : CS 2 ℂ) - (hψpos : ∀ y, 0 ≤ (𝓕 (ψ : ℝ → ℂ) y).re ∧ (𝓕 (ψ : ℝ → ℂ) y).im = 0) - (hx : 0 < x) : - ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - - A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = - ∫ (t : ℝ), (G (1 + t * I)) * (ψ t) * x ^ (t * I) := by - - have l2 := limiting_fourier_lim2_gt_zero (A := A) (x := x) ψ hx - have l3 := limiting_fourier_lim3_gt_zero (G := G) (x := x) hG ψ hx - - let S : ℝ → ℂ := fun σ' => - ∑' n : ℕ, - term (fun n ↦ (f n : ℂ)) σ' n * - 𝓕 ψ.toFun (1 / (2 * π) * Real.log ((n : ℝ) / x)) - let Pole : ℝ → ℂ := fun σ' => - (A : ℂ) * ((x ^ (1 - σ') : ℝ) : ℂ) * - ∫ u in Set.Ici (-Real.log x), - (rexp (-u * (σ' - 1)) : ℂ) * - 𝓕 (W21.ofCS2 ψ).toFun (u / (2 * π)) - let RHS : ℝ → ℂ := fun σ' => - ∫ t : ℝ, G (σ' + t * I) * ψ.toFun t * (x : ℂ) ^ (t * I) - - - have haux : - (fun (σ' : ℝ) ↦ - ∑' (n : ℕ), - term (fun n ↦ (f n : ℂ)) (σ' : ℂ) n * - 𝓕 ψ.toFun (π⁻¹ * 2⁻¹ * Real.log ((n : ℝ) / x)) - - (A : ℂ) * ((x ^ (1 - σ') : ℝ) : ℂ) * - ∫ (u : ℝ) in Ici (-Real.log x), - cexp (-( (u : ℂ) * ((σ' : ℂ) - 1))) * - 𝓕 (W21.ofCS2 ψ).toFun (u / (2 * π))) - =ᶠ[𝓝[>] (1 : ℝ)] - (fun σ' ↦ - ∫ (t : ℝ), G ((σ' : ℂ) + (t : ℂ) * I) * ψ.toFun t * (x : ℂ) ^ ((t : ℂ) * I)) := by - rw [Filter.EventuallyEq] - - refine eventually_nhdsWithin_of_forall ?_ - intro σ' hσ' - have hσ' : (1 : ℝ) < σ' := by - simpa [Set.mem_Ioi] using hσ' - simpa using! (limiting_fourier_aux_gt_zero (G := G) (f := f) (A := A) hG' hf ψ hx σ' hσ') - - have haux' : - (fun σ' : ℝ => S σ') =ᶠ[𝓝[>] (1 : ℝ)] (fun σ' : ℝ => RHS σ' + Pole σ') := by - rw [Filter.EventuallyEq] at haux ⊢ - filter_upwards [haux] with σ' hσ' - have hσ'' : S σ' - Pole σ' = RHS σ' := by - simpa [S, Pole, RHS] using hσ' - have hadd : (S σ' - Pole σ') + Pole σ' = RHS σ' + Pole σ' := - congrArg (fun z : ℂ => z + Pole σ') hσ'' - simpa [sub_eq_add_neg, add_assoc, add_left_comm, add_comm] using hadd - - let Pole₁ : ℂ := (A : ℂ) * ∫ u in Set.Ici (-Real.log x), 𝓕 (W21.ofCS2 ψ).toFun (u / (2 * π)) - let RHS₁ : ℂ := ∫ t : ℝ, G (1 + (t : ℂ) * I) * ψ.toFun t * (x : ℂ) ^ ((t : ℂ) * I) - - have hRHS_le : - ∀ᶠ σ' : ℝ in 𝓝[>] (1 : ℝ), ‖RHS σ'‖ ≤ ‖RHS₁‖ + 1 := by - have hball : Metric.ball RHS₁ (1 : ℝ) ∈ 𝓝 RHS₁ := by - simpa using (Metric.ball_mem_nhds (x := RHS₁) (ε := (1 : ℝ)) (by norm_num)) - have hpre : {σ' : ℝ | RHS σ' ∈ Metric.ball RHS₁ (1 : ℝ)} ∈ (𝓝[>] (1 : ℝ)) := - l3 hball - filter_upwards [hpre] with σ' hmem - have hdist' : dist (RHS σ') RHS₁ < (1 : ℝ) := by - simpa [Metric.mem_ball] using hmem - have hdist : ‖RHS σ' - RHS₁‖ < (1 : ℝ) := by - simpa [dist_eq_norm] using hdist' - have htri : ‖RHS σ'‖ ≤ ‖RHS₁‖ + ‖RHS σ' - RHS₁‖ := by - have h := norm_add_le (RHS σ' - RHS₁) RHS₁ - simpa [sub_add_cancel, add_comm, add_left_comm, add_assoc] using h - have hle : ‖RHS₁‖ + ‖RHS σ' - RHS₁‖ ≤ ‖RHS₁‖ + (1 : ℝ) := by - exact add_le_add_right (le_of_lt hdist) ‖RHS₁‖ - exact htri.trans hle - - have hPole_le : - ∀ᶠ σ' : ℝ in 𝓝[>] (1 : ℝ), ‖Pole σ'‖ ≤ ‖Pole₁‖ + 1 := by - have hball : Metric.ball Pole₁ 1 ∈ 𝓝 Pole₁ := by - simpa using (Metric.ball_mem_nhds Pole₁ (by norm_num : (0 : ℝ) < 1)) - have hpre : {σ' : ℝ | Pole σ' ∈ Metric.ball Pole₁ 1} ∈ (𝓝[>] (1 : ℝ)) := l2 hball - filter_upwards [hpre] with σ' hmem - have hdist : ‖Pole σ' - Pole₁‖ < 1 := by - simpa [Metric.mem_ball, dist_eq_norm] using hmem - have htri : ‖Pole σ'‖ ≤ ‖Pole₁‖ + ‖Pole σ' - Pole₁‖ := by - have hdecomp : Pole σ' = Pole₁ + (Pole σ' - Pole₁) := by abel - have hnorm_eq : ‖Pole σ'‖ = ‖Pole₁ + (Pole σ' - Pole₁)‖ := by - simp [congrArg (fun z : ℂ => ‖z‖) hdecomp] - calc - ‖Pole σ'‖ = ‖Pole₁ + (Pole σ' - Pole₁)‖ := hnorm_eq - _ ≤ ‖Pole₁‖ + ‖Pole σ' - Pole₁‖ := norm_add_le _ _ - have hdist_le : ‖Pole σ' - Pole₁‖ ≤ 1 := le_of_lt hdist - have hsum : ‖Pole₁‖ + ‖Pole σ' - Pole₁‖ ≤ ‖Pole₁‖ + 1 := by - simpa [add_comm, add_left_comm, add_assoc] using (add_le_add_left hdist_le ‖Pole₁‖) - exact htri.trans hsum - - have hS_le : - ∀ᶠ σ' : ℝ in 𝓝[>] (1 : ℝ), - ‖S σ'‖ ≤ (‖RHS₁‖ + 1) + (‖Pole₁‖ + 1) := by - rw [Filter.EventuallyEq] at haux' - filter_upwards [haux', hRHS_le, hPole_le] with σ' hEq hR hP - calc - ‖S σ'‖ = ‖RHS σ' + Pole σ'‖ := by simp [hEq] - _ ≤ ‖RHS σ'‖ + ‖Pole σ'‖ := norm_add_le _ _ - _ ≤ (‖RHS₁‖ + 1) + (‖Pole₁‖ + 1) := by - exact add_le_add hR hP - - have hbounded : BoundedAtFilter (𝓝[>] (1 : ℝ)) (fun σ' : ℝ => ‖S σ'‖) := by - let C : ℝ := ‖RHS₁‖ + 1 + (‖Pole₁‖ + 1) - simp only [BoundedAtFilter, Asymptotics.IsBigO, Asymptotics.IsBigOWith] - refine ⟨C, ?_⟩ - filter_upwards [hS_le] with σ' hσ' - simpa [Real.norm_eq_abs, abs_of_nonneg (norm_nonneg (S σ'))] using hσ' - - have hcoef : (1 / (2 * π) : ℝ) = (π⁻¹ * 2⁻¹ : ℝ) := by field_simp [pi_ne_zero] - - have l1 := - limiting_fourier_variant_lim1 - (f := f) (x := x) (ψ := ψ) - hpos hψpos - (S := S) - (hSdef := by - intro σ - simp [S, hcoef] ) - hbounded - hf - have l1S : - Tendsto S (𝓝[>] (1 : ℝ)) - (𝓝 (∑' n : ℕ, (f n : ℂ) / (n : ℂ) * 𝓕 ψ.toFun (1 / (2 * π) * Real.log (↑n / x)))) := by - simpa [S, hcoef] using l1 - - have l12 : Tendsto (fun σ' : ℝ => S σ' - Pole σ') (𝓝[>] (1 : ℝ)) - (𝓝 ((∑' n : ℕ, (f n : ℂ) / (n : ℂ) * 𝓕 ψ.toFun (1 / (2 * π) * Real.log (↑n / x))) - Pole₁)) := - l1S.sub l2 - - have hPole : (Pole : ℝ → ℂ) =ᶠ[𝓝[>] (1 : ℝ)] Pole := by simp - have haux_sub : - (fun σ' : ℝ => S σ' - Pole σ') =ᶠ[𝓝[>] (1 : ℝ)] RHS := by - filter_upwards [haux'] with σ' hσ' - calc - S σ' - Pole σ' - = (RHS σ' + Pole σ') - Pole σ' := by simp [hσ'] - _ = RHS σ' := by simp - have hlim := - tendsto_nhds_unique_of_eventuallyEq (l1S.sub l2) l3 haux_sub - - simpa [Pole₁, RHS₁] using! hlim - - -lemma norm_mul_integral_Ici_le_integral_norm - (A : ℂ) (F : ℝ → ℂ) (a : ℝ) - (hF : IntegrableOn F (Set.Ici a)) - (hnorm : Integrable (fun u : ℝ => ‖F u‖)) : - ‖A * (∫ u in Set.Ici a, F u)‖ ≤ ‖A‖ * (∫ u : ℝ, ‖F u‖) := by - have hmul : ‖A * (∫ u in Set.Ici a, F u)‖ = ‖A‖ * ‖∫ u in Set.Ici a, F u‖ := by - simp - have hnormI : - ‖∫ u in Set.Ici a, F u‖ ≤ ∫ u in Set.Ici a, ‖F u‖ := by - have _ : Integrable F (Measure.restrict volume (Set.Ici a)) := hF - have h : - ‖∫ u, F u ∂Measure.restrict volume (Set.Ici a)‖ - ≤ ∫ u, ‖F u‖ ∂Measure.restrict volume (Set.Ici a) := - norm_integral_le_integral_norm (μ := Measure.restrict volume (Set.Ici a)) (f := F) - simpa using h - - have hdom : - (∫ u in Set.Ici a, ‖F u‖) ≤ ∫ u : ℝ, ‖F u‖ := by - have hEq : - (∫ u in Set.Ici a, ‖F u‖) = - ∫ u : ℝ, Set.indicator (Set.Ici a) (fun u => ‖F u‖) u := by - have h := (integral_indicator (μ := (volume : Measure ℝ)) - (s := Set.Ici a) (f := fun u => ‖F u‖)) - have h' := h measurableSet_Ici - simpa using h'.symm - have hind_int : - Integrable (Set.indicator (Set.Ici a) (fun u => ‖F u‖)) := - hnorm.indicator measurableSet_Ici - have hpoint : - Set.indicator (Set.Ici a) (fun u => ‖F u‖) - ≤ᵐ[volume] (fun u : ℝ => ‖F u‖) := by - filter_upwards with u - by_cases hu : u ∈ Set.Ici a - · simp [Set.indicator_of_mem hu] - · simp [Set.indicator_of_notMem hu] - have hmono := - integral_mono_ae (μ := (volume : Measure ℝ)) - hind_int hnorm hpoint - simpa [hEq] using hmono - - calc - ‖A * (∫ u in Set.Ici a, F u)‖ - = ‖A‖ * ‖∫ u in Set.Ici a, F u‖ := hmul - _ ≤ ‖A‖ * (∫ u in Set.Ici a, ‖F u‖) := - mul_le_mul_of_nonneg_left hnormI (by simp) - _ ≤ ‖A‖ * (∫ u : ℝ, ‖F u‖) := - mul_le_mul_of_nonneg_left hdom (by simp) - -lemma fourier_decay_of_CS2 - (ψ : CS 2 ℂ) : - ∃ C : ℝ, ∀ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ C / (1 + u ^ 2) := by - let ψ' : W21 := (ψ : W21) - obtain ⟨C, hC⟩ : - ∃ C : ℝ, ∀ u : ℝ, ‖𝓕 (ψ' : ℝ → ℂ) u‖ ≤ C / (1 + u ^ 2) := by - simpa using (decay_bounds_cor (ψ := ψ')) - refine ⟨C, ?_⟩ - intro u - simpa [ψ'] using! (hC u) - -lemma integrable_norm_fourier_scaled_of_CS2 - (ψ : CS 2 ℂ) : - Integrable (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := by - obtain ⟨C, hdecay⟩ := fourier_decay_of_CS2 (ψ := ψ) - have hC_nonneg : 0 ≤ C := by - have h0 := hdecay 0 - have hnorm : 0 ≤ ‖𝓕 (ψ : ℝ → ℂ) 0‖ := norm_nonneg _ - have hC' : ‖𝓕 (ψ : ℝ → ℂ) 0‖ ≤ C := by simpa using h0 - exact hnorm.trans hC' - have hmaj_int : Integrable (fun u : ℝ => (C : ℝ) / (1 + (u / (2 * Real.pi))^2)) := by - have hbase : Integrable (fun u : ℝ => (1 + u ^ 2)⁻¹) := integrable_inv_one_add_sq - have hscale : - Integrable (fun u : ℝ => (1 + (u / (2 * Real.pi)) ^ 2)⁻¹) := - hbase.comp_div (by nlinarith [Real.pi_pos]) - simpa [div_eq_mul_inv, mul_comm, mul_left_comm, mul_assoc, pow_two] using - hscale.const_mul C - have hle : - (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) - ≤ᵐ[volume] - (fun u : ℝ => (C : ℝ) / (1 + (u / (2 * Real.pi))^2)) := by - refine Filter.Eventually.of_forall ?_ - intro u - simpa using (hdecay (u / (2 * Real.pi))) - have hle_norm : - (fun u : ℝ => ‖‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖‖) - ≤ᵐ[volume] - (fun u : ℝ => ‖(C : ℝ) / (1 + (u / (2 * Real.pi))^2)‖) := by - refine hle.mono ?_ - intro u hu - have hden_pos : 0 < 1 + (u / (2 * Real.pi)) ^ 2 := by nlinarith - have hnonneg : 0 ≤ (C : ℝ) / (1 + (u / (2 * Real.pi))^2) := - div_nonneg hC_nonneg hden_pos.le - have hleft_nonneg : 0 ≤ ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖ := norm_nonneg _ - have hbound : ‖‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖‖ ≤ - (C : ℝ) / (1 + (u / (2 * Real.pi))^2) := by - simpa [Real.norm_eq_abs, abs_of_nonneg hleft_nonneg] using hu - have hC_abs : |C| = C := abs_of_nonneg hC_nonneg - have hden_abs : |1 + (u / (2 * Real.pi))^2| = 1 + (u / (2 * Real.pi))^2 := by - have : 0 ≤ 1 + (u / (2 * Real.pi))^2 := by nlinarith - simpa using abs_of_nonneg this - have hnorm : - ‖(C : ℝ) / (1 + (u / (2 * Real.pi))^2)‖ = - (C : ℝ) / (1 + (u / (2 * Real.pi))^2) := by - have hrec : - ‖(C : ℝ) / (1 + (u / (2 * Real.pi))^2)‖ = - |C| / |1 + (u / (2 * Real.pi))^2| := by - simp [Real.norm_eq_abs] - simp [hC_abs, hden_abs, hrec] - simpa [hnorm] using hbound - have hmaj_int_norm : - Integrable (fun u : ℝ => ‖(C : ℝ) / (1 + (u / (2 * Real.pi))^2)‖) := - hmaj_int.norm - have hmeas : - AEStronglyMeasurable (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := by - have hcont : Continuous fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) u := by - simpa using! continuous_FourierIntegral (ψ : W21) - have hcont_scaled : Continuous fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi)) := - hcont.comp (by continuity) - exact hcont_scaled.aestronglyMeasurable.norm - exact hmaj_int_norm.mono' hmeas hle_norm - -lemma exists_bound_norm_G_on_tsupport - (hG : ContinuousOn G {s : ℂ | 1 ≤ s.re}) - (ψ : CS 2 ℂ) : - ∃ K : ℝ, ∀ t : ℝ, t ∈ tsupport (ψ : ℝ → ℂ) → - ‖G (1 + t * Complex.I)‖ ≤ K := by - let s : Set ℝ := tsupport (ψ : ℝ → ℂ) - have hscompact : IsCompact s := by - simpa [s] using (ψ.h2.isCompact : IsCompact (tsupport (ψ : ℝ → ℂ))) - have hphi_cont : Continuous (fun t : ℝ => (1 : ℂ) + t * Complex.I) := by continuity - have hphi_maps : - Set.MapsTo (fun t : ℝ => (1 : ℂ) + t * Complex.I) s {z : ℂ | 1 ≤ z.re} := by - intro t ht - simp - have hGcomp : ContinuousOn (fun t : ℝ => G ((1 : ℂ) + t * Complex.I)) s := - hG.comp hphi_cont.continuousOn hphi_maps - have hnorm_contOn : ContinuousOn (fun t : ℝ => ‖G ((1 : ℂ) + t * Complex.I)‖) s := hGcomp.norm - have hbdd : BddAbove ((fun t : ℝ => ‖G ((1 : ℂ) + t * Complex.I)‖) '' s) := - (hscompact.image_of_continuousOn hnorm_contOn).bddAbove - refine ⟨sSup ((fun t : ℝ => ‖G ((1 : ℂ) + t * Complex.I)‖) '' s), ?_⟩ - intro t ht - have : ‖G ((1 : ℂ) + t * Complex.I)‖ ∈ - (fun t : ℝ => ‖G ((1 : ℂ) + t * Complex.I)‖) '' s := ⟨t, ht, rfl⟩ - exact le_csSup hbdd this - -lemma norm_integrand_le_K_mul_norm_psi - {x K : ℝ} - (hx : 0 < x) - (hK : ∀ t : ℝ, t ∈ Function.support ψ → ‖G (1 + t * Complex.I)‖ ≤ K) : - ∀ t : ℝ, - ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ ≤ K * ‖ψ t‖ := by - intro t - by_cases ht : t ∈ Function.support ψ - · have hxnorm : ‖((x : ℂ) ^ (t * Complex.I))‖ = 1 := norm_x_cpow_it x t hx - calc - ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ - = ‖G (1 + t * Complex.I)‖ * ‖ψ t‖ * ‖((x : ℂ) ^ (t * Complex.I))‖ := by - simp [mul_left_comm, mul_comm] - _ = ‖G (1 + t * Complex.I)‖ * ‖ψ t‖ * 1 := by simp [hxnorm] - _ ≤ K * ‖ψ t‖ := by - have hGle : ‖G (1 + t * Complex.I)‖ ≤ K := hK t ht - have : ‖G (1 + t * Complex.I)‖ * ‖ψ t‖ ≤ K * ‖ψ t‖ := - mul_le_mul_of_nonneg_right hGle (norm_nonneg _) - simpa [mul_assoc, mul_left_comm, mul_comm] using this - · have hψ0 : ψ t = 0 := by - by_contra hψ0 - exact ht (by simpa [Function.support] using hψ0) - simp [hψ0, mul_comm] - - -lemma norm_error_integral_le - (ψ : ℝ → ℂ) (x K : ℝ) - (hGline_meas : Measurable (fun t : ℝ => G (1 + t * I))) - (hψ_meas : AEStronglyMeasurable ψ) - (hx : 0 < x) - (hK : ∀ t : ℝ, t ∈ Function.support ψ → ‖G (1 + t * Complex.I)‖ ≤ K) - (hψ : Integrable (fun t : ℝ => ‖ψ t‖) ) : - ‖∫ t : ℝ, (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ - ≤ K * (∫ t : ℝ, ‖ψ t‖) := by - have h1 : ‖∫ t : ℝ, (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ - ≤ ∫ t : ℝ, ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ := by - simpa using (norm_integral_le_integral_norm - (f := fun t : ℝ => (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I)))) - have hmeas_main : AEStronglyMeasurable - (fun t : ℝ => (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))) := by - have hG' : AEMeasurable fun t : ℝ => G (1 + t * Complex.I) := hGline_meas.aemeasurable - have hψ_meas' : AEMeasurable ψ := hψ_meas.aemeasurable - have hx_ne : (x : ℂ) ≠ 0 := by exact_mod_cast (ne_of_gt hx) - have hx_ne' : NeZero (x : ℂ) := ⟨hx_ne⟩ - have hxpow_meas : AEMeasurable fun t : ℝ => ((x : ℂ) ^ (t * Complex.I)) := by - have hcontℂ : Continuous fun z : ℂ => ((x : ℂ) ^ z) := - continuous_const_cpow (z := (x : ℂ)) - have hcont : Continuous fun t : ℝ => ((x : ℂ) ^ ((t : ℂ) * Complex.I)) := - hcontℂ.comp (by - have h : Continuous fun t : ℝ => (t : ℂ) * Complex.I := by - simpa using! (continuous_ofReal.mul continuous_const) - simpa [mul_comm] using h) - exact hcont.measurable.aemeasurable - have hGψ_meas : AEMeasurable fun t : ℝ => (G (1 + t * Complex.I)) * (ψ t) := hG'.mul hψ_meas' - have htotal : AEMeasurable (fun t : ℝ => - (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))) := - hGψ_meas.mul hxpow_meas - exact htotal.aestronglyMeasurable - have hpt : (fun t : ℝ => - ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖) - ≤ᵐ[volume] (fun t : ℝ => K * ‖ψ t‖) := by - refine Eventually.of_forall ?_ - intro t - exact norm_integrand_le_K_mul_norm_psi (hx := hx) (hK := hK) t - have hR : Integrable (fun t : ℝ => K * ‖ψ t‖) := hψ.const_mul K - have hL : Integrable (fun t : ℝ => - ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖) := by - have hpt_norm : - (fun t : ℝ => ‖‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖‖) - ≤ᵐ[volume] (fun t : ℝ => K * ‖ψ t‖) := hpt.mono (by - intro t ht - simpa [norm_mul, mul_comm, mul_left_comm, mul_assoc] using ht) - exact hR.mono' hmeas_main.norm hpt_norm - have h2 : (∫ t : ℝ, ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖) - ≤ ∫ t : ℝ, K * ‖ψ t‖ := integral_mono_ae (μ := (volume : Measure ℝ)) hL hR hpt - have h3 : (∫ t : ℝ, K * ‖ψ t‖) = K * (∫ t : ℝ, ‖ψ t‖) := by - simp [integral_const_mul] - calc - ‖∫ t : ℝ, (G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ - ≤ ∫ t : ℝ, ‖(G (1 + t * Complex.I)) * (ψ t) * ((x : ℂ) ^ (t * Complex.I))‖ := h1 - _ ≤ ∫ t : ℝ, K * ‖ψ t‖ := h2 - _ = K * (∫ t : ℝ, ‖ψ t‖) := h3 - - - -@[blueprint "crude-upper-bound" - (title := "crude-upper-bound") - (statement := /-- - If $\psi: \R \to \C$ is $C^2$ and compactly supported with $f$ and $\hat \psi$ non-negative, then there exists a constant $B$ such that - $$ |\sum_{n=1}^\infty \frac{f(n)}{n} \hat \psi( \frac{1}{2\pi} \log \frac{n}{x} )| \leq B$$ - for all $x > 0$. - -/) - (proof := /-- This readily follows from the previous lemma and the triangle inequality. -/) - (proofUses := ["limiting-fourier-variant"]) - (latexEnv := "corollary")] -lemma crude_upper_bound - (hpos : 0 ≤ f) - (hG : ContinuousOn G {s | 1 ≤ s.re}) - (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) - (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (ψ : CS 2 ℂ) - (hψpos : ∀ y, 0 ≤ (𝓕 (ψ : ℝ → ℂ) y).re ∧ (𝓕 (ψ : ℝ → ℂ) y).im = 0) : - ∃ B : ℝ, ∀ x : ℝ, 0 < x → ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ B := by - - -- Integrability of ψ - have hψ_int : MeasureTheory.Integrable (ψ : ℝ → ℂ) := by - simpa using (ψ.h1.continuous.integrable_of_hasCompactSupport ψ.h2) - have hψ_norm_int : MeasureTheory.Integrable (fun t : ℝ => ‖(ψ : ℝ → ℂ) t‖) := - hψ_int.norm - have hψ_meas : MeasureTheory.AEStronglyMeasurable (ψ : ℝ → ℂ) := - hψ_int.aestronglyMeasurable - - -- Uniform bound K for ‖G(1+it)‖ on support ψ - rcases exists_bound_norm_G_on_tsupport (G := G) hG ψ with ⟨K, hK_ts⟩ - have hK_support : - ∀ t : ℝ, t ∈ Function.support (ψ : ℝ → ℂ) → ‖G (1 + t * Complex.I)‖ ≤ K := by - have hbnG (hKts : ∀ t : ℝ, t ∈ tsupport ψ → ‖G (1 + t * Complex.I)‖ ≤ K) : - ∀ t : ℝ, t ∈ Function.support ψ → ‖G (1 + t * Complex.I)‖ ≤ K := by - intro t ht - exact hKts t ((subset_tsupport ψ) ht) - exact hbnG hK_ts - - -- Measurability of the line restriction t ↦ G(1 + t I) from continuity-on - have hGline_meas : Measurable (fun t : ℝ => G (1 + t * Complex.I)) := by - have hline_cont : Continuous (fun t : ℝ => (1 : ℂ) + t * Complex.I) := by - continuity - have hmem : ∀ t : ℝ, ((1 : ℂ) + t * Complex.I) ∈ {s : ℂ | 1 ≤ s.re} := by - intro t - simp - have hcont : Continuous (G ∘ fun t : ℝ => (1 : ℂ) + t * Complex.I) := - hG.comp_continuous hline_cont hmem - simpa [Function.comp] using! hcont.measurable - - -- L¹ bound for the scaled Fourier transform norm - have hF_norm_int : - MeasureTheory.Integrable (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := - integrable_norm_fourier_scaled_of_CS2 ψ - have hF_meas : - MeasureTheory.AEStronglyMeasurable - (fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) := by - have hcont : Continuous fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) u := by - simpa using! continuous_FourierIntegral (ψ : W21) - have hcont_scaled : Continuous fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi)) := - hcont.comp (by continuity) - exact hcont_scaled.aestronglyMeasurable - have hF_int : - MeasureTheory.Integrable (fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) := - by - have hfin_norm : - MeasureTheory.HasFiniteIntegral - (fun u : ℝ => ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := - hF_norm_int.hasFiniteIntegral - have hfin : - MeasureTheory.HasFiniteIntegral - (fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) := by - simpa [MeasureTheory.hasFiniteIntegral_iff_norm] using hfin_norm - exact ⟨hF_meas, hfin⟩ - refine ⟨K * (∫ t : ℝ, ‖(ψ : ℝ → ℂ) t‖) - + ‖A‖ * (∫ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖), ?_⟩ - intro x hx - set I : ℂ := ∫ u in Set.Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi)) with hI - - -- Lemma 12 - have hlim := - limiting_fourier_variant (f := f) (A := A) (G := G) - hpos hG hG' hf ψ hψpos hx - have hlim' : - (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * Real.pi) * Real.log (n / x))) - - A * I - = ∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I) := by - simpa [hI] using hlim - - -- express the tsum as RHS + A*I - have htsum : - (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * Real.pi) * Real.log (n / x))) - = (∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I := by - have h' : - (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * Real.pi) * Real.log (n / x))) - = (∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I := - eq_add_of_sub_eq hlim' - simpa [add_comm, mul_comm, mul_left_comm, mul_assoc] using h' - - -- bound the RHS integral - have hRHS_bound : - ‖∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)‖ - ≤ K * (∫ t : ℝ, ‖(ψ : ℝ → ℂ) t‖) := - norm_error_integral_le (G := G) (ψ := (ψ : ℝ → ℂ)) (x := x) (K := K) - hGline_meas hψ_meas hx hK_support hψ_norm_int - - -- bound the A * I term - have hA_bound : - ‖A * I‖ ≤ ‖A‖ * (∫ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := by - have hF_on : MeasureTheory.IntegrableOn - (fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) - (Set.Ici (-Real.log x)) := - hF_int.integrableOn - simpa [hI] using - norm_mul_integral_Ici_le_integral_norm (A := A) - (F := fun u : ℝ => 𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))) - (a := -Real.log x) hF_on hF_norm_int - - -- combine bounds - have htsum_std : - (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * Real.pi) * Real.log ((n : ℝ) / x))) - = (∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I := by - simpa [one_div, mul_comm, mul_left_comm, mul_assoc] using htsum - - -- bound in the normalized form - have hbound : - ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) - (1 / (2 * Real.pi) * Real.log ((n : ℝ) / x))‖ - ≤ K * (∫ t : ℝ, ‖(ψ : ℝ → ℂ) t‖) - + ‖A‖ * (∫ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := by - have hnorm : - ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) - (1 / (2 * Real.pi) * Real.log ((n : ℝ) / x))‖ = - ‖(∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I‖ := - congrArg norm htsum_std - calc - ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) - (1 / (2 * Real.pi) * Real.log ((n : ℝ) / x))‖ - = ‖(∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)) + A * I‖ := hnorm - _ ≤ ‖∫ (t : ℝ), (G (1 + t * Complex.I)) * (ψ t) * x ^ (t * Complex.I)‖ + ‖A * I‖ := - norm_add_le _ _ - _ ≤ K * (∫ t : ℝ, ‖(ψ : ℝ → ℂ) t‖) - + ‖A‖ * (∫ u : ℝ, ‖𝓕 (ψ : ℝ → ℂ) (u / (2 * Real.pi))‖) := - add_le_add hRHS_bound hA_bound - exact hbound - -set_option backward.isDefEq.respectTransparency false in -lemma Real.fourierIntegral_convolution {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) : - 𝓕 (convolution f g (ContinuousLinearMap.mul ℂ ℂ) volume) = 𝓕 f * 𝓕 g := by - ext y - simp only [Pi.mul_apply, FourierTransform.fourier, MeasureTheory.convolution, - VectorFourier.fourierIntegral, ContinuousLinearMap.mul_apply'] - have h_int : Integrable (fun p : ℝ × ℝ ↦ 𝐞 (-(y * p.1)) • (f p.2 * g (p.1 - p.2))) := by - simp only [Circle.smul_def, smul_eq_mul] - refine (Integrable.convolution_integrand (ContinuousLinearMap.mul ℂ ℂ) hf hg).bdd_mul - (c := 1) ?_ ?_ - · exact (by continuity : Continuous _).aestronglyMeasurable - · filter_upwards with p; simp - calc ∫ v, 𝐞 (-(y * v)) • ∫ t, f t * g (v - t) - = ∫ v, ∫ t, 𝐞 (-(y * v)) • (f t * g (v - t)) := by - simp only [Circle.smul_def, smul_eq_mul, ← integral_const_mul] - _ = ∫ t, ∫ v, 𝐞 (-(y * v)) • (f t * g (v - t)) := integral_integral_swap h_int - _ = ∫ t, f t • ∫ v, 𝐞 (-(y * v)) • g (v - t) := by - simp only [Circle.smul_def, smul_eq_mul, mul_left_comm, integral_const_mul] - _ = ∫ t, f t • ∫ u, 𝐞 (-(y * (u + t))) • g u := by - congr 1; ext t - rw [← integral_add_right_eq_self (fun v ↦ 𝐞 (-(y * v)) • g (v - t)) t]; simp - _ = ∫ t, f t • ∫ u, (𝐞 (-(y * t)) * 𝐞 (-(y * u))) • g u := by - congr 2 with t; congr 1 - simp only [mul_add, neg_add, mul_comm, Real.fourierChar.map_add_eq_mul] - _ = ∫ t, 𝐞 (-(y * t)) • f t • ∫ u, 𝐞 (-(y * u)) • g u := by - congr 1; ext t - simp only [mul_smul, Circle.smul_def, smul_eq_mul, integral_const_mul]; ring - _ = (∫ t, 𝐞 (-(y * t)) • f t) * ∫ u, 𝐞 (-(y * u)) • g u := by - simp only [Circle.smul_def, smul_eq_mul, ← mul_assoc, integral_mul_const] - -lemma Real.fourierIntegral_conj_neg {f : ℝ → ℂ} (y : ℝ) : - 𝓕 (fun x ↦ conj (f (-x))) y = conj (𝓕 f y) := by - simp only [fourier_real_eq] - have h_conj : ∀ x, 𝐞 (-(x * y)) • conj (f (-x)) = conj (𝐞 (x * y) • f (-x)) := fun x ↦ by - simp only [Circle.smul_def, Real.fourierChar_apply, map_mul, smul_eq_mul, neg_mul, - Complex.ofReal_neg, mul_neg] - congr 1 - rw [← Complex.exp_conj] - simp only [map_mul, Complex.conj_I, Complex.conj_ofReal, mul_neg] - calc ∫ x, 𝐞 (-(x * y)) • conj (f (-x)) - = ∫ x, conj (𝐞 (x * y) • f (-x)) := by congr 1; ext x; exact h_conj x - _ = conj (∫ x, 𝐞 (x * y) • f (-x)) := integral_conj - _ = conj (∫ x, 𝐞 (-(x * y)) • f x) := by - rw [← integral_neg_eq_self (fun x => 𝐞 (-(x * y)) • f x)] - congr 2 with x; ring_nf - -/-- Smooth compactly supported function with non-negative Fourier transform via self-convolution. -/ -lemma auto_cheby_exists_smooth_nonneg_fourier_kernel : - ∃ (ψ : ℝ → ℂ), ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ - (∀ y, 0 ≤ (𝓕 ψ y).re ∧ (𝓕 ψ y).im = 0) ∧ 0 < (𝓕 ψ 0).re := by - obtain ⟨φ_real, hφSmooth, hφCompact, hφIcc, _, hφsupp⟩ := - smooth_urysohn_support_Ioo (a := 1/2) (b := 1) (c := 1) (d := 2) (by norm_num) (by norm_num) - let φ : ℝ → ℂ := Complex.ofReal ∘ φ_real - let φ_rev : ℝ → ℂ := fun x ↦ conj (φ (-x)) - let ψ_fun : ℝ → ℂ := convolution φ φ_rev (ContinuousLinearMap.mul ℂ ℂ) volume - have hφSmooth' : ContDiff ℝ ∞ φ := contDiff_ofReal.comp hφSmooth - have hφCompact' : HasCompactSupport φ := hφCompact.comp_left rfl - have hφRevSmooth : ContDiff ℝ ∞ φ_rev := Complex.conjCLE.contDiff.comp (hφSmooth'.comp contDiff_neg) - have hφRevCompact : HasCompactSupport φ_rev := (hφCompact'.comp_homeomorph (Homeomorph.neg ℝ)).comp_left (by simp) - have hφInt : Integrable φ := hφSmooth'.continuous.integrable_of_hasCompactSupport hφCompact' - have hφRevInt : Integrable φ_rev := hφRevSmooth.continuous.integrable_of_hasCompactSupport hφRevCompact - have hψSmooth : ContDiff ℝ ∞ ψ_fun := by - convert! hφRevCompact.contDiff_convolution_right (ContinuousLinearMap.mul ℝ ℂ) - (hφSmooth'.continuous.locallyIntegrable (μ := volume)) hφRevSmooth - have hψCompact : HasCompactSupport ψ_fun := - HasCompactSupport.convolution (ContinuousLinearMap.mul ℂ ℂ) hφCompact' hφRevCompact - refine ⟨ψ_fun, hψSmooth, hψCompact, fun y ↦ ?_, ?_⟩ - · rw [Real.fourierIntegral_convolution hφInt hφRevInt, Pi.mul_apply, - Real.fourierIntegral_conj_neg y, mul_comm, ← Complex.normSq_eq_conj_mul_self] - exact ⟨Complex.normSq_nonneg _, rfl⟩ - · have hφ_nonneg : ∀ x, 0 ≤ φ_real x := fun x ↦ by - have hx := hφIcc x; by_cases h : x ∈ Set.Icc (1:ℝ) 1 - · simp only [Set.indicator_of_mem h, Pi.one_apply] at hx; linarith - · simp only [Set.indicator_of_notMem h] at hx; exact hx - have hvol_supp : (1 : ENNReal) ≤ volume (Function.support φ_real) := by - have hsub : Set.Ico (1:ℝ) 2 ⊆ Function.support φ_real := fun x hx ↦ - hφsupp.symm ▸ Set.mem_Ioo.mpr ⟨by linarith [hx.1], hx.2⟩ - calc _ = volume (Set.Ico (1:ℝ) 2) := by simp [Real.volume_Ico]; norm_num - _ ≤ _ := volume.mono hsub - have hφint_pos : 0 < ∫ x, φ_real x := - (integral_pos_iff_support_of_nonneg_ae (.of_forall hφ_nonneg) - (hφSmooth.continuous.integrable_of_hasCompactSupport hφCompact)).2 - (lt_of_lt_of_le (by simp) hvol_supp) - have hFφ0_re : 0 < (𝓕 φ 0).re := by - simp only [φ, fourier_real_eq, mul_zero, neg_zero, AddChar.map_zero_eq_one, one_smul, - Function.comp_apply] - have hint : Integrable (fun x => (φ_real x : ℂ)) := - (hφSmooth.continuous.integrable_of_hasCompactSupport hφCompact).ofReal - calc (∫ x, (φ_real x : ℂ)).re = ∫ x, (φ_real x : ℂ).re := (integral_re hint).symm - _ = ∫ x, φ_real x := by simp only [Complex.ofReal_re] - _ > 0 := hφint_pos - rw [Real.fourierIntegral_convolution hφInt hφRevInt, Pi.mul_apply, - Real.fourierIntegral_conj_neg 0, mul_comm, ← Complex.normSq_eq_conj_mul_self] - exact Complex.normSq_pos.2 (fun h ↦ (ne_of_gt hFφ0_re) (by simp [h])) - - -/-- The series `∑ f(n)/n · 𝓕ψ(log(n/x)/(2π))` is summable for `x ≥ 1`. -/ -lemma auto_cheby_fourier_summable (hpos : 0 ≤ f) (hf : ∀ σ', 1 < σ' → Summable (nterm f σ')) - (hG : ContinuousOn G {s | 1 ≤ s.re}) - (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) - (ψ : ℝ → ℂ) (hψSmooth : ContDiff ℝ ∞ ψ) (hψCompact : HasCompactSupport ψ) - (hψpos : ∀ y, 0 ≤ (𝓕 ψ y).re ∧ (𝓕 ψ y).im = 0) (x : ℝ) (hx : 1 ≤ x) : - Summable fun n ↦ (f n : ℂ) / n * 𝓕 ψ (1 / (2 * π) * Real.log (n / x)) := by - let ψCS : CS 2 ℂ := ⟨ψ, hψSmooth.of_le (by norm_cast), hψCompact⟩ - let S : ℝ → ℂ := fun σ' ↦ ∑' n, term (f · : ℕ → ℂ) σ' n * 𝓕 ψCS.toFun (1 / (2 * π) * Real.log (n / x)) - let Pole : ℝ → ℂ := fun σ' ↦ (A : ℂ) * (x ^ (1 - σ') : ℝ) * - ∫ u in Set.Ici (-Real.log x), (rexp (-u * (σ' - 1)) : ℂ) * 𝓕 (W21.ofCS2 ψCS).toFun (u / (2 * π)) - let RHS : ℝ → ℂ := fun σ' ↦ ∫ t : ℝ, G (σ' + t * I) * ψCS.toFun t * (x : ℂ) ^ (t * I) - have l2 := limiting_fourier_lim2 (A := A) (x := x) ψCS hx - have l3 := limiting_fourier_lim3 (G := G) hG ψCS hx - have haux : (fun σ' ↦ S σ' - Pole σ') =ᶠ[𝓝[>] 1] RHS := eventually_nhdsWithin_of_forall fun σ' hσ' ↦ by - simpa [S, Pole, RHS] using! limiting_fourier_aux hG' hf ψCS hx σ' hσ' - have hS_tendsto : Tendsto S (𝓝[>] 1) (𝓝 (RHS 1 + A * ∫ u in Set.Ici (-Real.log x), - 𝓕 (W21.ofCS2 ψCS).toFun (u / (2 * π)))) := by - convert! (l3.congr' haux.symm).add l2 using 1; ext σ'; simp [S, Pole] - have hbounded : BoundedAtFilter (𝓝[>] 1) (fun σ' ↦ ‖S σ'‖) := by - simp only [BoundedAtFilter] - let L := ‖RHS 1 + A * ∫ u in Set.Ici (-Real.log x), 𝓕 (W21.ofCS2 ψCS).toFun (u / (2 * π))‖ - have : ∀ᶠ σ' in 𝓝[>] 1, ‖S σ'‖ < L + 1 := - hS_tendsto.norm.eventually_lt tendsto_const_nhds (lt_add_one L) - exact Asymptotics.IsBigO.of_bound (L + 1) (by filter_upwards [this] with σ h; simpa using h.le) - let y : ℕ → ℝ := fun n ↦ (1 / (2 * π)) * Real.log (n / x) - let w : ℕ → ℝ := fun n ↦ (𝓕 ψCS.toFun (y n)).re - have hw : ∀ n, 0 ≤ w n := fun n ↦ (hψpos (y n)).1 - let rt : ℝ → ℕ → ℝ := fun σ n ↦ if n = 0 then 0 else f n / (n : ℝ) ^ σ * w n - have rt_nn σ n : 0 ≤ rt σ n := by - simp only [rt]; split_ifs with hn - · rfl - · exact mul_nonneg (div_nonneg (hpos n) (Real.rpow_pos_of_pos (Nat.cast_pos.mpr - (Nat.pos_of_ne_zero hn)) σ).le) (hw n) - have hS_eq σ' (hσ' : 1 < σ') : S σ' = ↑(∑' n, rt σ' n) := by - rw [Complex.ofReal_tsum]; apply tsum_congr; intro n - simp only [rt, term, LSeries.term, y, w, one_div, mul_inv_rev] - split_ifs with hn <;> simp only [hn, CharP.cast_eq_zero, Complex.ofReal_zero, zero_mul, - Complex.ofReal_mul, Complex.ofReal_div] - rw [Complex.ofReal_cpow (Nat.cast_nonneg n)]; congr 1 - exact Complex.ext rfl (hψpos _).2 - have hMono n : AntitoneOn (fun σ ↦ rt σ n) (Set.Ioi 1) := fun σ₁ _ σ₂ _ h ↦ by - simp only [rt]; split_ifs with hn; · rfl - apply mul_le_mul_of_nonneg_right _ (hw n) - apply div_le_div_of_nonneg_left (hpos n) (Real.rpow_pos_of_pos (Nat.cast_pos.mpr - (Nat.pos_of_ne_zero hn)) σ₁) - exact Real.rpow_le_rpow_of_exponent_le (Nat.one_le_cast.mpr (Nat.pos_of_ne_zero hn)) h - have hT_bdd : BoundedAtFilter (𝓝[>] 1) fun σ ↦ ∑' n, rt σ n := by - rw [BoundedAtFilter, Asymptotics.isBigO_iff] at hbounded ⊢ - obtain ⟨C, hC⟩ := hbounded - refine ⟨C, ?_⟩ - filter_upwards [hC, self_mem_nhdsWithin] with σ hnorm hσ - rw [hS_eq σ hσ] at hnorm; simpa using hnorm - have hSumm σ (hσ : 1 < σ) : Summable (rt σ ·) := by - simpa [rt, w, y] using limiting_fourier_variant_lim1_aux ψCS hpos hf hψpos σ hσ - have hSumm_1 : Summable (rt 1 ·) := by - let σ_seq : ℕ → ℝ := fun k ↦ 1 + 1 / ((k : ℝ) + 1) - have hσ_gt k : 1 < σ_seq k := by simp only [σ_seq, lt_add_iff_pos_right, one_div]; positivity - have h_tendsto : Tendsto σ_seq atTop (𝓝[>] 1) := by - rw [tendsto_nhdsWithin_iff] - refine ⟨?_, by filter_upwards with k; exact hσ_gt k⟩ - have : Tendsto (fun k : ℕ ↦ 1 / ((k : ℝ) + 1)) atTop (𝓝 0) := by - simp only [one_div]; exact (tendsto_natCast_atTop_atTop.atTop_add tendsto_const_nhds).inv_tendsto_atTop - simpa [σ_seq] using tendsto_const_nhds.add this - have h_ptwise n : Tendsto (fun k ↦ rt (σ_seq k) n) atTop (𝓝 (rt 1 n)) := by - simp only [rt]; split_ifs with hn; · exact tendsto_const_nhds - refine ((tendsto_const_nhds.rpow (tendsto_nhdsWithin_iff.mp h_tendsto).1 (Or.inl ?_)).inv₀ - (by simp [hn])).const_mul (f n) |>.mul_const (w n) - exact (Nat.cast_pos.mpr (Nat.pos_of_ne_zero hn)).ne' - obtain ⟨C, hC⟩ := Asymptotics.isBigO_iff.mp (hT_bdd.comp_tendsto h_tendsto) - refine summable_of_sum_range_le (c := C) (rt_nn 1) fun m ↦ le_of_tendsto (tendsto_finsetSum _ - fun i _ ↦ h_ptwise i) ?_ - filter_upwards [h_tendsto.eventually self_mem_nhdsWithin, hC] with k hk hCk - calc ∑ i ∈ Finset.range m, rt (σ_seq k) i - ≤ ∑' n, rt (σ_seq k) n := (hSumm _ hk).sum_le_tsum _ fun n _ ↦ rt_nn _ n - _ ≤ |∑' n, rt (σ_seq k) n| := le_abs_self _ - _ ≤ C := by simpa using hCk - rw [show (fun n ↦ (f n : ℂ) / n * 𝓕 ψ (1 / (2 * π) * Real.log (n / x))) = - Complex.ofRealCLM ∘ (rt 1 ·) from ?_] - · exact hSumm_1.map Complex.ofRealCLM Complex.ofRealCLM.continuous - ext n; simp only [rt, Real.rpow_one, one_div, w, y, Function.comp_apply] - split_ifs with hn; · simp [hn] - have him0 : (𝓕 ψCS.toFun ((2 * π)⁻¹ * Real.log (n / x))).im = 0 := (hψpos _).2 - have hre_eq : 𝓕 ψCS.toFun ((2 * π)⁻¹ * Real.log (n / x)) = - Complex.ofReal ((𝓕 ψCS.toFun ((2 * π)⁻¹ * Real.log (n / x))).re) := by - rw [← Complex.re_add_im (𝓕 ψCS.toFun _), him0]; simp - conv_lhs => rw [show ψ = ψCS.toFun from rfl, hre_eq] - simp only [Complex.ofRealCLM_apply, Complex.ofReal_div, Complex.ofReal_mul, Complex.ofReal_natCast] - -/-- Short interval bound from global filtered bound: if `∑ f(n)/n · 𝓕ψ(log(n/x)) ≤ B`, -then `∑_{(1-ε)x < n ≤ x} f(n) ≤ Cx` for some `ε, C > 0`. -/ -lemma auto_cheby_short_interval_bound (hpos : 0 ≤ f) - (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hG : ContinuousOn G {s | 1 ≤ s.re}) - (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) - (B : ℝ) (ψ : ℝ → ℂ) (hψSmooth : ContDiff ℝ ∞ ψ) (hψCompact : HasCompactSupport ψ) - (hψpos : ∀ y, 0 ≤ (𝓕 ψ y).re ∧ (𝓕 ψ y).im = 0) (hψ0 : 0 < (𝓕 ψ 0).re) - (hB_bound : ∀ x ≥ 1, ‖∑' n, f n / n * 𝓕 ψ (1 / (2 * Real.pi) * Real.log (n / x))‖ ≤ B) : - ∃ (ε : ℝ) (C : ℝ), ε > 0 ∧ ε < 1 ∧ C > 0 ∧ ∀ x ≥ 1, - ∑' n, (f n) * (Set.indicator (Set.Ioc ((1 - ε) * x) x) (fun _ ↦ 1) (n : ℝ)) ≤ C * x := by - have hF : Continuous (𝓕 ψ) := VectorFourier.fourierIntegral_continuous Real.continuous_fourierChar - (by continuity) (hψSmooth.continuous.integrable_of_hasCompactSupport hψCompact) - have hg : Continuous fun y ↦ (𝓕 ψ y).re := Complex.continuous_re.comp hF - obtain ⟨δ, hδpos, hball⟩ := Metric.mem_nhds_iff.1 <| - hg.continuousAt.preimage_mem_nhds (IsOpen.mem_nhds isOpen_Ioi (half_lt_self hψ0)) - let c := (𝓕 ψ 0).re / 2 - have hcpos : 0 < c := by dsimp only [c]; linarith - have h_psi_ge_c : ∀ y, |y| < δ → c ≤ (𝓕 ψ y).re := fun y hy ↦ (hball (mem_ball_zero_iff.mpr hy)).le - let ε := 1 - Real.exp (-2 * π * δ) - have hε : 0 < ε ∧ ε < 1 := by - have h1 : Real.exp (-2 * π * δ) < 1 := Real.exp_lt_one_iff.mpr (by nlinarith [Real.pi_pos]) - exact ⟨by simp only [ε]; linarith, by simp only [ε]; linarith [Real.exp_pos (-2 * π * δ)]⟩ - have hB_nonneg : 0 ≤ B := (norm_nonneg _).trans (hB_bound 1 le_rfl) - refine ⟨ε, B / c + 1, hε.1, hε.2, by positivity, fun x hx ↦ ?_⟩ - have h_summable : Summable fun n ↦ (f n : ℂ) / n * 𝓕 ψ (1 / (2 * π) * Real.log (n / x)) := - auto_cheby_fourier_summable hpos hf hG hG' ψ hψSmooth hψCompact hψpos x hx - have hx_pos : 0 < x := by linarith - have h_sum_lower : c / x * ∑' n, f n * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (n : ℝ) - ≤ ∑' n, f n / n * (𝓕 ψ (1 / (2 * π) * Real.log (n / x))).re := by - rw [← tsum_mul_left] - refine Summable.tsum_le_tsum (fun n ↦ ?_) ?_ ?_ - · by_cases hn : (n : ℝ) ∈ Set.Ioc ((1 - ε) * x) x - · rw [Set.indicator_of_mem hn, Pi.one_apply, mul_one] - have hn_pos : 0 < (n : ℝ) := by nlinarith [hn.1, hε.2] - let y := (1 / (2 * π)) * Real.log (n / x) - have h_arg_small : |y| < δ := by - have h2pi : 0 < 2 * π := by linarith [Real.pi_pos] - simp only [y, abs_mul, abs_div, abs_one, abs_of_pos h2pi] - field_simp [ne_of_gt h2pi]; rw [mul_comm, abs_lt] - have h_log_lower : -2 * π * δ < Real.log (n / x) := by - rw [← Real.log_exp (-2 * π * δ), Real.log_lt_log_iff (Real.exp_pos _) (by positivity)] - have : Real.exp (-2 * π * δ) = 1 - ε := by simp only [ε]; ring - rw [this]; field_simp; exact hn.1 - have h_log_upper : Real.log (n / x) ≤ 0 := - Real.log_nonpos (by positivity) (div_le_one_of_le₀ hn.2 hx_pos.le) - constructor <;> nlinarith [Real.pi_pos] - have h1 : x⁻¹ ≤ (n : ℝ)⁻¹ := by rw [inv_le_inv₀ hx_pos hn_pos]; exact hn.2 - have h2 : c ≤ (𝓕 ψ y).re := h_psi_ge_c y h_arg_small - have hfn : 0 ≤ f n := hpos n - have hre : 0 ≤ (𝓕 ψ y).re := (hψpos y).1 - have hn_inv : 0 ≤ (n : ℝ)⁻¹ := inv_nonneg.mpr hn_pos.le - calc c / x * f n = c * x⁻¹ * f n := by rw [div_eq_mul_inv] - _ ≤ c * (n : ℝ)⁻¹ * f n := by gcongr - _ ≤ (𝓕 ψ y).re * (n : ℝ)⁻¹ * f n := by gcongr - _ = (n : ℝ)⁻¹ * (𝓕 ψ y).re * f n := by ring - _ = f n / n * (𝓕 ψ y).re := by ring - · rw [Set.indicator_of_notMem hn, mul_zero, mul_zero] - exact mul_nonneg (div_nonneg (hpos n) (Nat.cast_nonneg n)) (hψpos _).1 - · refine summable_of_hasFiniteSupport <| (Set.finite_le_nat ⌊x⌋₊).subset fun n hn ↦ ?_ - simp only [Function.mem_support, ne_eq, mul_eq_zero, not_or, Set.indicator_apply_ne_zero] at hn - exact Nat.le_floor hn.2.2.1.2 - · rw [← Complex.summable_ofReal]; convert h_summable using 1; ext n - rw [Complex.ofReal_mul, Complex.ofReal_div] - norm_cast - rw [Complex.ofReal_mul] - congr 1 - apply Complex.ext - · simp only [Complex.ofReal_re] - · simp only [Complex.ofReal_im]; exact (hψpos _).2.symm - have h_real_eq : ∑' n, f n / n * (𝓕 ψ (1 / (2 * π) * Real.log (n / x))).re = - (∑' n, (f n : ℂ) / n * 𝓕 ψ (1 / (2 * π) * Real.log (n / x))).re := by - rw [Complex.re_tsum h_summable]; congr with n - rw [Complex.mul_re]; norm_cast; simp only [zero_mul, sub_zero] - calc ∑' n, f n * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (n : ℝ) - = x / c * (c / x * ∑' n, f n * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (n : ℝ)) := by - field_simp [ne_of_gt hcpos, ne_of_gt hx_pos] - _ ≤ x / c * B := by - gcongr; rw [h_real_eq] at h_sum_lower - exact h_sum_lower.trans ((Complex.re_le_norm _).trans (hB_bound x hx)) - _ = (B / c) * x := by field_simp [ne_of_gt hcpos] - _ ≤ (B / c + 1) * x := by nlinarith - -/-- Bootstraps short interval bounds to global Chebyshev bound via strong induction. -If `∑_{(1-ε)x < n ≤ x} f(n) ≤ Cx` for all `x ≥ 1`, then `∑_{n ≤ x} f(n) = O(x)`. -/ -lemma auto_cheby_bootstrap_induction (hpos : 0 ≤ f) - (h_short : ∃ (ε : ℝ) (C : ℝ), ε > 0 ∧ ε < 1 ∧ C > 0 ∧ ∀ x ≥ 1, - ∑' n, (f n) * (Set.indicator (Set.Ioc ((1 - ε) * x) x) (fun _ ↦ 1) (n : ℝ)) ≤ C * x) : - cheby f := by - obtain ⟨ε, C₀, hε, hε1, hC₀, h_bound⟩ := h_short - let C := C₀ / ε + f 0 + 1 - have hf0 : (0 : ℝ) ≤ f 0 := hpos 0 - have hdiv : 0 ≤ C₀ / ε := div_nonneg hC₀.le hε.le - have hC : 0 ≤ C := by linarith - refine ⟨C, fun n ↦ ?_⟩ - induction n using Nat.strong_induction_on with | h n ih => - rcases lt_or_ge n 2 with hn | hn - · interval_cases n - · simp [cumsum] - · simp only [cumsum, Finset.sum_range_one, Complex.norm_real, Real.norm_eq_abs, abs_of_nonneg hf0, - Nat.cast_one, mul_one, C] - linarith - let x := (n : ℝ) - 1 - have hx : x ≥ 1 := by simp only [x, ge_iff_le, le_sub_iff_add_le]; norm_cast - let m := ⌊(1 - ε) * x⌋₊ + 1 - have hm_lt : m < n := by - simp only [m, x] - have h1 : (1 - ε) * (n - 1 : ℝ) < (n - 1 : ℕ) := by - calc (1 - ε) * (↑n - 1) < 1 * (↑n - 1) := by gcongr; linarith - _ = ↑n - 1 := by ring - _ = ↑(n - 1) := by simp [Nat.cast_sub (by omega : 1 ≤ n)] - have h2 : ⌊(1 - ε) * (n - 1 : ℝ)⌋₊ < n - 1 := - (Nat.floor_lt (mul_nonneg (by linarith) (by linarith : (0 : ℝ) ≤ n - 1))).mpr h1 - omega - have hm_gt : (m : ℝ) > (1 - ε) * x := by - simp only [m, Nat.cast_add, Nat.cast_one, gt_iff_lt] - exact Nat.lt_floor_add_one ((1 - ε) * x) - have h_decomp : cumsum (fun k ↦ ‖(f k : ℂ)‖) n = cumsum (fun k ↦ ‖(f k : ℂ)‖) m + ∑ k ∈ Finset.Ico m n, f k := by - simp only [cumsum, Complex.norm_real, Real.norm_eq_abs, abs_of_nonneg (hpos _), - Finset.sum_range_add_sum_Ico _ (by omega : m ≤ n)] - have h_Ico : ∑ k ∈ Finset.Ico m n, f k ≤ C₀ * x := by - calc ∑ k ∈ Finset.Ico m n, f k - = ∑ k ∈ Finset.Ico m n, f k * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (k : ℝ) := by - refine Finset.sum_congr rfl fun k hk ↦ ?_ - have ⟨hkm, hkn⟩ := Finset.mem_Ico.mp hk - have hk_gt : (k : ℝ) > (1 - ε) * x := by linarith [hm_gt, (Nat.cast_le (α := ℝ)).mpr hkm] - have hk_le : (k : ℝ) ≤ x := by - have h1 : k ≤ n - 1 := Nat.le_pred_of_lt hkn - have h2 : (k : ℝ) ≤ (n - 1 : ℕ) := by exact_mod_cast h1 - simp only [Nat.cast_sub (by omega : 1 ≤ n), Nat.cast_one, x] at h2 ⊢; exact h2 - simp only [Set.indicator_of_mem (Set.mem_Ioc.mpr ⟨hk_gt, hk_le⟩), Pi.one_apply, mul_one] - _ ≤ ∑' k, f k * Set.indicator (Set.Ioc ((1 - ε) * x) x) 1 (k : ℝ) := by - refine Summable.sum_le_tsum _ (fun k _ ↦ mul_nonneg (hpos k) (Set.indicator_nonneg (by simp) _)) ?_ - refine summable_of_hasFiniteSupport <| (Set.finite_le_nat ⌊x⌋₊).subset fun k hk ↦ ?_ - simp only [Function.mem_support, ne_eq, mul_eq_zero, not_or, Set.indicator_apply_ne_zero] at hk - exact Nat.le_floor hk.2.1.2 - _ ≤ C₀ * x := h_bound x hx - have hm_le : (m : ℝ) ≤ (1 - ε) * x + 1 := by - have hpos' : 0 ≤ (1 - ε) * x := mul_nonneg (by linarith) (by linarith : (0 : ℝ) ≤ x) - simp only [m, Nat.cast_add, Nat.cast_one] - linarith [Nat.floor_le hpos'] - have hnorm : ∀ k, ‖(f k : ℂ)‖ = f k := fun k ↦ by simp [abs_of_nonneg (hpos k)] - simp only [hnorm] at h_decomp ih ⊢ - calc cumsum f n = cumsum f m + ∑ k ∈ Finset.Ico m n, f k := h_decomp - _ ≤ C * m + C₀ * x := by linarith [ih m hm_lt, h_Ico] - _ ≤ C * ((1 - ε) * x + 1) + C₀ * x := by nlinarith [hC] - _ = (C * (1 - ε) + C₀) * x + C := by ring - _ ≤ C * x + C := by - have : C₀ ≤ C * ε := by - calc C₀ = (C₀ / ε) * ε := by field_simp [ne_of_gt hε] - _ ≤ (C₀ / ε + f 0 + 1) * ε := by gcongr; linarith [hpos 0] - _ = C * ε := by simp only [C] - nlinarith [hε, hε1, hx] - _ ≤ C * n := by simp only [x]; ring_nf; linarith [hC] - -@[blueprint "auto-cheby" - (title := "auto-cheby") - (statement := /-- One has $$ \sum_{n \leq x} f(n) = O(x)$$ for all $x \geq 1$. -/) - (proof := /-- - By applying Corollary \ref{crude-upper-bound} for a specific compactly supported function $\psi$, - one can obtain a bound of the form $\sum_{(1-\varepsilon)x < n \leq x} f(n) = O(x)$ for all $x$ - and some absolute constant $\varepsilon$ (which can be made explicit). - - If $C$ is a sufficiently large constant, the claim $|\sum_{n \leq x} f(n)| \leq Cx$ can now be - proven by strong induction on $x$, as the claim for $(1-\varepsilon)x$ implies the claim for $x$ - by the triangle inequality (and the claim is trivial for $x < 1$). - -/) - (proofUses := ["crude-upper-bound", "WienerIkehara"]) - (latexEnv := "corollary")] -lemma auto_cheby (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hG : ContinuousOn G {s | 1 ≤ s.re}) - (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : cheby f := by - obtain ⟨ψ_fun, hψSmooth, hψCompact, hψpos, hψ0⟩ := auto_cheby_exists_smooth_nonneg_fourier_kernel - obtain ⟨B, hB⟩ := crude_upper_bound hpos hG hG' hf ⟨ψ_fun, hψSmooth.of_le ENat.LEInfty.out, hψCompact⟩ hψpos - exact auto_cheby_bootstrap_induction hpos <| auto_cheby_short_interval_bound hpos hf hG hG' B ψ_fun - hψSmooth hψCompact hψpos hψ0 fun x hx ↦ hB x (by linarith) - -@[blueprint "WienerIkehara2" - (title := "Wiener-Ikehara Theorem (2)") - (statement := /-- We have $$ \sum_{n\leq x} f(n) = A x + o(x).$$ -/) - (proof := /-- Use Corollary \ref{auto-cheby} to remove the Chebyshev hypothesis in Theorem \ref{WienerIkehara}. -/) - (latexEnv := "theorem")] -theorem WienerIkeharaTheorem'' (hpos : 0 ≤ f) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) - (hG : ContinuousOn G {s | 1 ≤ s.re}) - (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : - Tendsto (fun N => cumsum f N / N) atTop (𝓝 A) := - WienerIkeharaTheorem' hpos hf (auto_cheby (f := f) (A := A) (G := G) hpos hf hG hG') hG hG' - -end auto_cheby - -blueprint_comment /-- -\section{The prime number theorem in arithmetic progressions} --/ - -@[blueprint "WeakPNT-character" - (title := "WeakPNT-character") - (statement := /-- - If $q ≥ 1$ and $a$ is coprime to $q$, and $\mathrm{Re} s > 1$, we have - $$ - \sum_{n: n = a\ (q)} \frac{\Lambda(n)}{n^s} = - \frac{1}{\varphi(q)} \sum_{\chi\ (q)} - \overline{\chi(a)} \frac{L'(s,\chi)}{L(s,\chi)}.$$ - -/) - (proof := /-- - From the Fourier inversion formula on the multiplicative group $(\Z/q\Z)^\times$, we have - $$ 1_{n=a\ (q)} = \frac{\varphi(q)}{q} \sum_{\chi\ (q)} \overline{\chi(a)} \chi(n).$$ - On the other hand, from standard facts about L-series we have for each character $\chi$ that - $$ - \sum_{n} \frac{\Lambda(n) \chi(n)}{n^s} = - \frac{L'(s,\chi)}{L(s,\chi)}.$$ - Combining these two facts, we obtain the claim. - -/) - (latexEnv := "lemma")] -theorem WeakPNT_character - {q a : ℕ} (hq : q ≥ 1) (ha : Nat.Coprime a q) (ha' : a < q) {s : ℂ} (hs : 1 < s.re) : - LSeries (fun n ↦ if n % q = a then Λ n else 0) s = - - (∑' χ : DirichletCharacter ℂ q, - ((starRingEnd ℂ) (χ a) * ((deriv (LSeries (fun n:ℕ ↦ χ n)) s)) / - (LSeries (fun n:ℕ ↦ χ n) s))) / (Nat.totient q : ℂ) := by - have : NeZero q := ⟨by omega⟩ - convert vonMangoldt.LSeries_residueClass_eq ((ZMod.isUnit_iff_coprime a q).mpr ha) hs using 1 - · congr with n - have : n % q = a ↔ (n : ZMod q) = a := by - rw [ZMod.natCast_eq_natCast_iff', Nat.mod_eq_of_lt ha'] - simp [this] - split_ifs <;> simp [*] - · rw [div_eq_inv_mul, neg_mul_comm, tsum_fintype] - congr 3 with χ - rw [DirichletCharacter.deriv_LFunction_eq_deriv_LSeries _ hs, - DirichletCharacter.LFunction_eq_LSeries _ hs, mul_div] - congr 2 - rw [starRingEnd_apply, MulChar.star_apply', MulChar.inv_apply_eq_inv', - ← ZMod.coe_unitOfCoprime a ha, ZMod.inv_coe_unit, map_units_inv] - - -@[blueprint "WeakPNT-AP-prelim" - (title := "WeakPNT-AP-prelim") - (statement := /-- - If $q ≥ 1$ and $a$ is coprime to $q$, the Dirichlet series - $\sum_{n \leq x: n = a\ (q)} \frac{\Lambda(n)}{n^s}$ converges for $\mathrm{Re}(s) > 1$ to - $\frac{1}{\varphi(q)} \frac{1}{s-1} + G(s)$ where $G$ has a continuous extension to - $\mathrm{Re}(s)=1$. - -/) - (proof := /-- - We expand out the left-hand side using Lemma \ref{WeakPNT-character}. The contribution of the - non-principal characters $\chi$ extend continuously to $\mathrm{Re}(s) = 1$ thanks to the - non-vanishing of $L(s,\chi)$ on this line (which should follow from another component of - this project), so it suffices to show that for the principal character $\chi_0$, that - $$ -\frac{L'(s,\chi_0)}{L(s,\chi_0)} - \frac{1}{s-1}$$ - also extends continuously here. But we already know that - $$ -\frac{\zeta'(s)}{\zeta(s)} - \frac{1}{s-1}$$ - extends, and from Euler product machinery one has the identity - $$ \frac{L'(s,\chi_0)}{L(s,\chi_0)} - = \frac{\zeta'(s)}{\zeta(s)} + \sum_{p|q} \frac{\log p}{p^s-1}.$$ - Since there are only finitely many primes dividing $q$, and each summand $\frac{\log p}{p^s-1}$ - extends continuously, the claim follows. - -/) - (proofUses := ["ChebyshevPsi", "WeakPNT-character"]) - (latexEnv := "proposition")] -theorem WeakPNT_AP_prelim {q : ℕ} {a : ℕ} (hq : q ≥ 1) (ha : Nat.Coprime a q) (ha' : a < q) : - ∃ G: ℂ → ℂ, (ContinuousOn G {s | 1 ≤ s.re}) ∧ - (Set.EqOn G (fun s ↦ LSeries (fun n ↦ if n % q = a then Λ n else 0) s - 1 / - ((Nat.totient q) * (s - 1))) {s | 1 < s.re}) := by - have : NeZero q := NeZero.of_pos hq - have hG : ∃ G : ℂ → ℂ, ContinuousOn G {s | 1 ≤ s.re} ∧ Set.EqOn G - (fun s ↦ LSeries (fun n ↦ if (n : ZMod q) = a then Λ n else 0) s - (q.totient : ℂ)⁻¹ / (s - 1)) {s | 1 < s.re} := by - use vonMangoldt.LFunctionResidueClassAux (a : ZMod q), vonMangoldt.continuousOn_LFunctionResidueClassAux (q := q) (a := a) - have := vonMangoldt.eqOn_LFunctionResidueClassAux ((ZMod.isUnit_iff_coprime a q).mpr ha) - convert this using 6; split <;> simp_all - convert hG using 6 - · simp [ZMod.natCast_eq_natCast_iff', Nat.mod_eq_of_lt ha'] - · rw [inv_eq_one_div, div_div] - -/-- The von Mangoldt function divided by `n ^ s` is summable for `s > 1`. -/ -lemma summable_vonMangoldt_div_rpow {s : ℝ} (hs : 1 < s) : Summable (fun n ↦ Λ n / n ^ s) := by - have h_log_bound : ∀ n : ℕ, (Λ n : ℝ) ≤ Real.log n := fun n ↦ vonMangoldt_le_log - suffices h_log_sum : Summable fun n : ℕ ↦ Real.log n / (n : ℝ) ^ s by - exact .of_nonneg_of_le (fun n ↦ div_nonneg vonMangoldt_nonneg (by positivity)) - (fun n ↦ div_le_div_of_nonneg_right (h_log_bound n) (by positivity)) h_log_sum - have h_log_le_n_eps : ∀ ε > 0, ∃ C > 0, ∀ n : ℕ, n ≥ 2 → Real.log n / (n : ℝ) ^ s ≤ C * (n : ℝ) ^ (ε - s) := by - intro ε hε_pos - obtain ⟨C, hC_pos, hC⟩ : ∃ C > 0, ∀ n : ℕ, n ≥ 2 → Real.log n ≤ C * (n : ℝ) ^ ε := by - refine ⟨1 / ε, by positivity, fun n hn ↦ ?_⟩ - have := log_le_sub_one_of_pos (by positivity : 0 < (n : ℝ) ^ ε) - rw [log_rpow (by positivity)] at this - nlinarith [rpow_pos_of_pos (by positivity : 0 < (n : ℝ)) ε, mul_div_cancel₀ 1 hε_pos.ne'] - refine ⟨C, hC_pos, fun n hn ↦ ?_⟩ - rw [rpow_sub (by positivity)] - exact le_trans (div_le_div_of_nonneg_right (hC n hn) (by positivity)) (by rw [div_eq_mul_inv]; ring_nf; norm_num) - obtain ⟨C, _, hC⟩ : ∃ C > 0, ∀ n : ℕ, n ≥ 2 → Real.log n / (n : ℝ) ^ s ≤ C * (n : ℝ) ^ ((s - 1) / 2 - s) := - h_log_le_n_eps ((s - 1) / 2) (by linarith) - rw [← summable_nat_add_iff 2] - exact Summable.of_nonneg_of_le (fun n ↦ div_nonneg (log_nonneg (by norm_cast; omega)) - (rpow_nonneg (by positivity) _)) (fun n ↦ hC _ (by omega)) (Summable.mul_left _ <| by - simpa using summable_nat_add_iff 2 |>.2 <| summable_nat_rpow.2 <| by linarith) - -@[blueprint "WeakPNT-AP" - (title := "WeakPNT-AP") - (statement := /-- - If $q ≥ 1$ and $a$ is coprime to $q$, we have - $$ \sum_{n \leq x: n = a\ (q)} \Lambda(n) = \frac{x}{\varphi(q)} + o(x).$$ - -/) - (proof := /-- Apply Theorem \ref{WienerIkehara} (or Theorem \ref{WienerIkehara2} to avoid - checking the Chebyshev condition) using Proposition \ref{WeakPNT-AP-prelim}.-/) - (proofUses := ["WienerIkehara", "WeakPNT-AP-prelim"])] -theorem WeakPNT_AP {q : ℕ} {a : ℕ} (hq : q ≥ 1) (ha : a.Coprime q) (ha' : a < q) : - Tendsto (fun N ↦ cumsum (fun n ↦ if n % q = a then Λ n else 0) N / N) atTop (𝓝 (1 / q.totient)) := by - have h_summable : ∀ s : ℝ, 1 < s → Summable (fun n ↦ (if n % q = a then Λ n else 0) / n ^ s) := by - intro s hs - refine .of_nonneg_of_le (fun n ↦ ?_) (fun n ↦ ?_) (summable_vonMangoldt_div_rpow hs) - · split_ifs <;> positivity - · split_ifs <;> norm_num; exact div_nonneg vonMangoldt_nonneg (by positivity) - obtain ⟨G, hG₁, hG₂⟩ := WeakPNT_AP_prelim hq ha ha' - convert WienerIkeharaTheorem'' _ _ _ _ using 1 - · use G - · intro n - simp_all only [ge_iff_le, one_div, mul_inv_rev, Pi.ofNat_apply] - split - next h => subst h; simp_all only [vonMangoldt_nonneg] - next h => simp_all only [le_refl] - · intro σ' hσ' - specialize h_summable σ' hσ' - simp_all only [ge_iff_le, one_div, mul_inv_rev] - convert h_summable using 1 - ext - simp only [nterm, norm_real, norm_eq_abs] - ring_nf - split_ifs <;> simp [*, mul_comm] - · assumption - · convert hG₂ using 3 - · exact tsum_congr fun n ↦ by cases n <;> aesop - · norm_num [div_eq_mul_inv, mul_assoc, mul_comm, mul_left_comm] - - -blueprint_comment /-- -\section{The Chebotarev density theorem: the case of cyclotomic extensions} - -Throughout this section, $K$ is a number field, $m \geq 1$ is a fixed integer, -$L = K(\mu_m)$, and $G = \mathrm{Gal}(L/K)$. (In particular $G$ is abelian, and for -$K=\mathbb{Q}$ one recovers $G \cong (\mathbb{Z}/m\mathbb{Z})^\times$.) -Write $\zeta_K$ and $\zeta_L$ for the Dedekind zeta functions of $K$ and $L$, and for -an abelian character $\chi : G \to \mathbb{C}^\times$ write $L(\chi,s)$ for the associated -Artin $L$-function (equivalently, the Hecke $L$-function of the ideal character attached to -$\chi$; cf.\ Notation~7.1.17 and Proposition~7.1.18 of -\url{https://www.math.ucla.edu/~sharifi/algnum.pdf}). - -The goal of this section is to prove the Chebotarev density theorem in the cyclotomic case -(Proposition~\ref{Chebotarev-cyclotomic-density} below), following the classical argument via -Artin $L$-functions as in Sharifi, Propositions~7.1.16--7.1.19 and Proposition~7.2.1. The -abelian and general cases are then reduced to this one in the subsequent sections. --/ - -blueprint_comment /-- -\begin{lemma}[Artin $L$-function as Euler product]\label{Artin-L-euler} -Let $\chi : G \to \mathbb{C}^\times$ be an abelian character. For $\Re(s) > 1$ one has -\[ -L(\chi,s) \;=\; \prod_{\mathfrak{p}} \bigl(1 - \chi(\mathfrak{p})\, N\mathfrak{p}^{-s}\bigr)^{-1} -\;=\; \sum_{\mathfrak{a} \subseteq \mathcal{O}_K} \chi(\mathfrak{a})\, N\mathfrak{a}^{-s}, -\] -where the product runs over nonzero prime ideals of $\mathcal{O}_K$, with the convention -$\chi(\mathfrak{p}) = 0$ if $\mathfrak{p}$ ramifies in the fixed field of $\ker\chi$. -\end{lemma} --/ - -blueprint_comment /-- -\begin{proof} -This is the specialisation of the Artin Euler product (Definition~7.1.15 of Sharifi) to -abelian characters; see Proposition~7.1.18 of -\url{https://www.math.ucla.edu/~sharifi/algnum.pdf}. Absolute convergence for $\Re(s)>1$ -follows from comparison with $\zeta_K(s)$. -\end{proof} --/ - -blueprint_comment /-- -\begin{lemma}[Dedekind-factor]\label{Dedekind-factor} -For $\Re(s) > 1$ one has -\[ -\zeta_L(s) \;=\; \prod_{\chi : G \to \mathbb{C}^\times} L(\chi,s), -\] -where the product runs over all (necessarily one-dimensional) irreducible characters of $G$. -\end{lemma} --/ - -blueprint_comment /-- -\begin{proof}\uses{Artin-L-euler} -In general, for a Galois extension $L/K$ and characters $\chi$ of irreducible representations of -$\mathrm{Gal}(L/K)$, Proposition~7.1.16 of -\url{https://www.math.ucla.edu/~sharifi/algnum.pdf} gives -$\zeta_L(s) = \prod_\chi L(\chi,s)^{\chi(1)}$ for $\Re(s)>1$. In the present abelian -(cyclotomic) setting every irreducible character is one-dimensional, so $\chi(1)=1$ and the -exponents disappear. Alternatively, comparing Euler factors at an unramified prime -$\mathfrak{p}$: the primes of $L$ above $\mathfrak{p}$ contribute the factor -$(1 - N\mathfrak{p}^{-fs})^{-g}$ to $\zeta_L$, while the Artin factors multiply to the same -quantity by the usual identity $\prod_\chi (1 - \chi(\varphi_{\mathfrak{p}}) X) = 1 - X^f$ -(with $X = N\mathfrak{p}^{-s}$ and $f$ the residue degree). -\end{proof} --/ - -blueprint_comment /-- -\begin{lemma}[Simple pole]\label{Dedekind-pole} -The Dedekind zeta function $\zeta_L$ admits a meromorphic continuation to a neighbourhood of -the line $\Re(s)=1$ with a single simple pole at $s=1$ (and is otherwise holomorphic and -nonvanishing on that line after removing the pole). In particular -$\log \zeta_L(s) \sim \log(s-1)^{-1}$ as $s \to 1^+$. -\end{lemma} --/ - -blueprint_comment /-- -\begin{proof} -This is the standard analytic continuation of Dedekind zeta (Theorem~7.1.12 of -\url{https://www.math.ucla.edu/~sharifi/algnum.pdf}): absolute convergence of the ideal -Dirichlet series and Euler product for $\Re(s)>1$, meromorphic continuation across -$\Re(s)>1-[L:\mathbb{Q}]^{-1}$, and a simple pole at $s=1$. The logarithmic asymptotic is -immediate from the simple pole. -\end{proof} --/ - -blueprint_comment /-- -\begin{lemma}[Continuation of nontrivial Artin $L$-functions]\label{Artin-L-continuation} -Let $\chi : G \to \mathbb{C}^\times$ be a nontrivial character. Then $L(\chi,s)$ extends to an -analytic function on the half-plane $\Re(s) > 1 - [K:\mathbb{Q}]^{-1}$, and in particular is -holomorphic at $s=1$. -\end{lemma} --/ - -blueprint_comment /-- -\begin{proof} -Following Proposition~7.1.19 of \url{https://www.math.ucla.edu/~sharifi/algnum.pdf}: let $n$ -be the order of $\chi$. Geometry of numbers supplies the estimate that, for each $n$th root of -unity $\zeta$, the number of ideals $\mathfrak{a}$ with $N\mathfrak{a} \leq N$ and -$\chi(\mathfrak{a})=\zeta$ is $CN + O\bigl(N^{1-[K:\mathbb{Q}]^{-1}}\bigr)$ with $C$ independent of -$\zeta$. Summing against $\zeta$ cancels the main terms, so -$\sum_{N\mathfrak{a}\leq N} \chi(\mathfrak{a}) = O\bigl(N^{1-[K:\mathbb{Q}]^{-1}}\bigr)$. -Lemma~7.1.5 of Sharifi then yields absolute uniform convergence of -$\sum_{\mathfrak{a}} \chi(\mathfrak{a})\, N\mathfrak{a}^{-s}$ on compact subsets of -$\Re(s) > 1 - [K:\mathbb{Q}]^{-1}$. -\end{proof} --/ - -blueprint_comment /-- -\begin{lemma}[Dedekind-nonvanishing]\label{Dedekind-nonvanishing} -For any nontrivial character $\chi$ of $G = \mathrm{Gal}(L/K)$, one has $L(\chi,1) \neq 0$. -Moreover $L(\chi,s)$ does not vanish for $\Re(s)=1$. -\end{lemma} --/ - -blueprint_comment /-- -\begin{proof}\uses{Dedekind-factor, Dedekind-pole, Artin-L-continuation} -For the value at $s=1$: write $\log\zeta_L(t) = \sum_\chi \log L(\chi,t)$ for real $t>1$. -As $t\to 1^+$, the left side is $\sim \log(t-1)^{-1}$ by Lemma~\ref{Dedekind-pole}. If some -nontrivial $L(\chi,\cdot)$ had a zero of order $m_\chi \geq 1$ at $s=1$, the right side would -behave like $\bigl(1 - \sum_\chi m_\chi\bigr)\log(t-1)^{-1}$ up to a bounded error -(the trivial character contributes the pole of $\zeta_K$, absorbed into the factorisation), -forcing $1-\sum m_\chi \leq 0$, a contradiction. Hence $L(\chi,1)\neq 0$ for all nontrivial -$\chi$ (Sharifi, Proposition~7.1.19). - -For the rest of the line $\Re(s)=1$, $s\neq 1$: adapt the classical nonvanishing argument for -Dirichlet $L$-functions (comparison of $\zeta_L(s)$, $\zeta_L(s)^3\,|L(\chi,s)|^4$, or the -$3+4\operatorname{Re}$ inequality) using the Euler product of Lemma~\ref{Artin-L-euler} and the -absence of poles of nontrivial $L(\chi,\cdot)$ on $\Re(s)=1$ from -Lemma~\ref{Artin-L-continuation}. -\end{proof} --/ - -blueprint_comment /-- -\begin{lemma}[Orthogonality for Frobenius classes]\label{Chebotarev-orthogonality} -Fix $\sigma \in G$. For every prime ideal $\mathfrak{p}$ of $\mathcal{O}_K$ unramified in $L$, -\[ -\sum_{\chi : G \to \mathbb{C}^\times} \chi(\sigma)^{-1}\,\chi(\varphi_{\mathfrak{p}}) -\;=\; -\begin{cases} -|G| & \text{if }\varphi_{\mathfrak{p}} = \sigma,\\ -0 & \text{otherwise.} -\end{cases} -\] -Equivalently, if $\sigma(\zeta_m) = \zeta_m^a$ with $\gcd(a,m)=1$, the sum equals $|G|$ -precisely when $N\mathfrak{p} \equiv a \pmod{m}$. -\end{lemma} --/ - -blueprint_comment /-- -\begin{proof} -Standard character orthogonality on the finite abelian group $G$. The reformulation in terms -of $N\mathfrak{p} \bmod m$ uses that $\varphi_{\mathfrak{p}}(\zeta_m) = \zeta_m^{N\mathfrak{p}}$ -for the cyclotomic character. -\end{proof} --/ - -blueprint_comment /-- -\begin{proposition}[Cyclotomic Chebotarev density]\label{Chebotarev-cyclotomic-density} -For every $\sigma \in G$, the set of prime ideals $\mathfrak{p}$ of $K$ unramified in $L$ with -Frobenius $\varphi_{\mathfrak{p}} = \sigma$ has Dirichlet density $1/|G|$. -\end{proposition} --/ - -blueprint_comment /-- -\begin{proof}\uses{Dedekind-factor, Dedekind-pole, Dedekind-nonvanishing, Artin-L-euler, -Chebotarev-orthogonality} -This is Proposition~7.2.1 of \url{https://www.math.ucla.edu/~sharifi/algnum.pdf}. For -$\Re(s)>1$ one has $\log L(\chi,s) \sim \sum_{\mathfrak{p}} \chi(\mathfrak{p})\, N\mathfrak{p}^{-s}$. -Summing against $\chi(\sigma)^{-1}$ and applying Lemma~\ref{Chebotarev-orthogonality} yields -\[ -\sum_{\chi} \chi(\sigma)^{-1} \log L(\chi,s) -\;\sim\; -|G| \sum_{\varphi_{\mathfrak{p}}=\sigma} N\mathfrak{p}^{-s}. -\] -On the other hand, by Lemmas~\ref{Dedekind-factor} and~\ref{Dedekind-nonvanishing} the left -side is $\sim \log\zeta_K(s) \sim \log(s-1)^{-1}$ as $s\to 1^+$ (only the trivial character -contributes a pole). Comparing the two asymptotics gives the asserted Dirichlet density. -\end{proof} --/ - -blueprint_comment /-- -\begin{lemma}[PNT for one character]\label{Dedekind-PNT} -For any nontrivial character $\chi$ of $G$, -\[ -\sum_{N\mathfrak{p} \leq x} \chi(\mathfrak{p})\, \log N\mathfrak{p} \;=\; o(x) -\qquad(x\to\infty). -\] -(Equivalently, writing $\Lambda_\chi$ for the von Mangoldt-type coefficients of $-\frac{L'}{L}(\chi,s)$, -one has $\sum_{n\leq x} \Lambda_\chi(n) = o(x)$.) -\end{lemma} - -\emph{Remark on prime powers.} -Expanding $-\frac{L'}{L}(\chi,s)$ as a Dirichlet series selects coefficients supported on -prime powers $\mathfrak{p}^j$ with weight $\chi(\varphi_{\mathfrak{p}})^j\log N\mathfrak{p}$. -Thus an \emph{exact} identity expressing $-\sum_\chi \chi(\sigma)^{-1}\frac{L'}{L}(\chi,s)$ as a -sum over primes with Frobenius $\sigma$ should use the condition $\varphi_{\mathfrak{p}}^j=\sigma$ -rather than $\varphi_{\mathfrak{p}}=\sigma$. For the density statement in -Proposition~\ref{Chebotarev-cyclotomic-density} this distinction is immaterial: the $j=1$ terms -agree with the Frobenius condition, while the $j\geq 2$ terms converge absolutely for -$\Re(s)>1/2$ and do not affect the residue at $s=1$. --/ - -blueprint_comment /-- -\begin{proof}\uses{Dedekind-nonvanishing, Artin-L-continuation} -By Lemmas~\ref{Artin-L-continuation} and~\ref{Dedekind-nonvanishing}, $L(\chi,s)$ is holomorphic -and nonvanishing on $\Re(s)\geq 1$, so $-\frac{L'}{L}(\chi,s)$ extends continuously to -$\Re(s)\geq 1$. The claimed prime-sum estimate then follows by the same Wiener--Ikehara / -Ingham contour argument used for Dirichlet $L$-functions in the prime-number theorem in -arithmetic progressions (cf.\ the material already formalised for Dirichlet $L$-functions -earlier in this file). Passing through $\Lambda_\chi$ (rather than the bare prime sum) makes -the $j\geq 2$ prime-power contributions explicit and shows they are $O(x^{1/2}\log x)$, -hence absorbable in the $o(x)$ error; cf.\ the remark after the statement. -\end{proof} --/ - -blueprint_comment /-- -\section{The Chebotarev density theorem: the case of abelian extensions} - -Now let $L/K$ be an arbitrary finite abelian extension with Galois group $G$, and fix -$\sigma \in G$. The goal is to show that the primes of $K$ with Frobenius $\sigma$ still have -Dirichlet density $1/|G|$, by reducing to the cyclotomic case already treated. -(Cf.\ Theorem~7.2.2, Step~2, of \url{https://www.math.ucla.edu/~sharifi/algnum.pdf}; cyclic -extensions already suffice for the later reduction to the general case.) --/ - -blueprint_comment /-- -\begin{lemma}[Cyclotomic crossing]\label{Chebotarev-abelian-crossing} -Choose an integer $m\geq 1$ not dividing the discriminant of $L/K$, large enough that -$H := \mathrm{Gal}(L(\mu_m)/L) \cong (\mathbb{Z}/m\mathbb{Z})^\times$ via the cyclotomic character -and $\mathrm{Gal}(L(\mu_m)/K) \cong G \times H$. For $\sigma\in G$ and $\tau\in H$ write -$S_{\sigma,\tau}$ for the set of primes of $K$ unramified in $L(\mu_m)$ with Frobenius -$(\sigma,\tau)\in G\times H$, and $S_\sigma$ for the set of primes of $K$ unramified in $L$ -with Frobenius $\sigma$ in $G$. Then -\[ -\delta_{\mathrm{inf}}(S_\sigma) \;=\; \sum_{\tau\in H} \delta_{\mathrm{inf}}(S_{\sigma,\tau}). -\] -\end{lemma} --/ - -blueprint_comment /-- -\begin{proof} -Every prime counted in $S_\sigma$ lifts to primes in the various $S_{\sigma,\tau}$ according to -the Frobenius in the cyclotomic layer; the identity of lower densities is the usual additivity -of Dirichlet densities over a finite partition (up to the finitely many ramified primes). -\end{proof} --/ - -blueprint_comment /-- -\begin{lemma}[Density after cyclotomic crossing]\label{Chebotarev-abelian-density} -In the notation of Lemma~\ref{Chebotarev-abelian-crossing}, if the order of $\tau\in H$ is -divisible by $|G|$, then $\langle(\sigma,\tau)\rangle \cap (G\times\{1\}) = \{1\}$, so -$L(\mu_m)$ is obtained by adjoining $\mu_m$ to the fixed field -$F := L(\mu_m)^{\langle(\sigma,\tau)\rangle}$. Applying Proposition~\ref{Chebotarev-cyclotomic-density} -to the cyclotomic extension $F(\mu_m)/F$ and transporting densities as in the reduction step -of Theorem~7.2.2 yields $\delta(S_{\sigma,\tau}) = 1/(|G|\,|H|)$. -\end{lemma} --/ - -blueprint_comment /-- -\begin{proof}\uses{Chebotarev-cyclotomic-density, Chebotarev-abelian-crossing} -See Sharifi, Theorem~7.2.2, Step~2 (display after ``Now suppose that $|G|$ divides the order of -$\tau$''). -\end{proof} --/ - -blueprint_comment /-- -\begin{proposition}[Abelian Chebotarev]\label{Chebotarev-abelian} -Let $L/K$ be finite abelian with Galois group $G$. For every $\sigma\in G$, the Dirichlet -density of primes of $K$ with Frobenius $\sigma$ exists and equals $1/|G|$. -\end{proposition} --/ - -blueprint_comment /-- -\begin{proof}\uses{Chebotarev-abelian-crossing, Chebotarev-abelian-density, -Chebotarev-cyclotomic-density} -Let $H_n \subset H$ be the set of elements whose order is divisible by $n$. Summing the -densities of Lemma~\ref{Chebotarev-abelian-density} over $\tau\in H_n$ gives -$\delta_{\mathrm{inf}}(S_\sigma) \geq |H_n|/(|G|\,|H|)$. Choosing $m$ so that $|H_n|/|H|$ is -arbitrarily close to $1$ (possible since there are primes $m\equiv 1\pmod{n^j}$ by the -cyclotomic case already proved, and $|H_n|/|H|$ tends to $1$ as $j\to\infty$), one obtains -$\delta_{\mathrm{inf}}(S_\sigma) \geq 1/|G|$. Summing over $\sigma\in G$ forces equality -throughout, so each density exists and equals $1/|G|$. -\end{proof} --/ - -blueprint_comment /-- -\section{The Chebotarev density theorem: the general case} - -Finally let $L/K$ be an arbitrary finite Galois extension with group $G$, and let $C\subset G$ -be a conjugacy class. The theorem reduces to the abelian (indeed cyclic) case already proved, -by passing to the fixed field of an element of $C$. --/ - -blueprint_comment /-- -\begin{lemma}[Reduction to a cyclic subextension]\label{Chebotarev-reduction} -Fix $\sigma\in C$ and let $E$ be the fixed field of $\langle\sigma\rangle$, so $L/E$ is cyclic of -degree $f = |\langle\sigma\rangle|$. Write $S$ for the set of primes of $K$ unramified in $L$ -whose Frobenius class equals $C$, and $T_\sigma$ for the set of primes $\mathfrak{P}$ of $E$ -unramified in $L$ (and lying over $K$) with Frobenius equal to $\sigma$. Then -\[ -\delta(S) \;=\; \frac{f\,|C|}{|G|}\,\delta(T_\sigma), -\] -whenever either density exists. In particular, the Chebotarev statement for $L/K$ and $C$ -follows from the abelian statement for the cyclic extension $L/E$ and the element $\sigma$. -\end{lemma} --/ - -blueprint_comment /-- -\begin{proof} -If $\mathfrak{P}\in T_\sigma$, then $\varphi_{\mathfrak{P}}=\sigma$ fixes $E$, so $\mathfrak{P}$ has -residue degree one over $K$. There are exactly $|G|/f$ primes of $L$ over $\mathfrak{P}\cap K$, -and their Frobenii are equidistributed among the $|C|$ elements of the conjugacy class $C$; -exactly $|G|/(f\,|C|)$ of them have Frobenius $\sigma$. Comparing the Dirichlet series -$\sum N\mathfrak{p}^{-s}$ over $S$ with $\sum N\mathfrak{P}^{-s}$ over $T_\sigma$ (and using -$\sum_{\mathfrak{p}} N\mathfrak{p}^{-s} \sim \sum_{\mathfrak{P}} N\mathfrak{P}^{-s}$) yields the -displayed identity. See Sharifi, Theorem~7.2.2, Step~1. -\end{proof} --/ - -blueprint_comment /-- -\begin{theorem}[Chebotarev density theorem]\label{Chebotarev-general} -Let $L/K$ be a finite Galois extension of number fields with Galois group $G$, and let -$C\subset G$ be a conjugacy class. The set of prime ideals $\mathfrak{p}$ of $K$ unramified in -$L$ whose Frobenius conjugacy class equals $C$ has Dirichlet density $|C|/|G|$. -\end{theorem} --/ - -blueprint_comment /-- -\begin{proof}\uses{Chebotarev-reduction, Chebotarev-abelian} -Combine Lemma~\ref{Chebotarev-reduction} with Proposition~\ref{Chebotarev-abelian} applied to -the cyclic extension $L/E$: the latter gives $\delta(T_\sigma) = 1/f$, whence -$\delta(S) = |C|/|G|$. -\end{proof} --/ diff --git a/PrimeNumberTheoremAnd/ZetaFive.lean b/PrimeNumberTheoremAnd/ZetaFive.lean new file mode 100644 index 0000000..6e3d2a8 --- /dev/null +++ b/PrimeNumberTheoremAnd/ZetaFive.lean @@ -0,0 +1,5 @@ +import PrimeNumberTheoremAnd.ZetaFive.Sobolev +import PrimeNumberTheoremAnd.ZetaFive.Fourier +import PrimeNumberTheoremAnd.ZetaFive.SmoothExistence +import PrimeNumberTheoremAnd.ZetaFive.Wiener +import PrimeNumberTheoremAnd.ZetaFive.Consequences diff --git a/PrimeNumberTheoremAnd/ZetaFive/Consequences.lean b/PrimeNumberTheoremAnd/ZetaFive/Consequences.lean new file mode 100644 index 0000000..aa7c25c --- /dev/null +++ b/PrimeNumberTheoremAnd/ZetaFive/Consequences.lean @@ -0,0 +1,66 @@ +import Mathlib.Analysis.Asymptotics.SpecificAsymptotics +import Mathlib.Analysis.SpecialFunctions.Log.Basic +import PrimeNumberTheoremAnd.ZetaFive.Wiener + +namespace ZetaFivePNT + +open ArithmeticFunction hiding log +open Nat hiding log +open _root_.Finset +open BigOperators _root_.Filter _root_.Real _root_.Asymptotics +open scoped Chebyshev + +theorem WeakPNT' : Tendsto (fun N ↦ (∑ n ∈ Iic N, Λ n) / N) atTop (nhds 1) := by + have : (fun N ↦ (∑ n ∈ Iic N, Λ n) / N) = + (fun N ↦ (∑ n ∈ range N, Λ n)/N + Λ N / N) := by + ext N + have : N ∈ Iic N := mem_Iic.mpr (le_refl _) + rw [← Finset.sum_erase_add _ _ this, ← Nat.Iio_eq_range, Iic_erase] + exact add_div _ _ _ + rw [this, ← add_zero 1] + apply Tendsto.add WeakPNT + convert squeeze_zero (f := fun N ↦ Λ N / N) (g := fun N ↦ log N / N) (t₀ := atTop) ?_ ?_ ?_ + · intro N + exact div_nonneg vonMangoldt_nonneg (cast_nonneg N) + · intro N + exact div_le_div_of_nonneg_right vonMangoldt_le_log (cast_nonneg N) + simpa only [Function.comp_def, pow_one, one_mul, add_zero] using + (Real.tendsto_pow_log_div_mul_add_atTop 1 0 1 one_ne_zero).comp + tendsto_natCast_atTop_atTop + +theorem WeakPNT'' : ψ ~[atTop] (fun x ↦ x) := by + rw [(by rfl : ψ = (fun x ↦ ψ x))] + simp_rw [Chebyshev.psi_eq_sum_Icc] + apply IsEquivalent.trans (v := fun x ↦ (⌊x⌋₊:ℝ)) + · rw [isEquivalent_iff_tendsto_one] + · convert Tendsto.comp WeakPNT' (tendsto_nat_floor_atTop (α := ℝ)) using 1 + ext x + rfl + rw [eventually_iff] + simp only [ne_eq, cast_eq_zero, floor_eq_zero, not_lt, mem_atTop_sets, + Set.mem_ofPred_eq] + use 1 + simp only [imp_self, implies_true] + exact Asymptotics.isEquivalent_nat_floor + +theorem isLittleO_sqrt_mul_log : (fun x : ℝ ↦ x.sqrt * x.log) =o[atTop] _root_.id := by + have : (fun x : ℝ ↦ x.sqrt * x.log) =o[atTop] fun x ↦ x := by + refine (isLittleO_mul_iff_isLittleO_div ?_).mpr ?_ + · filter_upwards [eventually_gt_atTop 0] with x hx; exact (sqrt_ne_zero hx.le).mpr hx.ne' + · convert isLittleO_log_rpow_atTop (by norm_num : (0 : ℝ) < 1 / 2) using 2 with x + rw [div_sqrt, sqrt_eq_rpow] + exact this + +theorem chebyshev_asymptotic : θ ~[atTop] id := by + rw [← sub_sub_self ψ θ] + refine WeakPNT''.sub_isLittleO + (IsBigO.trans_isLittleO (g := fun x ↦ 2 * x.sqrt * x.log) ?_ ?_) + · rw [isBigO_iff']; refine ⟨1, one_pos, ?_⟩ + simp only [one_mul, eventually_atTop] + exact ⟨2, fun x hx ↦ by + rw [Pi.sub_apply, norm_eq_abs, norm_eq_abs, abs_of_nonneg (by bound : 0 ≤ 2 * √x * log x)] + exact (abs_of_nonneg (sub_nonneg.mpr (Chebyshev.theta_le_psi x))).symm ▸ + Chebyshev.abs_psi_sub_theta_le_sqrt_mul_log (by linarith : 1 ≤ x)⟩ + · convert isLittleO_sqrt_mul_log.const_mul_left 2 using 1 <;> first | rfl | (funext x; ring) + +end ZetaFivePNT diff --git a/PrimeNumberTheoremAnd/ZetaFive/Fourier.lean b/PrimeNumberTheoremAnd/ZetaFive/Fourier.lean new file mode 100644 index 0000000..95d8904 --- /dev/null +++ b/PrimeNumberTheoremAnd/ZetaFive/Fourier.lean @@ -0,0 +1,42 @@ +import Mathlib.Topology.ContinuousMap.Bounded.Basic +import Mathlib.Analysis.Fourier.FourierTransformDeriv +import PrimeNumberTheoremAnd.ZetaFive.Sobolev + +namespace ZetaFivePNT + +open FourierTransform Real Complex MeasureTheory Filter Topology BoundedContinuousFunction + SchwartzMap VectorFourier BigOperators + +section lemmas + +@[simp] theorem F_neg {f : ℝ → ℂ} {u : ℝ} : 𝓕 (fun x => -f x) u = - 𝓕 f u := by + simp [fourier_eq, integral_neg] + +@[simp] theorem F_add {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) (x : ℝ) : + 𝓕 (fun x => f x + g x) x = 𝓕 f x + 𝓕 g x := by + exact congr_fun (fourierIntegral_add continuous_fourierChar continuous_inner hf hg) x + +@[simp] theorem F_sub {f g : ℝ → ℂ} (hf : Integrable f) (hg : Integrable g) (x : ℝ) : + 𝓕 (fun x => f x - g x) x = 𝓕 f x - 𝓕 g x := by + simpa [sub_eq_add_neg, Pi.neg_def] using F_add hf hg.neg x + +@[simp] theorem F_mul {f : ℝ → ℂ} {c : ℂ} {u : ℝ} : + 𝓕 (fun x => c * f x) u = c * 𝓕 f u := by + exact congr_fun (VectorFourier.fourierIntegral_const_smul 𝐞 _ _ f c) u + +end lemmas + +theorem fourierIntegral_self_add_deriv_deriv (f : W21) (u : ℝ) : + (1 + u ^ 2) * 𝓕 (f : ℝ → ℂ) u = + 𝓕 (fun u : ℝ => (f u - (1 / (4 * π ^ 2)) * deriv^[2] f u : ℂ)) u := by + have l1 : Integrable (fun x => (((π : ℂ) ^ 2)⁻¹ * 4⁻¹) * deriv (deriv f) x) := by + apply Integrable.const_mul ; simpa [iteratedDeriv_succ] using f.integrable le_rfl + have l4 : Differentiable ℝ f := f.differentiable + have l5 : Differentiable ℝ (deriv f) := f.deriv.differentiable + simp [f.hf, l1, add_mul, Real.fourier_deriv f.hf' l5 f.hf'', Real.fourier_deriv f.hf l4 f.hf'] + field_simp [pi_ne_zero] ; ring_nf ; simp + +@[simp] theorem deriv_ofReal : deriv ofReal = fun _ => 1 := by + ext x ; exact ((hasDerivAt_id x).ofReal_comp).deriv + +end ZetaFivePNT diff --git a/PrimeNumberTheoremAnd/ZetaFive/SmoothExistence.lean b/PrimeNumberTheoremAnd/ZetaFive/SmoothExistence.lean new file mode 100644 index 0000000..6dad927 --- /dev/null +++ b/PrimeNumberTheoremAnd/ZetaFive/SmoothExistence.lean @@ -0,0 +1,43 @@ +import Mathlib.Geometry.Manifold.PartitionOfUnity +import Mathlib.Tactic.Bound + +namespace ZetaFivePNT + +open MeasureTheory Set Real +open scoped ContDiff + +theorem smooth_urysohn_support_Ioo {a b c d : ℝ} (h1 : a < b) (h3 : c < d) : + ∃ Ψ : ℝ → ℝ, (ContDiff ℝ ∞ Ψ) ∧ (HasCompactSupport Ψ) ∧ + Set.indicator (Set.Icc b c) 1 ≤ Ψ ∧ Ψ ≤ Set.indicator (Set.Ioo a d) 1 ∧ + (Function.support Ψ = Set.Ioo a d) := by + have := exists_contDiff_zero_iff_one_iff_of_isClosed (n := ⊤) + (s := Set.Iic a ∪ Set.Ici d) (t := Set.Icc b c) + (IsClosed.union isClosed_Iic isClosed_Ici) isClosed_Icc + (by + simp_rw [Set.disjoint_union_left, Set.disjoint_iff, Set.subset_def, + Set.mem_inter_iff, Set.mem_Iic, Set.mem_Icc, Set.mem_empty_iff_false, + and_imp, imp_false, not_le, Set.mem_Ici] + constructor <;> intros <;> linarith) + obtain ⟨Ψ, hΨSmooth, hΨrange, hΨ0, hΨ1⟩ := this + simp only [Set.mem_union, Set.mem_Iic, Set.mem_Ici, Set.mem_Icc] at * + use Ψ + simp only [range_subset_iff, mem_Icc] at hΨrange + refine ⟨hΨSmooth, ?_, ?_, ?_, ?_⟩ + · apply HasCompactSupport.of_support_subset_isCompact (K := Set.Icc a d) isCompact_Icc + simp only [Function.support_subset_iff, ne_eq, mem_Icc, ← hΨ0, not_or] + bound + · apply Set.indicator_le' + · intro x hx + rw [hΨ1 x |>.mp, Pi.one_apply] + simpa using hx + · exact fun x _ ↦ (hΨrange x).1 + · intro x + apply Set.le_indicator_apply + · exact fun _ ↦ (hΨrange x).2 + · intro hx + rw [← hΨ0 x |>.mp] + simpa [-not_and, mem_Ioo, not_and_or, not_lt] using hx + · ext x + simp only [Function.mem_support, ne_eq, mem_Ioo, ← hΨ0, not_or, not_le] + +end ZetaFivePNT diff --git a/PrimeNumberTheoremAnd/ZetaFive/Sobolev.lean b/PrimeNumberTheoremAnd/ZetaFive/Sobolev.lean new file mode 100644 index 0000000..10b6035 --- /dev/null +++ b/PrimeNumberTheoremAnd/ZetaFive/Sobolev.lean @@ -0,0 +1,401 @@ +import Mathlib.Analysis.Calculus.Deriv.Support +import Mathlib.Analysis.Calculus.IteratedDeriv.Lemmas +import Mathlib.Analysis.Distribution.SchwartzSpace.Deriv +import Mathlib.Order.Filter.ZeroAndBoundedAtFilter + +namespace ZetaFivePNT + +open Real Complex MeasureTheory Filter Topology BoundedContinuousFunction SchwartzMap BigOperators +open scoped ContDiff + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {n : ℕ} + + + +structure CS (n : ℕ) (E : Type*) [NormedAddCommGroup E] [NormedSpace ℝ E] where + + toFun : ℝ → E + h1 : ContDiff ℝ n toFun + h2 : HasCompactSupport toFun + +@[ext] protected theorem CS.ext {n : ℕ} {E : Type*} + [NormedAddCommGroup E] [NormedSpace ℝ E] {x y : CS n E} + (h : x.toFun = y.toFun) : x = y := by + cases x + cases y + cases h + rfl + + + +structure trunc extends (CS 2 ℝ) where + h3 : (Set.Icc (-1) (1)).indicator 1 ≤ toFun + h4 : toFun ≤ Set.indicator (Set.Ioo (-2) (2)) 1 + + + +structure W1 (n : ℕ) (E : Type*) [NormedAddCommGroup E] [NormedSpace ℝ E] where + + toFun : ℝ → E + smooth : ContDiff ℝ n toFun + integrable : ∀ ⦃k⦄, k ≤ n → Integrable (iteratedDeriv k toFun) + + + +abbrev W21 := W1 2 ℂ + +section lemmas + + +noncomputable def funscale {E : Type*} (g : ℝ → E) (R x : ℝ) : E := g (R⁻¹ • x) + +theorem contDiff_ofReal : ContDiff ℝ ∞ ofReal := Complex.ofRealCLM.contDiff + +omit [NormedSpace ℝ E] in +theorem tendsto_funscale {f : ℝ → E} (hf : ContinuousAt f 0) (x : ℝ) : + Tendsto (fun R => funscale f R x) atTop (𝓝 (f 0)) := + hf.tendsto.comp (by simpa using tendsto_inv_atTop_zero.mul_const x) + +end lemmas + +namespace CS + +variable {f : CS n E} {R x v : ℝ} + +instance : CoeFun (CS n E) (fun _ => ℝ → E) where coe := CS.toFun + +instance : Coe (CS n ℝ) (CS n ℂ) where coe f := ⟨fun x => f x, + contDiff_ofReal.of_le (mod_cast le_top) |>.comp f.h1, f.h2.comp_left (g := ofReal) rfl⟩ + + +def neg (f : CS n E) : CS n E where + toFun := -f + h1 := f.h1.neg + h2 := f.h2.neg + +instance : Neg (CS n E) where neg := neg + +@[simp] theorem neg_apply {x : ℝ} : (-f) x = - (f x) := rfl + + +def smul (R : ℝ) (f : CS n E) : CS n E := ⟨R • f, f.h1.const_smul R, f.h2.smul_left⟩ + +instance : HSMul ℝ (CS n E) (CS n E) where hSMul := smul + +@[simp] theorem smul_apply : (R • f) x = R • f x := rfl + +theorem continuous (f : CS n E) : Continuous f := f.h1.continuous + + + +noncomputable def deriv (f : CS (n + 1) E) : CS n E where + toFun := _root_.deriv f + h1 := (contDiff_succ_iff_deriv.mp f.h1).2.2 + h2 := f.h2.deriv + +theorem hasDerivAt (f : CS (n + 1) E) (x : ℝ) : HasDerivAt f (f.deriv x) x := + (f.h1.differentiable (by simp)).differentiableAt.hasDerivAt + +theorem deriv_apply {f : CS (n + 1) E} {x : ℝ} : f.deriv x = _root_.deriv f x := rfl + +theorem deriv_smul {f : CS (n + 1) E} : (R • f).deriv = R • f.deriv := by + ext x ; exact (f.hasDerivAt x |>.const_smul R).deriv + + + +noncomputable def scale (g : CS n E) (R : ℝ) : CS n E := by + by_cases h : R = 0 + · exact ⟨0, contDiff_const, by simp [HasCompactSupport, tsupport]⟩ + · refine ⟨fun x => funscale g R x, ?_, ?_⟩ + · exact g.h1.comp (contDiff_const_smul R⁻¹) + · exact g.h2.comp_smul (inv_ne_zero h) + +theorem deriv_scale {f : CS (n + 1) E} : (f.scale R).deriv = R⁻¹ • f.deriv.scale R := by + ext v ; by_cases hR : R = 0 + · simp [hR, scale, deriv] + · simp only [scale, hR, ↓reduceDIte, smul_apply] + exact ((f.hasDerivAt (R⁻¹ • v)).scomp v + (by convert (hasDerivAt_const_mul (x := v) R⁻¹) using 1)).deriv + +theorem deriv_scale' {f : CS (n + 1) E} : + (f.scale R).deriv v = R⁻¹ • f.deriv (R⁻¹ • v) := by + rw [deriv_scale, smul_apply] + by_cases hR : R = 0 <;> simp [hR, scale, funscale] + +theorem hasDerivAt_scale (f : CS (n + 1) E) (R x : ℝ) : + HasDerivAt (f.scale R) (R⁻¹ • _root_.deriv f (R⁻¹ • x)) x := by + convert hasDerivAt (f.scale R) x ; rw [deriv_scale'] ; rfl + +theorem tendsto_scale (f : CS n E) (x : ℝ) : Tendsto (fun R => f.scale R x) atTop (𝓝 (f 0)) := by + apply (tendsto_funscale f.continuous.continuousAt x).congr' + filter_upwards [eventually_ne_atTop 0] with R hR ; simp [scale, hR] + +theorem bounded : ∃ C, ∀ v, ‖f v‖ ≤ C := by + obtain ⟨x, hx⟩ := + (continuous_norm.comp f.continuous).exists_forall_ge_of_hasCompactSupport f.h2.norm + exact ⟨_, hx⟩ + +end CS + +namespace trunc + +instance : CoeFun trunc (fun _ => ℝ → ℝ) where coe f := f.toFun + +instance : Coe trunc (CS 2 ℝ) where coe := trunc.toCS + +theorem nonneg (g : trunc) (x : ℝ) : 0 ≤ g x := (Set.indicator_nonneg (by simp) x).trans (g.h3 x) + +theorem le_one (g : trunc) (x : ℝ) : g x ≤ 1 := + (g.h4 x).trans <| Set.indicator_le_self' (by simp) x + +theorem zero (g : trunc) : g =ᶠ[𝓝 0] 1 := by + have : Set.Icc (-1) 1 ∈ 𝓝 (0 : ℝ) := by apply Icc_mem_nhds <;> linarith + exact eventually_of_mem this (fun x hx => le_antisymm (g.le_one x) (by simpa [hx] using g.h3 x)) + +@[simp] theorem zero_at {g : trunc} : g 0 = 1 := g.zero.eq_of_nhds + +end trunc + +namespace W1 + +instance : CoeFun (W1 n E) (fun _ => ℝ → E) where coe := W1.toFun + +theorem continuous (f : W1 n E) : Continuous f := f.smooth.continuous + +theorem differentiable (f : W1 (n + 1) E) : Differentiable ℝ f := + f.smooth.differentiable (by simp) + +theorem iteratedDeriv_sub {f g : ℝ → E} (hf : ContDiff ℝ n f) (hg : ContDiff ℝ n g) : + iteratedDeriv n (f - g) = iteratedDeriv n f - iteratedDeriv n g := by + funext x + exact _root_.iteratedDeriv_sub hf.contDiffAt hg.contDiffAt + + + +noncomputable def deriv (f : W1 (n + 1) E) : W1 n E where + toFun := _root_.deriv f + smooth := contDiff_succ_iff_deriv.mp f.smooth |>.2.2 + integrable k hk := by + simpa [iteratedDeriv_succ'] using f.integrable (Nat.succ_le_succ hk) + +theorem hasDerivAt (f : W1 (n + 1) E) (x : ℝ) : HasDerivAt f (f.deriv x) x := + f.differentiable.differentiableAt.hasDerivAt + + + +def sub (f g : W1 n E) : W1 n E where + toFun := f - g + smooth := f.smooth.sub g.smooth + integrable k hk := by + have hf : ContDiff ℝ k f := f.smooth.of_le (by simp [hk]) + have hg : ContDiff ℝ k g := g.smooth.of_le (by simp [hk]) + simpa [iteratedDeriv_sub hf hg] using (f.integrable hk).sub (g.integrable hk) + +instance : Sub (W1 n E) where sub := sub + +theorem integrable_iteratedDeriv_Schwarz {f : 𝓢(ℝ, ℂ)} : Integrable (iteratedDeriv n f) := by + induction n generalizing f with + | zero => exact f.integrable + | succ n ih => + rw [iteratedDeriv_succ'] + have hd : (SchwartzMap.derivCLM ℝ ℂ f : ℝ → ℂ) = _root_.deriv f := by + funext x + exact SchwartzMap.derivCLM_apply ℝ f x + rw [← hd] + exact ih (f := SchwartzMap.derivCLM ℝ ℂ f) + + + +noncomputable def ofSchwartz (f : 𝓢(ℝ, ℂ)) : W1 n ℂ where + toFun := f + smooth := f.smooth n + integrable _ _ := integrable_iteratedDeriv_Schwarz + +end W1 + +namespace W21 + +variable {f : W21} + + + +noncomputable def norm (f : ℝ → ℂ) : ℝ := + (∫ v, ‖f v‖) + (4 * π ^ 2)⁻¹ * (∫ v, ‖deriv (deriv f) v‖) + +theorem norm_nonneg {f : ℝ → ℂ} : 0 ≤ norm f := + add_nonneg (integral_nonneg (fun t => by simp)) + (mul_nonneg (by positivity) (integral_nonneg (fun t => by simp))) + +noncomputable instance : Norm W21 where norm := norm ∘ W1.toFun + +noncomputable instance : Coe 𝓢(ℝ, ℂ) W21 where coe := W1.ofSchwartz + + +def ofCS2 (f : CS 2 ℂ) : W21 := by + refine ⟨f, f.h1, ?_⟩ + intro k hk + cases k with + | zero => exact f.h1.continuous.integrable_of_hasCompactSupport f.h2 + | succ k => + cases k with + | zero => + simpa using (f.h1.continuous_deriv one_le_two).integrable_of_hasCompactSupport f.h2.deriv + | succ k => + have hk0 : k = 0 := + Nat.eq_zero_of_le_zero (Nat.le_of_succ_le_succ (Nat.le_of_succ_le_succ hk)) + subst k + simpa [iteratedDeriv_succ] using + (f.h1.iterate_deriv' 0 2).continuous.integrable_of_hasCompactSupport f.h2.deriv.deriv + +instance : Coe (CS 2 ℂ) W21 where coe := ofCS2 + +instance : HMul (CS 2 ℂ) W21 (CS 2 ℂ) where + hMul g f := ⟨g * f, g.h1.mul f.smooth, g.h2.mul_right⟩ + +instance : HMul (CS 2 ℝ) W21 (CS 2 ℂ) where hMul g f := (g : CS 2 ℂ) * f + +theorem hf (f : W21) : Integrable f := f.integrable zero_le_two + +theorem hf' (f : W21) : Integrable (deriv f) := by + simpa [iteratedDeriv_succ] using f.integrable one_le_two + +theorem hf'' (f : W21) : Integrable (deriv (deriv f)) := by + simpa [iteratedDeriv_succ] using f.integrable le_rfl + +end W21 + +theorem W21_approximation (f : W21) (g : trunc) : + Tendsto (fun R => ‖f - (g.scale R * f : W21)‖) atTop (𝓝 0) := by + + let f' := f.deriv + let f'' := f'.deriv + let g' := (g : CS 2 ℝ).deriv + let g'' := g'.deriv + let h R v := 1 - g.scale R v + let h' R := - (g.scale R).deriv + let h'' R := - (g.scale R).deriv.deriv + + have ch {R} : Continuous (fun v => (h R v : ℂ)) := + continuous_ofReal.comp <| continuous_const.sub (CS.continuous _) + have ch' {R} : Continuous (fun v => (h' R v : ℂ)) := continuous_ofReal.comp (CS.continuous _) + have ch'' {R} : Continuous (fun v => (h'' R v : ℂ)) := continuous_ofReal.comp (CS.continuous _) + have dh R v : HasDerivAt (h R) (h' R v) v := by + convert CS.hasDerivAt_scale (g : CS 2 ℝ) R v |>.const_sub 1 using 1 + simp [h', CS.deriv_scale', show g.deriv.toFun = deriv g.toFun from rfl] + have dh' R v : HasDerivAt (h' R) (h'' R v) v := ((g.scale R).deriv.hasDerivAt v).neg + have hh1 R v : |h R v| ≤ 1 := by + by_cases hR : R = 0 <;> + simp only [CS.scale, funscale, smul_eq_mul, hR, ↓reduceDIte, Pi.zero_apply, sub_zero, + abs_one, le_refl, h] + rw [abs_le] ; constructor <;> + linarith [g.le_one (R⁻¹ * v), g.nonneg (R⁻¹ * v)] + have vR v : Tendsto (fun R : ℝ => v * R⁻¹) atTop (𝓝 0) := by + simpa using tendsto_inv_atTop_zero.const_mul v + + convert_to Tendsto (fun R => W21.norm (fun v => h R v * f v)) atTop (𝓝 0) + · ext R ; change W21.norm _ = _ ; congr ; ext v ; simp [h, sub_mul] ; rfl + rw [show (0 : ℝ) = 0 + ((4 * π ^ 2)⁻¹ : ℝ) * 0 by simp] + refine Tendsto.add ?_ (Tendsto.const_mul _ ?_) + · let F R v := ‖h R v * f v‖ + have eh v : ∀ᶠ R in atTop, h R v = 0 := by + filter_upwards [(vR v).eventually g.zero, eventually_ne_atTop 0] with R hR hR' + simp [h, hR, CS.scale, hR', funscale, mul_comm R⁻¹] + have e1 : ∀ᶠ (n : ℝ) in atTop, AEStronglyMeasurable (F n) volume := by + apply Eventually.of_forall ; intro R + exact (ch.mul f.continuous).norm.aestronglyMeasurable + have e2 : ∀ᶠ (n : ℝ) in atTop, ∀ᵐ (a : ℝ), ‖F n a‖ ≤ ‖f a‖ := by + apply Eventually.of_forall ; intro R + apply Eventually.of_forall ; intro v + simpa [F] using mul_le_mul (hh1 R v) le_rfl (by simp) zero_le_one + have e4 : ∀ᵐ (a : ℝ), Tendsto (fun n ↦ F n a) atTop (𝓝 0) := by + apply Eventually.of_forall ; intro v + apply tendsto_nhds_of_eventually_eq ; filter_upwards [eh v] with R hR ; simp [F, hR] + simpa [F] using tendsto_integral_filter_of_dominated_convergence _ e1 e2 f.hf.norm e4 + · let F R v := ‖h'' R v * f v + 2 * h' R v * f' v + h R v * f'' v‖ + convert_to Tendsto (fun R ↦ ∫ (v : ℝ), F R v) atTop (𝓝 0) + · have this R v : + deriv (deriv (fun v => h R v * f v)) v = + h'' R v * f v + 2 * h' R v * f' v + h R v * f'' v := by + have df v : HasDerivAt f (f' v) v := f.hasDerivAt v + have df' v : HasDerivAt f' (f'' v) v := f'.hasDerivAt v + have l3 v : HasDerivAt (fun v => h R v * f v) (h' R v * f v + h R v * f' v) v := + (dh R v).ofReal_comp.mul (df v) + have l5 : HasDerivAt (fun v => h' R v * f v) (h'' R v * f v + h' R v * f' v) v := + (dh' R v).ofReal_comp.mul (df v) + have l7 : HasDerivAt (fun v => h R v * f' v) (h' R v * f' v + h R v * f'' v) v := + (dh R v).ofReal_comp.mul (df' v) + have d1 : deriv (fun v => h R v * f v) = fun v => h' R v * f v + h R v * f' v := + funext (fun v => (l3 v).deriv) + rw [d1] ; convert (l5.add l7).deriv using 1 ; ring + simp_rw [this, F] + obtain ⟨c1, mg'⟩ := g'.bounded + obtain ⟨c2, mg''⟩ := g''.bounded + let bound v := c2 * ‖f v‖ + 2 * c1 * ‖f' v‖ + ‖f'' v‖ + have e1 : ∀ᶠ (n : ℝ) in atTop, AEStronglyMeasurable (F n) volume := by + apply Eventually.of_forall ; intro R ; apply (Continuous.norm ?_).aestronglyMeasurable + exact ((ch''.mul f.continuous).add ((continuous_const.mul ch').mul f.deriv.continuous)).add + (ch.mul f.deriv.deriv.continuous) + have e2 : ∀ᶠ R in atTop, ∀ᵐ (a : ℝ), ‖F R a‖ ≤ bound a := by + have hc1 : ∀ᶠ R in atTop, ∀ v, |h' R v| ≤ c1 := by + filter_upwards [eventually_ge_atTop 1] with R hR v + have hR' : R ≠ 0 := by linarith + have : 0 ≤ R := by linarith + simp only [CS.deriv_scale, CS.neg_apply, CS.smul_apply, smul_eq_mul, abs_neg, abs_mul, + abs_inv, abs_eq_self.mpr this, ge_iff_le, h'] + simp only [CS.scale, hR', ↓reduceDIte, funscale, smul_eq_mul] + convert_to _ ≤ c1 * 1 + · simp + · rw [mul_comm] + apply mul_le_mul (mg' _) + (inv_le_of_inv_le₀ (by linarith) (by simpa using hR)) (by positivity) + exact (abs_nonneg _).trans (mg' 0) + have hc2 : ∀ᶠ R in atTop, ∀ v, |h'' R v| ≤ c2 := by + filter_upwards [eventually_ge_atTop 1] with R hR v + have e1 : 0 ≤ R := by linarith + have e2 : R⁻¹ ≤ 1 := inv_le_of_inv_le₀ (by linarith) (by simpa using hR) + have e3 : R ≠ 0 := by linarith + simp only [CS.deriv_scale, CS.deriv_smul, CS.neg_apply, CS.smul_apply, smul_eq_mul, abs_neg, + abs_mul, abs_inv, abs_eq_self.mpr e1, ge_iff_le, h''] + convert_to _ ≤ 1 * (1 * c2) + · simp + apply mul_le_mul e2 ?_ (by positivity) zero_le_one + apply mul_le_mul e2 ?_ (by positivity) zero_le_one + simp only [CS.scale, e3, ↓reduceDIte, funscale, smul_eq_mul] ; apply mg'' + filter_upwards [hc1, hc2] with R hc1 hc2 + apply Eventually.of_forall ; intro v ; specialize hc1 v ; specialize hc2 v + simp only [F, bound, norm_norm] + refine (norm_add_le _ _).trans ?_ ; apply add_le_add + · refine (norm_add_le _ _).trans ?_ ; apply add_le_add <;> simp only [Complex.norm_mul, + Complex.norm_ofNat, norm_real, norm_eq_abs] <;> gcongr + · simpa using mul_le_mul (hh1 R v) le_rfl (by simp) zero_le_one + have e3 : Integrable bound volume := + (((f.hf.norm).const_mul _).add ((f.hf'.norm).const_mul _)).add f.hf''.norm + have e4 : ∀ᵐ (a : ℝ), Tendsto (fun n ↦ F n a) atTop (𝓝 0) := by + apply Eventually.of_forall ; intro v + have evg' : (g' : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 0) := by + have hzero : (g : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 1) := g.zero + change _root_.deriv (g : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 0) + simpa only [deriv_const'] using hzero.deriv + have evg'' : (g'' : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 0) := by + change _root_.deriv (g' : ℝ → ℝ) =ᶠ[𝓝 (0 : ℝ)] (fun _ : ℝ => 0) + simpa only [deriv_const'] using evg'.deriv + refine tendsto_norm_zero.comp <| (ZeroAtFilter.add ?_ ?_).add ?_ + · have eh'' v : ∀ᶠ R in atTop, h'' R v = 0 := by + filter_upwards [(vR v).eventually evg'', eventually_ne_atTop 0] with R hR hR' + simp only [CS.deriv_scale, CS.deriv_smul, CS.neg_apply, CS.smul_apply, smul_eq_mul, + neg_eq_zero, mul_eq_zero, inv_eq_zero, hR', false_or, h''] + simp only [CS.scale, hR', ↓reduceDIte, funscale, smul_eq_mul, mul_comm R⁻¹] + exact hR + apply tendsto_nhds_of_eventually_eq + filter_upwards [eh'' v] with R hR ; simp [hR] + · have eh' v : ∀ᶠ R in atTop, h' R v = 0 := by + filter_upwards [(vR v).eventually evg'] with R hR + simp [g'] at hR + simp [h', CS.deriv_scale', mul_comm R⁻¹, hR] + apply tendsto_nhds_of_eventually_eq + filter_upwards [eh' v] with R hR ; simp [hR] + · simpa [h, Filter.ZeroAtFilter] using + ((g.tendsto_scale v).const_sub 1).ofReal.mul tendsto_const_nhds + simpa [F] using tendsto_integral_filter_of_dominated_convergence bound e1 e2 e3 e4 + +end ZetaFivePNT diff --git a/PrimeNumberTheoremAnd/ZetaFive/Wiener.lean b/PrimeNumberTheoremAnd/ZetaFive/Wiener.lean new file mode 100644 index 0000000..18c58cb --- /dev/null +++ b/PrimeNumberTheoremAnd/ZetaFive/Wiener.lean @@ -0,0 +1,2358 @@ +import Mathlib.Analysis.Fourier.RiemannLebesgueLemma +import Mathlib.Analysis.Normed.Group.Tannery +import Mathlib.Analysis.SumIntegralComparisons +import Mathlib.NumberTheory.Chebyshev +import Mathlib.NumberTheory.LSeries.PrimesInAP +import Mathlib.NumberTheory.MulChar.Lemmas +import PrimeNumberTheoremAnd.ZetaFive.Fourier +import PrimeNumberTheoremAnd.ZetaFive.SmoothExistence +import Mathlib.Analysis.Convolution +import Mathlib.MeasureTheory.Group.Circle + +namespace ZetaFivePNT + +open Real BigOperators ArithmeticFunction MeasureTheory Filter Set FourierTransform LSeries + Asymptotics SchwartzMap +open Complex hiding log +open scoped Topology +open scoped ContDiff +open scoped ComplexConjugate + +variable {n : ℕ} {A a b c d u x y t σ' : ℝ} {ψ Ψ : ℝ → ℂ} {F G : ℂ → ℂ} {f : ℕ → ℂ} {𝕜 : Type} + [RCLike 𝕜] + + + + + + + + + + + + + +noncomputable +def nterm (f : ℕ → ℂ) (σ' : ℝ) (n : ℕ) : ℝ := if n = 0 then 0 else ‖f n‖ / n ^ σ' + +theorem nterm_eq_norm_term {f : ℕ → ℂ} : nterm f σ' n = ‖term f σ' n‖ := by + by_cases h : n = 0 <;> simp [nterm, term, h] + +theorem norm_term_eq_nterm_re (s : ℂ) : + ‖term f s n‖ = nterm f (s.re) n := by + simpa only [nterm] using LSeries.norm_term_eq f s n + +theorem hf_coe1 (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (hσ : 1 < σ') : + ∑' i, (‖term f σ' i‖₊ : ENNReal) ≠ ⊤ := by + simp_rw [ENNReal.tsum_coe_ne_top_iff_summable_coe, ← norm_toNNReal] + norm_cast + apply Summable.toNNReal + convert hf σ' hσ with i + simp [nterm_eq_norm_term] + + +attribute [fun_prop] Real.continuous_fourierChar + +theorem first_fourier_aux1 (hψ : AEMeasurable ψ) {x : ℝ} (n : ℕ) : AEMeasurable fun (u : ℝ) ↦ + (‖fourierChar (-(u * ((1 : ℝ) / ((2 : ℝ) * π) * (n / x).log))) • ψ u‖ₑ : ENNReal) := by + fun_prop + +theorem first_fourier_aux2a : + (2 : ℂ) * π * -(y * (1 / (2 * π) * Real.log ((n) / x))) = -(y * ((n) / x).log) := by + calc + _ = -(y * (((2 : ℂ) * π) / (2 * π) * Real.log ((n) / x))) := by ring + _ = _ := by rw [div_self (by norm_num), one_mul] + +theorem first_fourier_aux2 (hx : 0 < x) (n : ℕ) : + term f σ' n * 𝐞 (-(y * (1 / (2 * π) * Real.log (n / x)))) • ψ y = + term f (σ' + y * I) n • (ψ y * x ^ (y * I)) := by + by_cases hn : n = 0 + · simp [term, hn] + simp only [term, hn, ↓reduceIte] + calc + _ = (f n * (cexp ((2 * π * -(y * (1 / (2 * π) * Real.log (n / x)))) * I) / + ↑((n : ℝ) ^ σ'))) • ψ y := by + rw [Circle.smul_def, fourierChar_apply, ofReal_cpow (by norm_num)] + simp only [one_div, mul_inv_rev, mul_neg, ofReal_neg, ofReal_mul, ofReal_ofNat, ofReal_inv, + neg_mul, smul_eq_mul, ofReal_natCast] + ring + _ = (f n * (x ^ (y * I) / n ^ (σ' + y * I))) • ψ y := by + congr 2 + have l1 : 0 < (n : ℝ) := by simpa using Nat.pos_iff_ne_zero.mpr hn + have l2 : (x : ℂ) ≠ 0 := by simp [hx.ne.symm] + have l3 : (n : ℂ) ≠ 0 := by simp [hn] + rw [Real.rpow_def_of_pos l1, Complex.cpow_def_of_ne_zero l2, Complex.cpow_def_of_ne_zero l3] + push_cast + simp_rw [← Complex.exp_sub] + congr 1 + rw [first_fourier_aux2a, Real.log_div l1.ne.symm hx.ne.symm] + push_cast + rw [Complex.ofReal_log hx.le] + ring + _ = _ := by simp ; group + + + + + + + + + + + + + + + + + + + + +theorem first_fourier (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hsupp : Integrable ψ) (hx : 0 < x) (hσ : 1 < σ') : + ∑' n : ℕ, term f σ' n * (𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))) = + ∫ t : ℝ, LSeries f (σ' + t * I) * ψ t * x ^ (t * I) := by + calc + _ = ∑' n, term f σ' n * ∫ (v : ℝ), 𝐞 (-(v * ((1 : ℝ) / + ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by + simp only [Real.fourier_eq] + simp only [one_div, mul_inv_rev, RCLike.inner_apply', conj_trivial] + _ = ∑' n, ∫ (v : ℝ), term f σ' n * 𝐞 (-(v * ((1 : ℝ) / + ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by + simp [integral_const_mul] + _ = ∫ (v : ℝ), ∑' n, term f σ' n * 𝐞 (-(v * ((1 : ℝ) / + ((2 : ℝ) * π) * Real.log (n / x)))) • ψ v := by + refine (integral_tsum ?_ ?_).symm + · refine fun _ ↦ AEMeasurable.aestronglyMeasurable ?_ + have := hsupp.aemeasurable + fun_prop + · simp only [enorm_mul] + simp_rw [lintegral_const_mul'' _ (first_fourier_aux1 hsupp.aemeasurable _)] + calc + _ = (∑' (i : ℕ), ‖term f σ' i‖ₑ) * ∫⁻ (a : ℝ), ‖ψ a‖ₑ ∂volume := by + simp [ENNReal.tsum_mul_right, enorm_eq_nnnorm] + _ ≠ ⊤ := ENNReal.mul_ne_top (hf_coe1 hf hσ) + (ne_top_of_lt hsupp.2) + _ = _ := by + congr 1; ext y + simp_rw [mul_assoc (LSeries _ _), ← smul_eq_mul (a := (LSeries _ _)), LSeries] + rw [← Summable.tsum_smul_const] + · simp_rw [first_fourier_aux2 hx] + · apply Summable.of_norm + convert hf σ' hσ with n + rw [norm_term_eq_nterm_re] + simp + + + +@[continuity] +theorem continuous_multiplicative_ofAdd : Continuous (⇑Multiplicative.ofAdd : ℝ → ℝ) := ⟨fun _ ↦ id⟩ + +attribute [fun_prop] measurable_coe_nnreal_ennreal + +theorem second_fourier_integrable_aux1a (hσ : 1 < σ') : + IntegrableOn (fun (x : ℝ) ↦ cexp (-((x : ℂ) * ((σ' : ℂ) - 1)))) (Ici (-Real.log x)) := by + norm_cast + suffices IntegrableOn (fun (x : ℝ) ↦ (rexp (-(x * (σ' - 1))))) (Ici (-x.log)) _ from this.ofReal + simp_rw [fun (a x : ℝ) ↦ (by ring : -(x * a) = -a * x)] + rw [integrableOn_Ici_iff_integrableOn_Ioi] + apply exp_neg_integrableOn_Ioi + linarith + +theorem second_fourier_integrable_aux1 (hcont : Measurable ψ) (hsupp : Integrable ψ) (hσ : 1 < σ') : + let ν : Measure (ℝ × ℝ) := (volume.restrict (Ici (-Real.log x))).prod volume + Integrable (Function.uncurry fun (u : ℝ) (a : ℝ) ↦ ((rexp (-u * (σ' - 1))) : ℂ) • + (𝐞 (Multiplicative.ofAdd (-(a * (u / (2 * π))))) : ℂ) • ψ a) ν := by + intro ν + constructor + · apply Measurable.aestronglyMeasurable + change Measurable (fun p : ℝ × ℝ => + (rexp (-p.1 * (σ' - 1)) : ℂ) * + ((fourierChar (-(p.2 * (p.1 / (2 * π)))) : ℂ) * ψ p.2)) + fun_prop + · let f1 : ℝ → ENNReal := fun a1 ↦ ‖cexp (-(↑a1 * (↑σ' - 1)))‖ₑ + let f2 : ℝ → ENNReal := fun a2 ↦ ‖ψ a2‖ₑ + suffices ∫⁻ (a : ℝ × ℝ), f1 a.1 * f2 a.2 ∂ν < ⊤ by + simpa [hasFiniteIntegral_iff_enorm, enorm_eq_nnnorm, Function.uncurry] + refine (lintegral_prod_mul ?_ ?_).trans_lt ?_ <;> try fun_prop + exact ENNReal.mul_lt_top (second_fourier_integrable_aux1a hσ).2 hsupp.2 + +theorem second_fourier_integrable_aux2 (hσ : 1 < σ') : + IntegrableOn (fun (u : ℝ) ↦ cexp ((1 - ↑σ' - ↑t * I) * ↑u)) (Ioi (-Real.log x)) := by + refine (integrable_norm_iff (Measurable.aestronglyMeasurable <| by fun_prop)).mp ?_ + suffices IntegrableOn (fun a ↦ rexp (-(σ' - 1) * a)) (Ioi (-x.log)) _ by simpa [Complex.norm_exp] + apply exp_neg_integrableOn_Ioi + linarith + +theorem second_fourier_aux (hx : 0 < x) : + -(cexp (-((1 - ↑σ' - ↑t * I) * ↑(Real.log x))) / (1 - ↑σ' - ↑t * I)) = + ↑(x ^ (σ' - 1)) * (↑σ' + ↑t * I - 1)⁻¹ * ↑x ^ (↑t * I) := by + calc + _ = cexp (↑(Real.log x) * ((↑σ' - 1) + ↑t * I)) * (↑σ' + ↑t * I - 1)⁻¹ := by + rw [← div_neg]; ring_nf + _ = (x ^ ((↑σ' - 1) + ↑t * I)) * (↑σ' + ↑t * I - 1)⁻¹ := by + rw [Complex.cpow_def_of_ne_zero (ofReal_ne_zero.mpr (ne_of_gt hx)), Complex.ofReal_log hx.le] + _ = (x ^ ((σ' : ℂ) - 1)) * (x ^ (↑t * I)) * (↑σ' + ↑t * I - 1)⁻¹ := by + rw [Complex.cpow_add _ _ (ofReal_ne_zero.mpr (ne_of_gt hx))] + _ = _ := by rw [ofReal_cpow hx.le]; push_cast; ring + + + + + + + + + + + + + + + + + + + + +theorem second_fourier (hcont : Measurable ψ) (hsupp : Integrable ψ) + {x σ' : ℝ} (hx : 0 < x) (hσ : 1 < σ') : + ∫ u in Ici (-log x), Real.exp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = + (x^(σ' - 1) : ℝ) * ∫ t, (1 / (σ' + t * I - 1)) * ψ t * x^(t * I) ∂ volume := by + conv in ↑(rexp _) * _ => { rw [Real.fourier_real_eq, ← smul_eq_mul, ← integral_smul] } + rw [MeasureTheory.integral_integral_swap] + swap + · exact second_fourier_integrable_aux1 hcont hsupp hσ + rw [← integral_const_mul] + congr 1; ext t + simp_rw [Circle.smul_def, smul_eq_mul, Real.fourierChar_apply, + ← mul_assoc, integral_mul_const] + rw [mul_right_comm _ (ψ t) _] + congr 1 + push_cast + simp_rw [← Complex.exp_add] + have (u : ℝ) : + -↑u * (↑σ' - 1) + 2 * ↑π * -(↑t * (↑u / (2 * ↑π))) * I = (1 - σ' - t * I) * u := calc + _ = -↑u * (↑σ' - 1) + (2 * ↑π) / (2 * ↑π) * -(↑t * ↑u) * I := by ring + _ = -↑u * (↑σ' - 1) + 1 * -(↑t * ↑u) * I := by rw [div_self (by norm_num)] + _ = _ := by ring + simp_rw [this] + let c : ℂ := (1 - ↑σ' - ↑t * I) + have : c ≠ 0 := by simp [Complex.ext_iff, c, sub_ne_zero.mpr hσ.ne] + let f' (u : ℝ) := cexp (c * u) + let f := fun (u : ℝ) ↦ (f' u) / c + have hderiv : ∀ u ∈ Ici (-Real.log x), HasDerivAt f (f' u) u := by + intro u _ + rw [show f' u = cexp (c * u) * (c * 1) / c by simp only [f']; field_simp] + exact (hasDerivAt_id' u).ofReal_comp.const_mul c |>.cexp.div_const c + have hf : Tendsto f atTop (𝓝 0) := by + apply tendsto_zero_iff_norm_tendsto_zero.mpr + suffices Tendsto (fun (x : ℝ) ↦ ‖cexp (c * ↑x)‖ / ‖c‖) atTop (𝓝 (0 / ‖c‖)) by + simpa [f, f'] using this + apply Filter.Tendsto.div_const + suffices Tendsto (· * (1 - σ')) atTop atBot by simpa [Complex.norm_exp, mul_comm (1 - σ'), c] + exact Tendsto.atTop_mul_const_of_neg (by linarith) fun ⦃s⦄ h ↦ h + rw [integral_Ici_eq_integral_Ioi, + integral_Ioi_of_hasDerivAt_of_tendsto' hderiv (second_fourier_integrable_aux2 hσ) hf] + simpa [f, f'] using second_fourier_aux hx + + + + + + + + + + + + +theorem one_add_sq_pos (u : ℝ) : 0 < 1 + u ^ 2 := zero_lt_one.trans_le (by simpa using sq_nonneg u) + + + + + + + + + + +theorem decay_bounds_key (f : W21) (u : ℝ) : ‖𝓕 (f : ℝ → ℂ) u‖ ≤ ‖f‖ * (1 + u ^ 2)⁻¹ := by + have l1 : 0 < 1 + u ^ 2 := one_add_sq_pos _ + have l2 : 1 + u ^ 2 = ‖(1 : ℂ) + u ^ 2‖ := by + norm_cast ; simp only [Real.norm_eq_abs, abs_eq_self.2 l1.le] + have l3 : ‖1 / ((4 : ℂ) * ↑π ^ 2)‖ ≤ (4 * π ^ 2)⁻¹ := by simp + have key := fourierIntegral_self_add_deriv_deriv f u + simp only [Function.iterate_succ _ 1, Function.iterate_one, Function.comp_apply] at key + rw [F_sub f.hf (f.hf''.const_mul (1 / (4 * ↑π ^ 2)))] at key + rw [← div_eq_mul_inv, le_div_iff₀ l1, mul_comm, l2, ← norm_mul, key, sub_eq_add_neg] + apply norm_add_le _ _ |>.trans + change _ ≤ W21.norm _ + rw [norm_neg, F_mul, norm_mul, W21.norm] + gcongr <;> apply VectorFourier.norm_fourierIntegral_le_integral_norm + +theorem decay_bounds_aux {f : ℝ → ℂ} (hf : AEStronglyMeasurable f volume) + (h : ∀ t, ‖f t‖ ≤ A * (1 + t ^ 2)⁻¹) : + ∫ t, ‖f t‖ ≤ π * A := by + have l1 : Integrable (fun x ↦ A * (1 + x ^ 2)⁻¹) := integrable_inv_one_add_sq.const_mul A + simp_rw [← integral_univ_inv_one_add_sq, mul_comm, ← integral_const_mul] + exact integral_mono (l1.mono' hf (Eventually.of_forall h)).norm l1 h + +theorem decay_bounds_W21 (f : W21) (hA : ∀ t, ‖f t‖ ≤ A / (1 + t ^ 2)) + (hA' : ∀ t, ‖deriv (deriv f) t‖ ≤ A / (1 + t ^ 2)) (u) : + ‖𝓕 (f : ℝ → ℂ) u‖ ≤ (π + 1 / (4 * π)) * A / (1 + u ^ 2) := by + have l0 : 1 * (4 * π)⁻¹ * A = (4 * π ^ 2)⁻¹ * (π * A) := by field_simp + have l1 : ∫ (v : ℝ), ‖f v‖ ≤ π * A := by + apply decay_bounds_aux f.continuous.aestronglyMeasurable + simp_rw [← div_eq_mul_inv] ; exact hA + have l2 : ∫ (v : ℝ), ‖deriv (deriv f) v‖ ≤ π * A := by + apply decay_bounds_aux f.deriv.deriv.continuous.aestronglyMeasurable + simp_rw [← div_eq_mul_inv] ; exact hA' + apply decay_bounds_key f u |>.trans + change W21.norm _ * _ ≤ _ + simp_rw [W21.norm, div_eq_mul_inv, add_mul, l0] ; gcongr + + + + + + + + + + + + + + + + + + +theorem decay_bounds (ψ : CS 2 ℂ) (hA : ∀ t, ‖ψ t‖ ≤ A / (1 + t ^ 2)) + (hA' : ∀ t, ‖deriv^[2] ψ t‖ ≤ A / (1 + t ^ 2)) : + ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ (π + 1 / (4 * π)) * A / (1 + u ^ 2) := by + exact decay_bounds_W21 ψ hA hA' u + +theorem decay_bounds_cor_aux (ψ : CS 2 ℂ) : ∃ C : ℝ, ∀ u, ‖ψ u‖ ≤ C / (1 + u ^ 2) := by + have l1 : HasCompactSupport (fun u : ℝ => ((1 + u ^ 2) : ℝ) * ψ u) := by exact ψ.h2.mul_left + have := ψ.h1.continuous + obtain ⟨C, hC⟩ := l1.exists_bound_of_continuous (by fun_prop) + refine ⟨C, fun u => ?_⟩ + specialize hC u + simp only [norm_mul, Complex.norm_real, norm_of_nonneg (one_add_sq_pos u).le] at hC + rwa [le_div_iff₀' (one_add_sq_pos _)] + +theorem decay_bounds_cor (ψ : W21) : + ∃ C : ℝ, ∀ u, ‖𝓕 (ψ : ℝ → ℂ) u‖ ≤ C / (1 + u ^ 2) := by + simpa only [div_eq_mul_inv] using ⟨_, decay_bounds_key ψ⟩ + +@[continuity, fun_prop] theorem continuous_FourierIntegral (ψ : W21) : Continuous (𝓕 (ψ : ℝ → ℂ)) := + VectorFourier.fourierIntegral_continuous continuous_fourierChar + (by simp only [innerₗ_apply_apply, RCLike.inner_apply', conj_trivial, continuous_mul]) + ψ.hf + +theorem W21.integrable_fourier (ψ : W21) (hc : c ≠ 0) : + Integrable fun u ↦ 𝓕 (ψ : ℝ → ℂ) (u / c) := by + have l1 (C) : Integrable (fun u ↦ C / (1 + (u / c) ^ 2)) volume := by + simpa only [div_eq_mul_inv] using (integrable_inv_one_add_sq.comp_div hc).const_mul C + have l2 : AEStronglyMeasurable (fun u ↦ 𝓕 (ψ : ℝ → ℂ) (u / c)) volume := by + apply Continuous.aestronglyMeasurable ; fun_prop + obtain ⟨C, h⟩ := decay_bounds_cor ψ + apply @Integrable.mono' ℝ ℂ _ volume _ _ (fun u => C / (1 + (u / c) ^ 2)) (l1 C) l2 ?_ + apply Eventually.of_forall (fun x => h _) + + + + + +theorem continuous_LSeries_aux (hf : Summable (nterm f σ')) : + Continuous fun x : ℝ => LSeries f (σ' + x * I) := by + have l1 i : Continuous fun x : ℝ ↦ term f (σ' + x * I) i := by + by_cases h : i = 0 + · simpa [h] using continuous_const + · simpa [h] using continuous_const.div₀ (continuous_const.cpow (by fun_prop) (by simp [h])) + (fun x => by simp [h]) + have l2 n (x : ℝ) : ‖term f (σ' + x * I) n‖ = nterm f σ' n := by + simpa using norm_term_eq_nterm_re (f := f) (n := n) (σ' + x * I) + exact continuous_tsum l1 hf (fun n x => le_of_eq (l2 n x)) + + +theorem limiting_fourier_aux (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 1 ≤ x) (σ' : ℝ) + (hσ' : 1 < σ') : + ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * (x ^ (1 - σ') : ℝ) * ∫ u in Ici (- log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) + (u / (2 * π)) = ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I) := by + have hint : Integrable ψ := ψ.h1.continuous.integrable_of_hasCompactSupport ψ.h2 + have l3 : 0 < x := zero_lt_one.trans_le hx + have l1 (σ') (hσ' : 1 < σ') := first_fourier hf hint l3 hσ' + have l2 (σ') (hσ' : 1 < σ') := second_fourier ψ.h1.continuous.measurable hint l3 hσ' + have l8 : Continuous fun t : ℝ ↦ (x : ℂ) ^ (t * I) := + continuous_const.cpow (continuous_ofReal.mul continuous_const) (by simp [l3]) + have l6 : Continuous fun t : ℝ ↦ LSeries f (↑σ' + ↑t * I) * ψ t * ↑x ^ (↑t * I) := by + apply ((continuous_LSeries_aux (hf _ hσ')).mul ψ.h1.continuous).mul l8 + have l4 : Integrable fun t : ℝ ↦ LSeries f (↑σ' + ↑t * I) * ψ t * ↑x ^ (↑t * I) := by + exact l6.integrable_of_hasCompactSupport ψ.h2.mul_left.mul_right + have e2 (u : ℝ) : σ' + u * I - 1 ≠ 0 := by + intro h ; have := congr_arg Complex.re h ; simp at this ; linarith + have l7 : Continuous fun a ↦ A * ↑(x ^ (1 - σ')) * (↑(x ^ (σ' - 1)) * + (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by + simp only [one_div, ← mul_assoc] + refine ((continuous_const.mul <| Continuous.inv₀ ?_ e2).mul ψ.h1.continuous).mul l8 + fun_prop + have l5 : Integrable fun a ↦ A * ↑(x ^ (1 - σ')) * (↑(x ^ (σ' - 1)) * + (1 / (σ' + a * I - 1) * ψ a * x ^ (a * I))) := by + apply l7.integrable_of_hasCompactSupport + exact ψ.h2.mul_left.mul_right.mul_left.mul_left + simp_rw [l1 σ' hσ', l2 σ' hσ', ← integral_const_mul, ← integral_sub l4 l5] + apply integral_congr_ae + apply Eventually.of_forall + intro u + have e1 : 1 < ((σ' : ℂ) + (u : ℂ) * I).re := by simp [hσ'] + simp_rw [hG' e1, sub_mul, ← mul_assoc] + simp only [one_div, sub_right_inj, mul_eq_mul_right_iff, cpow_eq_zero_iff, ofReal_eq_zero, ne_eq, + mul_eq_zero, I_ne_zero, or_false] + left ; left + field_simp [e2] + norm_cast + simp [mul_assoc, ← rpow_add l3] + +section nabla + +variable {α E : Type*} [OfNat α 1] [Add α] [Sub α] {u : α → ℂ} + + +def cumsum [AddCommMonoid E] (u : ℕ → E) (n : ℕ) : E := ∑ i ∈ Finset.range n, u i + + +def nabla [Sub E] (u : α → E) (n : α) : E := u (n + 1) - u n + + + +def nnabla [Sub E] (u : α → E) (n : α) : E := u n - u (n + 1) + + +def shift (u : α → E) (n : α) : E := u (n + 1) + +@[simp] theorem cumsum_zero [AddCommMonoid E] {u : ℕ → E} : cumsum u 0 = 0 := by simp [cumsum] + +theorem cumsum_succ [AddCommMonoid E] {u : ℕ → E} (n : ℕ) : + cumsum u (n + 1) = cumsum u n + u n := by + simp [cumsum, Finset.sum_range_succ] + +@[simp] theorem nabla_cumsum [AddCommGroup E] {u : ℕ → E} : nabla (cumsum u) = u := by + ext n ; simp [nabla, cumsum, Finset.range_add_one] + +theorem neg_cumsum [AddCommGroup E] {u : ℕ → E} : -(cumsum u) = cumsum (-u) := + funext (fun n => by simp [cumsum]) + +theorem cumsum_nonneg {u : ℕ → ℝ} (hu : 0 ≤ u) : 0 ≤ cumsum u := + fun _ => Finset.sum_nonneg (fun i _ => hu i) + +omit [Sub α] in +theorem neg_nabla [Ring E] {u : α → E} : -(nabla u) = nnabla u := by ext n ; simp [nabla, nnabla] + +omit [Sub α] in +@[simp] theorem nabla_mul [Ring E] {u : α → E} {c : E} : + nabla (fun n => c * u n) = c • nabla u := by + ext n ; simp [nabla, mul_sub] + +omit [Sub α] in +@[simp] theorem nnabla_mul [Ring E] {u : α → E} {c : E} : + nnabla (fun n => c * u n) = c • nnabla u := by + ext n ; simp [nnabla, mul_sub] + +theorem nnabla_cast (u : ℝ → E) [Sub E] : nnabla u ∘ ((↑) : ℕ → ℝ) = nnabla (u ∘ (↑)) := by + ext n ; simp [nnabla] + +end nabla + +theorem Finset.sum_shift_front {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : + cumsum u (n + 1) = u 0 + cumsum (shift u) n := by + simp_rw [add_comm n, cumsum, _root_.Finset.sum_range_add, + _root_.Finset.sum_range_one, add_comm 1] ; rfl + +theorem Finset.sum_shift_front' {E : Type*} [Ring E] {u : ℕ → E} : + shift (cumsum u) = (fun _ => u 0) + cumsum (shift u) := by + ext n ; apply Finset.sum_shift_front + +theorem Finset.sum_shift_back {E : Type*} [Ring E] {u : ℕ → E} {n : ℕ} : + cumsum u (n + 1) = cumsum u n + u n := by + simp [cumsum, Finset.range_add_one, add_comm] + +theorem Finset.sum_shift_back' {E : Type*} [Ring E] {u : ℕ → E} : + shift (cumsum u) = cumsum u + u := by + ext n ; apply Finset.sum_shift_back + +theorem summation_by_parts {E : Type*} [Ring E] {a A b : ℕ → E} (ha : a = nabla A) {n : ℕ} : + cumsum (a * b) (n + 1) = A (n + 1) * b n - A 0 * b 0 - + cumsum (shift A * fun i => (b (i + 1) - b i)) n := by + have l1 : ∑ x ∈ Finset.range (n + 1), A (x + 1) * b x = ∑ x ∈ Finset.range n, + A (x + 1) * b x + A (n + 1) * b n := + Finset.sum_shift_back + have l2 : ∑ x ∈ Finset.range (n + 1), A x * b x = A 0 * b 0 + ∑ x ∈ Finset.range n, + A (x + 1) * b (x + 1) := + Finset.sum_shift_front + simp only [cumsum, ha, Pi.mul_apply, nabla, sub_mul, Finset.sum_sub_distrib, l1, l2, shift, + mul_sub] + abel + +theorem summation_by_parts' {E : Type*} [Ring E] {a b : ℕ → E} {n : ℕ} : + cumsum (a * b) (n + 1) = cumsum a (n + 1) * b n - cumsum (shift (cumsum a) * nabla b) n := by + change cumsum (a * b) (n + 1) = cumsum a (n + 1) * b n - + cumsum (shift (cumsum a) * (fun i : ℕ => b (i + 1) - b i)) n + simpa using summation_by_parts (a := a) (b := b) (A := cumsum a) (by simp) + +theorem summation_by_parts'' {E : Type*} [Ring E] {a b : ℕ → E} : + shift (cumsum (a * b)) = shift (cumsum a) * b - cumsum (shift (cumsum a) * nabla b) := by + ext n ; apply summation_by_parts' + +theorem summable_iff_bounded {u : ℕ → ℝ} (hu : 0 ≤ u) : + Summable u ↔ BoundedAtFilter atTop (cumsum u) := by + have l1 : (cumsum u =O[atTop] 1) ↔ _ := isBigO_one_nat_atTop_iff + have l2 n : ‖cumsum u n‖ = cumsum u n := by simpa using cumsum_nonneg hu n + simp only [BoundedAtFilter, l1, l2] + constructor <;> intro h <;> rcases h with ⟨C, h1⟩ + · exact ⟨C, fun n => sum_le_hasSum _ (fun i _ => hu i) h1⟩ + · exact summable_of_sum_range_le hu h1 + +theorem Filter.EventuallyEq.summable {u v : ℕ → ℝ} (h : u =ᶠ[atTop] v) (hu : Summable v) : + Summable u := + summable_of_isBigO_nat hu h.isBigO + +theorem summable_congr_ae {u v : ℕ → ℝ} (huv : u =ᶠ[atTop] v) : Summable u ↔ Summable v := by + exact ⟨ZetaFivePNT.Filter.EventuallyEq.summable huv.symm, + ZetaFivePNT.Filter.EventuallyEq.summable huv⟩ + +theorem BoundedAtFilter.add_const {u : ℕ → ℝ} {c : ℝ} : + BoundedAtFilter atTop (fun n => u n + c) ↔ BoundedAtFilter atTop u := by + have : u = fun n => (u n + c) + (-c) := by ext n ; ring + simp only [BoundedAtFilter] + constructor <;> intro h + on_goal 1 => rw [this] + all_goals { exact h.add (const_boundedAtFilter _ _) } + +theorem BoundedAtFilter.comp_add {u : ℕ → ℝ} {N : ℕ} : + BoundedAtFilter atTop (fun n => u (n + N)) ↔ BoundedAtFilter atTop u := by + simp only [BoundedAtFilter, isBigO_iff, norm_eq_abs, Pi.one_apply, one_mem, + CStarRing.norm_of_mem_unitary, mul_one, eventually_atTop] + constructor <;> intro hbound <;> rcases hbound with ⟨C, n₀, h⟩ <;> use C + · refine ⟨n₀ + N, fun n hn => ?_⟩ + obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le' (m := N) (n := n) (by grind) + exact h _ <| Nat.add_le_add_iff_right.mp hn + · exact ⟨n₀, fun n hn => h _ (by grind)⟩ + +theorem summable_iff_bounded' {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, 0 ≤ u n) : + Summable u ↔ BoundedAtFilter atTop (cumsum u) := by + obtain ⟨N, hu⟩ := eventually_atTop.mp hu + have e2 : cumsum (fun i ↦ u (i + N)) = fun n => cumsum u (n + N) - cumsum u N := by + ext n ; simp_rw [cumsum, add_comm _ N, Finset.sum_range_add] ; ring + rw [← summable_nat_add_iff N, summable_iff_bounded (fun n => hu _ <| Nat.le_add_left N n), e2] + simp_rw [sub_eq_add_neg, BoundedAtFilter.add_const, BoundedAtFilter.comp_add] + +theorem bounded_of_shift {u : ℕ → ℝ} (h : BoundedAtFilter atTop (shift u)) : + BoundedAtFilter atTop u := by + simp only [BoundedAtFilter, isBigO_iff, eventually_atTop] at h ⊢ + obtain ⟨C, N, hC⟩ := h + refine ⟨C, N + 1, fun n hn => ?_⟩ + simp only [shift] at hC + have r1 : n - 1 ≥ N := Nat.le_sub_one_of_lt hn + have r2 : n - 1 + 1 = n := Nat.sub_add_cancel (by omega) + simpa [r2] using hC (n - 1) r1 + +theorem dirichlet_test' {a b : ℕ → ℝ} (ha : 0 ≤ a) (hb : 0 ≤ b) + (hAb : BoundedAtFilter atTop (shift (cumsum a) * b)) (hbb : ∀ᶠ n in atTop, b (n + 1) ≤ b n) + (h : Summable (shift (cumsum a) * nnabla b)) : Summable (a * b) := by + have l1 : ∀ᶠ n in atTop, 0 ≤ (shift (cumsum a) * nnabla b) n := by + filter_upwards [hbb] with n hb + exact mul_nonneg (by simpa [shift] using cumsum_nonneg ha (n + 1)) (sub_nonneg.mpr hb) + rw [summable_iff_bounded (mul_nonneg ha hb)] + rw [summable_iff_bounded' l1] at h + apply bounded_of_shift + simpa only [summation_by_parts'', sub_eq_add_neg, neg_cumsum, ← mul_neg, neg_nabla] + using hAb.add h + +theorem exists_antitone_of_eventually {u : ℕ → ℝ} (hu : ∀ᶠ n in atTop, u (n + 1) ≤ u n) : + ∃ v : ℕ → ℝ, range v ⊆ range u ∧ Antitone v ∧ v =ᶠ[atTop] u := by + obtain ⟨N, hN⟩ := eventually_atTop.mp hu + let v (n : ℕ) := u (if n < N then N else n) + refine ⟨v, ?_, ?_, ?_⟩ + · intro x hx + rcases hx with ⟨n, hn⟩ + exact ⟨if n < N then N else n, hn⟩ + · refine antitone_nat_of_succ_le (fun n => ?_) + by_cases h : n < N + · by_cases h' : n + 1 < N <;> simp [v, h, h'] + have : n + 1 = N := by linarith + simp [this] + · have : ¬(n + 1 < N) := by linarith + simp only [this, ↓reduceIte, h, ge_iff_le, v] ; apply hN ; linarith + · have : ∀ᶠ n in atTop, ¬(n < N) := by simpa using ⟨N, fun b hb => by linarith⟩ + filter_upwards [this] with n hn ; simp [v, hn] + +theorem summable_inv_mul_log_sq : Summable (fun n : ℕ => (n * (Real.log n) ^ 2)⁻¹) := by + let u (n : ℕ) := (n * (Real.log n) ^ 2)⁻¹ + have l7 : ∀ᶠ n : ℕ in atTop, 1 ≤ Real.log n := + tendsto_atTop.mp (tendsto_log_atTop.comp tendsto_natCast_atTop_atTop) 1 + have l8 : ∀ᶠ n : ℕ in atTop, 1 ≤ n := eventually_ge_atTop 1 + have l9 : ∀ᶠ n in atTop, u (n + 1) ≤ u n := by + filter_upwards [l7, l8] with n l2 l8; dsimp [u]; gcongr <;> simp + obtain ⟨v, l1, l2, l3⟩ := exists_antitone_of_eventually l9 + rw [summable_congr_ae l3.symm] + have l4 (n : ℕ) : 0 ≤ v n := by obtain ⟨k, hk⟩ := l1 ⟨n, rfl⟩ ; rw [← hk] ; positivity + apply (summable_condensed_iff_of_nonneg l4 (fun _ _ _ a ↦ l2 a)).mp + suffices this : ∀ᶠ k : ℕ in atTop, 2 ^ k * v (2 ^ k) = ((k : ℝ) ^ 2)⁻¹ * ((Real.log 2) ^ 2)⁻¹ by + exact (summable_congr_ae this).mpr <| (Real.summable_nat_pow_inv.mpr one_lt_two).mul_right _ + have l5 : ∀ᶠ k in atTop, v (2 ^ k) = u (2 ^ k) := + l3.comp_tendsto <| tendsto_pow_atTop_atTop_of_one_lt Nat.le.refl + filter_upwards [l5, l8] with k l5 l8 + simp only [l5, mul_inv_rev, Nat.cast_pow, Nat.cast_ofNat, log_pow, u] + field_simp + +theorem tendsto_mul_add_atTop {a : ℝ} (ha : 0 < a) (b : ℝ) : + Tendsto (fun x => a * x + b) atTop atTop := + tendsto_atTop_add_const_right _ b (tendsto_id.const_mul_atTop ha) + +theorem isLittleO_const_of_tendsto_atTop {α : Type*} [Preorder α] (a : ℝ) {f : α → ℝ} + (hf : Tendsto f atTop atTop) : (fun _ => a) =o[atTop] f := by + simp [tendsto_norm_atTop_atTop.comp hf] + +theorem isLittleO_mul_add_sq (a b : ℝ) : (fun x => a * x + b) =o[atTop] (fun x => x ^ 2) := by + apply IsLittleO.add + · apply IsLittleO.const_mul_left ; simpa using isLittleO_pow_pow_atTop_of_lt (𝕜 := ℝ) one_lt_two + · apply isLittleO_const_of_tendsto_atTop _ <| tendsto_pow_atTop (by linarith) + +theorem log_mul_add_isBigO_log {a : ℝ} (ha : 0 < a) (b : ℝ) : + (fun x => Real.log (a * x + b)) =O[atTop] Real.log := by + apply IsBigO.of_bound (2 : ℕ) + have l2 : ∀ᶠ x : ℝ in atTop, 0 ≤ log x := tendsto_atTop.mp tendsto_log_atTop 0 + have l3 : ∀ᶠ x : ℝ in atTop, 0 ≤ log (a * x + b) := + tendsto_atTop.mp (tendsto_log_atTop.comp (tendsto_mul_add_atTop ha b)) 0 + have l5 : ∀ᶠ x : ℝ in atTop, 1 ≤ a * x + b := tendsto_atTop.mp (tendsto_mul_add_atTop ha b) 1 + have l1 : ∀ᶠ x : ℝ in atTop, a * x + b ≤ x ^ 2 := by + filter_upwards [(isLittleO_mul_add_sq a b).eventuallyLE, l5] with x r2 l5 + simpa [abs_eq_self.mpr (zero_le_one.trans l5)] using r2 + filter_upwards [l1, l2, l3, l5] with x l1 l2 l3 l5 + simpa [abs_eq_self.mpr l2, abs_eq_self.mpr l3, Real.log_pow] using + Real.log_le_log (by linarith) l1 + +theorem isBigO_log_mul_add {a : ℝ} (ha : 0 < a) (b : ℝ) : + Real.log =O[atTop] (fun x => Real.log (a * x + b)) := by + convert (log_mul_add_isBigO_log (b := -b / a) (inv_pos.mpr ha)).comp_tendsto + (tendsto_mul_add_atTop (b := b) ha) using 1 + · ext x + simp only [Function.comp_apply] + congr + field_simp + simp + · rfl + +theorem log_isbigo_log_div {d : ℝ} (hb : 0 < d) : + (fun n ↦ Real.log n) =O[atTop] (fun n ↦ Real.log (n / d)) := by + convert isBigO_log_mul_add (inv_pos.mpr hb) 0 using 1; simp only [add_zero]; field_simp + +theorem Asymptotics.IsBigO.add_isLittleO_right {f g : ℝ → ℝ} (h : g =o[atTop] f) : + f =O[atTop] (f + g) := by + exact h.right_isBigO_add' + +theorem Asymptotics.IsBigO.sq {α : Type*} [Preorder α] {f g : α → ℝ} (h : f =O[atTop] g) : + (fun n ↦ f n ^ 2) =O[atTop] (fun n => g n ^ 2) := + h.pow 2 + +theorem log_sq_isbigo_mul {a b : ℝ} (hb : 0 < b) : + (fun x ↦ Real.log x ^ 2) =O[atTop] (fun x ↦ a + Real.log (x / b) ^ 2) := by + apply (ZetaFivePNT.Asymptotics.IsBigO.sq (log_isbigo_log_div hb)).trans + simp_rw [add_comm a] + refine ZetaFivePNT.Asymptotics.IsBigO.add_isLittleO_right <| + isLittleO_const_of_tendsto_atTop _ ?_ + exact (tendsto_pow_atTop two_ne_zero).comp <| + tendsto_log_atTop.comp <| tendsto_id.atTop_div_const hb + +theorem log_add_div_isBigO_log (a : ℝ) {b : ℝ} (hb : 0 < b) : + (fun x ↦ Real.log ((x + a) / b)) =O[atTop] fun x ↦ Real.log x := by + convert log_mul_add_isBigO_log (inv_pos.mpr hb) (a / b) using 3 ; ring + +theorem log_add_one_sub_log_le {x : ℝ} (hx : 0 < x) : nabla Real.log x ≤ x⁻¹ := by + rw [nabla, ← Real.log_div (by linarith) hx.ne'] + calc + _ ≤ (x + 1) / x - 1 := Real.log_le_sub_one_of_pos (by positivity) + _ = x⁻¹ := by field_simp; ring + +theorem nabla_log_main : nabla Real.log =O[atTop] fun x ↦ 1 / x := by + apply IsBigO.of_bound 1 + filter_upwards [eventually_gt_atTop 0] with x l1 + have l2 : log x ≤ log (x + 1) := log_le_log l1 (by linarith) + simpa [nabla, abs_eq_self.mpr l1.le, abs_eq_self.mpr (sub_nonneg.mpr l2)] using + log_add_one_sub_log_le l1 + +theorem nabla_log {b : ℝ} (hb : 0 < b) : + nabla (fun x => Real.log (x / b)) =O[atTop] (fun x => 1 / x) := by + refine EventuallyEq.trans_isBigO ?_ nabla_log_main + filter_upwards [eventually_gt_atTop 0] with x l2 + rw [nabla, log_div (by linarith) (by linarith), log_div l2.ne.symm (by linarith), nabla] ; ring + +theorem nnabla_mul_log_sq (a : ℝ) {b : ℝ} (hb : 0 < b) : + nabla (fun x => x * (a + Real.log (x / b) ^ 2)) =O[atTop] (fun x => Real.log x ^ 2) := by + have l1 : nabla (fun n => n * (a + Real.log (n / b) ^ 2)) = fun n => + a + Real.log ((n + 1) / b) ^ 2 + + (n * (Real.log ((n + 1) / b) ^ 2 - Real.log (n / b) ^ 2)) := by + ext n ; simp [nabla] ; ring + have l2 := (isLittleO_const_of_tendsto_atTop a + ((tendsto_pow_atTop two_ne_zero).comp tendsto_log_atTop)).isBigO + have l3 := ZetaFivePNT.Asymptotics.IsBigO.sq (log_add_div_isBigO_log 1 hb) + have l4 : (fun x => Real.log ((x + 1) / b) + Real.log (x / b)) =O[atTop] Real.log := by + simpa using (log_add_div_isBigO_log _ hb).add (log_add_div_isBigO_log 0 hb) + have e2 : (fun x : ℝ => x * (Real.log x * (1 / x))) =ᶠ[atTop] Real.log := by + filter_upwards [eventually_ge_atTop 1] with x hx using by field_simp + have l5 : (fun n ↦ n * (Real.log n * (1 / n))) =O[atTop] (fun n ↦ (Real.log n) ^ 2) := + e2.trans_isBigO + (by simpa [Function.comp_def] using + (isLittleO_mul_add_sq 1 0).isBigO.comp_tendsto Real.tendsto_log_atTop) + simp_rw [l1, _root_.sq_sub_sq] + exact ((l2.add l3).add (isBigO_refl (·) atTop |>.mul (l4.mul (nabla_log hb)) |>.trans l5)) + +theorem nnabla_bound_aux1 (a : ℝ) {b : ℝ} (hb : 0 < b) : + Tendsto (fun x => x * (a + Real.log (x / b) ^ 2)) atTop atTop := + tendsto_id.atTop_mul_atTop₀ <| tendsto_atTop_add_const_left _ _ <| + (tendsto_pow_atTop two_ne_zero).comp <| tendsto_log_atTop.comp <| tendsto_id.atTop_div_const hb + +theorem nnabla_bound_aux2 (a : ℝ) {b : ℝ} (hb : 0 < b) : + ∀ᶠ x in atTop, 0 < x * (a + Real.log (x / b) ^ 2) := + (nnabla_bound_aux1 a hb).eventually (eventually_gt_atTop 0) + +theorem Real.log_eventually_gt_atTop (a : ℝ) : + ∀ᶠ x in atTop, a < Real.log x := + Real.tendsto_log_atTop.eventually (eventually_gt_atTop a) + + +@[local gcongr] +theorem norm_lt_norm_of_nonneg (x y : ℝ) (hx : 0 ≤ x) (hxy : x ≤ y) : + ‖x‖ ≤ ‖y‖ := by + simp_rw [Real.norm_eq_abs] + apply abs_le_abs hxy + linarith + +theorem nnabla_bound_aux {x : ℝ} (hx : 0 < x) : + nnabla (fun n ↦ 1 / (n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2))) =O[atTop] + (fun n ↦ 1 / (Real.log n ^ 2 * n ^ 2)) := by + let d n : ℝ := n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2) + change (fun x_1 ↦ nnabla (fun n ↦ 1 / d n) x_1) =O[atTop] _ + have l2 : ∀ᶠ n in atTop, 0 < d n := (nnabla_bound_aux2 ((2 * π) ^ 2) hx) + have l3 : ∀ᶠ n in atTop, 0 < d (n + 1) := + (tendsto_atTop_add_const_right atTop (1 : ℝ) tendsto_id).eventually l2 + have l1 : ∀ᶠ n : ℝ in atTop, + nnabla (fun n ↦ 1 / d n) n = (d (n + 1) - d n) * (d n)⁻¹ * (d (n + 1))⁻¹ := by + filter_upwards [l2, l3] with n l2 l3 + rw [nnabla, one_div, one_div, inv_sub_inv l2.ne.symm l3.ne.symm, div_eq_mul_inv, mul_inv, + mul_assoc] + have l4 : (fun n => (d n)⁻¹) =O[atTop] (fun n => (n * (Real.log n) ^ 2)⁻¹) := by + apply IsBigO.inv_rev + · refine (isBigO_refl _ _).mul <| (log_sq_isbigo_mul hx) + · filter_upwards [Real.log_eventually_gt_atTop 0, eventually_gt_atTop 0] with x hx hx' + rw [← not_imp_not] + intro _ + positivity + have l5 : (fun n => (d (n + 1))⁻¹) =O[atTop] (fun n => (n * (Real.log n) ^ 2)⁻¹) := by + refine IsBigO.trans ?_ l4 + rw [isBigO_iff]; use 1 + have e3 : ∀ᶠ n in atTop, d n ≤ d (n + 1) := by + filter_upwards [eventually_ge_atTop x] with n hn + have e2 : 1 ≤ n / x := (one_le_div hx).mpr hn + have : 0 ≤ n := hx.le.trans hn + simp only [d] + gcongr <;> simp [Real.log_nonneg, *] + filter_upwards [l2, l3, e3] with n e1 e2 e3 + simp_rw [one_mul] + gcongr + have l6 : (fun n => d (n + 1) - d n) =O[atTop] (fun n => (Real.log n) ^ 2) := by + change nabla (fun n : ℝ => n * ((2 * π) ^ 2 + Real.log (n / x) ^ 2)) + =O[atTop] (fun n => (Real.log n) ^ 2) + exact nnabla_mul_log_sq ((2 * π) ^ 2) hx + apply EventuallyEq.trans_isBigO l1 + apply ((l6.mul l4).mul l5).trans_eventuallyEq + filter_upwards [eventually_ge_atTop 2, Real.log_eventually_gt_atTop 0] with n hn hn' + field_simp + +theorem nnabla_bound (C : ℝ) {x : ℝ} (hx : 0 < x) : + nnabla (fun n => C / (1 + (Real.log (n / x) / (2 * π)) ^ 2) / n) =O[atTop] + (fun n => (n ^ 2 * (Real.log n) ^ 2)⁻¹) := by + field_simp + simp only [div_eq_mul_inv, mul_inv, nnabla_mul, one_mul] + apply IsBigO.const_mul_left + simpa [div_eq_mul_inv, mul_pow, mul_comm] using nnabla_bound_aux hx + + +theorem cheby.bigO (h : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + cumsum (‖f ·‖) =O[atTop] ((↑) : ℕ → ℝ) := by + have l1 : 0 ≤ cumsum (‖f ·‖) := cumsum_nonneg (fun _ => norm_nonneg _) + obtain ⟨C, hC⟩ := h + apply isBigO_of_le' (c := C) atTop + intro n + rw [Real.norm_eq_abs, abs_eq_self.mpr (l1 n)] + simpa using hC n + +theorem limiting_fourier_lim1_aux + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hx : 0 < x) (C : ℝ) (hC : 0 ≤ C) : + Summable fun n ↦ ‖f n‖ / ↑n * (C / (1 + (1 / (2 * π) * Real.log (↑n / x)) ^ 2)) := by + let a (n : ℕ) := (C / (1 + (Real.log (↑n / x) / (2 * π)) ^ 2) / ↑n) + replace hcheby := cheby.bigO hcheby + have l1 : shift (cumsum (‖f ·‖)) =O[atTop] (fun n : ℕ => (↑(n + 1) : ℝ)) := + hcheby.comp_tendsto <| tendsto_add_atTop_nat 1 + have l2 : shift (cumsum (‖f ·‖)) =O[atTop] (fun n => (n : ℝ)) := + l1.trans + (by simpa using (isBigO_refl _ _).add <| isBigO_iff.mpr ⟨1, by simpa using ⟨1, by tauto⟩⟩) + have l5 : BoundedAtFilter atTop (fun n : ℕ => C / (1 + (Real.log (↑n / x) / (2 * π)) ^ 2)) := by + simp only [BoundedAtFilter] + field_simp + apply isBigO_of_le' (c := C) ; intro n + have : 0 ≤ 2 ^ 2 * π ^ 2 + Real.log (n / x) ^ 2 := by positivity + simp only [norm_div, norm_mul, norm_eq_abs, abs_eq_self.mpr hC, norm_pow, + abs_eq_self.mpr pi_nonneg, abs_eq_self.mpr this, Pi.one_apply, one_mem, + CStarRing.norm_of_mem_unitary, mul_one, ge_iff_le, Nat.abs_ofNat] + apply div_le_of_le_mul₀ this hC + rw [mul_add, ← mul_assoc] + apply le_add_of_le_of_nonneg le_rfl + positivity + have l3 : a =O[atTop] (fun n => 1 / (n : ℝ)) := by + convert IsBigO.mul l5 (isBigO_refl (fun n : ℕ => 1 / (n : ℝ)) _) using 1 + · ext n + simp [a, div_eq_mul_inv] + · ext n + simp + have l4 : nnabla a =O[atTop] (fun n : ℕ => (n ^ 2 * (Real.log n) ^ 2)⁻¹) := by + convert (nnabla_bound C hx).natCast_atTop ; simp [nnabla, a] + simp_rw [div_mul_eq_mul_div, mul_div_assoc, one_mul] + apply dirichlet_test' + · intro n ; exact norm_nonneg _ + · intro n ; positivity + · apply (l2.mul l3).trans_eventuallyEq + apply eventually_of_mem (Ici_mem_atTop 1) + intro x (hx : 1 ≤ x) + have : x ≠ 0 := Nat.one_le_iff_ne_zero.mp hx + simp [this] + · have : ∀ᶠ n : ℕ in atTop, x ≤ n := by simpa using eventually_ge_atTop ⌈x⌉₊ + filter_upwards [this] with n hn + have e1 : 0 < (n : ℝ) := by linarith + have e2 : 1 ≤ n / x := (one_le_div hx).mpr hn + have e3 := Nat.le_succ n + gcongr + refine div_nonneg (Real.log_nonneg e2) (by norm_num [pi_nonneg]) + · apply summable_of_isBigO_nat summable_inv_mul_log_sq + apply (l2.mul l4).trans_eventuallyEq + apply eventually_of_mem (Ici_mem_atTop 2) + intro x (hx : 2 ≤ x) + have : (x : ℝ) ≠ 0 := by simp ; linarith + have : Real.log x ≠ 0 := by + have ll : 2 ≤ (x : ℝ) := by simp [hx] + simp + grind + field_simp + +theorem limiting_fourier_lim1 + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (ψ : W21) (hx : 0 < x) : + Tendsto (fun σ' : ℝ ↦ + ∑' n, term f σ' n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (n / x))) (𝓝[>] 1) + (𝓝 (∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (n / x)))) := by + obtain ⟨C, hC⟩ := decay_bounds_cor ψ + have : 0 ≤ C := by simpa using (norm_nonneg _).trans (hC 0) + refine tendsto_tsum_of_dominated_convergence + (limiting_fourier_lim1_aux hcheby hx C this) (fun n => ?_) ?_ + · apply Tendsto.mul_const + by_cases h : n = 0 <;> simp only [term, h, ↓reduceIte, CharP.cast_eq_zero, div_zero, + tendsto_const_nhds_iff] + refine tendsto_const_nhds.div ?_ (by simp [h]) + simpa using ((continuous_ofReal.tendsto 1).mono_left nhdsWithin_le_nhds).const_cpow + · rw [eventually_nhdsWithin_iff] + apply Eventually.of_forall + intro σ' (hσ' : 1 < σ') n + rw [norm_mul, ← nterm_eq_norm_term] + refine mul_le_mul ?_ (hC _) (norm_nonneg _) (div_nonneg (norm_nonneg _) (Nat.cast_nonneg _)) + by_cases h : n = 0 <;> simp only [nterm, h, ↓reduceIte, CharP.cast_eq_zero, div_zero, le_refl] + have : 1 ≤ (n : ℝ) := by exact_mod_cast (show 1 ≤ n by omega) + refine div_le_div₀ (norm_nonneg _) le_rfl (by simpa [Nat.pos_iff_ne_zero]) ?_ + simpa using Real.rpow_le_rpow_of_exponent_le this hσ'.le + +theorem limiting_fourier_lim2_aux (x : ℝ) (C : ℝ) : + Integrable (fun t ↦ max |x| 1 * (C / (1 + (t / (2 * π)) ^ 2))) + (Measure.restrict volume (Ici (-Real.log x))) := by + simp_rw [div_eq_mul_inv C] + exact (((integrable_inv_one_add_sq.comp_div + (by simp [pi_ne_zero])).const_mul _).const_mul _).restrict + +theorem limiting_fourier_lim2 (A : ℝ) (ψ : W21) (hx : 1 ≤ x) : + Tendsto (fun σ' ↦ A * ↑(x ^ (1 - σ')) * + ∫ u in Ici (-Real.log x), rexp (-u * (σ' - 1)) * 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) + (𝓝[>] 1) (𝓝 (A * ∫ u in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)))) := by + obtain ⟨C, hC⟩ := decay_bounds_cor ψ + apply Tendsto.mul + · suffices h : Tendsto (fun σ' : ℝ ↦ ofReal (x ^ (1 - σ'))) (𝓝[>] 1) (𝓝 1) by + simpa using h.const_mul ↑A + suffices h : Tendsto (fun σ' : ℝ ↦ x ^ (1 - σ')) (𝓝[>] 1) (𝓝 1) from + (continuous_ofReal.tendsto 1).comp h + have : Tendsto (fun σ' : ℝ ↦ σ') (𝓝 1) (𝓝 1) := fun _ a ↦ a + have : Tendsto (fun σ' : ℝ ↦ 1 - σ') (𝓝[>] 1) (𝓝 0) := + tendsto_nhdsWithin_of_tendsto_nhds (by simpa using this.const_sub 1) + simpa using tendsto_const_nhds.rpow this (Or.inl (zero_lt_one.trans_le hx).ne.symm) + · refine tendsto_integral_filter_of_dominated_convergence _ ?_ ?_ + (limiting_fourier_lim2_aux x C) ?_ + · apply Eventually.of_forall ; intro σ' + apply Continuous.aestronglyMeasurable + have := continuous_FourierIntegral ψ + continuity + · apply eventually_of_mem (U := Ioo 1 2) + · apply Ioo_mem_nhdsGT_of_mem ; simp + · intro σ' hσ + have h1 := hσ.1 + have h2 := hσ.2 + rw [ae_restrict_iff' measurableSet_Ici] + apply Eventually.of_forall + intro t (ht : - Real.log x ≤ t) + rw [norm_mul] + have hdom_nonneg : 0 ≤ max |x| 1 := by + exact (abs_nonneg x).trans (le_max_left _ _) + refine mul_le_mul ?_ (hC _) (norm_nonneg _) hdom_nonneg + simp only [neg_mul, ofReal_exp, ofReal_neg, ofReal_mul, ofReal_sub, ofReal_one, norm_exp, + neg_re, mul_re, ofReal_re, sub_re, one_re, ofReal_im, sub_im, one_im, sub_self, mul_zero, + sub_zero] + have : -Real.log x * (σ' - 1) ≤ t * (σ' - 1) := mul_le_mul_of_nonneg_right ht (by linarith) + have : -(t * (σ' - 1)) ≤ Real.log x * (σ' - 1) := by simpa using neg_le_neg this + have := Real.exp_monotone this + apply this.trans + have l1 : σ' - 1 ≤ 1 := by linarith + have : 0 ≤ Real.log x := Real.log_nonneg hx + have := mul_le_mul_of_nonneg_left l1 this + refine (Real.exp_monotone this).trans ?_ + have hxabs : |x| = x := abs_of_nonneg (zero_le_one.trans hx) + calc + Real.exp (Real.log x * 1) = |x| := by + simpa [mul_one, hxabs] using (Real.exp_log (zero_lt_one.trans_le hx)) + _ ≤ max |x| 1 := le_max_left _ _ + · apply Eventually.of_forall + intro x + suffices h : Tendsto (fun n ↦ ((rexp (-x * (n - 1))) : ℂ)) (𝓝[>] 1) (𝓝 1) by + simpa using h.mul_const _ + apply Tendsto.mono_left ?_ nhdsWithin_le_nhds + suffices h : Continuous (fun n ↦ ((rexp (-x * (n - 1))) : ℂ)) by simpa using h.tendsto 1 + continuity + +theorem limiting_fourier_lim3 (hG : ContinuousOn G {s | 1 ≤ s.re}) (ψ : CS 2 ℂ) (hx : 1 ≤ x) : + Tendsto (fun σ' : ℝ ↦ ∫ t : ℝ, G (σ' + t * I) * ψ t * x ^ (t * I)) (𝓝[>] 1) + (𝓝 (∫ t : ℝ, G (1 + t * I) * ψ t * x ^ (t * I))) := by + by_cases hh : tsupport ψ = ∅ + · simp [tsupport_eq_empty_iff.mp hh] + obtain ⟨a₀, ha₀⟩ := Set.nonempty_iff_ne_empty.mpr hh + let S : Set ℂ := reProdIm (Icc 1 2) (tsupport ψ) + have l1 : IsCompact S := by + refine Metric.isCompact_iff_isClosed_bounded.mpr ⟨?_, ?_⟩ + · exact isClosed_Icc.reProdIm (isClosed_tsupport ψ) + · exact (Metric.isBounded_Icc 1 2).reProdIm ψ.h2.isBounded + have l2 : S ⊆ {s : ℂ | 1 ≤ s.re} := fun z hz => (mem_reProdIm.mp hz).1.1 + have l3 : ContinuousOn (‖G ·‖) S := (hG.mono l2).norm + have l4 : S.Nonempty := ⟨1 + a₀ * I, by simp [S, mem_reProdIm, ha₀]⟩ + obtain ⟨z, -, hmax⟩ := l1.exists_isMaxOn l4 l3 + let MG := ‖G z‖ + let bound (a : ℝ) : ℝ := MG * ‖ψ a‖ + apply tendsto_integral_filter_of_dominated_convergence (bound := bound) + · apply eventually_of_mem (U := Icc 1 2) (Icc_mem_nhdsGT_of_mem (by simp)) ; intro u hu + apply Continuous.aestronglyMeasurable + apply Continuous.mul + · exact (hG.comp_continuous (by fun_prop) (by simp [hu.1])).mul ψ.h1.continuous + · apply Continuous.const_cpow (by fun_prop) ; simp ; linarith + · apply eventually_of_mem (U := Icc 1 2) (Icc_mem_nhdsGT_of_mem (by simp)) + intro u hu + apply Eventually.of_forall ; intro v + by_cases h : v ∈ tsupport ψ + · have r1 : u + v * I ∈ S := by simp [S, mem_reProdIm, hu.1, hu.2, h] + have r2 := isMaxOn_iff.mp hmax _ r1 + have r4 : (x : ℂ) ≠ 0 := by simp ; linarith + have r5 : arg x = 0 := by simp [arg_eq_zero_iff] ; linarith + have r3 : ‖(x : ℂ) ^ (v * I)‖ = 1 := by simp [norm_cpow_of_ne_zero r4, r5] + simp_rw [norm_mul, r3, mul_one] + exact mul_le_mul_of_nonneg_right r2 (norm_nonneg _) + · have : v ∉ Function.support ψ := fun a ↦ h (subset_tsupport ψ a) + simp at this ; simp [this, bound] + · suffices h : Continuous bound by exact h.integrable_of_hasCompactSupport ψ.h2.norm.mul_left + have := ψ.h1.continuous ; fun_prop + · apply Eventually.of_forall ; intro t + apply Tendsto.mul_const + apply Tendsto.mul_const + refine (hG (1 + t * I) (by simp)).tendsto.comp <| tendsto_nhdsWithin_iff.mpr ⟨?_, ?_⟩ + · exact ((continuous_ofReal.tendsto _).add tendsto_const_nhds).mono_left nhdsWithin_le_nhds + · exact eventually_nhdsWithin_of_forall (fun x (hx : 1 < x) => by simp [hx.le]) + + + + + + + + + + + + + + + + + + + + +theorem limiting_fourier (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) (ψ : CS 2 ℂ) (hx : 1 ≤ x) : + ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) = + ∫ (t : ℝ), (G (1 + t * I)) * (ψ t) * x ^ (t * I) := by + have l1 := limiting_fourier_lim1 hcheby ψ (by linarith) + have l2 := limiting_fourier_lim2 A ψ hx + have l3 := limiting_fourier_lim3 hG ψ hx + apply tendsto_nhds_unique_of_eventuallyEq (l1.sub l2) l3 + simpa [eventuallyEq_nhdsWithin_iff, W21.ofCS2] using + Eventually.of_forall (limiting_fourier_aux hG' hf ψ hx) + + + + +theorem limiting_cor_aux {f : ℝ → ℂ} : + Tendsto (fun x : ℝ ↦ ∫ t, f t * x ^ (t * I)) atTop (𝓝 0) := by + have l1 : ∀ᶠ x : ℝ in atTop, ∀ t : ℝ, x ^ (t * I) = exp (log x * t * I) := by + filter_upwards [eventually_ne_atTop 0, eventually_ge_atTop 0] with x hx hx' t + rw [Complex.cpow_def_of_ne_zero (ofReal_ne_zero.mpr hx), ofReal_log hx'] ; ring_nf + have l2 : ∀ᶠ x : ℝ in atTop, ∫ t, f t * x ^ (t * I) = ∫ t, f t * exp (log x * t * I) := by + filter_upwards [l1] with x hx + refine integral_congr_ae (Eventually.of_forall (fun x => by simp [hx])) + simp_rw [tendsto_congr' l2] + convert_to Tendsto (fun x => 𝓕 f (-Real.log x / (2 * π))) atTop (𝓝 0) + · funext x + rw [Real.fourier_real_eq_integral_exp_smul] + apply integral_congr_ae + filter_upwards [] with t + have hphase : -2 * π * t * (-Real.log x / (2 * π)) = Real.log x * t := by + field_simp + rw [hphase, ofReal_mul, smul_eq_mul] + exact mul_comm _ _ + refine (Real.zero_at_infty_fourier f).comp <| Tendsto.mono_right ?_ _root_.atBot_le_cocompact + exact (tendsto_neg_atBot_iff.mpr tendsto_log_atTop).atBot_mul_const (inv_pos.mpr two_pi_pos) + + + + + + + + + + + + + + + +theorem limiting_cor (ψ : CS 2 ℂ) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := by + apply limiting_cor_aux.congr' + filter_upwards [eventually_ge_atTop 1] with x hx using + limiting_fourier hcheby hG hG' hf ψ hx |>.symm + + + + + + + + + + + + + + + + + + +theorem smooth_urysohn (a b c d : ℝ) (h1 : a < b) (h3 : c < d) : ∃ Ψ : ℝ → ℝ, + (ContDiff ℝ ∞ Ψ) ∧ (HasCompactSupport Ψ) ∧ + Set.indicator (Set.Icc b c) 1 ≤ Ψ ∧ Ψ ≤ Set.indicator (Set.Ioo a d) 1 := by + obtain ⟨ψ, l1, l2, l3, l4, -⟩ := smooth_urysohn_support_Ioo h1 h3 + refine ⟨ψ, l1, l2, l3, l4⟩ + + + + + +noncomputable def compactTruncation : trunc := by + choose ψ h1 h2 h3 h4 using smooth_urysohn (-2) (-1) (1) (2) (by linarith) (by linarith) + exact ⟨⟨ψ, h1.of_le (by norm_cast), h2⟩, h3, h4⟩ + +theorem one_div_sub_one (n : ℕ) : 1 / (↑(n - 1) : ℝ) ≤ 2 / n := by + cases n with + | zero => simp + | succ n => + cases n with + | zero => simp + | succ n => norm_cast ; rw [div_le_div_iff₀] <;> simp [mul_add] <;> linarith + + + +noncomputable def pp (a x : ℝ) : ℝ := a ^ 2 * (x + 1) ^ 2 + (1 - a) * (1 + a) + + + +noncomputable def pp' (a x : ℝ) : ℝ := a ^ 2 * (2 * (x + 1)) + +theorem pp_pos {a : ℝ} (ha : a ∈ Ioo (-1) 1) (x : ℝ) : 0 < pp a x := by + simp only [pp] + have : 0 < 1 - a := by linarith [ha.2] + have : 0 < 1 + a := by linarith [ha.1] + positivity + +theorem pp_deriv (a x : ℝ) : HasDerivAt (pp a) (pp' a x) x := by + unfold pp pp' + simpa using hasDerivAt_id x |>.add_const 1 |>.pow 2 |>.const_mul _ + +theorem pp_deriv_eq (a : ℝ) : deriv (pp a) = pp' a := by + ext x ; exact pp_deriv a x |>.deriv + +theorem pp'_deriv (a x : ℝ) : HasDerivAt (pp' a) (a ^ 2 * 2) x := by + change HasDerivAt (fun y : ℝ => a ^ 2 * (2 * (y + 1))) (a ^ 2 * 2) x + convert hasDerivAt_id x |>.add_const 1 |>.const_mul 2 |>.const_mul (a ^ 2) + using 1 <;> first | rfl | ring + +theorem pp'_deriv_eq (a : ℝ) : deriv (pp' a) = fun _ => a ^ 2 * 2 := by + ext x ; exact pp'_deriv a x |>.deriv + + + +noncomputable def hh (a t : ℝ) : ℝ := (t * (1 + (a * log t) ^ 2))⁻¹ + + + +noncomputable def hh' (a t : ℝ) : ℝ := - pp a (log t) * hh a t ^ 2 + +theorem hh_nonneg (a : ℝ) {t : ℝ} (ht : 0 ≤ t) : 0 ≤ hh a t := by dsimp only [hh] ; positivity + +theorem hh_le (a t : ℝ) (ht : 0 ≤ t) : |hh a t| ≤ t⁻¹ := by + by_cases h0 : t = 0 + · simp [hh, h0] + replace ht : 0 < t := lt_of_le_of_ne ht (by tauto) + unfold hh + rw [abs_inv, inv_le_inv₀ (by positivity) ht, abs_mul, abs_eq_self.mpr ht.le] + convert_to t * 1 ≤ _ + · simp + apply mul_le_mul le_rfl ?_ zero_le_one ht.le + rw [abs_eq_self.mpr (by positivity)] + simp only [le_add_iff_nonneg_right] + positivity + +theorem hh_deriv (a : ℝ) {t : ℝ} (ht : t ≠ 0) : HasDerivAt (hh a) (hh' a t) t := by + have e1 : t * (1 + (a * log t) ^ 2) ≠ 0 := mul_ne_zero ht (_root_.ne_of_lt (by positivity)).symm + have l5 : HasDerivAt (fun t : ℝ => log t) t⁻¹ t := Real.hasDerivAt_log ht + have l4 : HasDerivAt (fun t : ℝ => a * log t) (a * t⁻¹) t := l5.const_mul _ + have l3 : HasDerivAt (fun t : ℝ => (a * log t) ^ 2) (2 * a ^ 2 * t⁻¹ * log t) t := by + convert l4.pow 2 using 1 ; ring + have l2 : HasDerivAt (fun t : ℝ => 1 + (a * log t) ^ 2) (2 * a ^ 2 * t⁻¹ * log t) t := + l3.const_add _ + have l1 : HasDerivAt (fun t : ℝ => t * (1 + (a * log t) ^ 2)) + (1 + 2 * a ^ 2 * log t + a ^ 2 * log t ^ 2) t := by + convert (hasDerivAt_id' t).mul l2 using 1; field_simp; ring + apply (l1.inv e1).congr_deriv + dsimp only [hh', pp, hh] + simp only [div_eq_mul_inv, inv_pow] + ring + +theorem hh_continuous (a : ℝ) : ContinuousOn (hh a) (Ioi 0) := + fun t (ht : 0 < t) => (hh_deriv a ht.ne.symm).continuousAt.continuousWithinAt + +theorem hh'_nonpos {a x : ℝ} (ha : a ∈ Ioo (-1) 1) : hh' a x ≤ 0 := by + have := pp_pos ha (log x) + simp only [hh', neg_mul, Left.neg_nonpos_iff, ge_iff_le] + positivity + +theorem hh_antitone {a : ℝ} (ha : a ∈ Ioo (-1) 1) : AntitoneOn (hh a) (Ioi 0) := by + have l1 x (hx : x ∈ interior (Ioi 0)) : + HasDerivWithinAt (hh a) (hh' a x) (interior (Ioi 0)) x := by + have : x ≠ 0 := by contrapose! hx ; simp [hx] + exact (hh_deriv a this).hasDerivWithinAt + apply antitoneOn_of_hasDerivWithinAt_nonpos (convex_Ioi _) (hh_continuous _) l1 + (fun x _ => hh'_nonpos ha) + + + +noncomputable def gg (x i : ℝ) : ℝ := 1 / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ + +theorem gg_of_hh {x : ℝ} (hx : x ≠ 0) (i : ℝ) : gg x i = x⁻¹ * hh (1 / (2 * π)) (i / x) := by + simp only [gg, hh] + field_simp + +theorem gg_l1 {x : ℝ} (hx : 0 < x) (n : ℕ) : |gg x n| ≤ 1 / n := by + simp only [gg_of_hh hx.ne.symm, one_div, mul_inv_rev, abs_mul] + apply mul_le_mul le_rfl (hh_le _ _ (by positivity)) (by positivity) (by positivity) |>.trans + (le_of_eq ?_) + simp [abs_inv, abs_eq_self.mpr hx.le] ; field_simp + +theorem gg_le_one (i : ℕ) : gg x i ≤ 1 := by + by_cases hi : i = 0 <;> simp only [gg, hi, CharP.cast_eq_zero, div_zero, one_div, mul_inv_rev, + zero_div, Real.log_zero, mul_zero, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, zero_pow, + add_zero, inv_one, mul_one, zero_le_one] + have l1 : 1 ≤ (i : ℝ) := by simp ; omega + have l2 : 1 ≤ 1 + (π⁻¹ * 2⁻¹ * Real.log (↑i / x)) ^ 2 := by + simp only [le_add_iff_nonneg_right] ; positivity + rw [← mul_inv] ; apply inv_le_one_of_one_le₀ ; simpa using mul_le_mul l1 l2 zero_le_one (by simp) + +theorem one_div_two_pi_mem_Ioo : 1 / (2 * π) ∈ Ioo (-1) 1 := by + constructor + · trans 0 + · linarith + · positivity + · rw [div_lt_iff₀ (by positivity)] + convert_to 1 * 1 < 2 * π + · simp + · simp + apply mul_lt_mul one_lt_two ?_ zero_lt_one zero_le_two + trans 2 + · exact one_le_two + · exact two_le_pi + +theorem cancel_aux {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : + ∑ i ∈ Finset.range n, f i * g i ≤ g (n - 1) * (C * n) + (C * (↑(n - 1 - 1) + 1) * g 0 + - C * (↑(n - 1 - 1) + 1) * g (n - 1) - + ((n - 1 - 1) • (C * g 0) - ∑ x ∈ Finset.range (n - 1 - 1), C * g (x + 1))) := by + have l1 (n : ℕ) : + (g n - g (n + 1)) * ∑ i ∈ Finset.range (n + 1), f i ≤ (g n - g (n + 1)) * (C * (n + 1)) := by + apply mul_le_mul le_rfl (by simpa only [cumsum, Nat.cast_add, Nat.cast_one] using hf' (n + 1)) + (Finset.sum_nonneg (fun i _ => hf i)) ?_ + simp only [sub_nonneg] ; apply hg' ; simp + have l2 (x : ℕ) : C * (↑(x + 1) + 1) - C * (↑x + 1) = C := by simp ; ring + have l3 (n : ℕ) : 0 ≤ cumsum f n := Finset.sum_nonneg (fun i _ => hf i) + convert_to ∑ i ∈ Finset.range n, (g i) • (f i) ≤ _ + · simp [mul_comm] + rw [Finset.sum_range_by_parts, sub_eq_add_neg, ← Finset.sum_neg_distrib] + simp_rw [← neg_smul, neg_sub, smul_eq_mul] + apply _root_.add_le_add + · exact mul_le_mul le_rfl (hf' n) (l3 n) (hg _) + · apply Finset.sum_le_sum (fun n _ => l1 n) |>.trans + convert_to ∑ i ∈ Finset.range (n - 1), (C * (↑i + 1)) • (g i - g (i + 1)) ≤ _ + · congr ; ext i ; simp ; ring + rw [Finset.sum_range_by_parts] + simp_rw [Finset.sum_range_sub', l2, smul_sub, smul_eq_mul, Finset.sum_sub_distrib, + Finset.sum_const, Finset.card_range] + apply le_of_eq ; ring_nf + +theorem sum_range_succ (a : ℕ → ℝ) (n : ℕ) : + ∑ i ∈ Finset.range n, a (i + 1) = (∑ i ∈ Finset.range (n + 1), a i) - a 0 := by + have := Finset.sum_range_sub a n + rw [Finset.sum_sub_distrib, sub_eq_iff_eq_add] at this + rw [Finset.sum_range_succ, this] ; ring + +theorem cancel_aux' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : + ∑ i ∈ Finset.range n, f i * g i ≤ + C * n * g (n - 1) + + C * cumsum g (n - 1 - 1 + 1) + - C * (↑(n - 1 - 1) + 1) * g (n - 1) + := by + have := cancel_aux hf hg hf' hg' n + simp only [nsmul_eq_mul, ← Finset.mul_sum, sum_range_succ] at this + convert this using 1 ; unfold cumsum ; ring + +theorem cancel_main {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) (hn : 2 ≤ n) : + cumsum (f * g) n ≤ C * cumsum g n := by + change (∑ i ∈ Finset.range n, f i * g i) ≤ C * cumsum g n + refine (cancel_aux' hf hg hf' hg' n).trans_eq ?_ + have hindex : n - 1 - 1 + 1 = n - 1 := by omega + have hcast : (n : ℝ) = ↑(n - 1) + 1 := by + exact_mod_cast (show n = (n - 1) + 1 by omega) + have hcast' : (↑(n - 1 - 1) : ℝ) + 1 = ↑(n - 1) := by + exact_mod_cast hindex + have hsum : cumsum g n = cumsum g (n - 1) + g (n - 1) := by + conv_lhs => rw [show n = (n - 1) + 1 by omega] + exact cumsum_succ (n - 1) + rw [hindex, hcast', hcast, hsum] + ring + +theorem cancel_main' {C : ℝ} {f g : ℕ → ℝ} (hf : 0 ≤ f) (hf0 : f 0 = 0) (hg : 0 ≤ g) + (hf' : ∀ n, cumsum f n ≤ C * n) (hg' : Antitone g) (n : ℕ) : + cumsum (f * g) n ≤ C * cumsum g n := by + cases n with + | zero => simp [cumsum] + | succ n => + cases n with + | zero => + have hC : 0 ≤ C := by simpa [cumsum, hf0] using hf' 1 + simpa [cumsum, hf0] using mul_nonneg hC (hg 0) + | succ n => exact cancel_main hf hg hf' hg' (n + 2) (by omega) + +theorem sum_le_integral {x₀ : ℝ} {f : ℝ → ℝ} {n : ℕ} (hf : AntitoneOn f (Ioc x₀ (x₀ + n))) + (hfi : IntegrableOn f (Icc x₀ (x₀ + n))) : + (∑ i ∈ Finset.range n, f (x₀ + ↑(i + 1))) ≤ ∫ x in x₀..x₀ + n, f x := by + cases n with simp only [Nat.cast_add, Nat.cast_one, CharP.cast_eq_zero, add_zero, + lt_self_iff_false, not_false_eq_true, + Ioc_eq_empty, Finset.range_zero, Nat.cast_add, Nat.cast_one, Finset.sum_empty, + intervalIntegral.integral_same, le_refl] at hf ⊢ + | succ n => + have : Finset.range (n + 1) = {0} ∪ Finset.Ico 1 (n + 1) := by + ext i ; by_cases hi : i = 0 <;> simp [hi] ; omega + simp only [this, Finset.singleton_union, Finset.mem_Ico, nonpos_iff_eq_zero, one_ne_zero, + lt_add_iff_pos_left, add_pos_iff, zero_lt_one, or_true, and_true, not_false_eq_true, + Finset.sum_insert, CharP.cast_eq_zero, zero_add, ge_iff_le] + have l4 : IntervalIntegrable f volume x₀ (x₀ + 1) := by + apply IntegrableOn.intervalIntegrable + simp only [le_add_iff_nonneg_right, zero_le_one, uIcc_of_le] + apply hfi.mono_set + apply Icc_subset_Icc le_rfl + simp + have l5 x (hx : x ∈ Ioc x₀ (x₀ + 1)) : (fun x ↦ f (x₀ + 1)) x ≤ f x := by + rcases hx with ⟨hx1, hx2⟩ + refine hf ⟨hx1, by linarith⟩ ⟨by linarith, by linarith⟩ hx2 + have l6 : ∫ x in x₀..x₀ + 1, f (x₀ + 1) = f (x₀ + 1) := by simp + have l1 : f (x₀ + 1) ≤ ∫ x in x₀..x₀ + 1, f x := by + rw [← l6] + apply intervalIntegral.integral_mono_on_of_le_Ioo (by linarith) (by simp) l4 + intro x hx + exact l5 x ⟨hx.1, hx.2.le⟩ + have l2 : AntitoneOn (fun x ↦ f (x₀ + x)) (Icc 1 ↑(n + 1)) := by + intro u hu v hv huv + have hu1 := hu.1 + have hv2 := hv.2 + push_cast at hv2 + refine hf ⟨?_, ?_⟩ ⟨?_, ?_⟩ ?_ <;> linarith + have l3 := @AntitoneOn.sum_le_integral_Ico 1 (n + 1) (fun x => f (x₀ + x)) (by simp) + (by simpa using l2) + simp only [Nat.cast_add, Nat.cast_one, intervalIntegral.integral_comp_add_left] at l3 + convert _root_.add_le_add l1 l3 + have := @intervalIntegral.integral_comp_mul_add ℝ _ _ 1 (n + 1) 1 f one_ne_zero x₀ + rw [intervalIntegral.integral_add_adjacent_intervals] + · exact l4 + · apply IntegrableOn.intervalIntegrable + simp only [add_le_add_iff_left, le_add_iff_nonneg_left, Nat.cast_nonneg, uIcc_of_le] + apply hfi.mono_set + apply Icc_subset_Icc + · linarith + · simp + +theorem hh_integrable_aux (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : + (IntegrableOn (fun t ↦ a * hh b (t / c)) (Ici 0)) ∧ + (∫ (t : ℝ) in Ioi 0, a * hh b (t / c) = a * c / b * π) := by + rw [integrableOn_Ici_iff_integrableOn_Ioi] + simp only [hh] + let g (x : ℝ) := (a * c / b) * Real.arctan (b * log (x / c)) + let g₀ (x : ℝ) := if x = 0 then ((a * c / b) * (- (π / 2))) else g x + let g' (x : ℝ) := a * (x / c * (1 + (b * Real.log (x / c)) ^ 2))⁻¹ + have l3 (x) (hx : 0 < x) : HasDerivAt Real.log x⁻¹ x := by apply Real.hasDerivAt_log (by linarith) + have l4 (x) : HasDerivAt (fun t => t / c) (1 / c) x := (hasDerivAt_id x).div_const c + have l2 (x) (hx : 0 < x) : HasDerivAt (fun t => log (t / c)) x⁻¹ x := by + have hcomp := (l3 (x / c) (by positivity)).comp x (l4 x) + convert hcomp using 1 + · rfl + · field_simp [hc.ne', hx.ne'] + have l5 (x) (hx : 0 < x) := (l2 x hx).const_mul b + have l1 (x) (hx : 0 < x) := (l5 x hx).arctan + have l6 (x) (hx : 0 < x) : HasDerivAt g (g' x) x := by + convert (l1 x hx).const_mul (a * c / b) using 1 + simp only [g'] + field_simp + have key (x) (hx : 0 < x) : HasDerivAt g₀ (g' x) x := by + apply (l6 x hx).congr_of_eventuallyEq + apply eventually_of_mem <| Ioi_mem_nhds hx + intro y (hy : 0 < y) + simp [g₀, hy.ne.symm] + have k1 : Tendsto g₀ atTop (𝓝 ((a * c / b) * (π / 2))) := by + have : g =ᶠ[atTop] g₀ := by + apply eventually_of_mem (Ioi_mem_atTop 0) + intro y (hy : 0 < y) + simp [g₀, hy.ne.symm] + apply Tendsto.congr' this + apply Tendsto.const_mul + apply (tendsto_arctan_atTop.mono_right nhdsWithin_le_nhds).comp + apply Tendsto.const_mul_atTop hb + apply tendsto_log_atTop.comp + apply Tendsto.atTop_div_const hc + apply tendsto_id + have k2 : Tendsto g₀ (𝓝[>] 0) (𝓝 (g₀ 0)) := by + have : g =ᶠ[𝓝[>] 0] g₀ := by + apply eventually_of_mem self_mem_nhdsWithin + intro x (hx : 0 < x) ; simp [g₀, hx.ne.symm] + simp only [g₀] + apply Tendsto.congr' this + apply Tendsto.const_mul + apply (tendsto_arctan_atBot.mono_right nhdsWithin_le_nhds).comp + apply Tendsto.const_mul_atBot hb + apply tendsto_log_nhdsGT_zero.comp + rw [Metric.tendsto_nhdsWithin_nhdsWithin] + intro ε hε + refine ⟨c * ε, by positivity, fun x hx1 hx2 => ⟨?_, ?_⟩⟩ + · simp only [mem_Ioi] at hx1 ⊢ ; positivity + · simp only [dist_zero_right, norm_eq_abs, norm_div, abs_eq_self.mpr hc.le] at hx2 ⊢ + rwa [div_lt_iff₀ hc, mul_comm] + have k3 : ContinuousWithinAt g₀ (Ici 0) 0 := by + rw [Metric.continuousWithinAt_iff] + rw [Metric.tendsto_nhdsWithin_nhds] at k2 + intro ε hε + obtain ⟨δ, hδ, hδx⟩ := k2 ε hε + refine ⟨δ, hδ, ?_⟩ + intro x hx hdist + change 0 ≤ x at hx + rcases lt_or_eq_of_le hx with hx | hx + · exact hδx hx hdist + · subst x + simpa only [dist_self] using hε + have k4 : ∀ x ∈ Ioi 0, 0 ≤ g' x := by + intro x (hx : 0 < x) ; simp only [mul_inv_rev, inv_div, g'] ; positivity + constructor + · convert_to IntegrableOn g' _ + exact integrableOn_Ioi_deriv_of_nonneg k3 key k4 k1 + · have := integral_Ioi_of_hasDerivAt_of_nonneg k3 key k4 k1 + simp only [mul_inv_rev, inv_div, mul_neg, ↓reduceIte, sub_neg_eq_add, g', g₀] at this ⊢ + convert this using 1 ; field_simp ; ring + +theorem hh_integrable (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : + IntegrableOn (fun t ↦ a * hh b (t / c)) (Ici 0) := + hh_integrable_aux ha hb hc |>.1 + +theorem hh_integral (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) : + ∫ (t : ℝ) in Ioi 0, a * hh b (t / c) = a * c / b * π := + hh_integrable_aux ha hb hc |>.2 + +theorem hh_integral' : ∫ t in Ioi 0, hh (1 / (2 * π)) t = 2 * π ^ 2 := by + have := hh_integral (a := 1) (b := 1 / (2 * π)) (c := 1) + (by positivity) (by positivity) (by positivity) + convert this using 1 <;> simp ; ring + +theorem bound_sum_log {C : ℝ} (hf0 : f 0 = 0) + (hf : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + {x : ℝ} (hx : 1 ≤ x) : + ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ + C * (1 + ∫ t in Ioi 0, hh (1 / (2 * π)) t) := by + let ggg (i : ℕ) : ℝ := if i = 0 then 1 else gg x i + have l0 : x ≠ 0 := by linarith + have l1 i : 0 ≤ ggg i := by by_cases hi : i = 0 <;> simp only [gg, one_div, mul_inv_rev, hi, + ↓reduceIte, zero_le_one, ggg] ; positivity + have l2 : Antitone ggg := by + intro i j hij ; by_cases hi : i = 0 <;> by_cases hj : j = 0 <;> simp only [hj, ↓reduceIte, hi, + le_refl, ggg] + · exact gg_le_one _ + · omega + · simp only [gg_of_hh l0] + gcongr + apply hh_antitone one_div_two_pi_mem_Ioo + · simp only [mem_Ioi] ; positivity + · simp only [mem_Ioi] ; positivity + · gcongr + have l3 : 0 ≤ C := by simpa [cumsum, hf0] using hf 1 + have l4 : 0 ≤ ∫ (t : ℝ) in Ioi 0, hh (π⁻¹ * 2⁻¹) t := + setIntegral_nonneg measurableSet_Ioi (fun x hx => hh_nonneg _ (LT.lt.le hx)) + have l5 {n : ℕ} : AntitoneOn (fun t ↦ x⁻¹ * hh (1 / (2 * π)) (t / x)) (Ioc 0 n) := by + intro u hu v hv huv + have hu1 := hu.1 + have hv1 := hv.1 + simp only + apply mul_le_mul le_rfl ?_ (hh_nonneg _ (by positivity)) (by positivity) + apply hh_antitone one_div_two_pi_mem_Ioo (by simp only [mem_Ioi] ; positivity) + (by simp only [mem_Ioi] ; positivity) + apply (div_le_div_iff_of_pos_right (by positivity)).mpr huv + have l6 {n : ℕ} : IntegrableOn (fun t ↦ x⁻¹ * hh (π⁻¹ * 2⁻¹) (t / x)) (Icc 0 n) volume := by + apply IntegrableOn.mono_set + (hh_integrable (by positivity) (by positivity) (by positivity)) Icc_subset_Ici_self + apply Real.tsum_le_of_sum_range_le (fun n => by positivity) ; intro n + convert_to ∑ i ∈ Finset.range n, ‖f i‖ * ggg i ≤ _ + · congr ; ext i + by_cases hi : i = 0 + · simp [hi, hf0] + · simp only [gg, hi, ↓reduceIte, ggg] + field_simp + apply cancel_main' (fun _ => norm_nonneg _) (by simp [hf0]) l1 hf l2 n |>.trans + gcongr ; simp only [cumsum, gg_of_hh l0, one_div, mul_inv_rev, ggg] + by_cases hn : n = 0 + · simp only [hn, Finset.range_zero, Finset.sum_empty] ; positivity + replace hn : 0 < n := by omega + have : Finset.range n = {0} ∪ Finset.Ico 1 n := by + ext i ; simp ; by_cases hi : i = 0 <;> simp [hi, hn] ; omega + simp only [this, Finset.singleton_union, Finset.mem_Ico, nonpos_iff_eq_zero, one_ne_zero, + false_and, not_false_eq_true, Finset.sum_insert, ↓reduceIte, add_le_add_iff_left, ge_iff_le] + convert_to ∑ x_1 ∈ Finset.Ico 1 n, x⁻¹ * hh (π⁻¹ * 2⁻¹) (↑x_1 / x) ≤ _ + · apply Finset.sum_congr rfl (fun i hi => ?_) + simp at hi + have : i ≠ 0 := by omega + simp [this] + simp_rw [Finset.sum_Ico_eq_sum_range, add_comm 1] + have := @sum_le_integral 0 (fun t => x⁻¹ * hh (π⁻¹ * 2⁻¹) (t / x)) (n - 1) + (by simpa using l5) (by simpa using l6) + simp only [zero_add] at this + apply this.trans + rw [@intervalIntegral.integral_comp_div ℝ _ _ 0 ↑(n - 1) x (fun t => x⁻¹ * hh (π⁻¹ * 2⁻¹) (t)) l0] + simp only [zero_div, intervalIntegral.integral_const_mul, smul_eq_mul, ← mul_assoc, + mul_inv_cancel₀ l0, one_mul] + have : (0 : ℝ) ≤ ↑(n - 1) / x := by positivity + rw [intervalIntegral.intervalIntegral_eq_integral_uIoc] + simp only [this, ↓reduceIte, uIoc_of_le, smul_eq_mul, one_mul, ge_iff_le] + apply integral_mono_measure + · apply Measure.restrict_mono Ioc_subset_Ioi_self le_rfl + · apply eventually_of_mem (self_mem_ae_restrict measurableSet_Ioi) + intro x (hx : 0 < x) + apply hh_nonneg _ hx.le + · have h := (@hh_integrable 1 (1 / (2 * π)) 1 (by positivity) (by positivity) (by positivity)) + have h' := h.mono_set Ioi_subset_Ici_self + unfold IntegrableOn at h' + apply h'.congr + exact Eventually.of_forall (fun t => by simp) + +theorem bound_sum_log0 {C : ℝ} + (hf : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + {x : ℝ} (hx : 1 ≤ x) : + ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ + C * (1 + ∫ t in Ioi 0, hh (1 / (2 * π)) t) := by + let f0 i := if i = 0 then 0 else f i + have l1 : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f0 k : ℂ)‖) n ≤ C * n) := by + intro n ; refine Finset.sum_le_sum (fun i _ => ?_) |>.trans (hf n) + by_cases hi : i = 0 <;> simp [hi, f0] + have l2 i : ‖f i‖ / i = ‖f0 i‖ / i := by by_cases hi : i = 0 <;> simp [hi, f0] + simp_rw [l2] ; apply bound_sum_log rfl l1 hx + +theorem bound_sum_log' {C : ℝ} + (hf : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + {x : ℝ} (hx : 1 ≤ x) : + ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ ≤ C * (1 + 2 * π ^ 2) := by + simpa only [hh_integral'] using bound_sum_log0 hf hx + +variable (f x) in +theorem summable_fourier_aux (ψ : W21) (i : ℕ) : + ‖f i / i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (i / x))‖ ≤ + W21.norm ψ * (‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹) := by + convert mul_le_mul_of_nonneg_left (decay_bounds_key ψ (1 / (2 * π) * log (i / x))) + (norm_nonneg (f i / i)) using 1 + · simp + · change _ = _ * (W21.norm ψ * _) + simp only [W21.norm, mul_inv_rev, one_div, Complex.norm_div, RCLike.norm_natCast] + ring + +theorem summable_fourier (x : ℝ) (hx : 0 < x) (ψ : W21) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + Summable fun i ↦ ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑i / x))‖ := by + have l5 : Summable fun i ↦ ‖f i‖ / ↑i * ((1 + (1 / (2 * ↑π) * ↑(Real.log (↑i / x))) ^ 2)⁻¹) := by + simpa using limiting_fourier_lim1_aux hcheby hx 1 (zero_le_one' ℝ) + have l6 := summable_fourier_aux x f ψ + exact Summable.of_nonneg_of_le (fun _ => norm_nonneg _) l6 + (by simpa using l5.const_smul (W21.norm ψ)) + +theorem bound_I1 (x : ℝ) (hx : 0 < x) (ψ : W21) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ + W21.norm ψ • ∑' i, ‖f i‖ / i * (1 + (1 / (2 * π) * log (i / x)) ^ 2)⁻¹ := by + have l5 : Summable fun i ↦ ‖f i‖ / ↑i * ((1 + (1 / (2 * ↑π) * ↑(Real.log (↑i / x))) ^ 2)⁻¹) := by + simpa using limiting_fourier_lim1_aux hcheby hx 1 (zero_le_one' ℝ) + have l6 := summable_fourier_aux x f ψ + have l1 : Summable fun i ↦ ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑i / x))‖ := by + exact summable_fourier x hx ψ hcheby + apply (norm_tsum_le_tsum_norm l1).trans + change (∑' i, ‖f i / ↑i * 𝓕 (ψ : ℝ → ℂ) + (1 / (2 * π) * Real.log (↑i / x))‖) ≤ W21.norm ψ * _ + rw [← tsum_mul_left] + exact Summable.tsum_mono l1 (l5.mul_left (W21.norm ψ)) l6 + +theorem bound_I1' {C : ℝ} (x : ℝ) (hx : 1 ≤ x) (ψ : W21) + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x))‖ ≤ + W21.norm ψ * C * (1 + 2 * π ^ 2) := by + apply bound_I1 x (by linarith) ψ ⟨_, hcheby⟩ |>.trans + rw [smul_eq_mul, mul_assoc] + apply mul_le_mul le_rfl (bound_sum_log' hcheby hx) ?_ W21.norm_nonneg + apply tsum_nonneg (fun i => by positivity) + +theorem bound_I2 (x : ℝ) (ψ : W21) : + ‖∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))‖ ≤ W21.norm ψ * (2 * π ^ 2) := by + have key a : ‖𝓕 (ψ : ℝ → ℂ) (a / (2 * π))‖ ≤ W21.norm ψ * (1 + (a / (2 * π)) ^ 2)⁻¹ := + decay_bounds_key ψ _ + have twopi : 0 ≤ 2 * π := by simp [pi_nonneg] + have l3 : Integrable (fun a ↦ (1 + (a / (2 * π)) ^ 2)⁻¹) := + integrable_inv_one_add_sq.comp_div (by norm_num [pi_ne_zero]) + have l2 : IntegrableOn (fun i ↦ W21.norm ψ * (1 + (i / (2 * π)) ^ 2)⁻¹) (Ici (-Real.log x)) := by + exact (l3.const_mul _).integrableOn + have l1 : IntegrableOn (fun i ↦ ‖𝓕 (ψ : ℝ → ℂ) (i / (2 * π))‖) (Ici (-Real.log x)) := by + refine ((l3.const_mul (W21.norm ψ)).mono' ?_ ?_).integrableOn + · apply Continuous.aestronglyMeasurable ; fun_prop + · simp only [norm_norm, key] ; simp + have l5 : 0 ≤ᵐ[volume] fun a ↦ (1 + (a / (2 * π)) ^ 2)⁻¹ := by + apply Eventually.of_forall ; intro x ; positivity + refine (norm_integral_le_integral_norm _).trans <| (setIntegral_mono l1 l2 key).trans ?_ + rw [integral_const_mul] ; gcongr + · apply W21.norm_nonneg + refine (setIntegral_le_integral l3 l5).trans ?_ + rw [Measure.integral_comp_div (fun x => (1 + x ^ 2)⁻¹) (2 * π)] + simp [abs_eq_self.mpr twopi] ; ring_nf ; rfl + +theorem bound_main {C : ℝ} (A : ℂ) (x : ℝ) (hx : 1 ≤ x) (ψ : W21) + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + ‖∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))‖ ≤ + W21.norm ψ * (C * (1 + 2 * π ^ 2) + ‖A‖ * (2 * π ^ 2)) := by + have l1 := bound_I1' x hx ψ hcheby + have l2 := mul_le_mul (le_refl ‖A‖) (bound_I2 x ψ) (by positivity) (by positivity) + apply norm_sub_le _ _ |>.trans ; rw [norm_mul] + convert _root_.add_le_add l1 l2 using 1 ; ring + + +theorem limiting_cor_W21 (ψ : W21) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := by + + let S1 x (ψ : ℝ → ℂ) := ∑' (n : ℕ), f n / ↑n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * Real.log (↑n / x)) + let S2 x (ψ : ℝ → ℂ) := ↑A * ∫ (u : ℝ) in Ici (-Real.log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π)) + let S x ψ := S1 x ψ - S2 x ψ ; change Tendsto (fun x ↦ S x ψ) atTop (𝓝 0) + + obtain g := compactTruncation + let Ψ R := g.scale R * ψ + have key R : Tendsto (fun x ↦ S x (Ψ R)) atTop (𝓝 0) := limiting_cor (Ψ R) hf hcheby hG hG' + + obtain ⟨C, hcheby⟩ := hcheby + have hC : 0 ≤ C := by + have : ‖f 0‖ ≤ C := by simpa [cumsum] using hcheby 1 + have : 0 ≤ ‖f 0‖ := by positivity + linarith + have key2 : Tendsto (fun R ↦ W21.norm (ψ - Ψ R)) atTop (𝓝 0) := W21_approximation ψ g + simp_rw [Metric.tendsto_nhds] at key key2 ⊢ ; intro ε hε + let M := C * (1 + 2 * π ^ 2) + ‖(A : ℂ)‖ * (2 * π ^ 2) + obtain ⟨R, hRψ⟩ := (key2 ((ε / 2) / (1 + M)) (by positivity)).exists + simp only [dist_zero_right, Real.norm_eq_abs, abs_eq_self.mpr W21.norm_nonneg] at hRψ key + + filter_upwards [eventually_ge_atTop 1, key R (ε / 2) (by positivity)] with x hx key + + have key3 : ‖S x (ψ - Ψ R)‖ < ε / 2 := by + have hbound := @bound_main f C A x hx (ψ - Ψ R) hcheby + change ‖S x (⇑ψ - ⇑(Ψ R))‖ ≤ W21.norm (⇑ψ - ⇑(Ψ R)) * M at hbound + apply hbound.trans_lt + calc + W21.norm (⇑ψ - ⇑(Ψ R)) * M ≤ W21.norm (⇑ψ - ⇑(Ψ R)) * (1 + M) := + mul_le_mul_of_nonneg_left (by linarith) W21.norm_nonneg + _ < ε / 2 := (lt_div_iff₀ (show 0 < 1 + M by positivity)).mp hRψ + + have S1_sub_1 x : 𝓕 (⇑ψ - ⇑(Ψ R)) x = 𝓕 (ψ : ℝ → ℂ) x - 𝓕 ⇑(Ψ R) x := + F_sub ψ.hf (Ψ R : W21).hf x + have S1_sub : S1 x (ψ - Ψ R) = S1 x ψ - S1 x (Ψ R) := by + simp only [one_div, mul_inv_rev, S1_sub_1, mul_sub, S1] ; apply Summable.tsum_sub + · have := summable_fourier x (by positivity) ψ ⟨_, hcheby⟩ + rw [summable_norm_iff] at this + simpa using this + · have hsum := summable_fourier x (by positivity) (Ψ R : W21) ⟨_, hcheby⟩ + rw [summable_norm_iff] at hsum + simpa only [W21.ofCS2, one_div, mul_inv_rev] using hsum + have S2_sub : S2 x (ψ - Ψ R) = S2 x ψ - S2 x (Ψ R) := by + simp only [S1_sub_1, S2] ; rw [integral_sub] + · ring + · exact ψ.integrable_fourier (by positivity) |>.restrict + · exact (Ψ R : W21).integrable_fourier (by positivity) |>.restrict + have S_sub : S x (ψ - Ψ R) = S x ψ - S x (Ψ R) := by simp [S, S1_sub, S2_sub] ; ring + simpa [S_sub, Ψ] using norm_add_le _ _ |>.trans_lt (_root_.add_lt_add key3 key) + + + + + + + + + + + + + + + + + + + + + + + + +theorem limiting_cor_schwartz (ψ : 𝓢(ℝ, ℂ)) (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun x : ℝ ↦ ∑' n, f n / n * 𝓕 (ψ : ℝ → ℂ) (1 / (2 * π) * log (n / x)) - + A * ∫ u in Set.Ici (-log x), 𝓕 (ψ : ℝ → ℂ) (u / (2 * π))) atTop (𝓝 0) := + limiting_cor_W21 ψ hf hcheby hG hG' + + + + + + + + + + + + + + + + + + + + + + + + +theorem fourier_surjection_on_schwartz (f : 𝓢(ℝ, ℂ)) : ∃ g : 𝓢(ℝ, ℂ), 𝓕 g = f := by + refine ⟨𝓕⁻ f, ?_⟩ + exact FourierTransform.fourier_fourierInv_eq f + + + + + + +noncomputable def toSchwartz (f : ℝ → ℂ) (h1 : ContDiff ℝ ∞ f) + (h2 : HasCompactSupport f) : 𝓢(ℝ, ℂ) := + h2.toSchwartzMap h1 + +@[simp] theorem toSchwartz_apply (f : ℝ → ℂ) {h1 h2 x} : SchwartzMap.mk f h1 h2 x = f x := rfl + +theorem comp_exp_support0 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : + ∀ᶠ x in 𝓝 0, Ψ x = 0 := + notMem_tsupport_iff_eventuallyEq.mp (fun h => lt_irrefl 0 <| mem_Ioi.mp (hplus h)) + +theorem comp_exp_support1 {Ψ : ℝ → ℂ} (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : + ∀ᶠ x in atBot, Ψ (exp x) = 0 := + Real.tendsto_exp_atBot <| comp_exp_support0 hplus + +theorem comp_exp_support2 {Ψ : ℝ → ℂ} (hsupp : HasCompactSupport Ψ) : + ∀ᶠ (x : ℝ) in atTop, (Ψ ∘ rexp) x = 0 := by + simp only [hasCompactSupport_iff_eventuallyEq, coclosedCompact_eq_cocompact, + cocompact_eq_atBot_atTop] at hsupp + exact Real.tendsto_exp_atTop hsupp.2 + +theorem comp_exp_support {Ψ : ℝ → ℂ} (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : HasCompactSupport (Ψ ∘ rexp) := by + simp only [hasCompactSupport_iff_eventuallyEq, coclosedCompact_eq_cocompact, + cocompact_eq_atBot_atTop] + exact ⟨comp_exp_support1 hplus, comp_exp_support2 hsupp⟩ + +theorem wiener_ikehara_smooth_aux (l0 : Continuous Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Ioi 0) (x : ℝ) (hx : 0 < x) : + ∫ (u : ℝ) in Ioi (-Real.log x), ↑(rexp u) * Ψ (rexp u) = ∫ (y : ℝ) in Ioi (1 / x), Ψ y := by + have l1 : ContinuousOn rexp (Ici (-Real.log x)) := by fun_prop + have l2 : Tendsto rexp atTop atTop := Real.tendsto_exp_atTop + have l3 t (_ : t ∈ Ioi (-log x)) : HasDerivWithinAt rexp (rexp t) (Ioi t) t := + (Real.hasDerivAt_exp t).hasDerivWithinAt + have l4 : ContinuousOn Ψ (rexp '' Ioi (-Real.log x)) := by fun_prop + have l5 : IntegrableOn Ψ (rexp '' Ici (-Real.log x)) volume := + (l0.integrable_of_hasCompactSupport hsupp).integrableOn + have l6 : IntegrableOn (fun x ↦ rexp x • (Ψ ∘ rexp) x) (Ici (-Real.log x)) volume := by + refine (Continuous.integrable_of_hasCompactSupport (by fun_prop) ?_).integrableOn + change HasCompactSupport (rexp • (Ψ ∘ rexp)) + exact (comp_exp_support hsupp hplus).smul_left + have := MeasureTheory.integral_deriv_smul_comp_Ioi l1 l2 l3 l4 l5 l6 + simpa [Real.exp_neg, Real.exp_log hx] using this + +theorem wiener_ikehara_smooth_sub (h1 : Integrable Ψ) + (hplus : closure (Function.support Ψ) ⊆ Ioi 0) : + Tendsto (fun x ↦ (↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y) - ↑A * ∫ (y : ℝ) in Ioi 0, Ψ y) + atTop (𝓝 0) := by + obtain ⟨ε, hε, hh⟩ := Metric.eventually_nhds_iff.mp <| comp_exp_support0 hplus + apply tendsto_nhds_of_eventually_eq ; filter_upwards [eventually_gt_atTop ε⁻¹] with x hxε + have l1 : Integrable (indicator (Ioi x⁻¹) (fun x : ℝ => Ψ x)) := h1.indicator measurableSet_Ioi + have l2 : Integrable (indicator (Ioi 0) (fun x : ℝ => Ψ x)) := h1.indicator measurableSet_Ioi + simp_rw [← MeasureTheory.integral_indicator measurableSet_Ioi, ← mul_sub, ← integral_sub l1 l2] + simp only [mul_eq_zero, ofReal_eq_zero] + right + apply MeasureTheory.integral_eq_zero_of_ae + apply Eventually.of_forall + intro t + simp only [Pi.zero_apply] + have hε' : 0 < ε⁻¹ := by positivity + have hx : 0 < x := by linarith + have hx' : 0 < x⁻¹ := by positivity + have hεx : x⁻¹ < ε := (inv_lt_comm₀ hε hx).mp hxε + have l3 : Ioi 0 = Ioc 0 x⁻¹ ∪ Ioi x⁻¹ := by + ext t ; simp only [mem_Ioi, mem_union, mem_Ioc] ; constructor <;> intro h + · simp [h, le_or_gt] + · cases h with + | inl h => exact h.1 + | inr h => exact hx'.trans h + have l4 : Disjoint (Ioc 0 x⁻¹) (Ioi x⁻¹) := by simp + have l5 := Set.indicator_union_of_disjoint l4 Ψ + rw [l3, l5] + simp only + rw [add_comm, sub_add_cancel_left] + by_cases ht : t ∈ Ioc 0 x⁻¹ + · simp only [ht, indicator_of_mem, neg_eq_zero] + apply hh ; simp only [mem_Ioc, dist_zero_right, norm_eq_abs] at ht ⊢ + apply hεx.trans_le' + rw [abs_le] ; constructor <;> linarith + simp [ht] + + + + + + + + + + + + + + + + + + + + + +theorem wiener_ikehara_smooth (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x - A * ∫ y in Set.Ioi 0, Ψ y) + atTop (𝓝 0) := by + let h (x : ℝ) : ℂ := rexp (2 * π * x) * Ψ (exp (2 * π * x)) + have h1 : ContDiff ℝ ∞ h := by + have : ContDiff ℝ ∞ (fun x : ℝ => (rexp (2 * π * x))) := (contDiff_const.mul contDiff_id).exp + exact (contDiff_ofReal.comp this).mul (hsmooth.comp this) + have h2 : HasCompactSupport h := by + have hπ : 2 * π ≠ 0 := by simp [pi_ne_zero] + have hh : HasCompactSupport (fun x : ℝ => Ψ (rexp (2 * π * x))) := by + simpa only [Function.comp_def, smul_eq_mul] using + (comp_exp_support hsupp hplus).comp_smul hπ + change HasCompactSupport + ((fun x : ℝ => (rexp (2 * π * x) : ℂ)) * fun x : ℝ => Ψ (rexp (2 * π * x))) + exact hh.mul_left + obtain ⟨g, hg⟩ := fourier_surjection_on_schwartz (toSchwartz h h1 h2) + have l1 {y} (hy : 0 < y) : y * Ψ y = 𝓕 g (1 / (2 * π) * Real.log y) := by + rw [hg] + change (y : ℂ) * Ψ y = h (1 / (2 * π) * Real.log y) + have harg : 2 * π * (1 / (2 * π) * Real.log y) = Real.log y := by + rw [← mul_assoc, mul_one_div_cancel (mul_ne_zero (by norm_num) pi_ne_zero), one_mul] + dsimp only [h] + rw [harg, Real.exp_log hy] + have key := limiting_cor_schwartz g hf hcheby hG hG' + have l2 : ∀ᶠ x in atTop, ∑' (n : ℕ), f n / ↑n * 𝓕 g (1 / (2 * π) * Real.log (↑n / x)) = + ∑' (n : ℕ), f n * Ψ (↑n / x) / x := by + filter_upwards [eventually_gt_atTop 0] with x hx + congr ; ext n + by_cases hn : n = 0 + · simp [hn, (comp_exp_support0 hplus).self_of_nhds] + rw [← l1 (by positivity)] + have : (n : ℂ) ≠ 0 := by simpa using hn + have : (x : ℂ) ≠ 0 := by simpa using hx.ne.symm + simp only [ofReal_div, ofReal_natCast] + field_simp + have l3 : ∀ᶠ x in atTop, ↑A * ∫ (u : ℝ) in Ici (-Real.log x), 𝓕 g (u / (2 * π)) = + ↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y := by + filter_upwards [eventually_gt_atTop 0] with x hx + congr 1 + rw [hg] + change (∫ u in Ici (-Real.log x), h (u / (2 * π))) = ∫ y in Ioi x⁻¹, Ψ y + dsimp only [h] + have hscale : (2 : ℝ) * π ≠ 0 := mul_ne_zero (by norm_num) pi_ne_zero + have harg (u : ℝ) : 2 * π * (u / (2 * π)) = u := mul_div_cancel₀ u hscale + simp_rw [harg] + rw [MeasureTheory.integral_Ici_eq_integral_Ioi] + simpa only [one_div] using wiener_ikehara_smooth_aux hsmooth.continuous hsupp hplus x hx + have l4 : Tendsto (fun x => (↑A * ∫ (y : ℝ) in Ioi x⁻¹, Ψ y) - ↑A * ∫ (y : ℝ) in Ioi 0, Ψ y) + atTop (𝓝 0) := by + exact wiener_ikehara_smooth_sub (hsmooth.continuous.integrable_of_hasCompactSupport hsupp) hplus + simpa [tsum_div_const] using (key.congr' <| EventuallyEq.sub l2 l3) |>.add l4 + + + +theorem wiener_ikehara_smooth' (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x) atTop (nhds (A * ∫ y in Set.Ioi 0, Ψ y)) := + tendsto_sub_nhds_zero_iff.mp <| wiener_ikehara_smooth hf hcheby hG hG' hsmooth hsupp hplus + + +local instance coeRealFunctionComplex {E : Type*} : Coe (E → ℝ) (E → ℂ) := + ⟨fun f n => f n⟩ + +@[norm_cast] +theorem set_integral_ofReal {f : ℝ → ℝ} {s : Set ℝ} : ∫ x in s, (f x : ℂ) = ∫ x in s, f x := + integral_ofReal + +theorem wiener_ikehara_smooth_real {f : ℕ → ℝ} {Ψ : ℝ → ℝ} + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (hsmooth : ContDiff ℝ ∞ Ψ) (hsupp : HasCompactSupport Ψ) + (hplus : closure (Function.support Ψ) ⊆ Set.Ioi 0) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * Ψ (n / x)) / x) atTop (nhds (A * ∫ y in Set.Ioi 0, Ψ y)) := by + let Ψ' := ofReal ∘ Ψ + have l1 : ContDiff ℝ ∞ Ψ' := contDiff_ofReal.comp hsmooth + have l2 : HasCompactSupport Ψ' := hsupp.comp_left rfl + have l3 : closure (Function.support Ψ') ⊆ Ioi 0 := by rwa [Function.support_comp_eq] ; simp + have key := (continuous_re.tendsto _).comp + (@wiener_ikehara_smooth' A Ψ G f hf hcheby hG hG' l1 l2 l3) + simp at key ; norm_cast at key + +theorem interval_approx_inf (ha : 0 < a) (hab : a < b) : + ∀ᶠ ε in 𝓝[>] 0, ∃ ψ : ℝ → ℝ, ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ + closure (Function.support ψ) ⊆ Set.Ioi 0 ∧ + ψ ≤ indicator (Ico a b) 1 ∧ b - a - ε ≤ ∫ y in Ioi 0, ψ y := by + have l1 : Iio ((b - a) / 3) ∈ 𝓝[>] 0 := nhdsWithin_le_nhds <| Iio_mem_nhds <| by + rw [← sub_pos] at hab + positivity + filter_upwards [self_mem_nhdsWithin, l1] with ε (hε : 0 < ε) (hε' : ε < (b - a) / 3) + have l2 : a < a + ε / 2 := by simp [hε] + have l3 : b - ε / 2 < b := by simp [hε] + obtain ⟨ψ, h1, h2, h3, h4, h5⟩ := smooth_urysohn_support_Ioo l2 l3 + refine ⟨ψ, h1, h2, ?_, ?_, ?_⟩ + · simp [h5, hab.ne, Icc_subset_Ioi_iff hab.le, ha] + · exact h4.trans <| indicator_le_indicator_of_subset Ioo_subset_Ico_self (by simp) + · have l4 : 0 ≤ b - a - ε := by linarith + have l5 : Icc (a + ε / 2) (b - ε / 2) ⊆ Ioi 0 := by + intro t ht + simp only [mem_Icc, mem_Ioi] at ht ⊢ + exact ha.trans <| l2.trans_le <| ht.1 + have l6 : Icc (a + ε / 2) (b - ε / 2) ∩ Ioi 0 = Icc (a + ε / 2) (b - ε / 2) := + inter_eq_left.mpr l5 + have l7 : ∫ y in Ioi 0, indicator (Icc (a + ε / 2) (b - ε / 2)) 1 y = b - a - ε := by + simp only [measurableSet_Icc, integral_indicator_one, measureReal_restrict_apply, l6, + volume_real_Icc] + convert max_eq_left l4 using 1 ; ring_nf + have l8 : IntegrableOn ψ (Ioi 0) volume := + (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + rw [← l7] ; apply setIntegral_mono ?_ l8 h3 + rw [IntegrableOn, integrable_indicator_iff measurableSet_Icc] + apply IntegrableOn.mono ?_ subset_rfl Measure.restrict_le_self + apply integrableOn_const <;> + simp + +theorem interval_approx_sup (ha : 0 < a) (hab : a < b) : + ∀ᶠ ε in 𝓝[>] 0, ∃ ψ : ℝ → ℝ, ContDiff ℝ ∞ ψ ∧ HasCompactSupport ψ ∧ + closure (Function.support ψ) ⊆ Set.Ioi 0 ∧ + indicator (Ico a b) 1 ≤ ψ ∧ ∫ y in Ioi 0, ψ y ≤ b - a + ε := by + have l1 : Iio (a / 2) ∈ 𝓝[>] 0 := nhdsWithin_le_nhds <| Iio_mem_nhds (by linarith) + filter_upwards [self_mem_nhdsWithin, l1] with ε (hε : 0 < ε) (hε' : ε < a / 2) + have l2 : a - ε / 2 < a := by linarith + have l3 : b < b + ε / 2 := by linarith + obtain ⟨ψ, h1, h2, h3, h4, h5⟩ := smooth_urysohn_support_Ioo l2 l3 + refine ⟨ψ, h1, h2, ?_, ?_, ?_⟩ + · have l4 : a - ε / 2 < b + ε / 2 := by linarith + have l5 : ε / 2 < a := by linarith + simp [h5, l4.ne, Icc_subset_Ioi_iff l4.le, l5] + · apply le_trans ?_ h3 + apply indicator_le_indicator_of_subset Ico_subset_Icc_self (by simp) + · have l4 : 0 ≤ b - a + ε := by linarith + have l5 : Ioo (a - ε / 2) (b + ε / 2) ⊆ Ioi 0 := by intro t ht ; simp at ht ⊢ ; linarith + have l6 : Ioo (a - ε / 2) (b + ε / 2) ∩ Ioi 0 = Ioo (a - ε / 2) (b + ε / 2) := + inter_eq_left.mpr l5 + have l7 : ∫ y in Ioi 0, indicator (Ioo (a - ε / 2) (b + ε / 2)) 1 y = b - a + ε := by + simp only [measurableSet_Ioo, integral_indicator_one, measureReal_restrict_apply, l6, + volume_real_Ioo] + convert max_eq_left l4 using 1 ; ring_nf + have l8 : IntegrableOn ψ (Ioi 0) volume := + (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + rw [← l7] + refine setIntegral_mono l8 ?_ h4 + rw [IntegrableOn, integrable_indicator_iff measurableSet_Ioo] + apply IntegrableOn.mono ?_ subset_rfl Measure.restrict_le_self + apply integrableOn_const <;> + simp + +theorem WI_summable {f : ℕ → ℝ} {g : ℝ → ℝ} (hg : HasCompactSupport g) (hx : 0 < x) : + Summable (fun n => f n * g (n / x)) := by + obtain ⟨M, hM⟩ := hg.bddAbove.mono subset_closure + apply summable_of_hasFiniteSupport + unfold Function.HasFiniteSupport + simp only [Function.support_mul] ; apply Finite.inter_of_right ; rw [finite_iff_bddAbove] + exact ⟨Nat.ceil (M * x), fun i hi => by simpa using Nat.ceil_mono ((div_le_iff₀ hx).mp (hM hi))⟩ + +theorem WI_sum_le {f : ℕ → ℝ} {g₁ g₂ : ℝ → ℝ} (hf : 0 ≤ f) (hg : g₁ ≤ g₂) (hx : 0 < x) + (hg₁ : HasCompactSupport g₁) (hg₂ : HasCompactSupport g₂) : + (∑' n, f n * g₁ (n / x)) / x ≤ (∑' n, f n * g₂ (n / x)) / x := by + apply div_le_div_of_nonneg_right ?_ hx.le + exact Summable.tsum_le_tsum (fun n => mul_le_mul_of_nonneg_left (hg _) (hf _)) + (WI_summable hg₁ hx) (WI_summable hg₂ hx) + +theorem WI_sum_Iab_le {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hb : 0 < b) (hxb : 2 / b < x) : + (∑' n, f n * indicator (Ico a b) 1 (n / x)) / x ≤ C * 2 * b := by + have hb' : 0 < 2 / b := by positivity + have hx : 0 < x := by linarith + have hxb' : 2 < x * b := (div_lt_iff₀ hb).mp hxb + have l1 (i : ℕ) (hi : i ∉ Finset.range ⌈b * x⌉₊) : f i * indicator (Ico a b) 1 (i / x) = 0 := by + simp_all [le_div_iff₀ hx] + have l2 (i : ℕ) (_ : i ∈ Finset.range ⌈b * x⌉₊) : + f i * indicator (Ico a b) 1 (i / x) ≤ |f i| := by + rw [abs_eq_self.mpr (hpos _)] + convert_to _ ≤ f i * 1 + · ring + apply mul_le_mul_of_nonneg_left ?_ (hpos _) + by_cases hi : (i / x) ∈ (Ico a b) <;> simp [hi] + rw [tsum_eq_sum l1, div_le_iff₀ hx, mul_assoc, mul_assoc] + apply Finset.sum_le_sum l2 |>.trans + have := hcheby ⌈b * x⌉₊ ; simp only [norm_real, norm_eq_abs] at this ; apply this.trans + have : 0 ≤ C := by have := hcheby 1 ; simp only [cumsum, Finset.range_one, norm_real, + Finset.sum_singleton, Nat.cast_one, mul_one] at this ; exact (abs_nonneg _).trans this + refine mul_le_mul_of_nonneg_left ?_ this + apply (Nat.ceil_lt_add_one (by positivity)).le.trans + linarith + +theorem WI_sum_Iab_le' {f : ℕ → ℝ} (hpos : 0 ≤ f) {C : ℝ} + (hcheby : (∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hb : 0 < b) : + ∀ᶠ x : ℝ in atTop, (∑' n, f n * indicator (Ico a b) 1 (n / x)) / x ≤ C * 2 * b := by + filter_upwards [eventually_gt_atTop (2 / b)] with x hx using WI_sum_Iab_le hpos hcheby hb hx + +theorem le_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[>] b, a ≤ c) : a ≤ b := by + exact ge_of_tendsto + (show Tendsto (fun c : ℝ => c) (𝓝[>] b) (𝓝 b) from nhdsWithin_le_nhds) h + +theorem ge_of_eventually_nhdsWithin {a b : ℝ} (h : ∀ᶠ c in 𝓝[<] b, c ≤ a) : b ≤ a := by + exact le_of_tendsto + (show Tendsto (fun c : ℝ => c) (𝓝[<] b) (𝓝 b) from nhdsWithin_le_nhds) h + +theorem WI_tendsto_aux (a b : ℝ) {A : ℝ} (hA : 0 < A) : + Tendsto (fun c => c / A - (b - a)) (𝓝[>] (A * (b - a))) (𝓝[>] 0) := by + rw [Metric.tendsto_nhdsWithin_nhdsWithin] + intro ε hε + refine ⟨A * ε, by positivity, ?_⟩ + intro x hx1 hx2 + constructor + · simpa [lt_div_iff₀' hA] + · simp only [Real.dist_eq, dist_zero_right, Real.norm_eq_abs] at hx2 ⊢ + have : |x / A - (b - a)| = |x - A * (b - a)| / A := by + rw [← abs_eq_self.mpr hA.le, ← abs_div, abs_eq_self.mpr hA.le] ; congr ; field_simp + rwa [this, div_lt_iff₀' hA] + +theorem WI_tendsto_aux' (a b : ℝ) {A : ℝ} (hA : 0 < A) : + Tendsto (fun c => (b - a) - c / A) (𝓝[<] (A * (b - a))) (𝓝[>] 0) := by + rw [Metric.tendsto_nhdsWithin_nhdsWithin] + intro ε hε + refine ⟨A * ε, by positivity, ?_⟩ + intro x hx1 hx2 + constructor + · simpa [div_lt_iff₀' hA] + · simp only [Real.dist_eq, dist_zero_right, norm_eq_abs] at hx2 ⊢ + have : |(b - a) - x / A| = |A * (b - a) - x| / A := by + rw [← abs_eq_self.mpr hA.le, ← abs_div, abs_eq_self.mpr hA.le] ; congr ; field_simp + rwa [this, div_lt_iff₀' hA, ← neg_sub, abs_neg] + +theorem residue_nonneg {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm (fun n ↦ ↑(f n)) σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : EqOn G (fun s ↦ LSeries (fun n ↦ ↑(f n)) s - ↑A / (s - 1)) {s | 1 < s.re}) : + 0 ≤ A := by + let S (g : ℝ → ℝ) (x : ℝ) := (∑' n, f n * g (n / x)) / x + have hSnonneg {g : ℝ → ℝ} (hg : 0 ≤ g) : ∀ᶠ x : ℝ in atTop, 0 ≤ S g x := by + filter_upwards [eventually_ge_atTop 0] with x hx + exact div_nonneg (tsum_nonneg (fun i => mul_nonneg (hpos _) (hg _))) hx + obtain ⟨ε, ψ, h1, h2, h3, h4, -⟩ := (interval_approx_sup zero_lt_one one_lt_two).exists + have key := @wiener_ikehara_smooth_real A G f ψ hf hcheby hG hG' h1 h2 h3 + have l2 : 0 ≤ ψ := by apply le_trans _ h4 ; apply indicator_nonneg ; simp + have l1 : ∀ᶠ x in atTop, 0 ≤ S ψ x := hSnonneg l2 + have l3 : 0 ≤ A * ∫ (y : ℝ) in Ioi 0, ψ y := ge_of_tendsto key l1 + have l4 : 0 < ∫ (y : ℝ) in Ioi 0, ψ y := by + have r1 : 0 ≤ᵐ[Measure.restrict volume (Ioi 0)] ψ := Eventually.of_forall l2 + have r2 : IntegrableOn (fun y ↦ ψ y) (Ioi 0) volume := + (h1.continuous.integrable_of_hasCompactSupport h2).integrableOn + have r3 : Ico 1 2 ⊆ Function.support ψ := by + intro x hx ; have := h4 x ; simp [hx] at this ⊢ ; linarith + have r4 : Ico 1 2 ⊆ Function.support ψ ∩ Ioi 0 := by + simp only [subset_inter_iff, r3, + true_and] ; apply Ico_subset_Icc_self.trans ; rw [Icc_subset_Ioi_iff] <;> linarith + have r5 : 1 ≤ volume ((Function.support fun y ↦ ψ y) ∩ Ioi 0) := by + convert volume.mono r4 ; norm_num + simpa [setIntegral_pos_iff_support_of_nonneg_ae r1 r2] using zero_lt_one.trans_le r5 + have := div_nonneg l3 l4.le ; field_simp at this ; exact this + + + + + + + + + + + + + + +theorem WienerIkeharaInterval {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun x : ℝ ↦ (∑' n, f n * (indicator (Ico a b) 1 (n / x))) / x) + atTop (nhds (A * (b - a))) := by + + by_cases hab : a = b + · simp [hab] + replace hb : a < b := lt_of_le_of_ne hb hab ; clear hab + + let S (g : ℝ → ℝ) (x : ℝ) := (∑' n, f n * g (n / x)) / x + have hSnonneg {g : ℝ → ℝ} (hg : 0 ≤ g) : ∀ᶠ x : ℝ in atTop, 0 ≤ S g x := by + filter_upwards [eventually_ge_atTop 0] with x hx + refine div_nonneg ?_ hx + refine tsum_nonneg (fun i => mul_nonneg (hpos _) (hg _)) + have hA : 0 ≤ A := residue_nonneg hpos hf hcheby hG hG' + + let Iab : ℝ → ℝ := indicator (Ico a b) 1 + change Tendsto (S Iab) atTop (𝓝 (A * (b - a))) + have hIab : HasCompactSupport Iab := by + simpa [Iab, HasCompactSupport, tsupport, hb.ne] using isCompact_Icc + have Iab_nonneg : ∀ᶠ x : ℝ in atTop, 0 ≤ S Iab x := hSnonneg (indicator_nonneg (by simp)) + have Iab2 : IsBoundedUnder (· ≤ ·) atTop (S Iab) := by + obtain ⟨C, hC⟩ := hcheby ; exact ⟨C * 2 * b, WI_sum_Iab_le' hpos hC (by linarith)⟩ + have Iab3 : IsBoundedUnder (· ≥ ·) atTop (S Iab) := ⟨0, Iab_nonneg⟩ + have Iab0 : IsCoboundedUnder (· ≥ ·) atTop (S Iab) := Iab2.isCoboundedUnder_ge + have Iab1 : IsCoboundedUnder (· ≤ ·) atTop (S Iab) := Iab3.isCoboundedUnder_le + + have sup_le : limsup (S Iab) atTop ≤ A * (b - a) := by + have l_sup : ∀ᶠ ε in 𝓝[>] 0, limsup (S Iab) atTop ≤ A * (b - a + ε) := by + filter_upwards [interval_approx_sup ha hb] with ε happrox + rcases happrox with ⟨ψ, h1, h2, h3, h4, h6⟩ + have l1 : Tendsto (S ψ) atTop _ := wiener_ikehara_smooth_real hf hcheby hG hG' h1 h2 h3 + have l6 : S Iab ≤ᶠ[atTop] S ψ := by + filter_upwards [eventually_gt_atTop 0] with x hx using WI_sum_le hpos h4 hx hIab h2 + have l5 : IsBoundedUnder (· ≤ ·) atTop (S ψ) := l1.isBoundedUnder_le + have l3 : limsup (S Iab) atTop ≤ limsup (S ψ) atTop := limsup_le_limsup l6 Iab1 l5 + apply l3.trans ; rw [l1.limsup_eq] ; gcongr + obtain rfl | h := eq_or_ne A 0 + · simpa using l_sup + apply le_of_eventually_nhdsWithin + have key : 0 < A := lt_of_le_of_ne hA h.symm + filter_upwards [WI_tendsto_aux a b key l_sup] with x hx + simpa [mul_div_cancel₀ _ h] using hx + + have le_inf : A * (b - a) ≤ liminf (S Iab) atTop := by + have l_inf : ∀ᶠ ε in 𝓝[>] 0, A * (b - a - ε) ≤ liminf (S Iab) atTop := by + filter_upwards [interval_approx_inf ha hb] with ε happrox + rcases happrox with ⟨ψ, h1, h2, h3, h5, h6⟩ + have l1 : Tendsto (S ψ) atTop _ := wiener_ikehara_smooth_real hf hcheby hG hG' h1 h2 h3 + have l2 : S ψ ≤ᶠ[atTop] S Iab := by + filter_upwards [eventually_gt_atTop 0] with x hx using WI_sum_le hpos h5 hx h2 hIab + have l4 : IsBoundedUnder (· ≥ ·) atTop (S ψ) := l1.isBoundedUnder_ge + have l3 : liminf (S ψ) atTop ≤ liminf (S Iab) atTop := liminf_le_liminf l2 l4 Iab0 + apply le_trans ?_ l3 ; rw [l1.liminf_eq] ; gcongr + obtain rfl | h := eq_or_ne A 0 + · simpa using l_inf + apply ge_of_eventually_nhdsWithin + have key : 0 < A := lt_of_le_of_ne hA h.symm + filter_upwards [WI_tendsto_aux' a b key l_inf] with x hx + simpa [mul_div_cancel₀ _ h] using hx + + have : liminf (S Iab) atTop ≤ limsup (S Iab) atTop := liminf_le_limsup Iab2 Iab3 + refine tendsto_of_liminf_eq_limsup ?_ ?_ Iab2 Iab3 <;> linarith + + + +theorem le_floor_mul_iff (hb : 0 ≤ b) (hx : 0 < x) : n ≤ ⌊b * x⌋₊ ↔ n / x ≤ b := by + rw [div_le_iff₀ hx, Nat.le_floor_iff] ; positivity + +theorem lt_ceil_mul_iff (hx : 0 < x) : n < ⌈b * x⌉₊ ↔ n / x < b := by + rw [div_lt_iff₀ hx, Nat.lt_ceil] + +theorem ceil_mul_le_iff (hx : 0 < x) : ⌈a * x⌉₊ ≤ n ↔ a ≤ n / x := by + rw [le_div_iff₀ hx, Nat.ceil_le] + +theorem mem_Icc_iff_div (hb : 0 ≤ b) (hx : 0 < x) : + n ∈ Finset.Icc ⌈a * x⌉₊ ⌊b * x⌋₊ ↔ n / x ∈ Icc a b := by + rw [Finset.mem_Icc, mem_Icc, ceil_mul_le_iff hx, le_floor_mul_iff hb hx] + +theorem mem_Ico_iff_div (hx : 0 < x) : n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊ ↔ n / x ∈ Ico a b := by + rw [Finset.mem_Ico, mem_Ico, ceil_mul_le_iff hx, lt_ceil_mul_iff hx] + +theorem tsum_indicator {f : ℕ → ℝ} (hx : 0 < x) : + ∑' n, f n * (indicator (Ico a b) 1 (n / x)) = ∑ n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n := by + have l1 : ∀ n ∉ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n * indicator (Ico a b) 1 (↑n / x) = 0 := by + simp [mem_Ico_iff_div hx] ; tauto + rw [tsum_eq_sum l1] ; apply Finset.sum_congr rfl ; simp only + [mem_Ico_iff_div hx] ; intro n hn ; simp [hn] + +theorem WienerIkeharaInterval_discrete {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun x : ℝ ↦ (∑ n ∈ Finset.Ico ⌈a * x⌉₊ ⌈b * x⌉₊, f n) / x) + atTop (nhds (A * (b - a))) := by + apply (WienerIkeharaInterval hpos hf hcheby hG hG' ha hb).congr' + filter_upwards [eventually_gt_atTop 0] with x hx + rw [tsum_indicator hx] + +theorem WienerIkeharaInterval_discrete' {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) + (ha : 0 < a) (hb : a ≤ b) : + Tendsto (fun N : ℕ ↦ (∑ n ∈ Finset.Ico ⌈a * N⌉₊ ⌈b * N⌉₊, f n) / N) + atTop (nhds (A * (b - a))) := + WienerIkeharaInterval_discrete hpos hf hcheby hG hG' ha hb |>.comp tendsto_natCast_atTop_atTop + + + + + + + + + +theorem tendsto_mul_ceil_div : + Tendsto (fun (p : ℝ × ℕ) => ⌈p.1 * p.2⌉₊ / (p.2 : ℝ)) (𝓝[>] 0 ×ˢ atTop) (𝓝 0) := by + rw [Metric.tendsto_nhds] ; intro δ hδ + have l1 : ∀ᶠ ε : ℝ in 𝓝[>] 0, ε ∈ Ioo 0 (δ / 2) := + inter_mem_nhdsWithin _ (Iio_mem_nhds (by positivity)) + have l2 : ∀ᶠ N : ℕ in atTop, 1 ≤ δ / 2 * N := by + apply Tendsto.eventually_ge_atTop + exact tendsto_natCast_atTop_atTop.const_mul_atTop (by positivity) + filter_upwards [l1.prod_mk l2] with p hp + rcases p with ⟨ε, N⟩ + rcases hp with ⟨⟨hε, h1⟩, h2⟩ + dsimp only at * + have l3 : 0 < (N : ℝ) := by + simp only [Nat.cast_pos, Nat.pos_iff_ne_zero] ; rintro rfl ; simp [zero_lt_one.not_ge] at h2 + have l5 : 0 ≤ ε * ↑N := by positivity + have l6 : ε * N ≤ δ / 2 * N := mul_le_mul h1.le le_rfl (by positivity) (by positivity) + simp only [dist_zero_right, norm_div, RCLike.norm_natCast, div_lt_iff₀ l3, gt_iff_lt] + convert (Nat.ceil_lt_add_one l5).trans_le (add_le_add l6 h2) using 1 ; ring + + + +noncomputable def S (f : ℕ → 𝕜) (ε : ℝ) (N : ℕ) : 𝕜 := (∑ n ∈ Finset.Ico ⌈ε * N⌉₊ N, f n) / N + +theorem S_sub_S {f : ℕ → 𝕜} {ε : ℝ} {N : ℕ} (hε : ε ≤ 1) : + S f 0 N - S f ε N = cumsum f ⌈ε * N⌉₊ / N := by + have r1 : Finset.range N = Finset.range ⌈ε * N⌉₊ ∪ Finset.Ico ⌈ε * N⌉₊ N := by + simp_rw [Finset.range_eq_Ico] + symm + apply Finset.Ico_union_Ico_eq_Ico (Nat.zero_le _) + simp only [Nat.ceil_le] + exact mul_le_of_le_one_left N.cast_nonneg hε + have r2 : Disjoint (Finset.range ⌈ε * N⌉₊) (Finset.Ico ⌈ε * N⌉₊ N) := by + rw [Finset.range_eq_Ico] ; apply Finset.Ico_disjoint_Ico_consecutive + simp [S, r1, Finset.sum_union r2, cumsum, add_div] + +theorem tendsto_S_S_zero {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) : + TendstoUniformlyOnFilter (S f) (S f 0) (𝓝[>] 0) atTop := by + rw [Metric.tendstoUniformlyOnFilter_iff] ; intro δ hδ + obtain ⟨C, hC⟩ := hcheby + have l1 : ∀ᶠ (p : ℝ × ℕ) in 𝓝[>] 0 ×ˢ atTop, C * ⌈p.1 * p.2⌉₊ / p.2 < δ := by + have r1 := tendsto_mul_ceil_div.const_mul C + simp only [mul_div_assoc', mul_zero] at r1 ; exact r1 (Iio_mem_nhds hδ) + have : Ioc 0 1 ∈ 𝓝[>] (0 : ℝ) := inter_mem_nhdsWithin _ (Iic_mem_nhds zero_lt_one) + filter_upwards [l1, Eventually.prod_inl this _] with p h1 h2 + rcases p with ⟨ε, N⟩ + have l2 : ‖cumsum f ⌈ε * ↑N⌉₊ / ↑N‖ ≤ C * ⌈ε * N⌉₊ / N := by + have r1 := hC ⌈ε * N⌉₊ + have r2 : 0 ≤ cumsum f ⌈ε * N⌉₊ := by apply cumsum_nonneg hpos + simp only [norm_real, norm_of_nonneg (hpos _), norm_div, + norm_of_nonneg r2, Real.norm_natCast] at r1 ⊢ + apply div_le_div_of_nonneg_right r1 (by positivity) + simpa [dist_eq_norm, ← S_sub_S h2.2] using l2.trans_lt h1 + + + + + + + + + + +theorem WienerIkeharaTheorem' {f : ℕ → ℝ} (hpos : 0 ≤ f) + (hf : ∀ (σ' : ℝ), 1 < σ' → Summable (nterm f σ')) + (hcheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(f k : ℂ)‖) n ≤ C * n)) + (hG : ContinuousOn G {s | 1 ≤ s.re}) + (hG' : Set.EqOn G (fun s ↦ LSeries f s - A / (s - 1)) {s | 1 < s.re}) : + Tendsto (fun N => cumsum f N / N) atTop (𝓝 A) := by + convert_to Tendsto (S f 0) atTop (𝓝 A) ; · ext N ; simp [S, cumsum] + apply (tendsto_S_S_zero hpos hcheby).tendsto_of_eventually_tendsto + · have L0 : Ioc 0 1 ∈ 𝓝[>] (0 : ℝ) := inter_mem_nhdsWithin _ (Iic_mem_nhds zero_lt_one) + apply eventually_of_mem L0 + · intro ε hε + convert WienerIkeharaInterval_discrete' hpos hf hcheby hG hG' hε.1 hε.2 using 1 + funext N + simp only [S, one_mul, Nat.ceil_natCast] + · have : Tendsto (fun ε : ℝ => ε) (𝓝[>] 0) (𝓝 0) := nhdsWithin_le_nhds + simpa using (this.const_sub 1).const_mul A + +theorem vonMangoldt_cheby : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(Λ k : ℂ)‖) n ≤ C * n) := by + use Real.log 4 + 4 + intro N + by_cases! h : N = 0 + · simp [h, cumsum] + simp only [cumsum, norm_real, norm_eq_abs] + rw [Nat.range_eq_Icc_zero_sub_one _ h, (by simp : N - 1 = ⌊(N : ℝ) - 1⌋₊)] + simp_rw [abs_of_nonneg vonMangoldt_nonneg] + rw [← Chebyshev.psi_eq_sum_Icc] + grw [Chebyshev.psi_le_const_mul_self <| sub_nonneg_of_le <| Nat.one_le_cast_iff_ne_zero.mpr h] + gcongr + linarith + + + + + + + + + + + + + + + + + +theorem WeakPNT : Tendsto (fun N ↦ cumsum Λ N / N) atTop (𝓝 1) := by + let F := vonMangoldt.LFunctionResidueClassAux (q := 1) 1 + have l1 (n : ℕ) : 0 ≤ Λ n := vonMangoldt_nonneg + have l2 s (hs : 1 < s.re) : F s = LSeries Λ s - 1 / (s - 1) := by + have := vonMangoldt.eqOn_LFunctionResidueClassAux (q := 1) isUnit_one hs + simp only [F, this, vonMangoldt.residueClass, Nat.totient_one, Nat.cast_one, + inv_one, one_div, sub_left_inj] + apply LSeries_congr + intro n _ + simp only [ofReal_inj, indicator_apply_eq_self, Set.mem_ofPred_eq] + exact fun hn ↦ absurd (Subsingleton.eq_one _) hn + have l3 : ContinuousOn F {s | 1 ≤ s.re} := vonMangoldt.continuousOn_LFunctionResidueClassAux 1 + have l4 : (∃ C : ℝ, ∀ n : ℕ, cumsum (fun k : ℕ ↦ ‖(Λ k : ℂ)‖) n ≤ C * n) := vonMangoldt_cheby + have l5 (σ' : ℝ) (hσ' : 1 < σ') : Summable (nterm Λ σ') := by + simpa only [← nterm_eq_norm_term] + using (@ArithmeticFunction.LSeriesSummable_vonMangoldt σ' hσ').norm + apply WienerIkeharaTheorem' l1 l5 l4 l3 l2 + +end ZetaFivePNT diff --git a/lakefile.toml b/lakefile.toml index 2f3660d..71d9c89 100644 --- a/lakefile.toml +++ b/lakefile.toml @@ -1,17 +1,5 @@ name = "PrimeNumberTheoremAnd" -defaultTargets = ["PrimeNumberTheoremAnd"] - -[leanOptions] -pp.unicode.fun = true -pp.proofs.withType = false -autoImplicit = false -relaxedAutoImplicit = false -linter.mathlibStandardSet = true -linter.style.header = false -linter.style.openClassical = false -linter.style.longLine = false -linter.style.emptyLine = false -linter.flexible = true +defaultTargets = ["PrimeNumberTheoremAnd.Wiener", "PrimeNumberTheoremAndZetaFive"] [[require]] name = "LeanArchitect" @@ -39,3 +27,24 @@ rev = "v4.34.0" [[lean_lib]] name = "PrimeNumberTheoremAnd" +leanOptions = { autoImplicit = false } + +[[lean_lib]] +name = "PrimeNumberTheoremAndZetaFive" +roots = ["PrimeNumberTheoremAnd.ZetaFive"] +globs = ["PrimeNumberTheoremAnd.ZetaFive.*"] + +[[lean_lib]] +name = "PrimeNumberTheoremAndCatalan" +roots = ["PrimeNumberTheoremAnd.Catalan"] +globs = ["PrimeNumberTheoremAnd.Catalan.*"] + +[[lean_lib]] +name = "PrimeNumberTheoremAndSiegelZeros" +roots = ["PrimeNumberTheoremAnd.SiegelZeros.HadamardSupport"] +globs = ["PrimeNumberTheoremAnd.SiegelZeros.*"] + +[[lean_lib]] +name = "PrimeNumberTheoremAndErdos970" +roots = ["PrimeNumberTheoremAnd.Erdos970"] +globs = ["PrimeNumberTheoremAnd.Erdos970.*"] diff --git a/lean-toolchain b/lean-toolchain index 664e12d..ba8ebf2 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:v4.34.0 \ No newline at end of file +leanprover/lean4:v4.34.1 diff --git a/PrimeNumberTheoremAnd/IEANTN/Mertens.lean b/PrimeNumberTheoremAnd/IEANTN/Mertens.lean --- a/PrimeNumberTheoremAnd/IEANTN/Mertens.lean +++ b/PrimeNumberTheoremAnd/IEANTN/Mertens.lean @@ -14,7 +14,7 @@ import Mathlib.Analysis.SpecialFunctions.Log.Summable import Mathlib.Algebra.Group.Submonoid.BigOperators import PrimeNumberTheoremAnd.EulerMaclaurin -import Architect + theorem Filter.EventuallyEq.iff_eventually {α : Type _} {β : Type _} {l : Filter α} {f g : α → β} : f =ᶠ[l] g ↔ ∀ᶠ (x : α) in l, f x = g x := by rfl @@ -284,23 +284,23 @@ namespace Mertens -blueprint_comment /-- -\section{Mertens' theorems} - -In this section we give explicit versions of Mertens' theorems: -\begin{itemize} -\item Mertens' first theorem (von Mangoldt form): $\sum_{n \leq x} \frac{\Lambda(n)}{n} = \log x + O(1)$. -\item Mertens' first theorem (prime form): $\sum_{p \leq x} \frac{\log p}{p} = \log x + O(1)$. -\item Mertens' second theorem (von Mangoldt form): $\sum_{n \leq x} \frac{\Lambda(n)}{n \log n} = \log \log x + \gamma + O(1/\log x)$. -\item Mertens' second theorem (prime form): $\sum_{p \leq x} \frac{1}{p} = \log \log x + M + O(1/\log x)$, where $M$ is the Meissel-Mertens constant. -\item Mertens' third theorem: $\prod_{p \leq x} (1 - \frac{1}{p}) = e^{-\gamma}/\log x + O(1/\log^2 x)$. -\end{itemize} -We aim to upstreaming these results to Mathlib. In particular, the arguments here should be self-contained and written for efficiency, coherency, and clarity. As such, extensive use of AI tools is \emph{strongly discouraged} in this section. - -The arguments here are drawn from Leo Goldmakher's ``A quick proof of Mertens' theorem'' from https://web.williams.edu/Mathematics/lg5/mertens.pdf - -The unfinished formalization of Mertens' theorems by Arend Mellendijk in https://github.com/FLDutchmann/Analytic/blob/main/Analytic/Mertens.lean may also be relevant here. --/ + + + + + + + + + + + + + + + + + open Real Finset Filter Asymptotics Topology @@ -311,17 +311,17 @@ rw [(by rfl : Ioc 0 x = Icc 1 x), ← add_sum_Ioc_eq_sum_Icc hx] simpa -@[blueprint - "Mertens-sum-log" - (title := "Partial sum of logarithm identity") - (statement := /-- For any $x \geq 1$, one has -$$ \sum_{n \leq x} \log n = x \log x - (\{ x \}-1/2) \log x - x + 1 + \int_1^x (\{ t \}-1/2) \frac{dt}{t} $$ -(NOTE: this identity is not actually needed in the proof of Mertens' theorems, but may be worth recording nevertheless.) - -/) - (proof := /-- Apply the Euler-Maclaurin formula. - -/) - (latexEnv := "lemma") - (discussion := 1303)] + + + + + + + + + + + theorem sum_log_eq {x : ℝ} (hx : 1 ≤ x) : ∑ n ∈ Ioc 0 ⌊ x ⌋₊, log n = x * log x - (x - ⌊x⌋₊ - 1 / 2) * log x - x + 1 + ∫ t in 1..x, (t - ⌊t⌋₊ - 1 / 2) / t := by @@ -339,16 +339,16 @@ · simp only [deriv_log', Set.uIcc_of_le hx] fun_prop (disch := grind) -@[blueprint - "Mertens-sum-log-le" - (title := "Partial sum of logarithm upper bound") - (statement := /-- For any $x \geq 1$, one has -$$ \sum_{n \leq x} \log n \leq x \log x.$$ - -/) - (proof := /-- Trivial since $\log n \leq \log x$. - -/) - (latexEnv := "lemma") - (discussion := 1304)] + + + + + + + + + + theorem sum_log_le {x : ℝ} (hx : 1 ≤ x) : ∑ n ∈ Ioc 0 ⌊ x ⌋₊, log n ≤ x * log x := by calc @@ -374,25 +374,25 @@ grw [← norm_eq_abs, intervalIntegral.norm_integral_le_of_norm_le_const this, abs_of_nonneg (by linarith)] -@[blueprint - "Mertens-sum-log-ge" - (title := "Partial sum of logarithm lower bound") - (statement := /-- For any $x \geq 1$, one has -$$ \sum_{n \leq x} \log n \geq x \log x - 2 x.$$ - -/) - (proof := /-- We have - \begin{align*} - \sum_{n \leq x} \log n &= \sum_{2 \leq n \leq \lfloor x \rfloor} \log n \\ - &\geq \sum_{2 \leq n \leq \lfloor x \rfloor} \int_{n-1}^n \log t \, dt \\ - &= \int_1^{\lfloor x \rfloor} \log t \, dt \\ - &\geq \int_1^x \log t\ dt - \log x \\ - &= x \log x - x - \log x \\ - &\geq x \log x - 2 x. -\end{align*} -Here we use the monotonicity of $\log n$ (and its vanishing at $n=1$) and the crude bound $\log x \leq x$. Note: the tools at Mathlib.Analysis.SumIntegralComparisons may be useful. - -/) - (latexEnv := "corollary") - (discussion := 1305)] + + + + + + + + + + + + + + + + + + + theorem sum_log_ge {x : ℝ} (hx : 1 ≤ x) : ∑ n ∈ Ioc 0 ⌊ x ⌋₊, log n ≥ x * log x - 2 * x := by have one_le_floor : 1 ≤ ⌊x⌋₊ := by simpa @@ -422,16 +422,16 @@ tsub_le_iff_right, sub_add_cancel, le_add_iff_nonneg_right, zero_le_one] _ ≥ _ := by linarith [log_le_self (by linarith : 0 ≤ x)] -@[blueprint - "Mertens-sum-log-eq-log-factorial" - (title := "Partial sum of logarithm as logarithm of factorial") - (statement := /-- For any $x \geq 1$, one has -$$ \sum_{n \leq x} \log n = \log(\lfloor x \rfloor!). $$ - -/) - (proof := /-- Follows from the definition of the factorial function. Is not needed for the Mertens theorems, but is a natural fact to have. - -/) - (latexEnv := "proposition") - (discussion := 1315)] + + + + + + + + + + theorem sum_log_eq_log_factorial (x : ℝ) : ∑ n ∈ Ioc 0 ⌊ x ⌋₊, log n = log (Nat.floor x).factorial := by rw [←prod_Ico_id_eq_factorial, ←log_prod, prod_natCast] @@ -439,47 +439,47 @@ intro x hx simp at hx ⊢; grind -@[blueprint - "Mertens-sum-log-eq-sum-mangoldt" - (title := "Partial sum of logarithm as sum of $\\Lambda(d)/d$") - (statement := /-- For any real $x$, one has -$$ \sum_{n \leq x} \log n = \sum_{d \leq x} \Lambda(d) \lfloor \frac{x}{d} \rfloor.$$ --/) - (proof := /-- We have -\begin{align*} -\sum_{n \leq x} \log n -&= \sum_{n \leq x} \sum_{d \mid n} \Lambda(d) -= \sum_{d \leq x} \Lambda(d) \sum_{n \leq x, d \mid n} 1 -= \sum_{d \leq x} \Lambda(d) \left\lfloor \frac{x}{d} \right\rfloor. -\end{align*} - -/) - (latexEnv := "lemma") - (discussion := 1306)] + + + + + + + + + + + + + + + + theorem sum_log_eq_sum_mangoldt {x : ℝ} : ∑ n ∈ Ioc 0 ⌊x⌋₊, log n = ∑ d ∈ Ioc 0 ⌊x⌋₊, Λ d * ⌊x / d⌋₊ := by have : ∀ n : ℕ, log n = (Λ * zeta) n := by simp [vonMangoldt_mul_zeta] simp_rw [this, sum_Ioc_mul_zeta_eq_sum, ← Nat.floor_div_natCast] -@[blueprint - "Mertens-first-error-mangoldt" - (title := "The remainder term in Mertens first theorem (von Mangoldt form)") - (statement := /-- We define $E_{1,\Lambda}(x) := \sum_{d \leq x} \frac{\Lambda(d)}{d} - \log x$. --/)] + + + + + noncomputable abbrev E₁Λ (x : ℝ) : ℝ := ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / d - log x theorem sum_mangoldt_div_eq (x : ℝ) : ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / d = log x + E₁Λ x := by grind -@[blueprint - "Mertens-first-error-mangoldt-ge" - (title := "Partial sum of $\\Lambda(d)/d$ lower bound") - (statement := /-- For any $x \geq 1$, one has -$$ E_{1,\Lambda}(x) \geq - 2.$$ --/) - (proof := /-- Insert Lemma \ref{Mertens-sum-log-eq-sum-mangoldt} into Lemma \ref{Mertens-sum-log-ge} and lower bound $x/d$ by $\lfloor x/d \rfloor$. - -/) - (latexEnv := "corollary") - (discussion := 1307)] + + + + + + + + + + theorem E₁Λ.ge {x : ℝ} (hx : 1 ≤ x) : E₁Λ x ≥ -2 := by unfold E₁Λ @@ -498,16 +498,16 @@ -@[blueprint - "Mertens-first-error-mangoldt-le" - (title := "Partial sum of $\\Lambda(d)/d$ upper bound") - (statement := /-- For any $x \geq 1$, one has -$$ E_{1,\Lambda}(x) \leq \log 4 + 4.$$ --/) - (proof := /-- Insert Lemma \ref{Mertens-sum-log-eq-sum-mangoldt} into Lemma \ref{Mertens-sum-log-le} and upper bound $x/d$ by $\lfloor x/d \rfloor + 1$, and use the Mathlib bound $\psi(x) \leq (\log 4 + 4) x$. - -/) - (latexEnv := "corollary") - (discussion := 1308)] + + + + + + + + + + theorem E₁Λ.le {x : ℝ} (hx : 1 ≤ x) : E₁Λ x ≤ log 4 + 4 := by unfold E₁Λ @@ -529,16 +529,16 @@ · exact Chebyshev.psi_le_const_mul_self (by linarith) _ = _ := by ring -@[blueprint - "Mertens-first-theorem-mangoldt" - (title := "Mertens' first theorem (von Mangoldt form)") - (statement := /-- For any $x \geq 1$, one has -$$ \sum_{n \leq x} \frac{\Lambda(n)}{n} = \log x + O(1). $$ --/) - (proof := /-- Immediate from previous two corollaries. - -/) - (latexEnv := "corollary") - (discussion := 1309)] + + + + + + + + + + theorem sum_mangoldt_div_eq_log {x : ℝ} (hx : 1 ≤ x) : |∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / d - log x| ≤ log 4 + 4 := by grind [E₁Λ.le hx, E₁Λ.ge hx, log_nonneg] @@ -548,9 +548,9 @@ -@[blueprint - "Mertens-first-error-mangoldt" - (discussion := 1309)] + + + theorem E₁Λ.bounded : E₁Λ =O[atTop] (fun _ ↦ (1:ℝ)) := by simp only [isBigO_iff, norm_eq_abs, norm_one, mul_one, eventually_atTop] @@ -560,34 +560,34 @@ simp only [isLittleO_one_left_iff, norm_eq_abs] exact tendsto_abs_atTop_atTop.comp tendsto_log_atTop -@[blueprint - "Mertens-first-error-mangoldt" - (discussion := 1309)] + + + theorem sum_mangoldt_div_eq_log' : (fun x ↦ ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / d) ~[atTop] (fun x ↦ log x) := by apply IsLittleO.isEquivalent (IsBigO.trans_isLittleO _ one_eq_o_log) convert! E₁Λ.bounded using 1 -@[blueprint - "Mertens-first-error-prime" - (title := "The remainder term in Mertens first theorem (prime form)") - (statement := /-- We define $E_{1,p}(x) := \sum_{p \leq x} \frac{\log p}{p} - \log x$. --/)] + + + + + noncomputable abbrev E₁p (x : ℝ) : ℝ := ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (log p) / p - log x theorem sum_log_prime_div_eq (x : ℝ) : ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (log p) / p = log x + E₁p x := by grind -@[blueprint - "Mertens-first-error-prime-le-mangoldt" - (title := "Prime error for Mertens first theorem bounded by von Mangoldt error") - (statement := /-- For any $x \geq 1$, one has -$$ E_{1,p}(x) \leq E_{1,\Lambda}(x). $$ --/) - (proof := /-- Drop all terms in Lemma \ref{Mertens-sum-log-eq-sum-mangoldt} arising from prime powers. - -/) - (latexEnv := "corollary") - (discussion := 1311)] + + + + + + + + + + theorem E₁p.le_E₁Λ (x : ℝ) : E₁p x ≤ E₁Λ x := by unfold E₁p E₁Λ; rw [sum_filter] @@ -597,15 +597,15 @@ have : 0 ≤ Λ p := vonMangoldt_nonneg positivity -@[blueprint - "Mertens-first-error-prime-le" - (title := "Partial sum of $\\frac{\\log p}{p}$ upper bound") - (statement := /-- For any $x \geq 1$, one has -$$ E_{1,p}(x) \leq \log 4 + 4.$$ --/) - (proof := /-- Drop all terms in Lemma \ref{Mertens-sum-mangoldt-div-le} arising from prime powers. - -/) - (latexEnv := "corollary")] + + + + + + + + + theorem E₁p.le {x : ℝ} (hx : 1 ≤ x) : E₁p x ≤ log 4 + 4 := by linarith [E₁Λ.le hx, E₁p.le_E₁Λ x] @@ -619,14 +619,14 @@ exact_mod_cast h.one_le · rfl -@[blueprint - "E1_summable" - (title := "$E_1$ summable") - (statement := /-- The series $E_1 := \sum_p \frac{\log p}{p(p-1)}$ converges. -/) - (proof := /-- We have $\sum_{n=2}^\infty \frac{\log n}{n(n-1)}$ converges by comparison with $\sum_{n=2}^\infty \frac{2\log n}{n^2}$, which converges by the integral test. By a further application of comparison test we can conclude that $E_1$ converges as well. - Alternatively bound $\log n$ by $2\sqrt n$ and use the existing Mathlib API for $\sum n^{-3/2}$.-/) - (latexEnv := "proposition") - (discussion := 1352)] + + + + + + + + theorem E₁.summable : Summable (fun p : ℕ ↦ if p.Prime then (log p) / (p*(p-1)) else 0) := by refine (Real.summable_one_div_nat_rpow.mpr (by norm_num: 1 < (3 : ℝ) / 2)|>.const_div 4).of_nonneg_of_le E₁.summand_nonneg fun n ↦ ?_ @@ -733,13 +733,13 @@ _ = _ := by exact integral_log_div_sq -@[blueprint - "E1_bound" - (title := "Upper bound on $E_1$") - (statement := /-- One has $E_1 \leq \frac{5 \log 2 + 3}{4}$-/) - (proof := /-- We can bound $E_1 \leq \sum_{n=2}^\infty \frac{\log n}{n(n-1)} \leq \frac{\log 2}{2} + \frac{3}{2} \sum_{n=3}^\infty \frac{\log n}{n^2}$. Calculus shows that $\log x / x^2$ is decreasing for $x \geq 2 > e^{1/2}$, so we can bound $\sum_{n=3}^\infty \frac{\log n}{n^2} \leq \int_2^\infty \frac{\log t}{t^2}\ dt = \frac{\log 2+1}{2}$.-/) - (latexEnv := "proposition") - (discussion := 1316)] + + + + + + + theorem E₁.le : E₁ ≤ (5 * log 2 + 3) / 4 := by unfold E₁ calc @@ -769,20 +769,20 @@ theorem E₁.nonneg : E₁ ≥ 0 := tsum_nonneg E₁.summand_nonneg -@[blueprint - "Mertens-first-error-prime-ge" - (title := "Partial sum of $\\frac{\\log p}{p}$ lower bound") - (statement := /-- For any $x \geq 1$, one has -$$ E_{1,\Lambda}(x) \leq E_{1,p}(x) + E_1$$ -and thus -$$ E_{1,p}(x) \geq -2 - E_1$$ -where -$$ E_1 := \sum_{p} \frac{\log p}{p(p-1)}. $$ --/) - (proof := /-- Use the triangle inequality and the geometric series formula to estimate in Lemma \ref{Mertens-sum-mangoldt-div-le} arising from prime powers. - -/) - (latexEnv := "corollary") - (discussion := 1312)] + + + + + + + + + + + + + + theorem E₁Λ.le_E₁p_add_E₁ {x : ℝ} (hx : 1 ≤ x) : E₁Λ x ≤ E₁p x + E₁ := by unfold E₁Λ E₁p @@ -831,15 +831,15 @@ linarith [E₁Λ.le_E₁p_add_E₁ hx, E₁Λ.ge hx] -@[blueprint - "Mertens-first-theorem-prime-bounded" - (title := "Error term in Mertens' first theorem bounded (prime form)") - (statement := /-- For any $x \geq 1$, one has -$$ \sum_{p \leq x} \frac{\log p}{p} = \log x + O(1). $$ --/) - (proof := /-- Immediate from previous two corollaries. - -/) - (discussion := 1313)] + + + + + + + + + theorem sum_log_prime_div_eq_log {x : ℝ} (hx : 1 ≤ x) : |∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (log p) / p - log x| ≤ log 4 + 4 := by rw [abs_le'] @@ -851,31 +851,31 @@ theorem E₁p.bounded : ∃ c > 0, ∀ x ≥ 1, |E₁p x| ≤ c := by exact ⟨log 4 + 4, (by positivity), fun _ hx ↦ sum_log_prime_div_eq_log hx⟩ -@[blueprint - "Mertens-first-theorem-prime-bounded"] + + theorem sum_log_prime_div_eq_log' : E₁p =O[atTop] (fun _ ↦ (1:ℝ)) := by simp only [isBigO_iff, norm_eq_abs, one_mem, CStarRing.norm_of_mem_unitary, mul_one, eventually_atTop, E₁p] exact ⟨ log 4 + 4, 1, fun _ ↦ sum_log_prime_div_eq_log ⟩ -@[blueprint - "Mertens-first-theorem-prime-bounded"] + + theorem sum_log_prime_div_eq_log'' : (fun x ↦ ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (log p) / p) ~[atTop] (fun x ↦ log x) := by apply IsLittleO.isEquivalent (IsBigO.trans_isLittleO _ one_eq_o_log) convert! sum_log_prime_div_eq_log' using 1 -@[blueprint - "Euler-Mascheroni-const-alt" - (title := "Alternate Formula for Euler-Mascheroni constant") - (statement := /-- We set $\gamma := \int_2^\infty \frac{E_{1,\Lambda}(t)}{t \log^2 t} \, dt + 1 - \log \log 2$. --/)] + + + + + noncomputable abbrev γ : ℝ := (∫ t in Set.Ioi 2, E₁Λ t / (t * log t^2)) + 1 - log (log 2) -@[blueprint - "Mertens-second-error-mangoldt" - (title := "The remainder term in Mertens second theorem (von Mangoldt form)") - (statement := /-- We define $E_{2,\Lambda}(x) := \sum_{d \leq x} \frac{\Lambda(d)}{d \log d} - \log \log x - \gamma$. --/)] + + + + + noncomputable abbrev E₂Λ (x : ℝ) : ℝ := ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d) - log (log x) - γ lemma sum_Ioc_one_eq_sum_Icc_zero {f : ℕ → ℝ} {x : ℕ} (hx : 1 ≤ x) (hf1 : f 1 = 0) (hf0 : f 0 = 0) : @@ -883,17 +883,17 @@ rw [sum_Ioc_one_eq_sum_Ioc_zero hx hf1, ← add_sum_Ioc_eq_sum_Icc (by linarith)] simpa -@[blueprint - "Mertens-integral-ident" - (title := "Integral identity involving inverse log weight") - (statement := /-- For any $x \geq 2$ and any $f : {\mathbb N} \mapsto {\mathbb R}$, one has -$$ \sum_{2 \leq n \leq x} \frac{f(n)}{\log n} = \frac{1}{\log x} \sum_{2 \leq n \leq x} f(n) + \int_2^x \frac{1}{t \log^2 t} \sum_{2 \leq n \leq t} f(n) \, dt$$-/) - (proof := /-- Establish the identity - $$ \frac{1}{\log n} = \frac{1}{\log x} + \int_2^x \frac{1}{t \log^2 t} 1_{t \geq n}\ dt$$ - for $2 \leq n \leq x$,multiply by $f(n)$, then sum. - - -/) - (latexEnv := "sublemma")] + + + + + + + + + + + private theorem sum_div_log_eq {x : ℝ} (hx : 2 ≤ x) (f : ℕ → ℝ) : ∑ n ∈ Ioc 1 ⌊ x ⌋₊, f n / log n = (∑ n ∈ Ioc 1 ⌊ x ⌋₊, f n) / log x + ∫ t in 2..x, (∑ n ∈ Ioc 1 ⌊ t ⌋₊, f n) / (t * log t^2) := by @@ -1008,19 +1008,19 @@ have : log t ≠ 0 := by simp; grind fun_prop (disch := grind) -@[blueprint - "Mertens-second-error-mangoldt-eq" - (title := "Integral form for second error (von Mangoldt form)") - (statement := /-- For any $x \geq 2$, one has -$$ E_{2,\Lambda}(x) = \frac{E_{1,\Lambda}(x)}{\log x} - \int_x^\infty \frac{E_{1,\Lambda}(t)}{t \log^2 t}\ dt$$ --/) - (proof := /-- -From Lemma \ref{Mertens-integral-ident} one has -$$ \sum_{n \leq x} \frac{\Lambda(n)}{n \log n} = \frac{1}{\log x} \sum_{n \leq x} \frac{\Lambda(n)}{n} + \int_2^x \frac{1}{t \log^2 t} \sum_{n \leq t} \frac{\Lambda(n)}{n} \, dt.$$ -Now substitute the definitions of $E_{1,\Lambda}$, $E_{2,\Lambda}$, $\gamma$ and simplify. - -/) - (latexEnv := "corollary") - (discussion := 1317)] + + + + + + + + + + + + + theorem E₂Λ.eq {x : ℝ} (hx : 2 ≤ x) : E₂Λ x = E₁Λ x / log x - ∫ t in Set.Ioi x, E₁Λ t / (t * log t^2) := by unfold E₂Λ @@ -1058,17 +1058,17 @@ convert! tendsto_log_atTop.inv_tendsto_atTop.const_mul (-c) using 1 simp -@[blueprint - "Mertens-second-error-mangoldt-bound" - (title := "Bound for second Mertens error (von Mangoldt form)") - (statement := /-- For any $x \geq 2$, one has -$$ |E_{2,\Lambda}(x)| \leq \frac{\log 4 + 6}{\log x}.$$ --/) - (proof := /-- - Insert Lemma \ref{Mertens-first-error-mangoldt-le} and Lemma \ref{Mertens-first-error-mangoldt-ge} into Lemma \ref{Mertens-second-error-mangoldt-eq} and use the triangle inequality to obtain the required upper and lower bounds. - -/) - (latexEnv := "corollary") - (discussion := 1318)] + + + + + + + + + + + theorem E₂Λ.abs_le {x : ℝ} (hx : 2 ≤ x) : |E₂Λ x| ≤ (log 4 + 6) / log x := by have : 0 < log x := by apply log_pos; linarith @@ -1100,8 +1100,8 @@ grind -@[blueprint - "Mertens-second-error-mangoldt-bound"] + + theorem E₂Λ.bound : E₂Λ =O[atTop] (fun x ↦ 1 / log x) := by simp only [one_div, isBigO_iff, norm_eq_abs, norm_inv, eventually_atTop] use log 4 + 6, 2 @@ -1110,22 +1110,22 @@ have : 0 < log x := by apply log_pos; linarith grind [abs_of_pos this] -@[blueprint - "Mertens-second-error-mangoldt-bound"] + + theorem E₂Λ.bound' : E₂Λ =o[atTop] (fun _ ↦ (1:ℝ)) := E₂Λ.bound.trans_isLittleO inv_log_eq_o_one -@[blueprint - "log-zeta-eq-1" - (title := "Dirichlet series for $\\log \\zeta(s)$") - (statement := /-- If $s > 1$ then $\log\zeta(s) = - \log (s-1) + \Gamma'(1) + \gamma + (s-1) \int_1^\infty E_{2,\Lambda}(x) x^{-s}\ ds$. --/) - (proof := /-- First use the fundamental theorem of calculus and decay of $\log \zeta(s)$ to write - $$ \log \zeta(s) = \int_s^\infty -\frac{\zeta'(u)}{\zeta(u)}\ du.$$ - Then substitute in the known identity - $-\frac{\zeta'(u)}{\zeta(u)} = \sum_n \frac{\Lambda(n)}{n^u}$ and integrate term by term. - -/) - (latexEnv := "sublemma") - (discussion := 1582)] + + + + + + + + + + + + theorem log_zeta_eq_sum (s : ℝ) (hs : 1 < s) : log (riemannZeta (s:ℂ)).re = ∑' n, Λ n / (n^s * log n) := by have hsc : (1 : ℝ) < ((s : ℂ)).re := by simpa using hs @@ -1449,41 +1449,41 @@ end LogZetaInteg end -@[blueprint - "log-zeta-eq-2" - (title := "Integration by parts identity for $\\log \\zeta(s)$") - (statement := /-- If $s > 1$ then $\log\zeta(s) = (s-1) \int_1^\infty (\log \log x + \gamma + E_{2,\Lambda}(x)) x^{-s})\ dx$. --/) - (proof := /-- Apply the preceding identity then integrate by parts. - -/) - (latexEnv := "sublemma") - (discussion := 1583)] + + + + + + + + + private theorem log_zeta_eq_integ (s : ℝ) (hs : 1 < s) : log (riemannZeta (s:ℂ)).re = (s - 1) * ∫ x in .Ioi 1, (log (log x) + γ + E₂Λ x) * x^(-s) := LogZetaInteg.log_zeta_eq_integ_aux s hs -@[blueprint - "log-zeta-eq-3" - (title := "First integral identity") - (statement := /-- If $s > 1$ then $(s-1) \int_1^\infty \log \log x \cdot x^{-s}\ dx = -\log (s-1) + \Gamma'(1)$. --/) - (proof := /-- Writing $t = \log x$, the LHS is $(s-1) \int_0^\infty \log t e^{-(s-1) t}\ dt$. Now differentiate $\Gamma(z) = (s-1)^z \int_0^\infty t^{z-1} e^{-(s-1)t}\ dt$ in $z$ at $z=1$. - -/) - (latexEnv := "sublemma") - (discussion := 1584)] + + + + + + + + + private theorem mul_integ_log_log_eq (s : ℝ) (hs : 1 < s) : (s - 1) * ∫ x in .Ioi 1, log (log x) * x^(-s) = - log (s - 1) + deriv Gamma 1 := mul_integ_log_log_eq_aux s hs -@[blueprint - "log-zeta-eq-4" - (title := "Second integral identity") - (statement := /-- If $s > 1$ then $(s-1) \int_1^\infty \gamma \cdot x^{-s}\ dx = \gamma$. --/) - (proof := /-- Apply the fundamental theorem of calculus. - -/) - (latexEnv := "sublemma") - (discussion := 1585)] + + + + + + + + + private theorem mul_integ_gamma_eq (s) (hs : 1 < s) : (s - 1) * ∫ x in .Ioi 1, γ * x^(-s) = γ := by rw [MeasureTheory.integral_const_mul γ (· ^ (-s)), @integral_Ioi_rpow_of_lt (-s), one_rpow] <;> grind @@ -1600,14 +1600,14 @@ div_le_div_of_nonneg_left hc hlog2 (Real.log_le_log (by norm_num) (le_of_lt hx)) exact (E₂Λ.abs_le (le_of_lt hx)).trans hb2 -@[blueprint - "log-zeta-eq" - (title := "An identity for $\\log \\zeta(s)$") - (statement := /-- If $s > 1$ then $\log\zeta(s) = - \log (s-1) + \Gamma'(1) + \gamma + (s-1) \int_1^\infty E_{2,\Lambda}(x) x^{-s}\ ds$. --/) - (proof := /-- Combine the previous four sublemmas.-/) - (latexEnv := "theorem") - (discussion := 1319)] + + + + + + + + private theorem log_zeta_eq (s : ℝ) (hs : 1 < s) : log (riemannZeta (s:ℂ)).re = - log (s - 1) + deriv Gamma 1 + γ + (s - 1) * ∫ x in Set.Ioi 1, E₂Λ x * x^(-s) := by -- Start from the integration-by-parts identity (#1583). @@ -1652,15 +1652,15 @@ (Complex.continuous_re.tendsto (1 : ℂ)).comp hcomplex simpa [Complex.ofReal_sub, Complex.ofReal_mul] using hreal -@[blueprint - "log-zeta-limit" - (title := "limiting behavior of log zeta") - (statement := /-- One has $\log \zeta(s) = - \log(s-1) + o(1)$ as $s \to 1^+$. --/) - (proof := /-- Start with the asymptotic $\zeta(s) = \frac{1}{s-1} + O(1)$ and take logarithms. - -/) - (latexEnv := "sublemma") - (discussion := 1586)] + + + + + + + + + private theorem log_zeta_limit : Filter.Tendsto (fun s : ℝ => Real.log (riemannZeta (s : ℂ)).re + Real.log (s - 1)) @@ -1895,14 +1895,14 @@ end -@[blueprint - "Euler-Mascheroni-eq" - (title := "Compatibility with Mathlib Euler-Mascheroni constant") - (statement := /-- $\gamma$ is the Euler--Mascheroni constant. --/) - (proof := /-- Take limits as $s \to 1$ in the previous asymptotic using known asymptotics for $\zeta(s)$, and using that $- \Gamma'(1)$ is the Euler--Mascheroni constant. -/) - (latexEnv := "theorem") - (discussion := 1320)] + + + + + + + + theorem deriv_gamma_add_γ_eq_zero : deriv Gamma 1 + γ = 0 := by -- For `s > 1`, `log_zeta_eq` rearranges to a constant identity. have key : ∀ s : ℝ, 1 < s → @@ -1930,15 +1930,15 @@ theorem sum_mangoldt_div_log_eq (x : ℝ) : ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d) = log (log x) + eulerMascheroniConstant + E₂Λ x := by grind [γ.eq_eulerMascheroni] -@[blueprint - "Mertens-second-theorem-mangoldt-weak" - (title := "Mertens' second theorem (weak von Mangoldt form)") - (statement := /-- For any $x \geq 2$, one has -$$ \sum_{n \leq x} \frac{\Lambda(n)}{n \log n} = \log \log x + O(1). $$ --/) - (proof := /-- Immediate from previous two corollaries. - -/) - (discussion := 1321)] + + + + + + + + + theorem sum_mangoldt_div_log_eq_log_log : ∃ C, ∀ x, 2 ≤ x → |∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d) - log (log x)| ≤ C := by use (log 4 + 6)/log 2 + |eulerMascheroniConstant| @@ -1949,8 +1949,8 @@ _ ≤ (log 4 + 6)/log x + |eulerMascheroniConstant| := by grw [abs_add_le, E₂Λ.abs_le hx] _ ≤ _ := by gcongr -@[blueprint - "Mertens-second-theorem-mangoldt-weak"] + + theorem sum_mangoldt_div_log_eq_log_log' : (fun x ↦ ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d) - log (log x)) =O[atTop] (fun _ ↦ (1:ℝ)) := by simp only [isBigO_iff, norm_eq_abs, one_mem, CStarRing.norm_of_mem_unitary, mul_one, eventually_atTop] @@ -1958,27 +1958,27 @@ use C, 2 -@[blueprint - "Mertens-second-theorem-mangoldt-weak"] + + theorem sum_mangoldt_div_log_eq_log_log'' : (fun x ↦ ∑ d ∈ Ioc 0 ⌊ x ⌋₊, (Λ d) / (d * log d)) ~[atTop] (fun x ↦ log (log x)) := by apply IsLittleO.isEquivalent (IsBigO.trans_isLittleO _ one_eq_o_log_log) convert! sum_mangoldt_div_log_eq_log_log' using 1 -@[blueprint - "Meissel-Mertens-constant" - (title := "The Meissel-Mertens constant") - (statement := /-- We define $M := \int_2^\infty \frac{E_{1,p}(t)}{t \log^2 t} \, dt + 1 - \log \log 2$.-/)] + + + + noncomputable def M : ℝ := (∫ t in Set.Ioi 2, E₁p t / (t * log t^2)) + 1 - log (log 2) -@[blueprint - "Mertens-second-constant-prime-le" - (title := "Upper bound for $M$") - (statement := /-- One has $M \leq \frac{\log 4 + 4}{\log 2} + 1 - \log \log 2$. --/) - (proof := /-- Insert Lemma \ref{Mertens-first-error-prime-le} into the definition of $M$ and use the fact that $\int_2^\infty \frac{dt}{t \log^2 t} = 1/\log 2$. - -/) - (latexEnv := "corollary") - (discussion := 1323)] + + + + + + + + + theorem M.le : M ≤ (log 4 + 4) / log 2 + 1 - log (log 2) := calc _ ≤ (∫ t in Set.Ioi 2, (log 4 + 4) / (t * log t^2)) + 1 - log (log 2) := by unfold M; gcongr with x hx @@ -1989,15 +1989,15 @@ simp at hx; exact E₁p.le (by linarith) _ = _ := by rw [integ_div_mul_log_sq _ (by norm_num)] -@[blueprint - "Mertens-second-constant-prime-ge" - (title := "Lower bound for $M$") - (statement := /-- One has $M \geq -\frac{2 + E_1}{\log 2} + 1 - \log \log 2$. --/) - (proof := /-- Insert Lemma \ref{Mertens-first-error-prime-ge} into the definition of $M$ and use the fact that $\int_2^\infty \frac{dt}{t \log^2 t} = 1/\log 2$. - -/) - (latexEnv := "corollary") - (discussion := 1324)] + + + + + + + + + theorem M.ge : M ≥ (-2 - E₁) / log 2 + 1 - log (log 2) := calc _ ≥ (∫ t in Set.Ioi 2, (-2 - E₁) / (t * log t^2)) + 1 - log (log 2) := by unfold M; gcongr with x hx @@ -2008,29 +2008,29 @@ simp at hx; exact E₁p.ge (by linarith) _ = _ := by rw [integ_div_mul_log_sq _ (by norm_num)] -@[blueprint - "Mertens-second-error-mangoldt" - (title := "The remainder term in Mertens second theorem (von Mangoldt form)") - (statement := /-- We define $E_{2,p}(x) := \sum_{p \leq x} \frac{1}{p} - \log \log x - M$. --/)] + + + + + noncomputable abbrev E₂p (x : ℝ) : ℝ := ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (1:ℝ) / p - log (log x) - M theorem sum_prime_div_eq (x : ℝ) : ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (1:ℝ) / p = log (log x) + M + E₂p x := by ring -@[blueprint - "Mertens-second-error-prime-eq" - (title := "Integral form for second error (prime form)") - (statement := /-- For any $x \geq 2$, one has -$$ E_{2,p}(x) = \frac{E_{1,p}(x)}{\log x} - \int_x^\infty \frac{E_{1,p}(t)}{t \log^2 t}\ dt$$ --/) - (proof := /-- -From Lemma \ref{Mertens-integral-ident} one has -$$ \sum_{p \leq x} \frac{1}{p} = \frac{1}{\log x} \sum_{p \leq x} \frac{\log p}{p} + \int_2^x \frac{1}{t \log^2 t} \sum_{p \leq t} \frac{\log p}{p} \, dt.$$ -Now substitute the definitions of $E_{1,p}$, $E_{2,p}$, $M$ and simplify. - -/) - (latexEnv := "corollary") - (discussion := 1325)] + + + + + + + + + + + + + theorem E₂p.eq {x : ℝ} (hx : 2 ≤ x) : E₂p x = E₁p x / log x - ∫ t in Set.Ioi x, E₁p t / (t * log t^2) := by unfold E₂p @@ -2061,16 +2061,16 @@ · rw [intervalIntegrable_iff, Set.uIoc_of_le hx] exact integrable_E₁p_div_mul_log_sq (x := 2) (by rfl)|>.mono (by grind) (by rfl) -@[blueprint - "Mertens-second-error-prime-abs-le" - (title := "Bound for second error (prime form)") - (statement := /-- For any $x \geq 2$, one has -$$ |E_{2,p}(x)| \leq \frac{\log 4 + 6 + E_1}{\log x}.$$ --/) - (proof := /-- Similar to Lemma \ref{Mertens-second-error-prime-eq}. - -/) - (latexEnv := "corollary") - (discussion := 1326)] + + + + + + + + + + theorem E₂p.abs_le {x : ℝ} (hx : 2 ≤ x) : |E₂p x| ≤ (log 4 + 6 + E₁) / log x := by have : 0 < log x := by apply log_pos; linarith @@ -2101,8 +2101,8 @@ grw [this] grind -@[blueprint - "Mertens-second-error-prime-abs-le"] + + theorem E₂p.bound : E₂p =O[atTop] (fun x ↦ 1 / log x) := by simp only [one_div, isBigO_iff, norm_eq_abs, norm_inv, eventually_atTop] use log 4 + 6 + E₁, 2 @@ -2111,19 +2111,19 @@ have : 0 < log x := by apply log_pos; linarith grind [abs_of_pos this] -@[blueprint - "Mertens-second-error-prime-abs-le"] + + theorem E₂p.bound' : E₂p =o[atTop] (fun _ ↦ (1:ℝ)) := E₂p.bound.trans_isLittleO inv_log_eq_o_one -@[blueprint - "Mertens-second-theorem-prime-weak" - (title := "Mertens' second theorem (weak prime form)") - (statement := /-- For any $x \geq 2$, one has -$$ \sum_{p \leq x} \frac{1}{p} = \log \log x + O(1). $$ --/) - (proof := /-- Immediate from previous two corollaries. - -/) - (discussion := 1327)] + + + + + + + + + theorem sum_prime_div_eq_log_log : ∃ C, ∀ x, 2 ≤ x → |∑ p ∈ Ioc 0 ⌊x⌋₊ with p.Prime, (1:ℝ) / p - log (log x)| ≤ C := by use |M| + (log 4 + 6 + E₁) / log 2 @@ -2137,16 +2137,16 @@ have : 0 < log 4 := by apply log_pos; norm_num linarith [E₁.nonneg] -@[blueprint - "Mertens-second-theorem-prime-weak"] + + theorem sum_prime_div_eq_log_log' : (fun x ↦ ∑ p ∈ Ioc 0 ⌊x⌋₊ with p.Prime, (1:ℝ) / p - log (log x)) =O[atTop] (fun _ ↦ (1:ℝ)) := by simp only [isBigO_iff, norm_eq_abs, one_mem, CStarRing.norm_of_mem_unitary, mul_one, eventually_atTop] obtain ⟨ C, hC ⟩ := sum_prime_div_eq_log_log use C, 2 -@[blueprint - "Mertens-second-theorem-prime-weak"] + + theorem sum_prime_div_eq_log_log'' : (fun x ↦ ∑ p ∈ Ioc 0 ⌊x⌋₊ with p.Prime, (1:ℝ) / p) ~[atTop] (fun x ↦ log (log x)) := by apply IsLittleO.isEquivalent (IsBigO.trans_isLittleO _ one_eq_o_log_log) convert! sum_prime_div_eq_log_log' using 1 @@ -2244,33 +2244,33 @@ ring_nf · ring -@[blueprint - "Meissel-Mertens-eq" - (title := "Formula for Meissel-Mertens constant") - (statement := /-- One has $M = \gamma + \sum_p \log(1-\frac{1}{p}) + \frac{1}{p}$. --/) - (proof := /-- The RHS can be Taylor expanded as $\sum_{j=2}^\infty \sum_p \frac{1}{jp^j}$. Meanwhile, the difference between $\sum_{n \leq x} \frac{\Lambda(n)}{n \log n}$ and $\sum_{p \leq x} \frac{1}{p}$ is equal to $\sum_{j=2}^\infty \sum_{p: p^j \leq x} \frac{1}{j p^j}$. Applying the monotone convergence theorem, Lemma \ref{Mertens-second-error-prime-abs-le}, and Lemma \ref{Mertens-second-error-mangoldt-bound} gives the claim. -/) - (discussion := 1328)] + + + + + + + theorem M.eq : M = γ + ∑' p : ℕ, if p.Prime then log (1 - 1 / p) + 1 / p else 0 := by rw [← tsum_M_eq_f_eq_tsum, M_eq_f.HasSum.tsum_eq] ring -@[blueprint - "Mertens-third-error" - (title := "The remainder term in Mertens third theorem ") - (statement := /-- We define $E_3(x) := \sum_{p \leq x} \log (1 - \frac{1}{p}) + \log\log x + \gamma$. --/)] + + + + + noncomputable def E₃ (x : ℝ) : ℝ := ∑ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, log (1 - (1:ℝ) / p) + log (log x) + eulerMascheroniConstant -@[blueprint - "Mertens-third-theorem-error" - (title := "Mertens' third theorem error term") - (statement := /-- For any $x \geq 2$, one has -$$ \prod_{p \leq x} \left(1 - \frac{1}{p}\right) = \frac{e^{-\gamma}}{\log x} \exp(E_3(x)). $$ --/) - (proof := /-- Immediate from definition - -/) - (discussion := 1329)] + + + + + + + + + theorem prod_one_minus_div_prime_eq {x : ℝ} (hx : 1 < x) : ∏ p ∈ Ioc 0 ⌊x⌋₊ with p.Prime, (1 - (1 : ℝ) / p) = exp (-eulerMascheroniConstant) * exp (E₃ x) / log x := by @@ -2365,17 +2365,17 @@ gcongr exact Nat.lt_floor_add_one _|>.le -@[blueprint - "Mertens-third-theorem-error-le" - (title := "Mertens' third theorem error bound") - (statement := /-- For any $x \geq 2$, one has -$$ E_3(x) = O\left(\frac{1}{\log x}\right) $$ --/) - (proof := /--Estimating the error in \ref{Meissel-Mertens-eq} using the first order Taylor expansion of log one gets -$$\sum_{p \le x}(\log (1-1/p)+1/p) = (M - \gamma) + O(1/x).$$ -The result follows by combining with \ref{Mertens-second-error-prime-abs-le}. - -/) - (discussion := 1330)] + + + + + + + + + + + theorem E₃.abs_le : ∃ C, ∀ x, 2 ≤ x → |E₃ x| ≤ C / log x := by unfold E₃ refine ⟨4 + (log 4 + 6 + E₁), fun x hx ↦ ?_⟩ @@ -2399,8 +2399,8 @@ grw [this] rw [← add_div] -@[blueprint - "Mertens-third-theorem-error-le"] + + theorem E₃.bound : E₃ =O[atTop] (fun x ↦ 1 / log x) := by simp only [isBigO_iff, norm_eq_abs, eventually_atTop] obtain ⟨ C, hC ⟩ := E₃.abs_le @@ -2410,12 +2410,12 @@ have : 0 < 1 / log x := by positivity grind [abs_of_pos this] -@[blueprint - "Mertens-third-theorem-error-le"] + + theorem E₃.bound' : E₃ =o[atTop] (fun _ ↦ (1:ℝ)) := E₃.bound.trans_isLittleO inv_log_eq_o_one -@[blueprint - "Mertens-third-theorem-error-le"] + + theorem E₃.bound'' : (fun x ↦ ∏ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (1 - (1:ℝ) / p)) ~[atTop] (fun x ↦ exp (-eulerMascheroniConstant) / log x) := by rw [isEquivalent_iff_tendsto_one] · convert Tendsto.congr' ?_ (Tendsto.rexp ((isLittleO_one_iff ℝ).mp E₃.bound')) using 2 with x @@ -2427,8 +2427,8 @@ simp only [ne_eq, div_eq_zero_iff, exp_ne_zero, log_eq_zero, eventually_atTop]; use 2 grind -@[blueprint - "Mertens-third-theorem-error-le"] + + theorem E₃.bound''' : (fun x ↦ ∏ p ∈ Ioc 0 ⌊ x ⌋₊ with p.Prime, (1 - (1:ℝ) / p) - exp (-eulerMascheroniConstant) / log x) =O[atTop] (fun x ↦ 1 / (log x)^2) := by obtain ⟨c, hc⟩ := E₃.abs_le rw [isBigO_iff] diff --git a/PrimeNumberTheoremAnd/PerronFormula.lean b/PrimeNumberTheoremAnd/PerronFormula.lean --- a/PrimeNumberTheoremAnd/PerronFormula.lean +++ b/PrimeNumberTheoremAnd/PerronFormula.lean @@ -6,5 +6,3 @@ import PrimeNumberTheoremAnd.Wiener - -set_option lang.lemmaCmd true - + open Asymptotics Complex ComplexConjugate Topology Filter Real MeasureTheory Set