From 130bd35305e2acbcd985ba7f3510b0aa240a5ae0 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 12 May 2025 21:41:28 +0100 Subject: [PATCH 001/128] Eisenstein E2 --- .../ModularForms/EisensteinSeries/UniformConvergence.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean index a0c229e96e5f37..95cf15d3f6ffc1 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean @@ -43,6 +43,9 @@ lemma norm_eq_max_natAbs (x : Fin 2 → ℤ) : ‖x‖ = max (x 0).natAbs (x 1). refine eq_of_forall_ge_iff fun c ↦ ?_ simp only [pi_nnnorm_le_iff, Fin.forall_fin_two, max_le_iff, NNReal.natCast_natAbs] +lemma norm_symm (x y : ℤ) : ‖![x, y]‖ = ‖![y,x]‖ := by + simp_rw [EisensteinSeries.norm_eq_max_natAbs] + simp [max_comm] section bounding_functions /-- Auxiliary function used for bounding Eisenstein series, defined as From 7ac9441fa53812a6a296d379c881cfd782fc81e8 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 13 May 2025 16:48:49 +0100 Subject: [PATCH 002/128] save --- .../EisensteinSeries/UniformConvergence.lean | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean index 95cf15d3f6ffc1..3e7f683c9e890f 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean @@ -46,6 +46,33 @@ lemma norm_eq_max_natAbs (x : Fin 2 → ℤ) : ‖x‖ = max (x 0).natAbs (x 1). lemma norm_symm (x y : ℤ) : ‖![x, y]‖ = ‖![y,x]‖ := by simp_rw [EisensteinSeries.norm_eq_max_natAbs] simp [max_comm] + +theorem abs_le_left_of_norm (m n : ℤ) : |n| ≤ ‖![n, m]‖ := by + rw [EisensteinSeries.norm_eq_max_natAbs] + simp only [Fin.isValue, Matrix.cons_val_zero, Matrix.cons_val_one, Matrix.cons_val_fin_one, + Nat.cast_max, le_sup_iff] + left + rw [Int.abs_eq_natAbs] + rfl + +theorem le_left_of_norm (m n : ℤ) : n ≤ ‖![n, m]‖ := by + apply le_trans _ (abs_le_left_of_norm m n) + norm_cast + exact le_abs_self n + +theorem abs_le_right_of_norm (m n : ℤ) : |m| ≤ ‖![n, m]‖ := by + rw [EisensteinSeries.norm_eq_max_natAbs] + simp only [Fin.isValue, Matrix.cons_val_zero, Matrix.cons_val_one, Matrix.cons_val_fin_one, + Nat.cast_max, le_sup_iff] + right + rw [Int.abs_eq_natAbs] + rfl + +theorem le_right_of_norm (m n : ℤ) : m ≤ ‖![n, m]‖ := by + apply le_trans _ (abs_le_right_of_norm m n) + norm_cast + exact le_abs_self m + section bounding_functions /-- Auxiliary function used for bounding Eisenstein series, defined as From e7617962a5ad88cd0036fd59d8e9efa22f80d1f7 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 13 May 2025 16:49:42 +0100 Subject: [PATCH 003/128] save --- .../ModularForms/EisensteinSeries/E2.lean | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean new file mode 100644 index 00000000000000..d243776bbad2da --- /dev/null +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean @@ -0,0 +1,129 @@ +import Mathlib.Algebra.Order.Ring.Star +import Mathlib.Analysis.CStarAlgebra.Classes +import Mathlib.Data.Int.Star +import Mathlib.NumberTheory.LSeries.RiemannZeta +import Mathlib.NumberTheory.ModularForms.EisensteinSeries.UniformConvergence + + + +open ModularForm EisensteinSeries UpperHalfPlane TopologicalSpace intervalIntegral + Metric Filter Function Complex MatrixGroups Finset + +open scoped Interval Real Topology BigOperators Nat + +noncomputable section + + +/-- This is an auxilary summand used to define the Eisenstein serires `G2`. -/ +def e2Summand (m : ℤ) (z : ℍ) : ℂ := ∑' (n : ℤ), eisSummand 2 ![m, n] z + +/-- The Eisenstein series of weight `2` and level `1` defined as the limit as `N` tends to +infinity of the partial sum of `m` in `[N,N)` of `e2Summand m`. This sum over non-symmetric +intervals is handy in proofs of its transformation property. -/ +def G2 : ℍ → ℂ := fun z => limUnder (atTop) (fun N : ℕ => ∑ m ∈ Ico (-N : ℤ) N, e2Summand m z) + +def E2 : ℍ → ℂ := (1 / (2 * riemannZeta 2)) • G2 + +def D2 (γ : SL(2, ℤ)) : ℍ → ℂ := fun z => (2 * π * Complex.I * γ 1 0) / (denom γ z) + +lemma Eis_isBigO (m : ℤ) (z : ℍ) : (fun (n : ℤ) => ((m : ℂ) * z + n)⁻¹) =O[cofinite] + (fun n => ((r z * ‖![n, m]‖))⁻¹) := by + rw [Asymptotics.isBigO_iff'] + refine ⟨1, Real.zero_lt_one, ?_⟩ + filter_upwards with n + have := EisensteinSeries.summand_bound z (k := 1) (by norm_num) ![m, n] + simp only [Fin.isValue, Matrix.cons_val_zero, Matrix.cons_val_one, Matrix.cons_val_fin_one, + Real.rpow_neg_one, norm_inv, Nat.succ_eq_add_one, Nat.reduceAdd, mul_inv_rev, norm_mul, + norm_norm, Real.norm_eq_abs, one_mul, ge_iff_le] at * + apply le_trans this + rw [abs_norm, mul_comm, show |r z| = r z by rw [abs_eq_self]; exact (r_pos z).le, norm_symm] + +lemma linear_bigO2 (m : ℤ) (z : ℍ) : (fun (n : ℤ) => ((m : ℂ) * z + n)⁻¹) =O[cofinite] + fun n => ((n : ℝ)⁻¹) := by + have h1 := Eis_isBigO m z + apply Asymptotics.IsBigO.trans h1 + rw [@Asymptotics.isBigO_iff'] + refine ⟨|(r z)|⁻¹, by simp [ne_of_gt (r_pos z)], ?_⟩ + rw [eventually_iff_exists_mem] + refine ⟨{0}ᶜ, Set.Finite.compl_mem_cofinite (Set.finite_singleton 0), ?_⟩ + simp only [Set.mem_compl_iff, Set.mem_singleton_iff, Nat.succ_eq_add_one, Nat.reduceAdd, + mul_inv_rev, norm_mul, norm_inv, norm_norm, Real.norm_eq_abs, abs_norm] + intro n hn + rw [mul_comm] + gcongr + simpa using abs_le_left_of_norm m n + +lemma linear_bigO (m : ℤ) (z : ℍ) : (fun (n : ℤ) => ((m : ℂ) * z + n)⁻¹) =O[cofinite] + fun n => (|(n : ℝ)|⁻¹) := by + have := Asymptotics.IsBigO.abs_right (linear_bigO2 m z) + simp_rw [abs_inv] at this + exact this + +lemma linear_bigO_pow (m : ℤ) (z : ℍ) (k : ℕ) : + (fun (n : ℤ) => ((((m : ℂ) * z + n)) ^ k )⁻¹) =O[cofinite] fun n => ((|(n : ℝ)| ^ k)⁻¹) := by + simp_rw [← inv_pow] + apply Asymptotics.IsBigO.pow + apply linear_bigO m z + + +lemma summable_hammerTime {α : Type} [NormedField α] [CompleteSpace α] (f : ℤ → α) (a : ℝ) + (hab : 1 < a) (hf : (fun n => (f n)⁻¹) =O[cofinite] fun n => (|(n : ℝ)| ^ (a : ℝ))⁻¹) : + Summable fun n => (f n)⁻¹ := by + apply summable_of_isBigO _ hf + have := Real.summable_abs_int_rpow hab + apply this.congr + intro b + refine Real.rpow_neg ?_ a + exact abs_nonneg (b : ℝ) + +lemma G2_summable_aux (n : ℤ) (z : ℍ) (k : ℤ) (hk : 2 ≤ k) : + Summable fun d : ℤ => ((((n : ℂ) * z) + d) ^ k)⁻¹ := by + apply summable_hammerTime _ k + · norm_cast + · lift k to ℕ using (by linarith) + have := linear_bigO_pow n z k + norm_cast at * + +lemma pnat_div_upper (n : ℕ+) (z : ℍ) : 0 < (-(n : ℂ) / z).im := by + norm_cast + rw [div_im] + simp only [Int.cast_neg, Int.cast_natCast, neg_im, natCast_im, neg_zero, coe_re, zero_mul, + zero_div, neg_re, natCast_re, coe_im, neg_mul, zero_sub, Left.neg_pos_iff, gt_iff_lt] + rw [@div_neg_iff] + right + simp only [Left.neg_neg_iff, Nat.cast_pos, PNat.pos, mul_pos_iff_of_pos_left, Complex.normSq_pos, + ne_eq] + refine ⟨z.2, ne_zero z⟩ + +lemma e2Summand_summable (z : ℍ) (n : ℤ) : Summable fun b : ℤ ↦ 1 / (((b : ℂ) * ↑z + ↑n) ^ 2) := by + have := (G2_summable_aux (-n) ⟨-1 /z, by simpa using pnat_div_upper 1 z⟩ 2 + (by norm_num)).mul_left ((z : ℂ)^2)⁻¹ + apply this.congr + intro b + simp only [UpperHalfPlane.coe, Int.cast_neg, neg_mul] + field_simp + norm_cast + congr 1 + rw [← mul_pow] + congr + have hz := ne_zero z --this come our with a coe that should be fixed + simp only [UpperHalfPlane.coe, ne_eq] at hz + field_simp + ring + +lemma Asymptotics.IsBigO.map {α β ι γ : Type*} [Norm α] [Norm β] {f : ι → α} {g : ι → β} + {p : Filter ι} (hf : f =O[p] g) (c : γ → ι) : + (fun (n : γ) => f (c n)) =O[p.comap c] fun n => g (c n) := by + rw [isBigO_iff] at * + obtain ⟨C, hC⟩ := hf + refine ⟨C, ?_⟩ + simp only [eventually_comap] at * + filter_upwards [hC] with n hn + exact fun a ha ↦ Eq.mpr (id (congrArg (fun _a ↦ ‖f _a‖ ≤ C * ‖g _a‖) ha)) hn + +lemma Asymptotics.IsBigO.nat_of_int {α β: Type*} [Norm α] [SeminormedAddCommGroup β] {f : ℤ → α} + {g : ℤ → β} (hf : f =O[cofinite] g) : (fun (n : ℕ) => f n) =O[cofinite] fun n => g n := by + have := Asymptotics.IsBigO.map hf Nat.cast + simp only [Int.cofinite_eq, isBigO_sup, comap_sup, Asymptotics.isBigO_sup] at * + rw [Nat.cofinite_eq_atTop] + simpa using this.2 From d53f78ef3e6f840075508c9fa388a8a063117c5d Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 21 May 2025 23:11:46 +0200 Subject: [PATCH 004/128] feat(Analysis/NormedSpace/FunctionSeries): Add SummableUniformlyOn versions and derivwithin_tsum --- .../Analysis/NormedSpace/FunctionSeries.lean | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/NormedSpace/FunctionSeries.lean b/Mathlib/Analysis/NormedSpace/FunctionSeries.lean index 8beeeacc7da0c0..17bb492f0dde90 100644 --- a/Mathlib/Analysis/NormedSpace/FunctionSeries.lean +++ b/Mathlib/Analysis/NormedSpace/FunctionSeries.lean @@ -3,8 +3,8 @@ Copyright (c) 2022 Sébastien Gouëzel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ -import Mathlib.Analysis.Normed.Group.InfiniteSum -import Mathlib.Topology.Instances.ENNReal.Lemmas +import Mathlib.Analysis.Calculus.UniformLimitsDeriv +import Mathlib.Topology.Algebra.InfiniteSum.UniformOn /-! # Continuity of series of functions @@ -36,6 +36,10 @@ theorem tendstoUniformlyOn_tsum {f : α → β → F} (hu : Summable u) {s : Set apply (norm_tsum_le_tsum_norm (A.subtype _)).trans exact (A.subtype _).tsum_le_tsum (fun n => hfu _ _ hx) (hu.subtype _) +theorem HasSumUniformlyOn_of_bounded {f : α → β → F} (hu : Summable u) {s : Set β} + (hfu : ∀ n x, x ∈ s → ‖f n x‖ ≤ u n) : HasSumUniformlyOn f (fun x => ∑' n, f n x) {s} := by + simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, tendstoUniformlyOn_tsum hu hfu] + /-- An infinite sum of functions with summable sup norm is the uniform limit of its partial sums. Version relative to a set, with index set `ℕ`. -/ theorem tendstoUniformlyOn_tsum_nat {f : ℕ → β → F} {u : ℕ → ℝ} (hu : Summable u) {s : Set β} @@ -72,6 +76,12 @@ theorem tendstoUniformlyOn_tsum_of_cofinite_eventually {ι : Type*} {f : ι → have : ¬ i ∈ hN.toFinset := fun hg ↦ hi (Finset.union_subset_left hn hg) aesop +theorem HasSumUniformlyOn_of_cofinite_eventually {ι : Type*} {f : ι → β → F} {u : ι → ℝ} + (hu : Summable u) {s : Set β} (hfu : ∀ᶠ n in cofinite, ∀ x ∈ s, ‖f n x‖ ≤ u n) : + HasSumUniformlyOn f (fun x => ∑' n, f n x) {s} := by + simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, + tendstoUniformlyOn_tsum_of_cofinite_eventually hu hfu] + theorem tendstoUniformlyOn_tsum_nat_eventually {α F : Type*} [NormedAddCommGroup F] [CompleteSpace F] {f : ℕ → α → F} {u : ℕ → ℝ} (hu : Summable u) {s : Set α} (hfu : ∀ᶠ n in atTop, ∀ x ∈ s, ‖f n x‖ ≤ u n) : @@ -120,3 +130,36 @@ theorem continuous_tsum [TopologicalSpace β] {f : α → β → F} (hf : ∀ i, (hu : Summable u) (hfu : ∀ n x, ‖f n x‖ ≤ u n) : Continuous fun x => ∑' n, f n x := by simp_rw [continuous_iff_continuousOn_univ] at hf ⊢ exact continuousOn_tsum hf hu fun n x _ => hfu n x + +variable {𝕜 𝕜' ι: Type*} [NormedAddCommGroup 𝕜'] [CompleteSpace 𝕜'] [TopologicalSpace 𝕜] + [LocallyCompactSpace 𝕜] + +lemma SummableLocallyUniformlyOn.of_locally_bounded (f : ι → 𝕜 → 𝕜') {s : Set 𝕜} (hs : IsOpen s) + (hu : ∀ K ⊆ s, IsCompact K → ∃ u : ι → ℝ, Summable u ∧ ∀ n (k : K), ‖f n k‖ ≤ u n) : + SummableLocallyUniformlyOn f s := by + apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := (fun x => ∑' i, f i x)) + rw [hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn, + tendstoLocallyUniformlyOn_iff_forall_isCompact hs] + intro K hK hKc + obtain ⟨u, hu1, hu2⟩ := hu K hK hKc + apply tendstoUniformlyOn_tsum hu1 fun n x hx ↦ hu2 n ⟨x, hx⟩ + +theorem derivWithin_tsum {ι F E : Type*} [NontriviallyNormedField E] [IsRCLikeNormedField E] + [NormedField F] [NormedSpace E F] (f : ι → E → F) {s : Set E} + (hs : IsOpen s) {x : E} (hx : x ∈ s) (hf : ∀ y ∈ s, Summable fun n ↦ f n y) + (h : SummableLocallyUniformlyOn (fun n ↦ (derivWithin (fun z ↦ f n z) s)) s) + (hf2 : ∀ n r, r ∈ s → DifferentiableAt E (f n) r) : + derivWithin (fun z ↦ ∑' n , f n z) s x = ∑' n, derivWithin (fun z ↦ f n z) s x := by + apply HasDerivWithinAt.derivWithin ?_ (IsOpen.uniqueDiffWithinAt hs hx) + apply HasDerivAt.hasDerivWithinAt + apply hasDerivAt_of_tendstoLocallyUniformlyOn hs _ _ (fun y hy ↦ Summable.hasSum (hf y hy)) hx + · use fun n : Finset ι ↦ fun a ↦ ∑ i ∈ n, derivWithin (fun z ↦ f i z) s a + · obtain ⟨g, hg⟩ := h + apply (hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp hg).congr_right + exact fun ⦃b⦄ hb ↦ Eq.symm (HasSumLocallyUniformlyOn.tsum_eqOn hg hb) + · filter_upwards with t r hr + apply HasDerivAt.sum + intro q hq + apply HasDerivWithinAt.hasDerivAt + · exact DifferentiableWithinAt.hasDerivWithinAt (hf2 q r hr).differentiableWithinAt + · exact IsOpen.mem_nhds hs hr From 9a0f6ccbc2ba78099ab059b205d6e75c0d86ef28 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 21 May 2025 23:41:42 +0200 Subject: [PATCH 005/128] update --- Mathlib/Analysis/NormedSpace/FunctionSeries.lean | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Mathlib/Analysis/NormedSpace/FunctionSeries.lean b/Mathlib/Analysis/NormedSpace/FunctionSeries.lean index 17bb492f0dde90..d91ca3d989bfbd 100644 --- a/Mathlib/Analysis/NormedSpace/FunctionSeries.lean +++ b/Mathlib/Analysis/NormedSpace/FunctionSeries.lean @@ -131,11 +131,9 @@ theorem continuous_tsum [TopologicalSpace β] {f : α → β → F} (hf : ∀ i, simp_rw [continuous_iff_continuousOn_univ] at hf ⊢ exact continuousOn_tsum hf hu fun n x _ => hfu n x -variable {𝕜 𝕜' ι: Type*} [NormedAddCommGroup 𝕜'] [CompleteSpace 𝕜'] [TopologicalSpace 𝕜] - [LocallyCompactSpace 𝕜] - -lemma SummableLocallyUniformlyOn.of_locally_bounded (f : ι → 𝕜 → 𝕜') {s : Set 𝕜} (hs : IsOpen s) - (hu : ∀ K ⊆ s, IsCompact K → ∃ u : ι → ℝ, Summable u ∧ ∀ n (k : K), ‖f n k‖ ≤ u n) : +lemma SummableLocallyUniformlyOn.of_locally_bounded [TopologicalSpace β] [LocallyCompactSpace β] + (f : α → β → F) {s : Set β} (hs : IsOpen s) + (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ ∀ n (k : K), ‖f n k‖ ≤ u n) : SummableLocallyUniformlyOn f s := by apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := (fun x => ∑' i, f i x)) rw [hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn, @@ -144,8 +142,8 @@ lemma SummableLocallyUniformlyOn.of_locally_bounded (f : ι → 𝕜 → 𝕜') obtain ⟨u, hu1, hu2⟩ := hu K hK hKc apply tendstoUniformlyOn_tsum hu1 fun n x hx ↦ hu2 n ⟨x, hx⟩ -theorem derivWithin_tsum {ι F E : Type*} [NontriviallyNormedField E] [IsRCLikeNormedField E] - [NormedField F] [NormedSpace E F] (f : ι → E → F) {s : Set E} +theorem derivWithin_tsum {F E : Type*} [NontriviallyNormedField E] [IsRCLikeNormedField E] + [NormedField F] [NormedSpace E F] (f : α → E → F) {s : Set E} (hs : IsOpen s) {x : E} (hx : x ∈ s) (hf : ∀ y ∈ s, Summable fun n ↦ f n y) (h : SummableLocallyUniformlyOn (fun n ↦ (derivWithin (fun z ↦ f n z) s)) s) (hf2 : ∀ n r, r ∈ s → DifferentiableAt E (f n) r) : @@ -153,7 +151,7 @@ theorem derivWithin_tsum {ι F E : Type*} [NontriviallyNormedField E] [IsRCLikeN apply HasDerivWithinAt.derivWithin ?_ (IsOpen.uniqueDiffWithinAt hs hx) apply HasDerivAt.hasDerivWithinAt apply hasDerivAt_of_tendstoLocallyUniformlyOn hs _ _ (fun y hy ↦ Summable.hasSum (hf y hy)) hx - · use fun n : Finset ι ↦ fun a ↦ ∑ i ∈ n, derivWithin (fun z ↦ f i z) s a + · use fun n : Finset α ↦ fun a ↦ ∑ i ∈ n, derivWithin (fun z ↦ f i z) s a · obtain ⟨g, hg⟩ := h apply (hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp hg).congr_right exact fun ⦃b⦄ hb ↦ Eq.symm (HasSumLocallyUniformlyOn.tsum_eqOn hg hb) From 41022888f5dc79c9ede2d1c42fe13981de1752eb Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 17 Jun 2025 10:22:09 +0100 Subject: [PATCH 006/128] mk_all --- Mathlib.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib.lean b/Mathlib.lean index ee8f7178090711..ed8915a454d09e 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4494,6 +4494,7 @@ import Mathlib.NumberTheory.ModularForms.Basic import Mathlib.NumberTheory.ModularForms.CongruenceSubgroups import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Basic import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Defs +import Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2 import Mathlib.NumberTheory.ModularForms.EisensteinSeries.IsBoundedAtImInfty import Mathlib.NumberTheory.ModularForms.EisensteinSeries.MDifferentiable import Mathlib.NumberTheory.ModularForms.EisensteinSeries.UniformConvergence From 73117944b85d41e395eeca2c64f557e19886b7b9 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 7 Jul 2025 14:49:07 +0100 Subject: [PATCH 007/128] move files --- .../Analysis/NormedSpace/FunctionSeries.lean | 41 ------------ .../Algebra/InfiniteSum/tsumUniformOn.lean | 67 +++++++++++++++++++ 2 files changed, 67 insertions(+), 41 deletions(-) create mode 100644 Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean diff --git a/Mathlib/Analysis/NormedSpace/FunctionSeries.lean b/Mathlib/Analysis/NormedSpace/FunctionSeries.lean index 4bb9e5616a4237..6c5e04c2650c46 100644 --- a/Mathlib/Analysis/NormedSpace/FunctionSeries.lean +++ b/Mathlib/Analysis/NormedSpace/FunctionSeries.lean @@ -39,10 +39,6 @@ theorem tendstoUniformlyOn_tsum {f : α → β → F} (hu : Summable u) {s : Set apply (norm_tsum_le_tsum_norm (A.subtype _)).trans exact (A.subtype _).tsum_le_tsum (fun n => hfu _ _ hx) (hu.subtype _) -theorem HasSumUniformlyOn_of_bounded {f : α → β → F} (hu : Summable u) {s : Set β} - (hfu : ∀ n x, x ∈ s → ‖f n x‖ ≤ u n) : HasSumUniformlyOn f (fun x => ∑' n, f n x) {s} := by - simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, tendstoUniformlyOn_tsum hu hfu] - /-- An infinite sum of functions with summable sup norm is the uniform limit of its partial sums. Version relative to a set, with index set `ℕ`. -/ theorem tendstoUniformlyOn_tsum_nat {f : ℕ → β → F} {u : ℕ → ℝ} (hu : Summable u) {s : Set β} @@ -79,12 +75,6 @@ theorem tendstoUniformlyOn_tsum_of_cofinite_eventually {ι : Type*} {f : ι → have : i ∉ hN.toFinset := fun hg ↦ hi (Finset.union_subset_left hn hg) aesop -theorem HasSumUniformlyOn_of_cofinite_eventually {ι : Type*} {f : ι → β → F} {u : ι → ℝ} - (hu : Summable u) {s : Set β} (hfu : ∀ᶠ n in cofinite, ∀ x ∈ s, ‖f n x‖ ≤ u n) : - HasSumUniformlyOn f (fun x => ∑' n, f n x) {s} := by - simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, - tendstoUniformlyOn_tsum_of_cofinite_eventually hu hfu] - theorem tendstoUniformlyOn_tsum_nat_eventually {α F : Type*} [NormedAddCommGroup F] [CompleteSpace F] {f : ℕ → α → F} {u : ℕ → ℝ} (hu : Summable u) {s : Set α} (hfu : ∀ᶠ n in atTop, ∀ x ∈ s, ‖f n x‖ ≤ u n) : @@ -133,34 +123,3 @@ theorem continuous_tsum [TopologicalSpace β] {f : α → β → F} (hf : ∀ i, (hu : Summable u) (hfu : ∀ n x, ‖f n x‖ ≤ u n) : Continuous fun x => ∑' n, f n x := by simp_rw [continuous_iff_continuousOn_univ] at hf ⊢ exact continuousOn_tsum hf hu fun n x _ => hfu n x - -lemma SummableLocallyUniformlyOn.of_locally_bounded [TopologicalSpace β] [LocallyCompactSpace β] - (f : α → β → F) {s : Set β} (hs : IsOpen s) - (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ ∀ n (k : K), ‖f n k‖ ≤ u n) : - SummableLocallyUniformlyOn f s := by - apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := (fun x => ∑' i, f i x)) - rw [hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn, - tendstoLocallyUniformlyOn_iff_forall_isCompact hs] - intro K hK hKc - obtain ⟨u, hu1, hu2⟩ := hu K hK hKc - apply tendstoUniformlyOn_tsum hu1 fun n x hx ↦ hu2 n ⟨x, hx⟩ - -theorem derivWithin_tsum {F E : Type*} [NontriviallyNormedField E] [IsRCLikeNormedField E] - [NormedField F] [NormedSpace E F] (f : α → E → F) {s : Set E} - (hs : IsOpen s) {x : E} (hx : x ∈ s) (hf : ∀ y ∈ s, Summable fun n ↦ f n y) - (h : SummableLocallyUniformlyOn (fun n ↦ (derivWithin (fun z ↦ f n z) s)) s) - (hf2 : ∀ n r, r ∈ s → DifferentiableAt E (f n) r) : - derivWithin (fun z ↦ ∑' n , f n z) s x = ∑' n, derivWithin (fun z ↦ f n z) s x := by - apply HasDerivWithinAt.derivWithin ?_ (IsOpen.uniqueDiffWithinAt hs hx) - apply HasDerivAt.hasDerivWithinAt - apply hasDerivAt_of_tendstoLocallyUniformlyOn hs _ _ (fun y hy ↦ Summable.hasSum (hf y hy)) hx - · use fun n : Finset α ↦ fun a ↦ ∑ i ∈ n, derivWithin (fun z ↦ f i z) s a - · obtain ⟨g, hg⟩ := h - apply (hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp hg).congr_right - exact fun ⦃b⦄ hb ↦ Eq.symm (HasSumLocallyUniformlyOn.tsum_eqOn hg hb) - · filter_upwards with t r hr - apply HasDerivAt.sum - intro q hq - apply HasDerivWithinAt.hasDerivAt - · exact DifferentiableWithinAt.hasDerivWithinAt (hf2 q r hr).differentiableWithinAt - · exact IsOpen.mem_nhds hs hr diff --git a/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean new file mode 100644 index 00000000000000..6e69252604aff9 --- /dev/null +++ b/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean @@ -0,0 +1,67 @@ +/- +Copyright (c) 2022 Sébastien Gouëzel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sébastien Gouëzel +-/ +import Mathlib.Analysis.NormedSpace.FunctionSeries +import Mathlib.Topology.Algebra.InfiniteSum.UniformOn + +/-! +# Continuity of series of functions + +We prove some HasSumUniformlyOn versions of theorems from +`Mathlib.Analysis.NormedSpace.FunctionSeries`. + +Alongside this we prove `derivWithin_tsum` which states that the derivative of a series of functions +is the sum of the derivatives, under suitable conditions. + +-/ + +open Set Metric TopologicalSpace Function Filter + +open scoped Topology NNReal + +variable {α β F : Type*} [NormedAddCommGroup F] [CompleteSpace F] {u : α → ℝ} + +theorem HasSumUniformlyOn_of_bounded {f : α → β → F} (hu : Summable u) {s : Set β} + (hfu : ∀ n x, x ∈ s → ‖f n x‖ ≤ u n) : HasSumUniformlyOn f (fun x => ∑' n, f n x) {s} := by + simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, tendstoUniformlyOn_tsum hu hfu] + +theorem HasSumUniformlyOn_of_cofinite_eventually {ι : Type*} {f : ι → β → F} {u : ι → ℝ} + (hu : Summable u) {s : Set β} (hfu : ∀ᶠ n in cofinite, ∀ x ∈ s, ‖f n x‖ ≤ u n) : + HasSumUniformlyOn f (fun x => ∑' n, f n x) {s} := by + simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, + tendstoUniformlyOn_tsum_of_cofinite_eventually hu hfu] + +lemma SummableLocallyUniformlyOn_of_locally_bounded [TopologicalSpace β] [LocallyCompactSpace β] + (f : α → β → F) {s : Set β} (hs : IsOpen s) + (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ ∀ n (k : K), ‖f n k‖ ≤ u n) : + SummableLocallyUniformlyOn f s := by + apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := (fun x => ∑' i, f i x)) + rw [hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn, + tendstoLocallyUniformlyOn_iff_forall_isCompact hs] + intro K hK hKc + obtain ⟨u, hu1, hu2⟩ := hu K hK hKc + apply tendstoUniformlyOn_tsum hu1 fun n x hx ↦ hu2 n ⟨x, hx⟩ + +/-- The `derivWithin` of a absolutely and uniformly converget sum on an open set `s` is the sum +of the derivatives of squence of functions on the open set `s` -/ +theorem derivWithin_tsum {F E : Type*} [NontriviallyNormedField E] [IsRCLikeNormedField E] + [NormedField F] [NormedSpace E F] (f : α → E → F) {s : Set E} + (hs : IsOpen s) {x : E} (hx : x ∈ s) (hf : ∀ y ∈ s, Summable fun n ↦ f n y) + (h : SummableLocallyUniformlyOn (fun n ↦ (derivWithin (fun z ↦ f n z) s)) s) + (hf2 : ∀ n r, r ∈ s → DifferentiableAt E (f n) r) : + derivWithin (fun z ↦ ∑' n , f n z) s x = ∑' n, derivWithin (fun z ↦ f n z) s x := by + apply HasDerivWithinAt.derivWithin ?_ (IsOpen.uniqueDiffWithinAt hs hx) + apply HasDerivAt.hasDerivWithinAt + apply hasDerivAt_of_tendstoLocallyUniformlyOn hs _ _ (fun y hy ↦ Summable.hasSum (hf y hy)) hx + · use fun n : Finset α ↦ fun a ↦ ∑ i ∈ n, derivWithin (fun z ↦ f i z) s a + · obtain ⟨g, hg⟩ := h + apply (hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp hg).congr_right + exact fun _ hb ↦ Eq.symm (HasSumLocallyUniformlyOn.tsum_eqOn hg hb) + · filter_upwards with t r hr + apply HasDerivAt.fun_sum + intro q hq + apply HasDerivWithinAt.hasDerivAt + · exact DifferentiableWithinAt.hasDerivWithinAt (hf2 q r hr).differentiableWithinAt + · exact IsOpen.mem_nhds hs hr From 2f47769987d8995bde6117804e7ba5f8fcd59a76 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 7 Jul 2025 14:55:22 +0100 Subject: [PATCH 008/128] imports --- Mathlib/Analysis/NormedSpace/FunctionSeries.lean | 4 ++-- Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/NormedSpace/FunctionSeries.lean b/Mathlib/Analysis/NormedSpace/FunctionSeries.lean index 6c5e04c2650c46..2a34e97f6244bc 100644 --- a/Mathlib/Analysis/NormedSpace/FunctionSeries.lean +++ b/Mathlib/Analysis/NormedSpace/FunctionSeries.lean @@ -3,8 +3,8 @@ Copyright (c) 2022 Sébastien Gouëzel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ -import Mathlib.Analysis.Calculus.UniformLimitsDeriv -import Mathlib.Topology.Algebra.InfiniteSum.UniformOn +import Mathlib.Analysis.Normed.Group.InfiniteSum +import Mathlib.Topology.Instances.ENNReal.Lemmas /-! # Continuity of series of functions diff --git a/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean index 6e69252604aff9..7f7f2f327c38ea 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean @@ -3,6 +3,8 @@ Copyright (c) 2022 Sébastien Gouëzel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ +import Mathlib.Algebra.Lie.OfAssociative +import Mathlib.Analysis.Calculus.UniformLimitsDeriv import Mathlib.Analysis.NormedSpace.FunctionSeries import Mathlib.Topology.Algebra.InfiniteSum.UniformOn From 5a4f0f3e8b26654bd8df0f30e6f0d894546d0d59 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 7 Jul 2025 14:55:51 +0100 Subject: [PATCH 009/128] mk_all --- Mathlib.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib.lean b/Mathlib.lean index 9cd4968141530b..a8b83cc4de2ccd 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6044,6 +6044,7 @@ import Mathlib.Topology.Algebra.InfiniteSum.Order import Mathlib.Topology.Algebra.InfiniteSum.Real import Mathlib.Topology.Algebra.InfiniteSum.Ring import Mathlib.Topology.Algebra.InfiniteSum.UniformOn +import Mathlib.Topology.Algebra.InfiniteSum.tsumUniformOn import Mathlib.Topology.Algebra.IntermediateField import Mathlib.Topology.Algebra.IsOpenUnits import Mathlib.Topology.Algebra.IsUniformGroup.Basic From da640637bfb83bee66597d8ee39421e956125925 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 7 Jul 2025 14:58:51 +0100 Subject: [PATCH 010/128] fix name --- Mathlib.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib.lean b/Mathlib.lean index a8b83cc4de2ccd..53b2904c18ef52 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6043,8 +6043,8 @@ import Mathlib.Topology.Algebra.InfiniteSum.Nonarchimedean import Mathlib.Topology.Algebra.InfiniteSum.Order import Mathlib.Topology.Algebra.InfiniteSum.Real import Mathlib.Topology.Algebra.InfiniteSum.Ring +import Mathlib.Topology.Algebra.InfiniteSum.TsumUniformOn import Mathlib.Topology.Algebra.InfiniteSum.UniformOn -import Mathlib.Topology.Algebra.InfiniteSum.tsumUniformOn import Mathlib.Topology.Algebra.IntermediateField import Mathlib.Topology.Algebra.IsOpenUnits import Mathlib.Topology.Algebra.IsUniformGroup.Basic From 880215019265990e1f7c9051dc8cdaf5e573529d Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 7 Jul 2025 14:59:54 +0100 Subject: [PATCH 011/128] fix name --- Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean index 7f7f2f327c38ea..51da5eeebcf2a3 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean @@ -1,7 +1,7 @@ /- -Copyright (c) 2022 Sébastien Gouëzel. All rights reserved. +Copyright (c) 2025 Chris Birkbeck. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Sébastien Gouëzel +Authors: Chris Birkbeck -/ import Mathlib.Algebra.Lie.OfAssociative import Mathlib.Analysis.Calculus.UniformLimitsDeriv From f78e8693304709801159029c081119cfd0230f1a Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 7 Jul 2025 15:03:24 +0100 Subject: [PATCH 012/128] name fix again --- Mathlib.lean | 2 +- .../InfiniteSum/{tsumUniformOn.lean => TsumUniformlyOn.lean} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename Mathlib/Topology/Algebra/InfiniteSum/{tsumUniformOn.lean => TsumUniformlyOn.lean} (100%) diff --git a/Mathlib.lean b/Mathlib.lean index 53b2904c18ef52..f2442d642fb945 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6043,7 +6043,7 @@ import Mathlib.Topology.Algebra.InfiniteSum.Nonarchimedean import Mathlib.Topology.Algebra.InfiniteSum.Order import Mathlib.Topology.Algebra.InfiniteSum.Real import Mathlib.Topology.Algebra.InfiniteSum.Ring -import Mathlib.Topology.Algebra.InfiniteSum.TsumUniformOn +import Mathlib.Topology.Algebra.InfiniteSum.TsumUniformlyOn import Mathlib.Topology.Algebra.InfiniteSum.UniformOn import Mathlib.Topology.Algebra.IntermediateField import Mathlib.Topology.Algebra.IsOpenUnits diff --git a/Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean similarity index 100% rename from Mathlib/Topology/Algebra/InfiniteSum/tsumUniformOn.lean rename to Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean From 991df0229c40b8ee489aaf205122cc0c197fb7b1 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 7 Jul 2025 15:12:04 +0100 Subject: [PATCH 013/128] fix --- Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index 51da5eeebcf2a3..6776a1712dd6a5 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -3,7 +3,6 @@ Copyright (c) 2025 Chris Birkbeck. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ -import Mathlib.Algebra.Lie.OfAssociative import Mathlib.Analysis.Calculus.UniformLimitsDeriv import Mathlib.Analysis.NormedSpace.FunctionSeries import Mathlib.Topology.Algebra.InfiniteSum.UniformOn From aaf9ca48e4ffc81e982d921a44b68bdc2c8c31f7 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 13:32:35 +0100 Subject: [PATCH 014/128] updates --- Mathlib/Algebra/BigOperators/Pi.lean | 22 +++++++ .../Algebra/InfiniteSum/TsumUniformlyOn.lean | 63 ++++++++++++++----- .../Algebra/InfiniteSum/UniformOn.lean | 7 +++ 3 files changed, 75 insertions(+), 17 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Pi.lean b/Mathlib/Algebra/BigOperators/Pi.lean index c4c60fd0a7bdff..a177831e41602e 100644 --- a/Mathlib/Algebra/BigOperators/Pi.lean +++ b/Mathlib/Algebra/BigOperators/Pi.lean @@ -205,3 +205,25 @@ lemma Pi.mulSingle_induction [CommMonoid M] (p : (ι → M) → Prop) (f : ι cases nonempty_fintype ι rw [← Finset.univ_prod_mulSingle f] exact Finset.prod_induction _ _ mul one (by simp [mulSingle]) + +section EqOn + +@[to_additive] +theorem eqOn_finsetProd {ι α β : Type*} [CommMonoid α] [DecidableEq ι] + (s : Set β) {f f' : ι → β → α} (h : ∀ (i : ι), Set.EqOn (f i) (f' i) s) (v : Finset ι) : + Set.EqOn (∏ i ∈ v, f i) (∏ i ∈ v, f' i) s := by + intro t ht + simp only [Finset.prod_apply] at * + congr + exact funext fun i ↦ h i ht + +@[to_additive] +theorem eqOn_fun_finsetProd {ι α β : Type*} [CommMonoid α] [DecidableEq ι] + (s : Set β) {f f' : ι → β → α} (h : ∀ (i : ι), Set.EqOn (f i) (f' i) s) (v : Finset ι) : + Set.EqOn (fun b ↦ ∏ i ∈ v, f i b) (fun b ↦ ∏ i ∈ v, f' i b) s := by + intro t ht + simp only at * + congr + exact funext fun i ↦ h i ht + +end EqOn diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index 6776a1712dd6a5..2aafa8d875bb8e 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -3,6 +3,7 @@ Copyright (c) 2025 Chris Birkbeck. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ +import Mathlib.Analysis.Calculus.IteratedDeriv.Defs import Mathlib.Analysis.Calculus.UniformLimitsDeriv import Mathlib.Analysis.NormedSpace.FunctionSeries import Mathlib.Topology.Algebra.InfiniteSum.UniformOn @@ -22,15 +23,17 @@ open Set Metric TopologicalSpace Function Filter open scoped Topology NNReal +section UniformlyOn + variable {α β F : Type*} [NormedAddCommGroup F] [CompleteSpace F] {u : α → ℝ} theorem HasSumUniformlyOn_of_bounded {f : α → β → F} (hu : Summable u) {s : Set β} - (hfu : ∀ n x, x ∈ s → ‖f n x‖ ≤ u n) : HasSumUniformlyOn f (fun x => ∑' n, f n x) {s} := by + (hfu : ∀ n x, x ∈ s → ‖f n x‖ ≤ u n) : HasSumUniformlyOn f (fun x ↦ ∑' n, f n x) {s} := by simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, tendstoUniformlyOn_tsum hu hfu] theorem HasSumUniformlyOn_of_cofinite_eventually {ι : Type*} {f : ι → β → F} {u : ι → ℝ} (hu : Summable u) {s : Set β} (hfu : ∀ᶠ n in cofinite, ∀ x ∈ s, ‖f n x‖ ≤ u n) : - HasSumUniformlyOn f (fun x => ∑' n, f n x) {s} := by + HasSumUniformlyOn f (fun x ↦ ∑' n, f n x) {s} := by simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, tendstoUniformlyOn_tsum_of_cofinite_eventually hu hfu] @@ -38,31 +41,57 @@ lemma SummableLocallyUniformlyOn_of_locally_bounded [TopologicalSpace β] [Local (f : α → β → F) {s : Set β} (hs : IsOpen s) (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ ∀ n (k : K), ‖f n k‖ ≤ u n) : SummableLocallyUniformlyOn f s := by - apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := (fun x => ∑' i, f i x)) + apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := (fun x ↦ ∑' i, f i x)) rw [hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn, tendstoLocallyUniformlyOn_iff_forall_isCompact hs] intro K hK hKc obtain ⟨u, hu1, hu2⟩ := hu K hK hKc apply tendstoUniformlyOn_tsum hu1 fun n x hx ↦ hu2 n ⟨x, hx⟩ +end UniformlyOn + +variable {ι F E : Type*} [NontriviallyNormedField E] [IsRCLikeNormedField E] + [NormedField F] [NormedSpace E F] {s : Set E} + /-- The `derivWithin` of a absolutely and uniformly converget sum on an open set `s` is the sum of the derivatives of squence of functions on the open set `s` -/ -theorem derivWithin_tsum {F E : Type*} [NontriviallyNormedField E] [IsRCLikeNormedField E] - [NormedField F] [NormedSpace E F] (f : α → E → F) {s : Set E} - (hs : IsOpen s) {x : E} (hx : x ∈ s) (hf : ∀ y ∈ s, Summable fun n ↦ f n y) +theorem derivWithin_tsum {f : ι → E → F} (hs : IsOpen s) {x : E} (hx : x ∈ s) + (hf : ∀ y ∈ s, Summable fun n ↦ f n y) (h : SummableLocallyUniformlyOn (fun n ↦ (derivWithin (fun z ↦ f n z) s)) s) (hf2 : ∀ n r, r ∈ s → DifferentiableAt E (f n) r) : - derivWithin (fun z ↦ ∑' n , f n z) s x = ∑' n, derivWithin (fun z ↦ f n z) s x := by - apply HasDerivWithinAt.derivWithin ?_ (IsOpen.uniqueDiffWithinAt hs hx) + derivWithin (fun z ↦ ∑' n , f n z) s x = ∑' n, derivWithin (f n) s x := by + apply HasDerivWithinAt.derivWithin ?_ (hs.uniqueDiffWithinAt hx) apply HasDerivAt.hasDerivWithinAt - apply hasDerivAt_of_tendstoLocallyUniformlyOn hs _ _ (fun y hy ↦ Summable.hasSum (hf y hy)) hx - · use fun n : Finset α ↦ fun a ↦ ∑ i ∈ n, derivWithin (fun z ↦ f i z) s a + apply hasDerivAt_of_tendstoLocallyUniformlyOn hs _ _ (fun y hy ↦(hf y hy).hasSum ) hx + (f' := fun n : Finset ι ↦ fun a ↦ ∑ i ∈ n, derivWithin (fun z ↦ f i z) s a) · obtain ⟨g, hg⟩ := h apply (hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp hg).congr_right - exact fun _ hb ↦ Eq.symm (HasSumLocallyUniformlyOn.tsum_eqOn hg hb) - · filter_upwards with t r hr - apply HasDerivAt.fun_sum - intro q hq - apply HasDerivWithinAt.hasDerivAt - · exact DifferentiableWithinAt.hasDerivWithinAt (hf2 q r hr).differentiableWithinAt - · exact IsOpen.mem_nhds hs hr + exact fun _ hb ↦ Eq.symm (hg.tsum_eqOn hb) + · filter_upwards with t r hr using HasDerivAt.fun_sum + (fun q hq ↦ ((hf2 q r hr).differentiableWithinAt.hasDerivWithinAt.hasDerivAt) + (hs.mem_nhds hr)) + +/-- If a sum of functions `∑ fₙ (z)` is summable for each `z` in an open set `s`, and +the `k`-th iterated derivatives of `fₙ` are summable locally uniformly on `s` for `1 ≤ k ≤ m`, +and each `fₙ` is `m`-times differentiable, then the `m`-th iterated derivative of the sum +is the sum of the `m`-th iterated derivatives. -/ +theorem iteratedDerivWithin_tsum [DecidableEq ι] (f : ι → E → F) (m : ℕ) (hs : IsOpen s) + {x : E} (hx : x ∈ s) (hsum : ∀ t ∈ s, Summable (fun n : ι ↦ f n t)) + (h : ∀ k, 1 ≤ k → k ≤ m → SummableLocallyUniformlyOn + (fun n ↦ (iteratedDerivWithin k (fun z ↦ f n z) s)) s) + (hf2 : ∀ n k r, k ≤ m → r ∈ s → + DifferentiableAt E (iteratedDerivWithin k (fun z ↦ f n z) s) r) : + iteratedDerivWithin m (fun z ↦ ∑' n , f n z) s x = ∑' n, iteratedDerivWithin m (f n) s x := by + induction' m with m hm generalizing x + · simp + · simp_rw [iteratedDerivWithin_succ] + rw [← derivWithin_tsum hs hx _ _ (fun n r hr ↦ hf2 n m r (by omega) hr)] + · exact derivWithin_congr (fun t ht ↦ hm ht (fun k hk1 hkm ↦ h k hk1 (by omega)) + (fun k r e hr he ↦ hf2 k r e (by omega) he)) (hm hx (fun k hk1 hkm ↦ h k hk1 (by omega)) + (fun k r e hr he ↦ hf2 k r e (by omega) he)) + · intro r hr + by_cases hm2 : m = 0 + · simp [hm2, hsum r hr] + · exact ((h m (by omega) (by omega)).summable hr).congr (fun _ ↦ by simp) + · exact SummableLocallyUniformlyOn_congr _ _ + (fun i ⦃t⦄ ht ↦ iteratedDerivWithin_succ) (h (m + 1) (by omega) (by omega)) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean index ec1ec82a296ece..ce3ffaee7e8a28 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean @@ -224,6 +224,13 @@ theorem HasProdLocallyUniformlyOn.tprod_eqOn [T2Space α] (h : HasProdLocallyUniformlyOn f g s) : Set.EqOn (∏' i, f i ·) g s := fun _ hx ↦ (h.hasProd hx).tprod_eq +@[to_additive] +lemma MultipliableLocallyUniformlyOn_congr [DecidableEq ι] [T2Space α] + (f f' : ι → β → α) (h : ∀ i, s.EqOn (f i) (f' i)) + (h2 : MultipliableLocallyUniformlyOn f s) : MultipliableLocallyUniformlyOn f' s := by + apply HasProdLocallyUniformlyOn.multipliableLocallyUniformlyOn + exact (h2.hasProdLocallyUniformlyOn).congr fun v ↦ eqOn_fun_finsetProd s h v + @[to_additive] lemma HasProdLocallyUniformlyOn.tendstoLocallyUniformlyOn_finsetRange {f : ℕ → β → α} (h : HasProdLocallyUniformlyOn f g s) : From 612c83a5260eb0e3cdb8a1ce2ceae49936aacc26 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 13:43:28 +0100 Subject: [PATCH 015/128] updates --- Mathlib/Algebra/BigOperators/Pi.lean | 13 ++++--------- .../Algebra/InfiniteSum/TsumUniformlyOn.lean | 5 +++-- Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Pi.lean b/Mathlib/Algebra/BigOperators/Pi.lean index a177831e41602e..4972526617d62b 100644 --- a/Mathlib/Algebra/BigOperators/Pi.lean +++ b/Mathlib/Algebra/BigOperators/Pi.lean @@ -210,20 +210,15 @@ section EqOn @[to_additive] theorem eqOn_finsetProd {ι α β : Type*} [CommMonoid α] [DecidableEq ι] - (s : Set β) {f f' : ι → β → α} (h : ∀ (i : ι), Set.EqOn (f i) (f' i) s) (v : Finset ι) : + {s : Set β} {f f' : ι → β → α} (h : ∀ (i : ι), Set.EqOn (f i) (f' i) s) (v : Finset ι) : Set.EqOn (∏ i ∈ v, f i) (∏ i ∈ v, f' i) s := by intro t ht - simp only [Finset.prod_apply] at * - congr - exact funext fun i ↦ h i ht + simp [funext fun i ↦ h i ht] @[to_additive] theorem eqOn_fun_finsetProd {ι α β : Type*} [CommMonoid α] [DecidableEq ι] - (s : Set β) {f f' : ι → β → α} (h : ∀ (i : ι), Set.EqOn (f i) (f' i) s) (v : Finset ι) : + {s : Set β} {f f' : ι → β → α} (h : ∀ (i : ι), Set.EqOn (f i) (f' i) s) (v : Finset ι) : Set.EqOn (fun b ↦ ∏ i ∈ v, f i b) (fun b ↦ ∏ i ∈ v, f' i b) s := by - intro t ht - simp only at * - congr - exact funext fun i ↦ h i ht + convert eqOn_finsetProd h v <;> simp end EqOn diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index 2aafa8d875bb8e..f8d1ab6e9f9bce 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -9,13 +9,14 @@ import Mathlib.Analysis.NormedSpace.FunctionSeries import Mathlib.Topology.Algebra.InfiniteSum.UniformOn /-! -# Continuity of series of functions +# Differentiability of sum of functions We prove some HasSumUniformlyOn versions of theorems from `Mathlib.Analysis.NormedSpace.FunctionSeries`. Alongside this we prove `derivWithin_tsum` which states that the derivative of a series of functions -is the sum of the derivatives, under suitable conditions. +is the sum of the derivatives, under suitable conditions we also prove an `iteratedDerivWithin` +version. -/ diff --git a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean index ce3ffaee7e8a28..7799229c3fa067 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean @@ -229,7 +229,7 @@ lemma MultipliableLocallyUniformlyOn_congr [DecidableEq ι] [T2Space α] (f f' : ι → β → α) (h : ∀ i, s.EqOn (f i) (f' i)) (h2 : MultipliableLocallyUniformlyOn f s) : MultipliableLocallyUniformlyOn f' s := by apply HasProdLocallyUniformlyOn.multipliableLocallyUniformlyOn - exact (h2.hasProdLocallyUniformlyOn).congr fun v ↦ eqOn_fun_finsetProd s h v + exact (h2.hasProdLocallyUniformlyOn).congr fun v ↦ eqOn_fun_finsetProd h v @[to_additive] lemma HasProdLocallyUniformlyOn.tendstoLocallyUniformlyOn_finsetRange From 9a292d7dfe4b7fde9041f97677b73eb4582190f2 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 13:44:36 +0100 Subject: [PATCH 016/128] updates2 --- Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean | 4 ++-- Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index f8d1ab6e9f9bce..28ef1021fc99e1 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -94,5 +94,5 @@ theorem iteratedDerivWithin_tsum [DecidableEq ι] (f : ι → E → F) (m : ℕ) by_cases hm2 : m = 0 · simp [hm2, hsum r hr] · exact ((h m (by omega) (by omega)).summable hr).congr (fun _ ↦ by simp) - · exact SummableLocallyUniformlyOn_congr _ _ - (fun i ⦃t⦄ ht ↦ iteratedDerivWithin_succ) (h (m + 1) (by omega) (by omega)) + · exact SummableLocallyUniformlyOn_congr + (fun _ _ ht ↦ iteratedDerivWithin_succ) (h (m + 1) (by omega) (by omega)) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean index 7799229c3fa067..7d665ae42a8892 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean @@ -226,7 +226,7 @@ theorem HasProdLocallyUniformlyOn.tprod_eqOn [T2Space α] @[to_additive] lemma MultipliableLocallyUniformlyOn_congr [DecidableEq ι] [T2Space α] - (f f' : ι → β → α) (h : ∀ i, s.EqOn (f i) (f' i)) + {f f' : ι → β → α} (h : ∀ i, s.EqOn (f i) (f' i)) (h2 : MultipliableLocallyUniformlyOn f s) : MultipliableLocallyUniformlyOn f' s := by apply HasProdLocallyUniformlyOn.multipliableLocallyUniformlyOn exact (h2.hasProdLocallyUniformlyOn).congr fun v ↦ eqOn_fun_finsetProd h v From 141652a5ea83e485868a807d46cdf0e7c8ef36f6 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 14:08:00 +0100 Subject: [PATCH 017/128] fix build --- Mathlib/Algebra/BigOperators/Pi.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Pi.lean b/Mathlib/Algebra/BigOperators/Pi.lean index 4972526617d62b..62dc62f306bfd7 100644 --- a/Mathlib/Algebra/BigOperators/Pi.lean +++ b/Mathlib/Algebra/BigOperators/Pi.lean @@ -209,14 +209,14 @@ lemma Pi.mulSingle_induction [CommMonoid M] (p : (ι → M) → Prop) (f : ι section EqOn @[to_additive] -theorem eqOn_finsetProd {ι α β : Type*} [CommMonoid α] [DecidableEq ι] +theorem eqOn_finsetProd {ι α β : Type*} [CommMonoid α] {s : Set β} {f f' : ι → β → α} (h : ∀ (i : ι), Set.EqOn (f i) (f' i) s) (v : Finset ι) : Set.EqOn (∏ i ∈ v, f i) (∏ i ∈ v, f' i) s := by intro t ht simp [funext fun i ↦ h i ht] @[to_additive] -theorem eqOn_fun_finsetProd {ι α β : Type*} [CommMonoid α] [DecidableEq ι] +theorem eqOn_fun_finsetProd {ι α β : Type*} [CommMonoid α] {s : Set β} {f f' : ι → β → α} (h : ∀ (i : ι), Set.EqOn (f i) (f' i) s) (v : Finset ι) : Set.EqOn (fun b ↦ ∏ i ∈ v, f i b) (fun b ↦ ∏ i ∈ v, f' i b) s := by convert eqOn_finsetProd h v <;> simp From 89406e30cb6f00fbd1281f630d019223a6f60081 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 14:44:17 +0100 Subject: [PATCH 018/128] fix --- Mathlib/Analysis/Calculus/Deriv/ZPow.lean | 28 +++++++++++++++++++ .../Analysis/Calculus/IteratedDeriv/Defs.lean | 17 +++++++++++ .../Calculus/IteratedDeriv/Lemmas.lean | 7 +++++ .../Algebra/InfiniteSum/TsumUniformlyOn.lean | 2 +- .../Algebra/InfiniteSum/UniformOn.lean | 2 +- 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean index 008174be2f0c3f..761fe9cff7064f 100644 --- a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean +++ b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean @@ -5,6 +5,7 @@ Authors: Sébastien Gouëzel, Yury Kudryashov -/ import Mathlib.Analysis.Calculus.Deriv.Pow import Mathlib.Analysis.Calculus.Deriv.Inv +import Mathlib.Analysis.Calculus.Deriv.Shift /-! # Derivatives of `x ^ m`, `m : ℤ` @@ -133,6 +134,33 @@ theorem iter_deriv_inv' (k : ℕ) : deriv^[k] Inv.inv = fun x : 𝕜 => (-1) ^ k * k ! * x ^ (-1 - k : ℤ) := funext (iter_deriv_inv k) +open Function in +theorem iter_deriv_inv_linear (k : ℕ) (c d : 𝕜) : + deriv^[k] (fun x ↦ (d * x + c)⁻¹) = + (fun x : 𝕜 ↦ (-1) ^ k * k ! * d ^ k * (d * x + c)^ (-1 - k : ℤ)) := by + induction' k with k ihk + · simp + · rw [Nat.factorial_succ, show k + 1 = 1 + k by ring, iterate_add_apply, ihk] + ext z + simp only [Int.reduceNeg, iterate_one, deriv_const_mul_field', + Nat.cast_add, Nat.cast_one] + by_cases hd : d = 0 + · simp [hd] + · have := deriv_comp_add_const (fun x ↦ (d * x) ^ (-1 - k : ℤ)) (c / d) z + have h0 : (fun x ↦ (d * (x + c / d)) ^ (-1 - (k : ℤ))) = + (fun x ↦ (d * x + c) ^ (-1 - (k : ℤ))) := by + ext y + field_simp + ring_nf + rw [h0, deriv_comp_mul_left d (fun x ↦ (x) ^ (-1 - k : ℤ)) (z + c / d)] at this + field_simp [this] + ring_nf + +theorem iter_deriv_inv_linear_sub (k : ℕ) (c d : 𝕜) : + deriv^[k] (fun x ↦ (d * x - c)⁻¹) = + (fun x : 𝕜 ↦ (-1) ^ k * k ! * d ^ k * (d * x - c)^ (-1 - k : ℤ)) := by + simpa [sub_eq_add_neg] using iter_deriv_inv_linear k (-c) d + variable {f : E → 𝕜} {t : Set E} {a : E} theorem DifferentiableWithinAt.zpow (hf : DifferentiableWithinAt 𝕜 f t a) (h : f a ≠ 0 ∨ 0 ≤ m) : diff --git a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean index 66fe7dd088c306..6ebd29398ed289 100644 --- a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean +++ b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean @@ -298,6 +298,23 @@ theorem iteratedDeriv_eq_iterate : iteratedDeriv n f = deriv^[n] f := by convert iteratedDerivWithin_eq_iterate (F := F) simp [derivWithin_univ] +theorem iteratedDerivWithin_of_isOpen (hs : IsOpen s) : + Set.EqOn (iteratedDerivWithin n f s) (iteratedDeriv n f) s := by + unfold iteratedDerivWithin iteratedDeriv + intro x hx + simp_rw [iteratedFDerivWithin_of_isOpen n hs hx] + +theorem iteratedDerivWithin_congr_of_isOpen (f : 𝕜 → F) (n : ℕ) {s t : Set 𝕜} (hs : IsOpen s) + (ht : IsOpen t) : (s ∩ t).EqOn (iteratedDerivWithin n f s) (iteratedDerivWithin n f t) := by + intro r hr + rw [iteratedDerivWithin_of_isOpen hs hr.1, iteratedDerivWithin_of_isOpen ht hr.2] + +theorem iteratedDerivWithin_of_isOpen_eq_iterate (hs : IsOpen s) : + EqOn (iteratedDerivWithin n f s) (deriv^[n] f) s := by + apply Set.EqOn.trans (iteratedDerivWithin_of_isOpen hs) + rw [iteratedDeriv_eq_iterate] + exact fun ⦃x⦄ ↦ congrFun rfl + /-- The `n+1`-th iterated derivative can be obtained by taking the `n`-th derivative of the derivative. -/ theorem iteratedDeriv_succ' : iteratedDeriv (n + 1) f = iteratedDeriv n (deriv f) := by diff --git a/Mathlib/Analysis/Calculus/IteratedDeriv/Lemmas.lean b/Mathlib/Analysis/Calculus/IteratedDeriv/Lemmas.lean index 5c789a9df962c9..b0c57b26cb4dc6 100644 --- a/Mathlib/Analysis/Calculus/IteratedDeriv/Lemmas.lean +++ b/Mathlib/Analysis/Calculus/IteratedDeriv/Lemmas.lean @@ -42,6 +42,13 @@ theorem iteratedDerivWithin_add simp_rw [iteratedDerivWithin, iteratedFDerivWithin_add_apply hf hg h hx, ContinuousMultilinearMap.add_apply] +include h hx in +theorem iteratedDerivWithin_fun_add + (hf : ContDiffWithinAt 𝕜 n f s x) (hg : ContDiffWithinAt 𝕜 n g s x) : + iteratedDerivWithin n (fun z ↦ f z + g z) s x = + iteratedDerivWithin n f s x + iteratedDerivWithin n g s x := by + simpa using iteratedDerivWithin_add hx h hf hg + theorem iteratedDerivWithin_const_add (hn : 0 < n) (c : F) : iteratedDerivWithin n (fun z => c + f z) s x = iteratedDerivWithin n f s x := by obtain ⟨n, rfl⟩ := n.exists_eq_succ_of_ne_zero hn.ne' diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index 28ef1021fc99e1..637bc3ed6ee9e1 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -76,7 +76,7 @@ theorem derivWithin_tsum {f : ι → E → F} (hs : IsOpen s) {x : E} (hx : x the `k`-th iterated derivatives of `fₙ` are summable locally uniformly on `s` for `1 ≤ k ≤ m`, and each `fₙ` is `m`-times differentiable, then the `m`-th iterated derivative of the sum is the sum of the `m`-th iterated derivatives. -/ -theorem iteratedDerivWithin_tsum [DecidableEq ι] (f : ι → E → F) (m : ℕ) (hs : IsOpen s) +theorem iteratedDerivWithin_tsum {f : ι → E → F} (m : ℕ) (hs : IsOpen s) {x : E} (hx : x ∈ s) (hsum : ∀ t ∈ s, Summable (fun n : ι ↦ f n t)) (h : ∀ k, 1 ≤ k → k ≤ m → SummableLocallyUniformlyOn (fun n ↦ (iteratedDerivWithin k (fun z ↦ f n z) s)) s) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean index 7d665ae42a8892..d9de6488cf76cf 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/UniformOn.lean @@ -225,7 +225,7 @@ theorem HasProdLocallyUniformlyOn.tprod_eqOn [T2Space α] fun _ hx ↦ (h.hasProd hx).tprod_eq @[to_additive] -lemma MultipliableLocallyUniformlyOn_congr [DecidableEq ι] [T2Space α] +lemma MultipliableLocallyUniformlyOn_congr [T2Space α] {f f' : ι → β → α} (h : ∀ i, s.EqOn (f i) (f' i)) (h2 : MultipliableLocallyUniformlyOn f s) : MultipliableLocallyUniformlyOn f' s := by apply HasProdLocallyUniformlyOn.multipliableLocallyUniformlyOn From 8f1c4a31f9e737878fb31db66f1c5759d11b9310 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 14:53:28 +0100 Subject: [PATCH 019/128] Add itereatedDerivWithin version of zpow lemmas --- Mathlib/Analysis/Calculus/Deriv/ZPow.lean | 28 +++++++++++++++++++ .../Analysis/Calculus/IteratedDeriv/Defs.lean | 17 +++++++++++ 2 files changed, 45 insertions(+) diff --git a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean index 008174be2f0c3f..e401d7b0cbe2d8 100644 --- a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean +++ b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean @@ -5,6 +5,7 @@ Authors: Sébastien Gouëzel, Yury Kudryashov -/ import Mathlib.Analysis.Calculus.Deriv.Pow import Mathlib.Analysis.Calculus.Deriv.Inv +import Mathlib.Analysis.Calculus.Deriv.Shift /-! # Derivatives of `x ^ m`, `m : ℤ` @@ -133,6 +134,33 @@ theorem iter_deriv_inv' (k : ℕ) : deriv^[k] Inv.inv = fun x : 𝕜 => (-1) ^ k * k ! * x ^ (-1 - k : ℤ) := funext (iter_deriv_inv k) +open Function in +theorem iter_deriv_inv_linear (k : ℕ) (c d : 𝕜) : + deriv^[k] (fun x ↦ (c * x + d)⁻¹) = + (fun x : 𝕜 ↦ (-1) ^ k * k ! * c ^ k * (c * x + d)^ (-1 - k : ℤ)) := by + induction' k with k ihk + · simp + · rw [Nat.factorial_succ, show k + 1 = 1 + k by ring, iterate_add_apply, ihk] + ext z + simp only [Int.reduceNeg, iterate_one, deriv_const_mul_field', + Nat.cast_add, Nat.cast_one] + by_cases hd : c = 0 + · simp [hd] + · have := deriv_comp_add_const (fun x ↦ (c * x) ^ (-1 - k : ℤ)) (d / c) z + have h0 : (fun x ↦ (c * (x + d / c)) ^ (-1 - (k : ℤ))) = + (fun x ↦ (c * x + d) ^ (-1 - (k : ℤ))) := by + ext y + field_simp + ring_nf + rw [h0, deriv_comp_mul_left c (fun x ↦ (x) ^ (-1 - k : ℤ)) (z + d / c)] at this + field_simp [this] + ring_nf + +theorem iter_deriv_inv_linear_sub (k : ℕ) (c d : 𝕜) : + deriv^[k] (fun x ↦ (c * x - d)⁻¹) = + (fun x : 𝕜 ↦ (-1) ^ k * k ! * c ^ k * (c * x - d)^ (-1 - k : ℤ)) := by + simpa [sub_eq_add_neg] using iter_deriv_inv_linear k c (-d) + variable {f : E → 𝕜} {t : Set E} {a : E} theorem DifferentiableWithinAt.zpow (hf : DifferentiableWithinAt 𝕜 f t a) (h : f a ≠ 0 ∨ 0 ≤ m) : diff --git a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean index 66fe7dd088c306..6ebd29398ed289 100644 --- a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean +++ b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean @@ -298,6 +298,23 @@ theorem iteratedDeriv_eq_iterate : iteratedDeriv n f = deriv^[n] f := by convert iteratedDerivWithin_eq_iterate (F := F) simp [derivWithin_univ] +theorem iteratedDerivWithin_of_isOpen (hs : IsOpen s) : + Set.EqOn (iteratedDerivWithin n f s) (iteratedDeriv n f) s := by + unfold iteratedDerivWithin iteratedDeriv + intro x hx + simp_rw [iteratedFDerivWithin_of_isOpen n hs hx] + +theorem iteratedDerivWithin_congr_of_isOpen (f : 𝕜 → F) (n : ℕ) {s t : Set 𝕜} (hs : IsOpen s) + (ht : IsOpen t) : (s ∩ t).EqOn (iteratedDerivWithin n f s) (iteratedDerivWithin n f t) := by + intro r hr + rw [iteratedDerivWithin_of_isOpen hs hr.1, iteratedDerivWithin_of_isOpen ht hr.2] + +theorem iteratedDerivWithin_of_isOpen_eq_iterate (hs : IsOpen s) : + EqOn (iteratedDerivWithin n f s) (deriv^[n] f) s := by + apply Set.EqOn.trans (iteratedDerivWithin_of_isOpen hs) + rw [iteratedDeriv_eq_iterate] + exact fun ⦃x⦄ ↦ congrFun rfl + /-- The `n+1`-th iterated derivative can be obtained by taking the `n`-th derivative of the derivative. -/ theorem iteratedDeriv_succ' : iteratedDeriv (n + 1) f = iteratedDeriv n (deriv f) := by From df2bf4a452b54be99323c85db3871275420b7cac Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 14:56:27 +0100 Subject: [PATCH 020/128] add file! --- Mathlib.lean | 1 + .../Calculus/IteratedDeriv/WithinZpow.lean | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 Mathlib/Analysis/Calculus/IteratedDeriv/WithinZpow.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9cd4968141530b..8919a5dc386f88 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1437,6 +1437,7 @@ import Mathlib.Analysis.Calculus.InverseFunctionTheorem.FiniteDimensional import Mathlib.Analysis.Calculus.IteratedDeriv.Defs import Mathlib.Analysis.Calculus.IteratedDeriv.FaaDiBruno import Mathlib.Analysis.Calculus.IteratedDeriv.Lemmas +import Mathlib.Analysis.Calculus.IteratedDeriv.WithinZpow import Mathlib.Analysis.Calculus.LHopital import Mathlib.Analysis.Calculus.LagrangeMultipliers import Mathlib.Analysis.Calculus.LineDeriv.Basic diff --git a/Mathlib/Analysis/Calculus/IteratedDeriv/WithinZpow.lean b/Mathlib/Analysis/Calculus/IteratedDeriv/WithinZpow.lean new file mode 100644 index 00000000000000..d38dd32e231c3b --- /dev/null +++ b/Mathlib/Analysis/Calculus/IteratedDeriv/WithinZpow.lean @@ -0,0 +1,34 @@ +/- +Copyright (c) 2025 Chris Birkbeck. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Birkbeck +-/ +import Mathlib.Analysis.Calculus.IteratedDeriv.Defs +import Mathlib.Analysis.Calculus.Deriv.ZPow + +/-! +# Derivatives of `x ^ m`, `m : ℤ` within an open set + +In this file we prove theorems about iterated derivatives of `x ^ m`, `m : ℤ` within an open set. + +## Keywords + +iterated, derivative, power, open set +-/ + +open scoped Nat + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {s : Set 𝕜} + +theorem iteratedDerivWithin_zpow (m : ℤ) (k : ℕ) (hs : IsOpen s) : + s.EqOn (iteratedDerivWithin k (fun y ↦ y ^ m) s) + (fun y ↦ (∏ i ∈ Finset.range k, ((m : 𝕜) - i)) * y ^ (m - k)) := by + apply Set.EqOn.trans (iteratedDerivWithin_of_isOpen_eq_iterate hs) + simp + +theorem iteratedDerivWithin_one_div (k : ℕ) (hs : IsOpen s) : + s.EqOn (iteratedDerivWithin k (fun y ↦ 1 / y) s) + (fun y ↦ (-1) ^ k * (k !) * (y ^ (-1 - k : ℤ))) := by + apply Set.EqOn.trans (iteratedDerivWithin_of_isOpen_eq_iterate hs) + intro t ht + simp only [one_div, iter_deriv_inv', Int.reduceNeg] From 217237c4fb90aea471570564d36a664827030ed3 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 15:12:35 +0100 Subject: [PATCH 021/128] fix build --- Mathlib/Analysis/Calculus/IteratedDeriv/WithinZpow.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Analysis/Calculus/IteratedDeriv/WithinZpow.lean b/Mathlib/Analysis/Calculus/IteratedDeriv/WithinZpow.lean index d38dd32e231c3b..1e532f3006280c 100644 --- a/Mathlib/Analysis/Calculus/IteratedDeriv/WithinZpow.lean +++ b/Mathlib/Analysis/Calculus/IteratedDeriv/WithinZpow.lean @@ -24,6 +24,7 @@ theorem iteratedDerivWithin_zpow (m : ℤ) (k : ℕ) (hs : IsOpen s) : s.EqOn (iteratedDerivWithin k (fun y ↦ y ^ m) s) (fun y ↦ (∏ i ∈ Finset.range k, ((m : 𝕜) - i)) * y ^ (m - k)) := by apply Set.EqOn.trans (iteratedDerivWithin_of_isOpen_eq_iterate hs) + intro t ht simp theorem iteratedDerivWithin_one_div (k : ℕ) (hs : IsOpen s) : From 17a3282fc3ede16bffb4b38ef95f78581662c7ff Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 16:53:43 +0100 Subject: [PATCH 022/128] add content --- Mathlib/Analysis/Complex/IntegerCompl.lean | 6 + .../Trigonometric/Cotangent.lean | 212 +++++++++++++++++- .../EisensteinSeries/Summable.lean | 16 ++ .../Algebra/InfiniteSum/TsumUniformlyOn.lean | 2 +- 4 files changed, 233 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/Complex/IntegerCompl.lean b/Mathlib/Analysis/Complex/IntegerCompl.lean index 5d71b18016adba..f0a5aabb1a6e6d 100644 --- a/Mathlib/Analysis/Complex/IntegerCompl.lean +++ b/Mathlib/Analysis/Complex/IntegerCompl.lean @@ -51,4 +51,10 @@ lemma integerComplement_pow_two_ne_pow_two {x : ℂ} (hx : x ∈ ℂ_ℤ) (n : simp only [sq_eq_sq_iff_eq_or_eq_neg] at * aesop +lemma upperHalfPlane_inter_integerComplement : + {z : ℂ | 0 < z.im} ∩ Complex.integerComplement = {z : ℂ | 0 < z.im} := by + ext z + simp only [Set.mem_inter_iff, Set.mem_setOf_eq, and_iff_left_iff_imp] + exact fun hz => UpperHalfPlane.coe_mem_integerComplement ⟨z, hz⟩ + end Complex diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index 68c7b70be59956..8efe194423a4eb 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -3,6 +3,7 @@ Copyright (c) 2024 Chris Birkbeck. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ +import Mathlib.Analysis.Calculus.IteratedDeriv.WithinZpow import Mathlib.Analysis.Complex.UpperHalfPlane.Exp import Mathlib.Analysis.Complex.IntegerCompl import Mathlib.Analysis.Complex.LocallyUniformLimit @@ -10,6 +11,7 @@ import Mathlib.Analysis.PSeries import Mathlib.Analysis.SpecialFunctions.Trigonometric.EulerSineProd import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Summable +import Mathlib.Topology.Algebra.InfiniteSum.TsumUniformlyOn /-! # Cotangent @@ -25,6 +27,15 @@ open Real Complex open scoped UpperHalfPlane +abbrev complexUpperHalfPlane := {z : ℂ | 0 < z.im} + +local notation "ℍₒ" => complexUpperHalfPlane + +lemma complexUpperHalPlane_isOpen : IsOpen ℍₒ := by + exact (isOpen_lt continuous_const Complex.continuous_im) + +local notation "ℂ_ℤ" => integerComplement + lemma Complex.cot_eq_exp_ratio (z : ℂ) : cot z = (Complex.exp (2 * I * z) + 1) / (I * (1 - Complex.exp (2 * I * z))) := by rw [Complex.cot, Complex.sin, Complex.cos] @@ -63,8 +74,6 @@ open Filter Function open scoped Topology BigOperators Nat Complex -local notation "ℂ_ℤ" => integerComplement - variable {x : ℂ} {Z : Set ℂ} /-- The main term in the infinite product for sine. -/ @@ -134,6 +143,15 @@ theorem sin_pi_z_ne_zero (hz : x ∈ ℂ_ℤ) : Complex.sin (π * x) ≠ 0 := by nth_rw 2 [mul_comm] exact Injective.ne (mul_right_injective₀ (ofReal_ne_zero.mpr Real.pi_ne_zero)) (by aesop) +theorem cot_pi_z_contDiffWithinAt (k : ℕ) (z : ℍ) : + ContDiffWithinAt ℂ (k) (fun x ↦ (↑π * x).cot) ℍₒ (z : ℂ) := by + simp_rw [Complex.cot, Complex.cos] + apply ContDiffWithinAt.div + · fun_prop + · simp_rw [Complex.sin] + fun_prop + · apply sin_pi_z_ne_zero (UpperHalfPlane.coe_mem_integerComplement z) + theorem tendsto_logDeriv_euler_sin_div (hx : x ∈ ℂ_ℤ) : Tendsto (fun n : ℕ ↦ logDeriv (fun z ↦ ∏ j ∈ Finset.range n, (1 + sineTerm z j)) x) atTop (𝓝 <| logDeriv (fun t ↦ (Complex.sin (π * t) / (π * t))) x) := by @@ -223,3 +241,193 @@ theorem cot_series_rep (hz : x ∈ ℂ_ℤ) : ring end MittagLeffler + +section iteratedDeriv + +open Set Complex UpperHalfPlane + +open scoped Nat + +theorem contDiffOn_inv_linear (d : ℤ) (k : ℕ) : ContDiffOn ℂ k (fun z : ℂ ↦ 1 / (z + d)) ℂ_ℤ := by + simpa using ContDiffOn.inv (by fun_prop) (fun x hx ↦ Complex.integerComplement_add_ne_zero hx d) + +theorem contDiffOn_inv_linear_sub (d : ℤ) (k : ℕ) : + ContDiffOn ℂ k (fun z : ℂ ↦ 1 / (z - d)) ℂ_ℤ := by + simpa [sub_eq_add_neg] using contDiffOn_inv_linear (-d) k + +lemma cotTerm_iteratedDeriv (d k : ℕ) : EqOn (iteratedDeriv k (fun (z : ℂ) ↦ cotTerm z d)) + (fun z : ℂ ↦ (-1) ^ k * k ! * ((z + (d + 1)) ^ (-1 - k : ℤ) + + (z - (d + 1)) ^ (-1 - k : ℤ))) ℂ_ℤ := by + intro z hz + have h1 : (fun z : ℂ ↦ 1 / (z - (d + 1)) + 1 / (z + (d + 1))) = + (fun z : ℂ ↦ 1 / (z - (d + 1))) + fun z : ℂ ↦ 1 / (z + (d +1)) := by rfl + rw [h1, iteratedDeriv_add ?_] + · have h2 := iter_deriv_inv_linear_sub k 1 ((d + 1 : ℂ)) + have h3 := iter_deriv_inv_linear k 1 (d + 1 : ℂ) + simp only [one_div, one_mul, one_pow, mul_one, Int.reduceNeg, iteratedDeriv_eq_iterate] at * + rw [h2, h3] + ring + · simpa using (contDiffOn_inv_linear (d + 1) k).contDiffAt + (IsOpen.mem_nhds (by apply Complex.isOpen_compl_range_intCast) hz) + · simpa using (contDiffOn_inv_linear_sub (d + 1) k).contDiffAt + (IsOpen.mem_nhds (by apply Complex.isOpen_compl_range_intCast) hz) + +lemma cotTerm_iteratedDerivWith (d k : ℕ) : + EqOn (iteratedDerivWithin k (fun (z : ℂ) ↦ cotTerm z d) ℂ_ℤ) + (fun z : ℂ ↦ (-1) ^ k * k ! * ((z + (d + 1)) ^ (-1 - k : ℤ) + + (z - (d + 1)) ^ (-1 - k : ℤ))) ℂ_ℤ := by + apply Set.EqOn.trans (iteratedDerivWithin_of_isOpen Complex.isOpen_compl_range_intCast) + apply cotTerm_iteratedDeriv + +lemma cotTerm_iteratedDerivWith' (d k : ℕ) : + EqOn (iteratedDerivWithin k (fun (z : ℂ) ↦ cotTerm z d) ℍₒ) + (fun z : ℂ ↦ (-1) ^ k * k ! * ((z + (d + 1)) ^ (-1 - k : ℤ) + + (z - (d + 1)) ^ (-1 - k : ℤ))) ℍₒ := by + apply Set.EqOn.trans (upperHalfPlane_inter_integerComplement ▸ + iteratedDerivWithin_congr_of_isOpen (fun (z : ℂ) ↦ cotTerm z d) k + complexUpperHalPlane_isOpen (Complex.isOpen_compl_range_intCast)) + intro z hz + simpa using cotTerm_iteratedDerivWith d k (UpperHalfPlane.coe_mem_integerComplement ⟨z, hz⟩) + +open EisensteinSeries in +private noncomputable abbrev cotTermUpperBound (A B : ℝ) (hB : 0 < B) (k a : ℕ) := + k ! * (2 * (r (⟨⟨A, B⟩, by simp [hB]⟩) ^ (-1 - (k : ℤ))) * ‖ ((a + 1) ^ (-1 - (k : ℤ)) : ℝ)‖) + +private lemma Summable_cotTermUpperBound (A B : ℝ) (hB : 0 < B) {k : ℕ} (hk : 1 ≤ k) : + Summable fun a : ℕ ↦ cotTermUpperBound A B hB k a := by + simp_rw [← mul_assoc] + apply Summable.mul_left + apply ((summable_nat_add_iff 1).mpr (summable_int_iff_summable_nat_and_neg.mp + (EisensteinSeries.linear_right_summable 0 1 (k := k + 1) (by omega))).1).norm.congr + simp only [Int.cast_one, mul_zero, Nat.cast_add, Nat.cast_one, Int.cast_add, Int.cast_natCast, + zero_add, ← zpow_neg, neg_add_rev, Int.reduceNeg, norm_zpow, sub_eq_add_neg, Real.norm_eq_abs] + norm_cast + exact fun n ↦ rfl + +open EisensteinSeries in +private lemma iteratedDerivWithin_cotTerm_bounded_uniformly {k : ℕ} (hk : 1 ≤ k) (K : Set ℂ) + (hK : K ⊆ ℍₒ) (A B : ℝ) (hB : 0 < B) + (HABK : inclusion hK '' univ ⊆ verticalStrip A B) (n : ℕ) (a : K) : + ‖iteratedDerivWithin k (fun z ↦ cotTerm z n) ℍₒ a‖ ≤ + cotTermUpperBound A B hB k n := by + simp only [cotTerm_iteratedDerivWith' n k (hK a.2), Complex.norm_mul, norm_pow, norm_neg, + norm_one, one_pow, Complex.norm_natCast, one_mul, cotTermUpperBound, Int.reduceNeg, norm_zpow, + Real.norm_eq_abs, two_mul, add_mul] + gcongr + apply le_trans (norm_add_le _ _) + apply add_le_add + · have := summand_bound_of_mem_verticalStrip (k := (k + 1)) (by norm_cast; omega) ![1, n+1] hB + (z := ⟨a, (hK a.2)⟩) (A := A) (by aesop) + simp only [coe_setOf, image_univ, Fin.isValue, Matrix.cons_val_zero, Int.cast_one, + coe_mk_subtype, one_mul, Matrix.cons_val_one, Matrix.cons_val_fin_one, Int.cast_add, + Int.cast_natCast, neg_add_rev, abs_norm_eq_max_natAbs, Int.reduceNeg, sub_eq_add_neg, + norm_zpow, ge_iff_le] at * + norm_cast at * + · have := summand_bound_of_mem_verticalStrip (k := k + 1) (by norm_cast; omega) ![1, -(n + 1)] hB + (z := ⟨a, (hK a.2)⟩) (A := A) (by aesop) + rw [abs_norm_eq_max_natAbs_neg] at this + simp only [coe_setOf, image_univ, neg_add_rev, Int.reduceNeg, Fin.isValue, Matrix.cons_val_zero, + Int.cast_one, coe_mk_subtype, one_mul, Matrix.cons_val_one, Matrix.cons_val_fin_one, + Int.cast_add, Int.cast_neg, Int.cast_natCast, sub_eq_add_neg, norm_zpow, ge_iff_le] at * + norm_cast at * + +lemma summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm (k : ℕ) (hk : 1 ≤ k) : + SummableLocallyUniformlyOn + (fun n : ℕ ↦ iteratedDerivWithin k (fun z : ℂ ↦ cotTerm z n) ℍₒ) ℍₒ := by + apply SummableLocallyUniformlyOn_of_locally_bounded (complexUpperHalPlane_isOpen) + intro K hK hKc + have hKK2 : IsCompact (Set.image (inclusion hK) univ) := by + exact (isCompact_iff_isCompact_univ.mp hKc).image_of_continuousOn + (continuous_inclusion hK |>.continuousOn) + obtain ⟨A, B, hB, HABK⟩ := subset_verticalStrip_of_isCompact hKK2 + exact ⟨cotTermUpperBound A B hB k, Summable_cotTermUpperBound A B hB hk, + iteratedDerivWithin_cotTerm_bounded_uniformly hk K hK A B hB HABK⟩ + +theorem DifferentiableOn_iteratedDeriv_cotTerm (n l : ℕ) : + DifferentiableOn ℂ (iteratedDerivWithin l (fun z ↦ cotTerm z n) ℍₒ) ℍₒ := by + suffices DifferentiableOn ℂ + (fun z : ℂ ↦ (-1) ^ l * l ! * ((z + (n + 1)) ^ (-1 - l : ℤ) + + (z - (n + 1)) ^ (-1 - l : ℤ))) ℍₒ by + apply this.congr + intro z hz + simpa using (cotTerm_iteratedDerivWith' n l hz) + apply DifferentiableOn.const_mul + apply DifferentiableOn.add <;> apply DifferentiableOn.zpow + any_goals try {fun_prop} <;> left <;> intro x hx + · simpa [add_eq_zero_iff_neg_eq'] using (UpperHalfPlane.ne_int ⟨x, hx⟩ (-(n+1))).symm + · simpa [sub_eq_zero] using (UpperHalfPlane.ne_int ⟨x, hx⟩ ((n+1))) + +private theorem aux_summable_add (k : ℕ) (hk : 1 ≤ k) (x : ℍ) : + Summable fun (n : ℕ) ↦ ((x : ℂ) + (n + 1)) ^ (-1 - k : ℤ) := by + apply ((summable_nat_add_iff 1).mpr (summable_int_iff_summable_nat_and_neg.mp + (EisensteinSeries.linear_right_summable x 1 (k := k + 1) (by omega))).1).congr + simp [← zpow_neg, sub_eq_add_neg] + +private theorem aux_summable_neg (k : ℕ) (hk : 1 ≤ k) (x : ℍ) : + Summable fun (n : ℕ) ↦ ((x : ℂ) - (n + 1)) ^ (-1 - k : ℤ) := by + apply ((summable_nat_add_iff 1).mpr (summable_int_iff_summable_nat_and_neg.mp + (EisensteinSeries.linear_right_summable x 1 (k := k + 1) (by omega))).2).congr + simp [← zpow_neg, sub_eq_add_neg] + +-- We have this auxilary ugly version on the lhs so the the rhs looks nicer. +private theorem aux_iteratedDeriv_tsum_cotTerm {k : ℕ} (hk : 1 ≤ k) (x : ℍ) : + (-1) ^ k * (k !) * (x : ℂ) ^ (-1 - k : ℤ) + iteratedDerivWithin k + (fun z : ℂ ↦ ∑' n : ℕ, cotTerm z n) ℍₒ x = + (-1) ^ (k : ℕ) * (k : ℕ)! * ∑' n : ℤ, ((x : ℂ) + n) ^ (-1 - k : ℤ) := by + rw [iteratedDerivWithin_tsum k complexUpperHalPlane_isOpen + (by simpa using x.2) (fun t ht ↦ Summable_cotTerm (coe_mem_integerComplement ⟨t, ht⟩)) + (fun l hl hl2 ↦ summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm l hl) + (fun n l z hl hz ↦ ((DifferentiableOn_iteratedDeriv_cotTerm n l)).differentiableAt + ((IsOpen.mem_nhds (complexUpperHalPlane_isOpen) hz)))] + conv => + enter [1,2,1] + ext n + rw [cotTerm_iteratedDerivWith' n k (by simp [UpperHalfPlane.coe])] + rw [tsum_of_add_one_of_neg_add_one (by simpa using aux_summable_add k hk x) + (by simpa [sub_eq_add_neg] using aux_summable_neg k hk x), + tsum_mul_left, Summable.tsum_add (aux_summable_add k hk x) (aux_summable_neg k hk x )] + simp only [Int.reduceNeg, sub_eq_add_neg, neg_add_rev, Int.cast_add, Int.cast_natCast, + Int.cast_one, Int.cast_zero, add_zero, Int.cast_neg] + ring + +theorem iteratedDerivWithin_cot_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : + iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x) - 1 / x) ℍₒ z = + -(-1) ^ k * (k !) * ((z : ℂ) ^ (-1 - k : ℤ)) + + (-1) ^ (k : ℕ) * (k : ℕ)! * ∑' n : ℤ, ((z : ℂ) + n) ^ (-1 - k : ℤ):= by + rw [← aux_iteratedDeriv_tsum_cotTerm hk] + simp only [one_div, neg_mul, neg_add_cancel_left] + refine iteratedDerivWithin_congr ?_ z.2 + intro x hx + simpa [cotTerm] using (cot_series_rep' (UpperHalfPlane.coe_mem_integerComplement ⟨x, hx⟩)) + +theorem iteratedDerivWithin_cot_pi_z_sub_inv (k : ℕ) (z : ℍ) : + iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x) - 1 / x) ℍₒ z = + (iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z) - + (-1) ^ k * (k !) * ((z : ℂ) ^ (-1 - k : ℤ)) := by + simp_rw [sub_eq_add_neg] + rw [iteratedDerivWithin_fun_add (by apply z.2) complexUpperHalPlane_isOpen.uniqueDiffOn] + · simpa [iteratedDerivWithin_fun_neg] using iteratedDerivWithin_one_div k + complexUpperHalPlane_isOpen z.2 + · exact ContDiffWithinAt.smul (by fun_prop) (cot_pi_z_contDiffWithinAt k z) + · simp only [one_div] + apply ContDiffWithinAt.neg + exact ContDiffWithinAt.inv (by fun_prop) (ne_zero z) + +theorem iteratedDerivWithin_cot_series_rep' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : + iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z = + (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, ((z : ℂ) + n) ^ (-1 - k : ℤ):= by + have h0 := iteratedDerivWithin_cot_pi_z_sub_inv k z + rw [iteratedDerivWithin_cot_series_rep hk z, add_comm] at h0 + rw [← add_left_inj (-(-1) ^ k * ↑k ! * (z : ℂ) ^ (-1 - k : ℤ)), h0] + ring + +theorem cot_series_rep_iteratedDeriv_one_div {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : + iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z = + (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) := by + simp only [iteratedDerivWithin_cot_series_rep' hk z, Int.reduceNeg, one_div, mul_eq_mul_left_iff, + mul_eq_zero, pow_eq_zero_iff', neg_eq_zero, one_ne_zero, ne_eq, Nat.cast_eq_zero, + show -1 - (k : ℤ) = -(k + 1) by ring] + left + rfl + +end iteratedDeriv diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Summable.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Summable.lean index 76389f1b787e14..e0753ab4cf918d 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Summable.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Summable.lean @@ -48,6 +48,22 @@ theorem abs_le_right_of_norm (m n : ℤ) : |m| ≤ ‖![n, m]‖ := by rw [Int.abs_eq_natAbs] exact Preorder.le_refl _ +lemma abs_norm_eq_max_natAbs (n : ℕ) : + ‖![1, (n + 1 : ℤ)]‖ = n + 1 := by + simp only [Nat.succ_eq_add_one, Nat.reduceAdd, EisensteinSeries.norm_eq_max_natAbs, Fin.isValue, + Matrix.cons_val_zero, isUnit_one, Int.natAbs_of_isUnit, Matrix.cons_val_one, + Matrix.cons_val_fin_one, Nat.cast_max, Nat.cast_one] + norm_cast + simp + +lemma abs_norm_eq_max_natAbs_neg (n : ℕ) : + ‖![1, -(n + 1 : ℤ)]‖ = n + 1 := by + simp only [EisensteinSeries.norm_eq_max_natAbs, Fin.isValue, Matrix.cons_val_zero, isUnit_one, + Int.natAbs_of_isUnit, Matrix.cons_val_one, Matrix.cons_val_fin_one, Nat.cast_max, + Int.natAbs_neg] + norm_cast + simp + section bounding_functions /-- Auxiliary function used for bounding Eisenstein series, defined as diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index 637bc3ed6ee9e1..0a76ac12fd76cd 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -39,7 +39,7 @@ theorem HasSumUniformlyOn_of_cofinite_eventually {ι : Type*} {f : ι → β → tendstoUniformlyOn_tsum_of_cofinite_eventually hu hfu] lemma SummableLocallyUniformlyOn_of_locally_bounded [TopologicalSpace β] [LocallyCompactSpace β] - (f : α → β → F) {s : Set β} (hs : IsOpen s) + {f : α → β → F} {s : Set β} (hs : IsOpen s) (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ ∀ n (k : K), ‖f n k‖ ≤ u n) : SummableLocallyUniformlyOn f s := by apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := (fun x ↦ ∑' i, f i x)) From 96a4c6989f4f87dfee40e634dbfd996d269a70f7 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 16:57:11 +0100 Subject: [PATCH 023/128] space --- Mathlib/Analysis/Calculus/Deriv/ZPow.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean index e401d7b0cbe2d8..621cce3c107aa2 100644 --- a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean +++ b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean @@ -137,7 +137,7 @@ theorem iter_deriv_inv' (k : ℕ) : open Function in theorem iter_deriv_inv_linear (k : ℕ) (c d : 𝕜) : deriv^[k] (fun x ↦ (c * x + d)⁻¹) = - (fun x : 𝕜 ↦ (-1) ^ k * k ! * c ^ k * (c * x + d)^ (-1 - k : ℤ)) := by + (fun x : 𝕜 ↦ (-1) ^ k * k ! * c ^ k * (c * x + d) ^ (-1 - k : ℤ)) := by induction' k with k ihk · simp · rw [Nat.factorial_succ, show k + 1 = 1 + k by ring, iterate_add_apply, ihk] @@ -148,7 +148,7 @@ theorem iter_deriv_inv_linear (k : ℕ) (c d : 𝕜) : · simp [hd] · have := deriv_comp_add_const (fun x ↦ (c * x) ^ (-1 - k : ℤ)) (d / c) z have h0 : (fun x ↦ (c * (x + d / c)) ^ (-1 - (k : ℤ))) = - (fun x ↦ (c * x + d) ^ (-1 - (k : ℤ))) := by +(fun x ↦ (c * x + d) ^ (-1 - (k : ℤ))) := by ext y field_simp ring_nf @@ -158,7 +158,7 @@ theorem iter_deriv_inv_linear (k : ℕ) (c d : 𝕜) : theorem iter_deriv_inv_linear_sub (k : ℕ) (c d : 𝕜) : deriv^[k] (fun x ↦ (c * x - d)⁻¹) = - (fun x : 𝕜 ↦ (-1) ^ k * k ! * c ^ k * (c * x - d)^ (-1 - k : ℤ)) := by + (fun x : 𝕜 ↦ (-1) ^ k * k ! * c ^ k * (c * x - d) ^ (-1 - k : ℤ)) := by simpa [sub_eq_add_neg] using iter_deriv_inv_linear k c (-d) variable {f : E → 𝕜} {t : Set E} {a : E} From d38505055f7911a818b6e7ff05cc6901c5e75de4 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 17:02:35 +0100 Subject: [PATCH 024/128] fix --- Mathlib/Analysis/Calculus/Deriv/ZPow.lean | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean index 621cce3c107aa2..3bac527be8999a 100644 --- a/Mathlib/Analysis/Calculus/Deriv/ZPow.lean +++ b/Mathlib/Analysis/Calculus/Deriv/ZPow.lean @@ -134,21 +134,20 @@ theorem iter_deriv_inv' (k : ℕ) : deriv^[k] Inv.inv = fun x : 𝕜 => (-1) ^ k * k ! * x ^ (-1 - k : ℤ) := funext (iter_deriv_inv k) -open Function in +open Nat Function in theorem iter_deriv_inv_linear (k : ℕ) (c d : 𝕜) : deriv^[k] (fun x ↦ (c * x + d)⁻¹) = (fun x : 𝕜 ↦ (-1) ^ k * k ! * c ^ k * (c * x + d) ^ (-1 - k : ℤ)) := by induction' k with k ihk · simp - · rw [Nat.factorial_succ, show k + 1 = 1 + k by ring, iterate_add_apply, ihk] + · rw [factorial_succ, add_comm k 1, iterate_add_apply, ihk] ext z - simp only [Int.reduceNeg, iterate_one, deriv_const_mul_field', - Nat.cast_add, Nat.cast_one] + simp only [Int.reduceNeg, iterate_one, deriv_const_mul_field', cast_add, cast_one] by_cases hd : c = 0 · simp [hd] · have := deriv_comp_add_const (fun x ↦ (c * x) ^ (-1 - k : ℤ)) (d / c) z have h0 : (fun x ↦ (c * (x + d / c)) ^ (-1 - (k : ℤ))) = -(fun x ↦ (c * x + d) ^ (-1 - (k : ℤ))) := by + (fun x ↦ (c * x + d) ^ (-1 - (k : ℤ))) := by ext y field_simp ring_nf From cd79ab4d696684984d2596c49c369c22c1b46c9a Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 17:05:27 +0100 Subject: [PATCH 025/128] fix name --- Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean index 6ebd29398ed289..4f52ae8ddc0b0d 100644 --- a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean +++ b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean @@ -304,7 +304,7 @@ theorem iteratedDerivWithin_of_isOpen (hs : IsOpen s) : intro x hx simp_rw [iteratedFDerivWithin_of_isOpen n hs hx] -theorem iteratedDerivWithin_congr_of_isOpen (f : 𝕜 → F) (n : ℕ) {s t : Set 𝕜} (hs : IsOpen s) +theorem iteratedDerivWithin_congr_right_of_isOpen (f : 𝕜 → F) (n : ℕ) {s t : Set 𝕜} (hs : IsOpen s) (ht : IsOpen t) : (s ∩ t).EqOn (iteratedDerivWithin n f s) (iteratedDerivWithin n f t) := by intro r hr rw [iteratedDerivWithin_of_isOpen hs hr.1, iteratedDerivWithin_of_isOpen ht hr.2] diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index 8efe194423a4eb..a4003df3b8bf85 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -284,7 +284,7 @@ lemma cotTerm_iteratedDerivWith' (d k : ℕ) : (fun z : ℂ ↦ (-1) ^ k * k ! * ((z + (d + 1)) ^ (-1 - k : ℤ) + (z - (d + 1)) ^ (-1 - k : ℤ))) ℍₒ := by apply Set.EqOn.trans (upperHalfPlane_inter_integerComplement ▸ - iteratedDerivWithin_congr_of_isOpen (fun (z : ℂ) ↦ cotTerm z d) k + iteratedDerivWithin_congr_right_of_isOpen (fun (z : ℂ) ↦ cotTerm z d) k complexUpperHalPlane_isOpen (Complex.isOpen_compl_range_intCast)) intro z hz simpa using cotTerm_iteratedDerivWith d k (UpperHalfPlane.coe_mem_integerComplement ⟨z, hz⟩) From 6d05eb4220d80b3a9d6eeba4afd87e00d04ab3e9 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 16 Jul 2025 17:28:14 +0100 Subject: [PATCH 026/128] add doc string --- .../Trigonometric/Cotangent.lean | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index a4003df3b8bf85..7b1611f2134da4 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -27,6 +27,8 @@ open Real Complex open scoped UpperHalfPlane +/-- The UpperHalfPlane as a subset of `ℂ`. This is convinient for takind derivatives of functions +on the upper half plane. -/ abbrev complexUpperHalfPlane := {z : ℂ | 0 < z.im} local notation "ℍₒ" => complexUpperHalfPlane @@ -390,7 +392,7 @@ private theorem aux_iteratedDeriv_tsum_cotTerm {k : ℕ} (hk : 1 ≤ k) (x : ℍ Int.cast_one, Int.cast_zero, add_zero, Int.cast_neg] ring -theorem iteratedDerivWithin_cot_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : +theorem iteratedDerivWithin_cot_sub_inv_eq_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x) - 1 / x) ℍₒ z = -(-1) ^ k * (k !) * ((z : ℂ) ^ (-1 - k : ℤ)) + (-1) ^ (k : ℕ) * (k : ℕ)! * ∑' n : ℤ, ((z : ℂ) + n) ^ (-1 - k : ℤ):= by @@ -413,18 +415,18 @@ theorem iteratedDerivWithin_cot_pi_z_sub_inv (k : ℕ) (z : ℍ) : apply ContDiffWithinAt.neg exact ContDiffWithinAt.inv (by fun_prop) (ne_zero z) -theorem iteratedDerivWithin_cot_series_rep' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : +theorem iteratedDerivWithin_cot_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z = - (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, ((z : ℂ) + n) ^ (-1 - k : ℤ):= by + (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, ((z : ℂ) + n) ^ (-1 - k : ℤ):= by have h0 := iteratedDerivWithin_cot_pi_z_sub_inv k z - rw [iteratedDerivWithin_cot_series_rep hk z, add_comm] at h0 + rw [iteratedDerivWithin_cot_sub_inv_eq_series_rep hk z, add_comm] at h0 rw [← add_left_inj (-(-1) ^ k * ↑k ! * (z : ℂ) ^ (-1 - k : ℤ)), h0] ring -theorem cot_series_rep_iteratedDeriv_one_div {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : +theorem iteratedDerivWithin_cot_series_rep_one_div {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z = - (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) := by - simp only [iteratedDerivWithin_cot_series_rep' hk z, Int.reduceNeg, one_div, mul_eq_mul_left_iff, + (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) := by + simp only [iteratedDerivWithin_cot_series_rep hk z, Int.reduceNeg, one_div, mul_eq_mul_left_iff, mul_eq_zero, pow_eq_zero_iff', neg_eq_zero, one_ne_zero, ne_eq, Nat.cast_eq_zero, show -1 - (k : ℤ) = -(k + 1) by ring] left From 4fca1af31ea9b12740c1418467680079842f3f3d Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 17 Jul 2025 10:17:25 +0100 Subject: [PATCH 027/128] add eventually version --- .../Algebra/InfiniteSum/TsumUniformlyOn.lean | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index 637bc3ed6ee9e1..c21c74929845ef 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -38,16 +38,25 @@ theorem HasSumUniformlyOn_of_cofinite_eventually {ι : Type*} {f : ι → β → simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, tendstoUniformlyOn_tsum_of_cofinite_eventually hu hfu] -lemma SummableLocallyUniformlyOn_of_locally_bounded [TopologicalSpace β] [LocallyCompactSpace β] - (f : α → β → F) {s : Set β} (hs : IsOpen s) - (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ ∀ n (k : K), ‖f n k‖ ≤ u n) : - SummableLocallyUniformlyOn f s := by - apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := (fun x ↦ ∑' i, f i x)) +lemma SummableLocallyUniformlyOn_of_locally_bounded_eventually [TopologicalSpace β] + [LocallyCompactSpace β] {f : α → β → F} {s : Set β} (hs : IsOpen s) + (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ + ∀ᶠ n in cofinite, ∀ k ∈ K, ‖f n k‖ ≤ u n) : SummableLocallyUniformlyOn f s := by + apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := fun x ↦ ∑' n, f n x) rw [hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn, tendstoLocallyUniformlyOn_iff_forall_isCompact hs] intro K hK hKc obtain ⟨u, hu1, hu2⟩ := hu K hK hKc - apply tendstoUniformlyOn_tsum hu1 fun n x hx ↦ hu2 n ⟨x, hx⟩ + apply tendstoUniformlyOn_tsum_of_cofinite_eventually hu1 hu2 + +lemma SummableLocallyUniformlyOn_of_locally_bounded [TopologicalSpace β] [LocallyCompactSpace β] + {f : α → β → F} {s : Set β} (hs : IsOpen s) + (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ ∀ n, ∀ k ∈ K, ‖f n k‖ ≤ u n) : + SummableLocallyUniformlyOn f s := by + apply SummableLocallyUniformlyOn_of_locally_bounded_eventually hs + intro K hK hKc + obtain ⟨u, hu1, hu2⟩ := hu K hK hKc + refine ⟨u, hu1, by filter_upwards using hu2⟩ end UniformlyOn From b06ce35e9d360dab889e5c4507600b9ec46b905b Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 17 Jul 2025 10:19:07 +0100 Subject: [PATCH 028/128] update --- .../Trigonometric/Cotangent.lean | 8 ++++---- .../Algebra/InfiniteSum/TsumUniformlyOn.lean | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index 7b1611f2134da4..5f246f081015c2 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -309,24 +309,24 @@ private lemma Summable_cotTermUpperBound (A B : ℝ) (hB : 0 < B) {k : ℕ} (hk open EisensteinSeries in private lemma iteratedDerivWithin_cotTerm_bounded_uniformly {k : ℕ} (hk : 1 ≤ k) (K : Set ℂ) (hK : K ⊆ ℍₒ) (A B : ℝ) (hB : 0 < B) - (HABK : inclusion hK '' univ ⊆ verticalStrip A B) (n : ℕ) (a : K) : + (HABK : inclusion hK '' univ ⊆ verticalStrip A B) (n : ℕ) {a : ℂ} (ha : a ∈ K) : ‖iteratedDerivWithin k (fun z ↦ cotTerm z n) ℍₒ a‖ ≤ cotTermUpperBound A B hB k n := by - simp only [cotTerm_iteratedDerivWith' n k (hK a.2), Complex.norm_mul, norm_pow, norm_neg, + simp only [cotTerm_iteratedDerivWith' n k (hK ha), Complex.norm_mul, norm_pow, norm_neg, norm_one, one_pow, Complex.norm_natCast, one_mul, cotTermUpperBound, Int.reduceNeg, norm_zpow, Real.norm_eq_abs, two_mul, add_mul] gcongr apply le_trans (norm_add_le _ _) apply add_le_add · have := summand_bound_of_mem_verticalStrip (k := (k + 1)) (by norm_cast; omega) ![1, n+1] hB - (z := ⟨a, (hK a.2)⟩) (A := A) (by aesop) + (z := ⟨a, (hK ha)⟩) (A := A) (by aesop) simp only [coe_setOf, image_univ, Fin.isValue, Matrix.cons_val_zero, Int.cast_one, coe_mk_subtype, one_mul, Matrix.cons_val_one, Matrix.cons_val_fin_one, Int.cast_add, Int.cast_natCast, neg_add_rev, abs_norm_eq_max_natAbs, Int.reduceNeg, sub_eq_add_neg, norm_zpow, ge_iff_le] at * norm_cast at * · have := summand_bound_of_mem_verticalStrip (k := k + 1) (by norm_cast; omega) ![1, -(n + 1)] hB - (z := ⟨a, (hK a.2)⟩) (A := A) (by aesop) + (z := ⟨a, (hK ha)⟩) (A := A) (by aesop) rw [abs_norm_eq_max_natAbs_neg] at this simp only [coe_setOf, image_univ, neg_add_rev, Int.reduceNeg, Fin.isValue, Matrix.cons_val_zero, Int.cast_one, coe_mk_subtype, one_mul, Matrix.cons_val_one, Matrix.cons_val_fin_one, diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index 0a76ac12fd76cd..c21c74929845ef 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -38,16 +38,25 @@ theorem HasSumUniformlyOn_of_cofinite_eventually {ι : Type*} {f : ι → β → simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, tendstoUniformlyOn_tsum_of_cofinite_eventually hu hfu] +lemma SummableLocallyUniformlyOn_of_locally_bounded_eventually [TopologicalSpace β] + [LocallyCompactSpace β] {f : α → β → F} {s : Set β} (hs : IsOpen s) + (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ + ∀ᶠ n in cofinite, ∀ k ∈ K, ‖f n k‖ ≤ u n) : SummableLocallyUniformlyOn f s := by + apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := fun x ↦ ∑' n, f n x) + rw [hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn, + tendstoLocallyUniformlyOn_iff_forall_isCompact hs] + intro K hK hKc + obtain ⟨u, hu1, hu2⟩ := hu K hK hKc + apply tendstoUniformlyOn_tsum_of_cofinite_eventually hu1 hu2 + lemma SummableLocallyUniformlyOn_of_locally_bounded [TopologicalSpace β] [LocallyCompactSpace β] {f : α → β → F} {s : Set β} (hs : IsOpen s) - (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ ∀ n (k : K), ‖f n k‖ ≤ u n) : + (hu : ∀ K ⊆ s, IsCompact K → ∃ u : α → ℝ, Summable u ∧ ∀ n, ∀ k ∈ K, ‖f n k‖ ≤ u n) : SummableLocallyUniformlyOn f s := by - apply HasSumLocallyUniformlyOn.summableLocallyUniformlyOn (g := (fun x ↦ ∑' i, f i x)) - rw [hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn, - tendstoLocallyUniformlyOn_iff_forall_isCompact hs] + apply SummableLocallyUniformlyOn_of_locally_bounded_eventually hs intro K hK hKc obtain ⟨u, hu1, hu2⟩ := hu K hK hKc - apply tendstoUniformlyOn_tsum hu1 fun n x hx ↦ hu2 n ⟨x, hx⟩ + refine ⟨u, hu1, by filter_upwards using hu2⟩ end UniformlyOn From 513cd6864d00519e59c85556e70b262656915c42 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 28 Jul 2025 10:45:18 +0100 Subject: [PATCH 029/128] golf --- Mathlib/Algebra/BigOperators/Pi.lean | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Pi.lean b/Mathlib/Algebra/BigOperators/Pi.lean index 62dc62f306bfd7..571b3e8b4f06a1 100644 --- a/Mathlib/Algebra/BigOperators/Pi.lean +++ b/Mathlib/Algebra/BigOperators/Pi.lean @@ -211,9 +211,8 @@ section EqOn @[to_additive] theorem eqOn_finsetProd {ι α β : Type*} [CommMonoid α] {s : Set β} {f f' : ι → β → α} (h : ∀ (i : ι), Set.EqOn (f i) (f' i) s) (v : Finset ι) : - Set.EqOn (∏ i ∈ v, f i) (∏ i ∈ v, f' i) s := by - intro t ht - simp [funext fun i ↦ h i ht] + Set.EqOn (∏ i ∈ v, f i) (∏ i ∈ v, f' i) s := + fun t ht => by simp [funext fun i ↦ h i ht] @[to_additive] theorem eqOn_fun_finsetProd {ι α β : Type*} [CommMonoid α] From 9e6816d3c26ac63e6b35d3963f355b01613ce5ce Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 28 Jul 2025 10:53:01 +0100 Subject: [PATCH 030/128] small fixes --- .../Algebra/InfiniteSum/TsumUniformlyOn.lean | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index c21c74929845ef..524e1fab2b5a01 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -28,11 +28,11 @@ section UniformlyOn variable {α β F : Type*} [NormedAddCommGroup F] [CompleteSpace F] {u : α → ℝ} -theorem HasSumUniformlyOn_of_bounded {f : α → β → F} (hu : Summable u) {s : Set β} +theorem HasSumUniformlyOn_of_norm_le_summable {f : α → β → F} (hu : Summable u) {s : Set β} (hfu : ∀ n x, x ∈ s → ‖f n x‖ ≤ u n) : HasSumUniformlyOn f (fun x ↦ ∑' n, f n x) {s} := by simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, tendstoUniformlyOn_tsum hu hfu] -theorem HasSumUniformlyOn_of_cofinite_eventually {ι : Type*} {f : ι → β → F} {u : ι → ℝ} +theorem HasSumUniformlyOn_of_norm_le_summable_eventually {ι : Type*} {f : ι → β → F} {u : ι → ℝ} (hu : Summable u) {s : Set β} (hfu : ∀ᶠ n in cofinite, ∀ x ∈ s, ‖f n x‖ ≤ u n) : HasSumUniformlyOn f (fun x ↦ ∑' n, f n x) {s} := by simp [hasSumUniformlyOn_iff_tendstoUniformlyOn, @@ -61,10 +61,10 @@ lemma SummableLocallyUniformlyOn_of_locally_bounded [TopologicalSpace β] [Local end UniformlyOn variable {ι F E : Type*} [NontriviallyNormedField E] [IsRCLikeNormedField E] - [NormedField F] [NormedSpace E F] {s : Set E} + [NormedAddCommGroup F] [NormedSpace E F] {s : Set E} -/-- The `derivWithin` of a absolutely and uniformly converget sum on an open set `s` is the sum -of the derivatives of squence of functions on the open set `s` -/ +/-- The `derivWithin` of a sum whose derivative is absolutely and uniformly convergent sum on an +open set `s` is the sum of the derivatives of sequence of functions on the open set `s` -/ theorem derivWithin_tsum {f : ι → E → F} (hs : IsOpen s) {x : E} (hx : x ∈ s) (hf : ∀ y ∈ s, Summable fun n ↦ f n y) (h : SummableLocallyUniformlyOn (fun n ↦ (derivWithin (fun z ↦ f n z) s)) s) @@ -81,10 +81,11 @@ theorem derivWithin_tsum {f : ι → E → F} (hs : IsOpen s) {x : E} (hx : x (fun q hq ↦ ((hf2 q r hr).differentiableWithinAt.hasDerivWithinAt.hasDerivAt) (hs.mem_nhds hr)) -/-- If a sum of functions `∑ fₙ (z)` is summable for each `z` in an open set `s`, and -the `k`-th iterated derivatives of `fₙ` are summable locally uniformly on `s` for `1 ≤ k ≤ m`, -and each `fₙ` is `m`-times differentiable, then the `m`-th iterated derivative of the sum -is the sum of the `m`-th iterated derivatives. -/ +/-- If a sequence of functions `fₙ` is such that `∑ fₙ (z)` is summable for each `z` in an +open set `s`, and for each `1 ≤ k ≤ m`, the series of `k`-th iterated derivatives +`∑ (iteratedDerivWithin k fₙ s) (z)` +is summable locally uniformly on `s`, and each `fₙ` is `m`-times differentiable, then the `m`-th +iterated derivative of the sum is the sum of the `m`-th iterated derivatives. -/ theorem iteratedDerivWithin_tsum {f : ι → E → F} (m : ℕ) (hs : IsOpen s) {x : E} (hx : x ∈ s) (hsum : ∀ t ∈ s, Summable (fun n : ι ↦ f n t)) (h : ∀ k, 1 ≤ k → k ≤ m → SummableLocallyUniformlyOn From deab207047c5734aaeab8b1dad97f76fe733ad42 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 28 Jul 2025 19:19:12 +0100 Subject: [PATCH 031/128] open --- Mathlib.lean | 2 + .../Analysis/Complex/SummableUniformlyOn.lean | 27 +++ Mathlib/Data/Complex/Exponential.lean | 4 + .../EisensteinSeries/QExpansion.lean | 197 ++++++++++++++++++ .../Algebra/InfiniteSum/TsumUniformlyOn.lean | 5 +- 5 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 Mathlib/Analysis/Complex/SummableUniformlyOn.lean create mode 100644 Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean diff --git a/Mathlib.lean b/Mathlib.lean index 6a74bed5668ae5..10a2ccdb9bbb23 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1509,6 +1509,7 @@ import Mathlib.Analysis.Complex.ReImTopology import Mathlib.Analysis.Complex.RealDeriv import Mathlib.Analysis.Complex.RemovableSingularity import Mathlib.Analysis.Complex.Schwarz +import Mathlib.Analysis.Complex.SummableUniformlyOn import Mathlib.Analysis.Complex.TaylorSeries import Mathlib.Analysis.Complex.Tietze import Mathlib.Analysis.Complex.UnitDisc.Basic @@ -4678,6 +4679,7 @@ import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Basic import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Defs import Mathlib.NumberTheory.ModularForms.EisensteinSeries.IsBoundedAtImInfty import Mathlib.NumberTheory.ModularForms.EisensteinSeries.MDifferentiable +import Mathlib.NumberTheory.ModularForms.EisensteinSeries.QExpansion import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Summable import Mathlib.NumberTheory.ModularForms.EisensteinSeries.UniformConvergence import Mathlib.NumberTheory.ModularForms.Identities diff --git a/Mathlib/Analysis/Complex/SummableUniformlyOn.lean b/Mathlib/Analysis/Complex/SummableUniformlyOn.lean new file mode 100644 index 00000000000000..087393e34210d2 --- /dev/null +++ b/Mathlib/Analysis/Complex/SummableUniformlyOn.lean @@ -0,0 +1,27 @@ +/- +Copyright (c) 2025 Chris Birkbeck. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Birkbeck +-/ +import Mathlib.Analysis.CStarAlgebra.Classes +import Mathlib.Analysis.Complex.LocallyUniformLimit +import Mathlib.Topology.Algebra.InfiniteSum.UniformOn + +/-! +# Differentiability of uniformly convergent series sums of functions + +We collect some results about the differentiability of infinite sums. + +-/ + +lemma summableUniformlyOn_differentiableOn {ι E : Type*} [NormedAddCommGroup E] + [NormedSpace ℂ E] [CompleteSpace E] {f : ι → ℂ → E} {s : Set ℂ} + (hs : IsOpen s) (h : SummableLocallyUniformlyOn (fun n ↦ ((fun z ↦ f n z))) s) + (hf2 : ∀ n r, r ∈ s → DifferentiableAt ℂ (f n) r) : + DifferentiableOn ℂ (fun z ↦ ∑' n , f n z) s := by + obtain ⟨g, hg⟩ := h + have hc := (hasSumLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp hg).differentiableOn ?_ hs + · apply hc.congr + apply hg.tsum_eqOn + · filter_upwards with t r hr using + DifferentiableWithinAt.fun_sum fun a ha => (hf2 a r hr).differentiableWithinAt diff --git a/Mathlib/Data/Complex/Exponential.lean b/Mathlib/Data/Complex/Exponential.lean index ce19f466669265..fb2a42dff3e66b 100644 --- a/Mathlib/Data/Complex/Exponential.lean +++ b/Mathlib/Data/Complex/Exponential.lean @@ -142,6 +142,10 @@ theorem exp_sum {α : Type*} (s : Finset α) (f : α → ℂ) : lemma exp_nsmul (x : ℂ) (n : ℕ) : exp (n • x) = exp x ^ n := @MonoidHom.map_pow (Multiplicative ℂ) ℂ _ _ expMonoidHom _ _ +lemma exp_nsmul' (x a p : ℂ) (n : ℕ) : exp (a * n * x / p) = exp (a * x / p) ^ n := by + rw [← Complex.exp_nsmul] + ring_nf + theorem exp_nat_mul (x : ℂ) : ∀ n : ℕ, exp (n * x) = exp x ^ n | 0 => by rw [Nat.cast_zero, zero_mul, exp_zero, pow_zero] | Nat.succ n => by rw [pow_succ, Nat.cast_add_one, add_mul, exp_add, ← exp_nat_mul _ n, one_mul] diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean new file mode 100644 index 00000000000000..bd5e685f6528c9 --- /dev/null +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -0,0 +1,197 @@ +/- +Copyright (c) 2025 Chris Birkbeck. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Birkbeck +-/ +import Mathlib.Algebra.Lie.OfAssociative +import Mathlib.Analysis.CStarAlgebra.Classes +import Mathlib.Analysis.SpecialFunctions.Trigonometric.Cotangent +import Mathlib.Data.Complex.FiniteDimensional +import Mathlib.Analysis.Complex.SummableUniformlyOn + +/-! +# Einstein series Q-expansions + +We give some identities for Q-expansions of Eisenstein series that will be used in describing their +Q-expansions. + +-/ + + +open Set Metric TopologicalSpace Function Filter Complex UpperHalfPlane + +open scoped Topology Real Nat Complex Pointwise + +local notation "ℍₒ" => complexUpperHalfPlane + +/- This will be used for showing general q-exansions are summable once we know that they are big O +of `n ^ k`. TODO: once added move this to a better place. -/ +open Nat Asymptotics in +theorem summable_norm_mul_geometric_of_norm_lt_one' {F : Type*} [NormedRing F] + [NormOneClass F] [NormMulClass F] {k : ℕ} {r : F} (hr : ‖r‖ < 1) {u : ℕ → F} + (hu : u =O[atTop] (fun n ↦ ((n ^ k : ℕ) : F))) : Summable fun n : ℕ ↦ ‖u n * r ^ n‖ := by + rcases exists_between hr with ⟨r', hrr', h⟩ + apply summable_of_isBigO_nat (summable_geometric_of_lt_one ((norm_nonneg _).trans hrr'.le) h).norm + calc + fun n ↦ ‖(u n) * r ^ n‖ + _ =O[atTop] fun n ↦ ‖u n‖ * ‖r‖ ^ n := by + apply (IsBigOWith.of_bound (c := ‖(1 : ℝ)‖) ?_).isBigO + filter_upwards [eventually_norm_pow_le r] with n hn + simp + _ =O[atTop] fun n ↦ ‖((n : F) ^ k)‖ * ‖r‖ ^ n := by + simpa [Nat.cast_pow] using (Asymptotics.isBigO_norm_left.mpr + (Asymptotics.isBigO_norm_right.mpr hu)).mul (isBigO_refl (fun n => (‖r‖ ^ n)) atTop) + _ =O[atTop] fun n ↦ ‖r' ^ n‖ := by + convert Asymptotics.isBigO_norm_right.mpr (Asymptotics.isBigO_norm_left.mpr + (isLittleO_pow_const_mul_const_pow_const_pow_of_norm_lt k hrr').isBigO) + simp only [norm_pow, norm_mul] + +lemma exp_iter_deriv_within (k m : ℕ) (f : ℕ → ℂ) (p : ℝ) : + EqOn (iteratedDerivWithin k (fun s : ℂ => (f m) * cexp (2 * ↑π * Complex.I * m * s / p)) ℍₒ) + (fun s => (f m) * (2 * ↑π * Complex.I * m / p) ^ k * + cexp (2 * ↑π * Complex.I * m * s / p)) ℍₒ := by + apply EqOn.trans (iteratedDerivWithin_of_isOpen complexUpperHalPlane_isOpen) + intro x hx + rw [iteratedDeriv_const_mul (by fun_prop)] + · have : (fun s ↦ cexp (2 * ↑π * Complex.I * ↑m * s / ↑p)) = + (fun s ↦ cexp (((2 * ↑π * Complex.I * ↑m) / p) * s)) := by + ext z + ring_nf + simp only [this, iteratedDeriv_cexp_const_mul] + ring_nf + +private lemma aux_IsBigO_mul (k : ℕ) (p : ℝ) {f : ℕ → ℂ} + (hf : f =O[atTop] (fun n => (↑(n ^ k) : ℝ))) : + (fun n => f n * (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] + (fun n => (↑(n ^ (2 * k)) : ℝ)) := by + have h0 : (fun n : ℕ => (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] + (fun n => (↑(n ^ (k)) : ℝ)) := by + have h1 : (fun n : ℕ => (2 * ↑π * Complex.I * ↑n / p) ^ k) = + (fun n : ℕ => ((2 * ↑π * Complex.I / p) ^ k) * ↑n ^ k) := by + ext z + ring + simpa [h1] using (Complex.isBigO_ofReal_right.mp (Asymptotics.isBigO_const_mul_self + ((2 * ↑π * Complex.I / p) ^ k) (fun (n : ℕ) ↦ (↑(n ^ k) : ℝ)) atTop)) + simp only [Nat.cast_pow] at * + convert hf.mul h0 + ring + +open BoundedContinuousFunction in +theorem qExpansion_summableLocallyUniformlyOn (k : ℕ) {f : ℕ → ℂ} {p : ℝ} (hp : 0 < p) + (hf : f =O[atTop] (fun n => (↑(n ^ k) : ℝ))) : + SummableLocallyUniformlyOn (fun n ↦ iteratedDerivWithin k + (fun z ↦ f n * cexp (2 * ↑π * Complex.I * z / p) ^ n) ℍₒ) ℍₒ := by + apply SummableLocallyUniformlyOn_of_locally_bounded complexUpperHalPlane_isOpen + intro K hK hKc + haveI : CompactSpace K := isCompact_univ_iff.mp (isCompact_iff_isCompact_univ.mp hKc) + let c : ContinuousMap K ℂ := ⟨fun r : K => Complex.exp (2 * ↑π * Complex.I * r / p), by fun_prop⟩ + let r : ℝ := ‖mkOfCompact c‖ + have hr : ‖r‖ < 1 := by + simp only [norm_norm, r, norm_lt_iff_of_compact Real.zero_lt_one, mkOfCompact_apply, + ContinuousMap.coe_mk, c] + intro x + have h1 : cexp (2 * ↑π * Complex.I * (↑x / ↑p)) = cexp (2 * ↑π * Complex.I * ↑x / ↑p) := by + congr 1 + ring + simpa using h1 ▸ UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨((x : ℂ) / p) , by aesop⟩ + refine ⟨_, by simpa using (summable_norm_mul_geometric_of_norm_lt_one' hr + (Asymptotics.isBigO_norm_left.mpr (aux_IsBigO_mul k p hf))), ?_⟩ + intro n z hz + have h0 := pow_le_pow_left₀ (by apply norm_nonneg _) (norm_coe_le_norm (mkOfCompact c) ⟨z, hz⟩) n + simp only [← exp_nsmul', exp_iter_deriv_within k n f p (hK hz), Complex.norm_mul, norm_pow, + Complex.norm_div, Complex.norm_ofNat, norm_real, norm_I, mul_one, + Complex.norm_natCast,Nat.cast_pow, norm_mkOfCompact, mkOfCompact_apply, ContinuousMap.coe_mk, + abs_norm, ge_iff_le, r, c] at * + gcongr + convert h0 + rw [← norm_pow, ← exp_nsmul'] + +theorem cot_q_ext_summableLocallyUniformlyOn (k : ℕ) : SummableLocallyUniformlyOn + (fun n ↦ iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ) ℍₒ := by + have h0 : (fun n : ℕ => (1 : ℂ)) =O[atTop] (fun n => (↑(n ^ k) : ℝ)) := by + simp only [Nat.cast_pow, Asymptotics.isBigO_iff, norm_one, norm_pow, Real.norm_natCast, + eventually_atTop, ge_iff_le] + refine ⟨1, 1, fun b hb => ?_⟩ + norm_cast + simp [Nat.one_le_pow k b hb] + simpa using qExpansion_summableLocallyUniformlyOn k (p := 1) (by norm_num) h0 + +theorem deriv_iterderivwithin (n a : ℕ) {s : Set ℂ} (hs : IsOpen s) {r : ℂ} (hr : r ∈ s) : + DifferentiableAt ℂ (iteratedDerivWithin a (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n) s) r := by + apply DifferentiableOn.differentiableAt _ (hs.mem_nhds hr) + suffices DifferentiableOn ℂ (iteratedDeriv a (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n)) s by + apply this.congr (iteratedDerivWithin_of_isOpen hs) + fun_prop + +lemma exp_deriv (k : ℕ) (z : ℍ) : iteratedDerivWithin k + (fun z => ( ∑' n : ℕ, Complex.exp (2 * π * Complex.I * z) ^ n)) {z : ℂ | 0 < z.im} z = + ∑' n : ℕ, iteratedDerivWithin k + (fun s : ℂ => Complex.exp (2 * ↑π * Complex.I * s) ^ n) {z : ℂ | 0 < z.im} z := by + rw [iteratedDerivWithin_tsum k complexUpperHalPlane_isOpen (by simpa using z.2)] + · exact fun x hx => summable_geometric_iff_norm_lt_one.mpr + (UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨x, hx⟩) + · exact fun n _ _ => cot_q_ext_summableLocallyUniformlyOn n + · exact fun n l z hl hz => deriv_iterderivwithin n l complexUpperHalPlane_isOpen hz + +theorem tsum_uexp_contDiffOn (k : ℕ) : + ContDiffOn ℂ k (fun z : ℂ => ∑' n : ℕ, Complex.exp (2 * ↑π * Complex.I * z) ^ n) ℍₒ := + contDiffOn_of_differentiableOn_deriv fun m _ z hz => + ((summableUniformlyOn_differentiableOn complexUpperHalPlane_isOpen + (cot_q_ext_summableLocallyUniformlyOn m) + (fun n _ hz => deriv_iterderivwithin n m complexUpperHalPlane_isOpen hz)) z hz).congr + (fun z hz => exp_deriv m ⟨z, hz⟩) (exp_deriv m ⟨z, hz⟩) + +private lemma exp_deriv' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : + iteratedDerivWithin k (fun z => (((π : ℂ) * Complex.I) - + (2 * π * Complex.I) * ∑' n : ℕ, Complex.exp (2 * π * Complex.I * z) ^ n)) ℍₒ z = + -(2 * π * Complex.I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by + suffices + iteratedDerivWithin k (fun z => (((π : ℂ) * Complex.I) - + (2 * π * Complex.I) * ∑' n : ℕ, Complex.exp (2 * π * Complex.I * z) ^ n)) {z : ℂ | 0 < z.im} z = + -(2 * π * Complex.I) * ∑' n : ℕ, iteratedDerivWithin k + (fun s : ℂ => Complex.exp (2 * ↑π * Complex.I * s) ^ n) {z : ℂ | 0 < z.im} z by + have h : -(2 * ↑π * Complex.I * (2 * ↑π * Complex.I) ^ k) * + ∑' (n : ℕ), ↑n ^ k * cexp (2 * ↑π * Complex.I * ↑z) ^ n = -(2 * π * Complex.I) * + ∑' n : ℕ, (2 * ↑π * Complex.I * n) ^ k * Complex.exp (2 * ↑π * Complex.I * z) ^ n := by + simp_rw [← tsum_mul_left] + congr + ext y + ring + simp only [h, neg_mul, show k + 1 = 1 + k by ring, pow_add, pow_one, this, neg_inj, + mul_eq_mul_left_iff, mul_eq_zero, OfNat.ofNat_ne_zero, ofReal_eq_zero, I_ne_zero, + or_false, Real.pi_ne_zero] + congr + ext n + have := exp_nsmul' (p := 1) (a := 2 * π * Complex.I) (n := n) + simp only [div_one] at this + simpa [this, ofReal_one, div_one, one_mul, UpperHalfPlane.coe] using + exp_iter_deriv_within k n (fun n => 1) 1 z.2 + rw [iteratedDerivWithin_const_sub hk , iteratedDerivWithin_fun_neg, iteratedDerivWithin_const_mul] + · simp only [exp_deriv, neg_mul] + · simpa using z.2 + · exact complexUpperHalPlane_isOpen.uniqueDiffOn + · exact (tsum_uexp_contDiffOn k).contDiffWithinAt (by simpa using z.2) + +theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : + ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = + ((-2 * π * Complex.I) ^ (k + 1) / (k !)) * + ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by + suffices (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = + -(2 * π * Complex.I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n by + simp_rw [(eq_inv_mul_iff_mul_eq₀ (by simp [Nat.factorial_ne_zero])).mpr + this, ← tsum_mul_left] + congr + ext n + have h3 : (k ! : ℂ) ≠ 0 := by + norm_cast + apply Nat.factorial_ne_zero + rw [show (-2 * ↑π * Complex.I) ^ (k + 1) = (-1)^ (k + 1) * (2 * π * Complex.I) ^ (k + 1) by + rw [← neg_pow]; ring] + field_simp [h3] + ring_nf + simp [Nat.mul_two] + rw [← exp_deriv' hk z, ← iteratedDerivWithin_cot_series_rep_one_div hk z] + apply iteratedDerivWithin_congr + · intro x hx + simpa using pi_mul_cot_pi_q_exp ⟨x, hx⟩ + · simpa using z.2 diff --git a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean index 524e1fab2b5a01..1b72bd9b60b315 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/TsumUniformlyOn.lean @@ -8,6 +8,7 @@ import Mathlib.Analysis.Calculus.UniformLimitsDeriv import Mathlib.Analysis.NormedSpace.FunctionSeries import Mathlib.Topology.Algebra.InfiniteSum.UniformOn + /-! # Differentiability of sum of functions @@ -20,9 +21,9 @@ version. -/ -open Set Metric TopologicalSpace Function Filter +open Set Metric TopologicalSpace Function Filter Complex -open scoped Topology NNReal +open scoped Topology NNReal Complex section UniformlyOn From 738c91f401c7c29c0de0c9d658ee694f42a457e6 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 28 Jul 2025 21:52:50 +0100 Subject: [PATCH 032/128] =?UTF-8?q?imports=C2=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index bd5e685f6528c9..d6fce17afecd11 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -3,10 +3,8 @@ Copyright (c) 2025 Chris Birkbeck. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ -import Mathlib.Algebra.Lie.OfAssociative import Mathlib.Analysis.CStarAlgebra.Classes import Mathlib.Analysis.SpecialFunctions.Trigonometric.Cotangent -import Mathlib.Data.Complex.FiniteDimensional import Mathlib.Analysis.Complex.SummableUniformlyOn /-! From 72b220eef32e71fcb499c5cd3783d00bf4c179b0 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 29 Jul 2025 15:35:25 +0100 Subject: [PATCH 033/128] cleanup --- .../Normed/Module/FiniteDimension.lean | 21 +++ .../EisensteinSeries/QExpansion.lean | 129 +++++++----------- 2 files changed, 74 insertions(+), 76 deletions(-) diff --git a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean index 1ee1fd797e7c37..4e3231f7e087ac 100644 --- a/Mathlib/Analysis/Normed/Module/FiniteDimension.lean +++ b/Mathlib/Analysis/Normed/Module/FiniteDimension.lean @@ -10,6 +10,7 @@ import Mathlib.Analysis.Normed.Affine.Isometry import Mathlib.Analysis.NormedSpace.OperatorNorm.NormedSpace import Mathlib.Analysis.NormedSpace.RieszLemma import Mathlib.Analysis.NormedSpace.Pointwise +import Mathlib.Analysis.SpecificLimits.Normed import Mathlib.Logic.Encodable.Pi import Mathlib.Topology.Algebra.Module.FiniteDimension import Mathlib.Topology.Algebra.InfiniteSum.Module @@ -662,6 +663,26 @@ theorem summable_of_isBigO_nat' {E F : Type*} [NormedAddCommGroup E] [CompleteSp (hg : Summable g) (h : f =O[atTop] g) : Summable f := summable_of_isBigO_nat hg.norm h.norm_right +open Nat Asymptotics in +theorem summable_norm_mul_geometric_of_norm_lt_one' {F : Type*} [NormedRing F] + [NormOneClass F] [NormMulClass F] {k : ℕ} {r : F} (hr : ‖r‖ < 1) {u : ℕ → F} + (hu : u =O[atTop] (fun n ↦ ((n ^ k : ℕ) : F))) : Summable fun n : ℕ ↦ ‖u n * r ^ n‖ := by + rcases exists_between hr with ⟨r', hrr', h⟩ + apply summable_of_isBigO_nat (summable_geometric_of_lt_one ((norm_nonneg _).trans hrr'.le) h).norm + calc + fun n ↦ ‖(u n) * r ^ n‖ + _ =O[atTop] fun n ↦ ‖u n‖ * ‖r‖ ^ n := by + apply (IsBigOWith.of_bound (c := ‖(1 : ℝ)‖) ?_).isBigO + filter_upwards [eventually_norm_pow_le r] with n hn + simp + _ =O[atTop] fun n ↦ ‖((n : F) ^ k)‖ * ‖r‖ ^ n := by + simpa [Nat.cast_pow] using (isBigO_norm_left.mpr + (isBigO_norm_right.mpr hu)).mul (isBigO_refl (fun n => (‖r‖ ^ n)) atTop) + _ =O[atTop] fun n ↦ ‖r' ^ n‖ := by + convert isBigO_norm_right.mpr (isBigO_norm_left.mpr + (isLittleO_pow_const_mul_const_pow_const_pow_of_norm_lt k hrr').isBigO) + simp only [norm_pow, norm_mul] + theorem summable_of_isEquivalent {ι E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] {f : ι → E} {g : ι → E} (hg : Summable g) (h : f ~[cofinite] g) : Summable f := diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index d6fce17afecd11..cef77a9a27869d 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -7,6 +7,7 @@ import Mathlib.Analysis.CStarAlgebra.Classes import Mathlib.Analysis.SpecialFunctions.Trigonometric.Cotangent import Mathlib.Analysis.Complex.SummableUniformlyOn + /-! # Einstein series Q-expansions @@ -15,48 +16,23 @@ Q-expansions. -/ - open Set Metric TopologicalSpace Function Filter Complex UpperHalfPlane open scoped Topology Real Nat Complex Pointwise local notation "ℍₒ" => complexUpperHalfPlane -/- This will be used for showing general q-exansions are summable once we know that they are big O -of `n ^ k`. TODO: once added move this to a better place. -/ -open Nat Asymptotics in -theorem summable_norm_mul_geometric_of_norm_lt_one' {F : Type*} [NormedRing F] - [NormOneClass F] [NormMulClass F] {k : ℕ} {r : F} (hr : ‖r‖ < 1) {u : ℕ → F} - (hu : u =O[atTop] (fun n ↦ ((n ^ k : ℕ) : F))) : Summable fun n : ℕ ↦ ‖u n * r ^ n‖ := by - rcases exists_between hr with ⟨r', hrr', h⟩ - apply summable_of_isBigO_nat (summable_geometric_of_lt_one ((norm_nonneg _).trans hrr'.le) h).norm - calc - fun n ↦ ‖(u n) * r ^ n‖ - _ =O[atTop] fun n ↦ ‖u n‖ * ‖r‖ ^ n := by - apply (IsBigOWith.of_bound (c := ‖(1 : ℝ)‖) ?_).isBigO - filter_upwards [eventually_norm_pow_le r] with n hn - simp - _ =O[atTop] fun n ↦ ‖((n : F) ^ k)‖ * ‖r‖ ^ n := by - simpa [Nat.cast_pow] using (Asymptotics.isBigO_norm_left.mpr - (Asymptotics.isBigO_norm_right.mpr hu)).mul (isBigO_refl (fun n => (‖r‖ ^ n)) atTop) - _ =O[atTop] fun n ↦ ‖r' ^ n‖ := by - convert Asymptotics.isBigO_norm_right.mpr (Asymptotics.isBigO_norm_left.mpr - (isLittleO_pow_const_mul_const_pow_const_pow_of_norm_lt k hrr').isBigO) - simp only [norm_pow, norm_mul] - -lemma exp_iter_deriv_within (k m : ℕ) (f : ℕ → ℂ) (p : ℝ) : - EqOn (iteratedDerivWithin k (fun s : ℂ => (f m) * cexp (2 * ↑π * Complex.I * m * s / p)) ℍₒ) - (fun s => (f m) * (2 * ↑π * Complex.I * m / p) ^ k * - cexp (2 * ↑π * Complex.I * m * s / p)) ℍₒ := by - apply EqOn.trans (iteratedDerivWithin_of_isOpen complexUpperHalPlane_isOpen) +lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (c : ℂ) (p : ℝ) {S : Set ℂ} (hs : IsOpen S) : + EqOn (iteratedDerivWithin k (fun s : ℂ => c * cexp (2 * ↑π * Complex.I * m * s / p)) S) + (fun s => c * (2 * ↑π * Complex.I * m / p) ^ k * cexp (2 * ↑π * Complex.I * m * s / p)) S := by + apply (iteratedDerivWithin_of_isOpen hs).trans intro x hx rw [iteratedDeriv_const_mul (by fun_prop)] - · have : (fun s ↦ cexp (2 * ↑π * Complex.I * ↑m * s / ↑p)) = + have : (fun s ↦ cexp (2 * ↑π * Complex.I * ↑m * s / ↑p)) = (fun s ↦ cexp (((2 * ↑π * Complex.I * ↑m) / p) * s)) := by - ext z - ring_nf - simp only [this, iteratedDeriv_cexp_const_mul] - ring_nf + ext z ; ring_nf + simp only [this, iteratedDeriv_cexp_const_mul] + ring_nf private lemma aux_IsBigO_mul (k : ℕ) (p : ℝ) {f : ℕ → ℂ} (hf : f =O[atTop] (fun n => (↑(n ^ k) : ℝ))) : @@ -66,8 +42,7 @@ private lemma aux_IsBigO_mul (k : ℕ) (p : ℝ) {f : ℕ → ℂ} (fun n => (↑(n ^ (k)) : ℝ)) := by have h1 : (fun n : ℕ => (2 * ↑π * Complex.I * ↑n / p) ^ k) = (fun n : ℕ => ((2 * ↑π * Complex.I / p) ^ k) * ↑n ^ k) := by - ext z - ring + ext z ; ring simpa [h1] using (Complex.isBigO_ofReal_right.mp (Asymptotics.isBigO_const_mul_self ((2 * ↑π * Complex.I / p) ^ k) (fun (n : ℕ) ↦ (↑(n ^ k) : ℝ)) atTop)) simp only [Nat.cast_pow] at * @@ -75,14 +50,14 @@ private lemma aux_IsBigO_mul (k : ℕ) (p : ℝ) {f : ℕ → ℂ} ring open BoundedContinuousFunction in -theorem qExpansion_summableLocallyUniformlyOn (k : ℕ) {f : ℕ → ℂ} {p : ℝ} (hp : 0 < p) - (hf : f =O[atTop] (fun n => (↑(n ^ k) : ℝ))) : +theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k : ℕ) {f : ℕ → ℂ} {p : ℝ} + (hp : 0 < p) (hf : f =O[atTop] (fun n => (↑(n ^ k) : ℝ))) : SummableLocallyUniformlyOn (fun n ↦ iteratedDerivWithin k (fun z ↦ f n * cexp (2 * ↑π * Complex.I * z / p) ^ n) ℍₒ) ℍₒ := by apply SummableLocallyUniformlyOn_of_locally_bounded complexUpperHalPlane_isOpen intro K hK hKc haveI : CompactSpace K := isCompact_univ_iff.mp (isCompact_iff_isCompact_univ.mp hKc) - let c : ContinuousMap K ℂ := ⟨fun r : K => Complex.exp (2 * ↑π * Complex.I * r / p), by fun_prop⟩ + let c : ContinuousMap K ℂ := ⟨fun r : K => cexp (2 * ↑π * Complex.I * r / p), by fun_prop⟩ let r : ℝ := ‖mkOfCompact c‖ have hr : ‖r‖ < 1 := by simp only [norm_norm, r, norm_lt_iff_of_compact Real.zero_lt_one, mkOfCompact_apply, @@ -96,61 +71,64 @@ theorem qExpansion_summableLocallyUniformlyOn (k : ℕ) {f : ℕ → ℂ} {p : (Asymptotics.isBigO_norm_left.mpr (aux_IsBigO_mul k p hf))), ?_⟩ intro n z hz have h0 := pow_le_pow_left₀ (by apply norm_nonneg _) (norm_coe_le_norm (mkOfCompact c) ⟨z, hz⟩) n - simp only [← exp_nsmul', exp_iter_deriv_within k n f p (hK hz), Complex.norm_mul, norm_pow, - Complex.norm_div, Complex.norm_ofNat, norm_real, norm_I, mul_one, - Complex.norm_natCast,Nat.cast_pow, norm_mkOfCompact, mkOfCompact_apply, ContinuousMap.coe_mk, - abs_norm, ge_iff_le, r, c] at * + simp only [Nat.cast_pow, norm_mkOfCompact, mkOfCompact_apply, ContinuousMap.coe_mk, ← + exp_nsmul', iteratedDerivWithin_cexp_mul_const k n (f n) p complexUpperHalPlane_isOpen (hK hz), + Complex.norm_mul, norm_pow, Complex.norm_div, norm_ofNat, norm_real, Real.norm_eq_abs, norm_I, + mul_one, norm_natCast, abs_norm, ge_iff_le, r, c] at * gcongr convert h0 rw [← norm_pow, ← exp_nsmul'] -theorem cot_q_ext_summableLocallyUniformlyOn (k : ℕ) : SummableLocallyUniformlyOn - (fun n ↦ iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ) ℍₒ := by +/-- This is a version of `summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion` for level one +and q-expansion coefficients all `1`. -/ +theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' (k : ℕ) : + SummableLocallyUniformlyOn (fun n ↦ iteratedDerivWithin k + (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ) ℍₒ := by have h0 : (fun n : ℕ => (1 : ℂ)) =O[atTop] (fun n => (↑(n ^ k) : ℝ)) := by simp only [Nat.cast_pow, Asymptotics.isBigO_iff, norm_one, norm_pow, Real.norm_natCast, eventually_atTop, ge_iff_le] - refine ⟨1, 1, fun b hb => ?_⟩ - norm_cast - simp [Nat.one_le_pow k b hb] - simpa using qExpansion_summableLocallyUniformlyOn k (p := 1) (by norm_num) h0 + refine ⟨1, 1, fun b hb => by norm_cast; simp [Nat.one_le_pow k b hb]⟩ + simpa using summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion k (p := 1) (by norm_num) h0 -theorem deriv_iterderivwithin (n a : ℕ) {s : Set ℂ} (hs : IsOpen s) {r : ℂ} (hr : r ∈ s) : +theorem differnetiableAt_iteratedDerivWithin_cexp (n a : ℕ) {s : Set ℂ} (hs : IsOpen s) {r : ℂ} + (hr : r ∈ s) : DifferentiableAt ℂ (iteratedDerivWithin a (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n) s) r := by apply DifferentiableOn.differentiableAt _ (hs.mem_nhds hr) suffices DifferentiableOn ℂ (iteratedDeriv a (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n)) s by apply this.congr (iteratedDerivWithin_of_isOpen hs) fun_prop -lemma exp_deriv (k : ℕ) (z : ℍ) : iteratedDerivWithin k - (fun z => ( ∑' n : ℕ, Complex.exp (2 * π * Complex.I * z) ^ n)) {z : ℂ | 0 < z.im} z = - ∑' n : ℕ, iteratedDerivWithin k - (fun s : ℂ => Complex.exp (2 * ↑π * Complex.I * s) ^ n) {z : ℂ | 0 < z.im} z := by +lemma iteratedDerivWithin_tsum_exp_eq (k : ℕ) (z : ℍ) : iteratedDerivWithin k (fun z => + ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n) ℍₒ z = + ∑' n : ℕ, iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * Complex.I * s) ^ n) ℍₒ z := by rw [iteratedDerivWithin_tsum k complexUpperHalPlane_isOpen (by simpa using z.2)] · exact fun x hx => summable_geometric_iff_norm_lt_one.mpr (UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨x, hx⟩) - · exact fun n _ _ => cot_q_ext_summableLocallyUniformlyOn n - · exact fun n l z hl hz => deriv_iterderivwithin n l complexUpperHalPlane_isOpen hz + · exact fun n _ _ => summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' n + · exact fun n l z hl hz => differnetiableAt_iteratedDerivWithin_cexp n l + complexUpperHalPlane_isOpen hz -theorem tsum_uexp_contDiffOn (k : ℕ) : - ContDiffOn ℂ k (fun z : ℂ => ∑' n : ℕ, Complex.exp (2 * ↑π * Complex.I * z) ^ n) ℍₒ := - contDiffOn_of_differentiableOn_deriv fun m _ z hz => +theorem contDiffOn_tsum_cexp (k : ℕ∞) : + ContDiffOn ℂ k (fun z : ℂ => ∑' n : ℕ, cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ := + contDiffOn_of_differentiableOn_deriv fun m _ z hz ↦ ((summableUniformlyOn_differentiableOn complexUpperHalPlane_isOpen - (cot_q_ext_summableLocallyUniformlyOn m) - (fun n _ hz => deriv_iterderivwithin n m complexUpperHalPlane_isOpen hz)) z hz).congr - (fun z hz => exp_deriv m ⟨z, hz⟩) (exp_deriv m ⟨z, hz⟩) + (summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' m) + (fun n _ hz => differnetiableAt_iteratedDerivWithin_cexp n m + complexUpperHalPlane_isOpen hz)) z hz).congr (fun z hz ↦ + iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) (iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) -private lemma exp_deriv' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : - iteratedDerivWithin k (fun z => (((π : ℂ) * Complex.I) - - (2 * π * Complex.I) * ∑' n : ℕ, Complex.exp (2 * π * Complex.I * z) ^ n)) ℍₒ z = +private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : + iteratedDerivWithin k (fun z => (((π : ℂ) * Complex.I) - + (2 * π * Complex.I) * ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n)) ℍₒ z = -(2 * π * Complex.I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by suffices - iteratedDerivWithin k (fun z => (((π : ℂ) * Complex.I) - - (2 * π * Complex.I) * ∑' n : ℕ, Complex.exp (2 * π * Complex.I * z) ^ n)) {z : ℂ | 0 < z.im} z = + iteratedDerivWithin k (fun z ↦ ((↑π * Complex.I) - + (2 * π * Complex.I) * ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n)) ℍₒ z = -(2 * π * Complex.I) * ∑' n : ℕ, iteratedDerivWithin k - (fun s : ℂ => Complex.exp (2 * ↑π * Complex.I * s) ^ n) {z : ℂ | 0 < z.im} z by + (fun s : ℂ => cexp (2 * ↑π * Complex.I * s) ^ n) ℍₒ z by have h : -(2 * ↑π * Complex.I * (2 * ↑π * Complex.I) ^ k) * ∑' (n : ℕ), ↑n ^ k * cexp (2 * ↑π * Complex.I * ↑z) ^ n = -(2 * π * Complex.I) * - ∑' n : ℕ, (2 * ↑π * Complex.I * n) ^ k * Complex.exp (2 * ↑π * Complex.I * z) ^ n := by + ∑' n : ℕ, (2 * ↑π * Complex.I * n) ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by simp_rw [← tsum_mul_left] congr ext y @@ -163,16 +141,15 @@ private lemma exp_deriv' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : have := exp_nsmul' (p := 1) (a := 2 * π * Complex.I) (n := n) simp only [div_one] at this simpa [this, ofReal_one, div_one, one_mul, UpperHalfPlane.coe] using - exp_iter_deriv_within k n (fun n => 1) 1 z.2 - rw [iteratedDerivWithin_const_sub hk , iteratedDerivWithin_fun_neg, iteratedDerivWithin_const_mul] - · simp only [exp_deriv, neg_mul] + iteratedDerivWithin_cexp_mul_const k n 1 1 complexUpperHalPlane_isOpen z.2 + rw [iteratedDerivWithin_const_sub hk, iteratedDerivWithin_fun_neg, iteratedDerivWithin_const_mul] + · simp only [iteratedDerivWithin_tsum_exp_eq, neg_mul] · simpa using z.2 · exact complexUpperHalPlane_isOpen.uniqueDiffOn - · exact (tsum_uexp_contDiffOn k).contDiffWithinAt (by simpa using z.2) + · exact (contDiffOn_tsum_cexp k).contDiffWithinAt (by simpa using z.2) theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : - ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = - ((-2 * π * Complex.I) ^ (k + 1) / (k !)) * + ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = ((-2 * π * Complex.I) ^ (k + 1) / (k !)) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by suffices (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = -(2 * π * Complex.I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n by @@ -188,8 +165,8 @@ theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) field_simp [h3] ring_nf simp [Nat.mul_two] - rw [← exp_deriv' hk z, ← iteratedDerivWithin_cot_series_rep_one_div hk z] + rw [← iteratedDerivWithin_tsum_exp_eq' hk z, ← iteratedDerivWithin_cot_series_rep_one_div hk z] apply iteratedDerivWithin_congr · intro x hx - simpa using pi_mul_cot_pi_q_exp ⟨x, hx⟩ + simpa using pi_mul_cot_pi_q_exp ⟨x, hx⟩ · simpa using z.2 From f1185b747e84f793d0f7f5a29cc9d3e894866396 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 29 Jul 2025 16:11:02 +0100 Subject: [PATCH 034/128] lint fix --- .../ModularForms/EisensteinSeries/QExpansion.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index cef77a9a27869d..efd9313ecaf6ff 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -30,7 +30,7 @@ lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (c : ℂ) (p : ℝ) {S : Se rw [iteratedDeriv_const_mul (by fun_prop)] have : (fun s ↦ cexp (2 * ↑π * Complex.I * ↑m * s / ↑p)) = (fun s ↦ cexp (((2 * ↑π * Complex.I * ↑m) / p) * s)) := by - ext z ; ring_nf + ext z; ring_nf simp only [this, iteratedDeriv_cexp_const_mul] ring_nf @@ -42,7 +42,7 @@ private lemma aux_IsBigO_mul (k : ℕ) (p : ℝ) {f : ℕ → ℂ} (fun n => (↑(n ^ (k)) : ℝ)) := by have h1 : (fun n : ℕ => (2 * ↑π * Complex.I * ↑n / p) ^ k) = (fun n : ℕ => ((2 * ↑π * Complex.I / p) ^ k) * ↑n ^ k) := by - ext z ; ring + ext z; ring simpa [h1] using (Complex.isBigO_ofReal_right.mp (Asymptotics.isBigO_const_mul_self ((2 * ↑π * Complex.I / p) ^ k) (fun (n : ℕ) ↦ (↑(n ^ k) : ℝ)) atTop)) simp only [Nat.cast_pow] at * From 7ec21bfcbacbdcc0c0520411edb1c80c57ec27a4 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 17:13:39 +0100 Subject: [PATCH 035/128] add q_exp --- Mathlib/NumberTheory/ArithmeticFunction.lean | 3 + Mathlib/NumberTheory/Divisors.lean | 33 ++ Mathlib/NumberTheory/LSeries/RiemannZeta.lean | 11 + .../ModularForms/EisensteinSeries/Basic.lean | 10 + .../ModularForms/EisensteinSeries/Defs.lean | 68 +++- .../EisensteinSeries/QExpansion.lean | 291 ++++++++++++++++-- .../Topology/Algebra/InfiniteSum/NatInt.lean | 54 +++- 7 files changed, 436 insertions(+), 34 deletions(-) diff --git a/Mathlib/NumberTheory/ArithmeticFunction.lean b/Mathlib/NumberTheory/ArithmeticFunction.lean index d87d0973dce566..d7a7ad588c981e 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction.lean @@ -817,6 +817,9 @@ theorem sigma_one_apply_prime_pow {p i : ℕ} (hp : p.Prime) : σ 1 (p ^ i) = ∑ k ∈ .range (i + 1), p ^ k := by simp [sigma_apply_prime_pow hp] +theorem sigma_eq_sum_div' (k n : ℕ) : sigma k n = ∑ d ∈ Nat.divisors n, (n / d) ^ k := by + rw [sigma, ArithmeticFunction.coe_mk, ← Nat.sum_div_divisors] + theorem sigma_zero_apply (n : ℕ) : σ 0 n = #n.divisors := by simp [sigma_apply] theorem sigma_zero_apply_prime_pow {p i : ℕ} (hp : p.Prime) : σ 0 (p ^ i) = i + 1 := by diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 577a50530a35f9..4dad67d28540ae 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -12,6 +12,7 @@ import Mathlib.Data.Nat.Cast.Order.Ring import Mathlib.Data.Nat.PrimeFin import Mathlib.Data.Nat.SuccPred import Mathlib.Order.Interval.Finset.Nat +import Mathlib.Data.PNat.Defs /-! # Divisor Finsets @@ -742,3 +743,35 @@ lemma mul_mem_zero_one_two_three_four_iff {a b : ℤ} (h₀ : a = 0 ↔ b = 0) : aesop end Int + +section pnat + +/-- The map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` +to `(a , b)`. -/ +def mapdiv (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := by + refine fun x => + ⟨⟨x.1.1, Nat.pos_of_mem_divisors (Nat.fst_mem_divisors_of_mem_antidiagonal x.2)⟩, + (⟨x.1.2, Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ : ℕ+), + Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ + +/-- The equivalence from the union over `n` of `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` +given by sending `n = a * b` to `(a , b)`. -/ +def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ℕ+ × ℕ+ where + toFun x := mapdiv x.1 x.2 + invFun x := + ⟨⟨x.1.1 * x.2.1, mul_pos x.1.2 x.2.2⟩, ⟨x.1, x.2⟩, by + simp only [PNat.mk_coe, Nat.mem_divisorsAntidiagonal, ne_eq, mul_eq_zero, not_or] + refine ⟨rfl, PNat.ne_zero x.1, PNat.ne_zero x.2⟩⟩ + left_inv := by + rintro ⟨n, ⟨k, l⟩, h⟩ + rw [Nat.mem_divisorsAntidiagonal] at h + simp_rw [mapdiv, PNat.mk_coe] + ext <;> simp [h] at * + rfl + right_inv := by + rintro ⟨n, ⟨k, l⟩, h⟩ + · simp_rw [mapdiv] + norm_cast + · rfl + +end pnat diff --git a/Mathlib/NumberTheory/LSeries/RiemannZeta.lean b/Mathlib/NumberTheory/LSeries/RiemannZeta.lean index 5650b242d836d9..02a6168d69e0f6 100644 --- a/Mathlib/NumberTheory/LSeries/RiemannZeta.lean +++ b/Mathlib/NumberTheory/LSeries/RiemannZeta.lean @@ -197,6 +197,17 @@ theorem zeta_nat_eq_tsum_of_gt_one {k : ℕ} (hk : 1 < k) : (by rwa [← ofReal_natCast, ofReal_re, ← Nat.cast_one, Nat.cast_lt] : 1 < re k), cpow_natCast] +lemma two_riemannZeta_eq_tsum_int_inv_even_pow {k : ℕ} (hk : 2 ≤ k) (hk2 : Even k) : + 2 * riemannZeta k = ∑' (n : ℤ), ((n : ℂ) ^ k)⁻¹ := by + have hkk : 1 < k := by linarith + rw [tsum_nat_eq_zero_two_pnat] + · have h0 : (0 ^ k : ℂ)⁻¹ = 0 := by simp; omega + norm_cast + simp [h0, zeta_eq_tsum_one_div_nat_add_one_cpow (s := k) (by simp [hkk]), + tsum_pnat_eq_tsum_succ' (f := fun n => ((n : ℂ) ^ k)⁻¹)] + · simp [Even.neg_pow hk2] + · exact (Summable.of_nat_of_neg (by simp [hkk]) (by simp [hkk])).of_norm + /-- The residue of `ζ(s)` at `s = 1` is equal to 1. -/ lemma riemannZeta_residue_one : Tendsto (fun s ↦ (s - 1) * riemannZeta s) (𝓝[≠] 1) (𝓝 1) := by exact hurwitzZetaEven_residue_one 0 diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean index 2d018f26c95902..e7dae0844ca1cf 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean @@ -34,4 +34,14 @@ def eisensteinSeries_MF {k : ℤ} {N : ℕ+} (hk : 3 ≤ k) (a : Fin 2 → ZMod holo' := eisensteinSeries_SIF_MDifferentiable hk a bdd_at_infty' := isBoundedAtImInfty_eisensteinSeries_SIF a hk +/-- The trivial congruence condition at level 1. -/ +def standardcongruencecondition : Fin 2 → ZMod ((1 : ℕ+) : ℕ) := 0 + +scoped notation "𝟙" => standardcongruencecondition + +/-- Normalised Eisenstein series of level 1 and weight `k`, +here they need `1/2` since we sum over coprime pairs. -/ +noncomputable def E (k : ℕ) (hk : 3 ≤ k) : ModularForm Γ(1) k := + (1/2 : ℂ) • eisensteinSeries_MF (by omega) 𝟙 + end ModularForm diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean index 6103e7d56f6d12..8665dd1c25cc49 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean @@ -25,7 +25,7 @@ import Mathlib.NumberTheory.ModularForms.CongruenceSubgroups noncomputable section -open ModularForm UpperHalfPlane Complex Matrix CongruenceSubgroup +open ModularForm UpperHalfPlane Complex Matrix CongruenceSubgroup Set open scoped MatrixGroups @@ -53,6 +53,72 @@ lemma gammaSet_one_eq (a a' : Fin 2 → ZMod 1) : gammaSet 1 a = gammaSet 1 a' : def gammaSet_one_equiv (a a' : Fin 2 → ZMod 1) : gammaSet 1 a ≃ gammaSet 1 a' := Equiv.setCongr (gammaSet_one_eq a a') +open Pointwise +def gammaSetN (N : ℕ) : Set (Fin 2 → ℤ) := ({N} : Set ℕ) • gammaSet 1 0 + +noncomputable def gammaSetN_map (N : ℕ) (v : gammaSetN N) : gammaSet 1 0 := by + have hv2 := v.2 + simp only [gammaSetN, singleton_smul, mem_smul_set, nsmul_eq_mul] at hv2 + refine ⟨hv2.choose, hv2.choose_spec.1⟩ + +lemma gammaSet_top_mem (v : Fin 2 → ℤ) : v ∈ gammaSet 1 0 ↔ IsCoprime (v 0) (v 1) := by + simpa [gammaSet] using fun h ↦ Subsingleton.eq_zero (Int.cast ∘ v) + +lemma gammaSetN_map_eq {N : ℕ} (v : gammaSetN N) : v.1 = N • gammaSetN_map N v := by + have hv2 := v.2 + simp only [gammaSetN, singleton_smul, mem_smul_set, nsmul_eq_mul] at hv2 + exact (hv2.choose_spec.2).symm + +noncomputable def gammaSetN_Equiv {N : ℕ} (hN : N ≠ 0) : gammaSetN N ≃ gammaSet 1 0 where + toFun v := gammaSetN_map N v + invFun v := by + use N • v + simp only [gammaSetN, singleton_smul, nsmul_eq_mul, mem_smul_set] + refine ⟨v, by simp⟩ + left_inv v := by + simp_rw [← gammaSetN_map_eq v] + right_inv v := by + have H : N • v.1 ∈ gammaSetN N := by + simp only [gammaSetN, singleton_smul, nsmul_eq_mul, mem_smul_set] + refine ⟨v.1, by simp⟩ + simp [gammaSetN, mem_smul_set] at * + let x := H.choose + have hx := H.choose_spec + have hxv : ⟨H.choose, H.choose_spec.1⟩ = v := by + ext i + simpa [hN] using (congr_fun H.choose_spec.2 i) + simp_all only [gammaSetN_map] + +private def fin_to_GammaSetN (v : Fin 2 → ℤ) : Σ n : ℕ, gammaSetN n := by + refine ⟨(v 0).gcd (v 1), ⟨(v 0).gcd (v 1) • ![(v 0)/(v 0).gcd (v 1), (v 1)/(v 0).gcd (v 1)], ?_⟩⟩ + by_cases hn : 0 < (v 0).gcd (v 1) + · apply Set.smul_mem_smul (by aesop) + rw [gammaSet_top_mem, Int.isCoprime_iff_gcd_eq_one] + apply Int.gcd_div_gcd_div_gcd hn + · simp only [gammaSetN, Fin.isValue, (nonpos_iff_eq_zero.mp (not_lt.mp hn)), singleton_smul, + Nat.succ_eq_add_one, Nat.reduceAdd, CharP.cast_eq_zero, zero_nsmul] + refine ⟨![1,1], by simpa [gammaSet_top_mem] using Int.isCoprime_iff_gcd_eq_one.mpr rfl⟩ + +def GammaSet_one_Equiv : (Fin 2 → ℤ) ≃ (Σ n : ℕ, gammaSetN n) where + toFun v := fin_to_GammaSetN v + invFun v := v.2 + left_inv v := by + ext i + fin_cases i + · exact Int.mul_ediv_cancel' (Int.gcd_dvd_left _ _) + · exact Int.mul_ediv_cancel' (Int.gcd_dvd_right _ _) + right_inv v := by + ext i + · have hv2 := v.2.2 + simp only [gammaSetN, singleton_smul, mem_smul_set, nsmul_eq_mul] at hv2 + obtain ⟨x, hx⟩ := hv2 + simp [← hx.2, fin_to_GammaSetN, Fin.isValue, Int.gcd_mul_left, + Int.isCoprime_iff_gcd_eq_one.mp hx.1.2] + · fin_cases i + · exact Int.mul_ediv_cancel' (Int.gcd_dvd_left _ _) + · exact Int.mul_ediv_cancel' (Int.gcd_dvd_right _ _) + + end gammaSet_def variable {N a} diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index efd9313ecaf6ff..f8b41b85feaa46 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -3,46 +3,53 @@ Copyright (c) 2025 Chris Birkbeck. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ -import Mathlib.Analysis.CStarAlgebra.Classes -import Mathlib.Analysis.SpecialFunctions.Trigonometric.Cotangent +import Mathlib.Algebra.Order.Ring.Star import Mathlib.Analysis.Complex.SummableUniformlyOn - +import Mathlib.Analysis.SpecialFunctions.Trigonometric.Cotangent +import Mathlib.Data.Int.Star +import Mathlib.NumberTheory.LSeries.Dirichlet +import Mathlib.NumberTheory.LSeries.HurwitzZetaValues +import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Basic +import Mathlib.Topology.EMetricSpace.Paracompact +import Mathlib.Topology.Separation.CompletelyRegular /-! # Einstein series Q-expansions -We give some identities for Q-expansions of Eisenstein series that will be used in describing their +We give some identities for q-expansions of Eisenstein series that will be used in describing their Q-expansions. -/ -open Set Metric TopologicalSpace Function Filter Complex UpperHalfPlane +open Set Metric TopologicalSpace Function Filter Complex UpperHalfPlane ArithmeticFunction + ModularForm EisensteinSeries open scoped Topology Real Nat Complex Pointwise local notation "ℍₒ" => complexUpperHalfPlane -lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (c : ℂ) (p : ℝ) {S : Set ℂ} (hs : IsOpen S) : - EqOn (iteratedDerivWithin k (fun s : ℂ => c * cexp (2 * ↑π * Complex.I * m * s / p)) S) - (fun s => c * (2 * ↑π * Complex.I * m / p) ^ k * cexp (2 * ↑π * Complex.I * m * s / p)) S := by - apply (iteratedDerivWithin_of_isOpen hs).trans +lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (p : ℝ) {S : Set ℂ} (hs : IsOpen S) : + EqOn (iteratedDerivWithin k (fun s : ℂ => cexp (2 * ↑π * Complex.I * m * s / p)) S) + (fun s => (2 * ↑π * Complex.I * m / p) ^ k * cexp (2 * ↑π * Complex.I * m * s / p)) S := by + apply EqOn.trans (iteratedDerivWithin_of_isOpen hs) intro x hx - rw [iteratedDeriv_const_mul (by fun_prop)] have : (fun s ↦ cexp (2 * ↑π * Complex.I * ↑m * s / ↑p)) = - (fun s ↦ cexp (((2 * ↑π * Complex.I * ↑m) / p) * s)) := by - ext z; ring_nf + (fun s ↦ cexp (((2 * ↑π * Complex.I * ↑m) / p) * s)) := by + ext z + ring_nf simp only [this, iteratedDeriv_cexp_const_mul] ring_nf -private lemma aux_IsBigO_mul (k : ℕ) (p : ℝ) {f : ℕ → ℂ} - (hf : f =O[atTop] (fun n => (↑(n ^ k) : ℝ))) : +private lemma aux_IsBigO_mul (k l : ℕ) (p : ℝ) {f : ℕ → ℂ} + (hf : f =O[atTop] (fun n => (↑(n ^ l) : ℝ))) : (fun n => f n * (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] - (fun n => (↑(n ^ (2 * k)) : ℝ)) := by + (fun n => (↑(n ^ (l + k)) : ℝ)) := by have h0 : (fun n : ℕ => (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] (fun n => (↑(n ^ (k)) : ℝ)) := by have h1 : (fun n : ℕ => (2 * ↑π * Complex.I * ↑n / p) ^ k) = (fun n : ℕ => ((2 * ↑π * Complex.I / p) ^ k) * ↑n ^ k) := by - ext z; ring + ext z + ring simpa [h1] using (Complex.isBigO_ofReal_right.mp (Asymptotics.isBigO_const_mul_self ((2 * ↑π * Complex.I / p) ^ k) (fun (n : ℕ) ↦ (↑(n ^ k) : ℝ)) atTop)) simp only [Nat.cast_pow] at * @@ -50,14 +57,14 @@ private lemma aux_IsBigO_mul (k : ℕ) (p : ℝ) {f : ℕ → ℂ} ring open BoundedContinuousFunction in -theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k : ℕ) {f : ℕ → ℂ} {p : ℝ} - (hp : 0 < p) (hf : f =O[atTop] (fun n => (↑(n ^ k) : ℝ))) : - SummableLocallyUniformlyOn (fun n ↦ iteratedDerivWithin k - (fun z ↦ f n * cexp (2 * ↑π * Complex.I * z / p) ^ n) ℍₒ) ℍₒ := by +theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f : ℕ → ℂ} {p : ℝ} + (hp : 0 < p) (hf : f =O[atTop] (fun n => (↑(n ^ l) : ℝ))) : + SummableLocallyUniformlyOn (fun n ↦ (f n) • + iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z / p) ^ n) ℍₒ) ℍₒ := by apply SummableLocallyUniformlyOn_of_locally_bounded complexUpperHalPlane_isOpen intro K hK hKc haveI : CompactSpace K := isCompact_univ_iff.mp (isCompact_iff_isCompact_univ.mp hKc) - let c : ContinuousMap K ℂ := ⟨fun r : K => cexp (2 * ↑π * Complex.I * r / p), by fun_prop⟩ + let c : ContinuousMap K ℂ := ⟨fun r : K => Complex.exp (2 * ↑π * Complex.I * r / p), by fun_prop⟩ let r : ℝ := ‖mkOfCompact c‖ have hr : ‖r‖ < 1 := by simp only [norm_norm, r, norm_lt_iff_of_compact Real.zero_lt_one, mkOfCompact_apply, @@ -68,13 +75,16 @@ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k : ℕ) {f : ring simpa using h1 ▸ UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨((x : ℂ) / p) , by aesop⟩ refine ⟨_, by simpa using (summable_norm_mul_geometric_of_norm_lt_one' hr - (Asymptotics.isBigO_norm_left.mpr (aux_IsBigO_mul k p hf))), ?_⟩ + (Asymptotics.isBigO_norm_left.mpr (aux_IsBigO_mul k l p hf))), ?_⟩ intro n z hz have h0 := pow_le_pow_left₀ (by apply norm_nonneg _) (norm_coe_le_norm (mkOfCompact c) ⟨z, hz⟩) n + simp simp only [Nat.cast_pow, norm_mkOfCompact, mkOfCompact_apply, ContinuousMap.coe_mk, ← - exp_nsmul', iteratedDerivWithin_cexp_mul_const k n (f n) p complexUpperHalPlane_isOpen (hK hz), - Complex.norm_mul, norm_pow, Complex.norm_div, norm_ofNat, norm_real, Real.norm_eq_abs, norm_I, - mul_one, norm_natCast, abs_norm, ge_iff_le, r, c] at * + exp_nsmul', iteratedDerivWithin_cexp_mul_const k n p complexUpperHalPlane_isOpen (hK hz), + norm_mul, norm_pow, norm_div, + RCLike.norm_ofNat, norm_real, norm_I, mul_one, RCLike.norm_natCast, abs_norm, r, + c] at * + rw [← mul_assoc] gcongr convert h0 rw [← norm_pow, ← exp_nsmul'] @@ -84,11 +94,12 @@ and q-expansion coefficients all `1`. -/ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' (k : ℕ) : SummableLocallyUniformlyOn (fun n ↦ iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ) ℍₒ := by - have h0 : (fun n : ℕ => (1 : ℂ)) =O[atTop] (fun n => (↑(n ^ k) : ℝ)) := by + have h0 : (fun n : ℕ => (1 : ℂ)) =O[atTop] (fun n => (↑(n ^ 1) : ℝ)) := by simp only [Nat.cast_pow, Asymptotics.isBigO_iff, norm_one, norm_pow, Real.norm_natCast, eventually_atTop, ge_iff_le] - refine ⟨1, 1, fun b hb => by norm_cast; simp [Nat.one_le_pow k b hb]⟩ - simpa using summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion k (p := 1) (by norm_num) h0 + refine ⟨1, 1, fun b hb => by norm_cast; simp [hb]⟩ + simpa using summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion k 1 (p := 1) + (by norm_num) h0 theorem differnetiableAt_iteratedDerivWithin_cexp (n a : ℕ) {s : Set ℂ} (hs : IsOpen s) {r : ℂ} (hr : r ∈ s) : @@ -141,7 +152,7 @@ private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ have := exp_nsmul' (p := 1) (a := 2 * π * Complex.I) (n := n) simp only [div_one] at this simpa [this, ofReal_one, div_one, one_mul, UpperHalfPlane.coe] using - iteratedDerivWithin_cexp_mul_const k n 1 1 complexUpperHalPlane_isOpen z.2 + iteratedDerivWithin_cexp_mul_const k n 1 complexUpperHalPlane_isOpen z.2 rw [iteratedDerivWithin_const_sub hk, iteratedDerivWithin_fun_neg, iteratedDerivWithin_const_mul] · simp only [iteratedDerivWithin_tsum_exp_eq, neg_mul] · simpa using z.2 @@ -153,8 +164,7 @@ theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by suffices (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = -(2 * π * Complex.I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n by - simp_rw [(eq_inv_mul_iff_mul_eq₀ (by simp [Nat.factorial_ne_zero])).mpr - this, ← tsum_mul_left] + simp_rw [(eq_inv_mul_iff_mul_eq₀ (by simp [Nat.factorial_ne_zero])).mpr this, ← tsum_mul_left] congr ext n have h3 : (k ! : ℂ) ≠ 0 := by @@ -170,3 +180,222 @@ theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) · intro x hx simpa using pi_mul_cot_pi_q_exp ⟨x, hx⟩ · simpa using z.2 + +theorem summable_pow_mul_cexp (k : ℕ) (e : ℕ+) (z : ℍ) : + Summable fun c : ℕ => (c : ℂ) ^ k * cexp (2 * ↑π * Complex.I * e * ↑z) ^ c := by + have he : 0 < (e * (z : ℂ)).im := by + simpa using z.2 + apply ((summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion 0 k (p := 1) + (f := fun n => (n ^ k : ℂ)) (by norm_num) + (by simp [← Complex.isBigO_ofReal_right, Asymptotics.isBigO_refl])).summable he).congr + intro b + simp only [ofReal_one, div_one, ← Complex.exp_nsmul, nsmul_eq_mul, iteratedDerivWithin_zero, + Pi.smul_apply, smul_eq_mul, mul_eq_mul_left_iff, pow_eq_zero_iff', Nat.cast_eq_zero, ne_eq] + left + ring_nf + +theorem EisensteinSeries.qExpansion_identity_pnat {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : + ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = ((-2 * π * Complex.I) ^ (k + 1) / (k !)) * + ∑' n : ℕ+, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ (n : ℕ) := by + have hk0 : k ≠ 0 := by omega + rw [EisensteinSeries.qExpansion_identity hk z, ← tsum_zero_pnat_eq_tsum_nat] + · simp only [neg_mul, CharP.cast_eq_zero, ne_eq, hk0, not_false_eq_true, zero_pow, pow_zero, + mul_one, zero_add] + · apply (summable_pow_mul_cexp k 1 z).congr + simp + +theorem summable_divisorsAntidiagonal_aux (k : ℕ) (z : ℍ) : + Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ + (c.2.1).1 ^ k * cexp (2 * ↑π * Complex.I * c.2.1.2 * z) ^ c.2.1.1 := by + apply Summable.of_norm + rw [summable_sigma_of_nonneg] + constructor + · apply fun n => (hasSum_fintype _).summable + · simp only [Complex.norm_mul, norm_pow, Complex.norm_natCast, tsum_fintype, + Finset.univ_eq_attach] + · apply Summable.of_nonneg_of_le (fun b => Finset.sum_nonneg (by simp)) ?_ ((summable_norm_iff + (f := fun c : ℕ+ => (c : ℂ) ^ (k + 1) * exp (2 * ↑π * Complex.I * (1: ℕ+) * ↑z) ^ (c : ℕ)).mpr + (by apply (summable_pow_mul_cexp (k+1) 1 z).subtype))) + intro b + apply le_trans (b := ∑ _ ∈ (b : ℕ).divisors, b ^ k * ‖exp (2 * ↑π * Complex.I * z) ^ (b : ℕ)‖) + · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun (x : ℕ × ℕ) => + (x.1 : ℝ) ^ (k : ℕ) * ‖Complex.exp (2 * ↑π * Complex.I * x.2 * z)‖ ^ x.1), + Nat.sum_divisorsAntidiagonal ((fun x y => + (x : ℝ) ^ (k : ℕ) * ‖Complex.exp (2 * ↑π * Complex.I * y * z)‖ ^ x))] + gcongr <;> rename_i i hi <;> simp at hi + · exact Nat.le_of_dvd b.2 hi + · apply le_of_eq + simp_rw [mul_assoc, ← norm_pow, ← Complex.exp_nsmul] + nth_rw 2 [← Nat.mul_div_cancel' hi] + simp + ring_nf + · simpa [← mul_assoc, add_comm k 1, pow_add] using Nat.card_divisors_le_self b + · simp + +theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ ↦ + (c.1 ^ k : ℂ) * Complex.exp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) := by + rw [sigmaAntidiagonalEquivProd.summable_iff.symm] + simp [sigmaAntidiagonalEquivProd, mapdiv] + apply summable_divisorsAntidiagonal_aux k z + +theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : + ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = + ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by + suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : ℂ) * cexp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) = + ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) by + rw [Summable.tsum_prod (summable_prod_aux k z), Summable.tsum_comm] at this + · simpa using this + · apply (summable_prod_aux k z).prod_symm.congr + simp + simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, + Equiv.coe_fn_mk, sigma_eq_sum_div', Nat.cast_sum, Nat.cast_pow] + rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k z)] + apply tsum_congr + intro n + simp only [tsum_fintype, Finset.univ_eq_attach,Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) + (fun (x : ℕ × ℕ) => (x.1 : ℂ) ^ k * cexp (2 * ↑π * Complex.I * x.2 * z) ^ x.1), + Nat.sum_divisorsAntidiagonal' (fun x y => (x : ℂ) ^ k * cexp (2 * ↑π * Complex.I * y * z) ^ x), + Finset.sum_mul] + refine Finset.sum_congr (rfl) fun i hi => ?_ + have hni : (n / i : ℕ) * (i : ℂ) = n := by + norm_cast + simp only [Nat.mem_divisors, ne_eq, PNat.ne_zero, not_false_eq_true, and_true] at * + exact Nat.div_mul_cancel hi + simp only [← Complex.exp_nsmul, nsmul_eq_mul, ← hni, mul_eq_mul_left_iff, pow_eq_zero_iff', + Nat.cast_eq_zero, Nat.div_eq_zero_iff, ne_eq] + left + ring_nf + +theorem summable_prod_eisSummand (k : ℕ) (hk : 3 ≤ k) (z : ℍ) : + Summable fun x : ℤ × ℤ ↦ eisSummand k ![x.1, x.2] z := by + simp [← (piFinTwoEquiv fun _ => ℤ).summable_iff, ← summable_norm_iff] + apply (EisensteinSeries.summable_norm_eisSummand (by linarith) z).congr + simp [EisensteinSeries.eisSummand] + +lemma tsum_prod_eisSummand_eq_sigma_cexp (k : ℕ) (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : + ∑' (x : Fin 2 → ℤ), eisSummand k x z = 2 * riemannZeta ↑k + + 2 * ((-2 * ↑π * Complex.I) ^ k / ↑(k - 1)!) * + ∑' (n : ℕ+), ↑((σ (k - 1)) ↑n) * cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ) := by + rw [← (piFinTwoEquiv fun _ => ℤ).symm.tsum_eq, Summable.tsum_prod + (by apply summable_prod_eisSummand k hk), tsum_nat_eq_zero_two_pnat] + · have (b : ℕ+) := EisensteinSeries.qExpansion_identity_pnat (k := k - 1) (by omega) + ⟨b * z , by simpa using z.2⟩ + have hk1 : k - 1 + 1 = k := by omega + simp only [coe_mk_subtype, hk1, one_div, neg_mul, mul_assoc, eisSummand, Fin.isValue, + piFinTwoEquiv_symm_apply, Fin.cons_zero, Int.cast_zero, zero_mul, Fin.cons_one, zero_add, + zpow_neg, zpow_natCast, Int.cast_natCast, + two_riemannZeta_eq_tsum_int_inv_even_pow (by omega) hk2, add_right_inj, mul_eq_mul_left_iff, + OfNat.ofNat_ne_zero, or_false] at * + conv => + rw [← tsum_mul_left] + enter [1,1] + ext c + rw [this c] + simp_rw [tsum_mul_left, ← mul_assoc, tsum_prod_pow_cexp_eq_tsum_sigma (k - 1) z] + · intro n + nth_rw 2 [(tsum_int_eq_tsum_neg _).symm] + congr + ext y + simp only [eisSummand, Fin.isValue, piFinTwoEquiv_symm_apply, Fin.cons_zero, Fin.cons_one, + zpow_neg, zpow_natCast, ← Even.neg_pow hk2 (n * (z : ℂ) + y), neg_add_rev, Int.cast_neg, + neg_mul, inv_inj] + ring + · simpa using Summable.prod (f := fun x : ℤ × ℤ => eisSummand k ![x.1, x.2] z) + (by apply summable_prod_eisSummand k hk) + +lemma gammaSetN_eisSummand (k : ℤ) (z : ℍ) {n : ℕ} (v : gammaSetN n) : eisSummand k v z = + ((n : ℂ) ^ k)⁻¹ * eisSummand k (gammaSetN_map n v) z := by + simp only [eisSummand, gammaSetN_map_eq v, Fin.isValue, Pi.smul_apply, nsmul_eq_mul, + Int.cast_mul, Int.cast_natCast, zpow_neg, ← mul_inv, ← mul_zpow] + ring_nf + +lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ k) (z : ℍ) : + ∑' (x : Fin 2 → ℤ), eisSummand k x z = (riemannZeta (k)) * (eisensteinSeries 𝟙 k z) := by + rw [← GammaSet_one_Equiv.symm.tsum_eq] + have hk1 : 1 < k := by omega + rw [eisensteinSeries , Summable.tsum_sigma, GammaSet_one_Equiv, zeta_nat_eq_tsum_of_gt_one hk1, + tsum_mul_tsum_of_summable_norm (by simp [hk1]) + (by apply (summable_norm_eisSummand (by omega) z).subtype)] + · simp only [Equiv.coe_fn_symm_mk, one_div] + rw [Summable.tsum_prod'] + · apply tsum_congr + intro b + by_cases hb : b = 0 + · simp [hb, CharP.cast_eq_zero, gammaSetN_eisSummand k z, show ((0 : ℂ) ^ k)⁻¹ = 0 by aesop] + · simpa [gammaSetN_eisSummand k z, zpow_natCast, tsum_mul_left, hb] using + (gammaSetN_Equiv hb).tsum_eq (fun v => eisSummand k v z) + · apply summable_mul_of_summable_norm (f:= fun (n : ℕ)=> ((n : ℂ) ^ k)⁻¹) + (g := fun (v : gammaSet 1 0) => eisSummand k v z) (by simp [hk1]) + apply (EisensteinSeries.summable_norm_eisSummand (by omega) z).subtype + · intro b + simpa using (Summable.of_norm (by apply (EisensteinSeries.summable_norm_eisSummand + (by omega) z).subtype)).mul_left (a := ((b : ℂ) ^ k)⁻¹) + · apply ((GammaSet_one_Equiv.symm.summable_iff (f := fun v => eisSummand k v z)).mpr + (EisensteinSeries.summable_norm_eisSummand (by omega) z).of_norm).congr + simp + +lemma EisensteinSeries.q_expansion {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : + (E k hk) z = 1 + (1 / (riemannZeta (k))) * ((-2 * ↑π * Complex.I) ^ k / (k - 1)!) * + ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * ↑π * Complex.I * z) ^ (n : ℤ) := by + have : (eisensteinSeries_MF (k := k) (by omega) standardcongruencecondition) z = + (eisensteinSeries_SIF standardcongruencecondition k) z := rfl + rw [E, ModularForm.smul_apply, this, eisensteinSeries_SIF_apply standardcongruencecondition k z, + eisensteinSeries, standardcongruencecondition] + have HE1 := tsum_prod_eisSummand_eq_sigma_cexp k (by omega) hk2 z + have HE2 := tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries (by omega) z + have z2 : (riemannZeta (k)) ≠ 0 := by + refine riemannZeta_ne_zero_of_one_lt_re ?_ + simp only [natCast_re, Nat.one_lt_cast] + omega + simp only [PNat.val_ofNat, standardcongruencecondition, eisSummand, Fin.isValue, + UpperHalfPlane.coe, zpow_neg, zpow_natCast, neg_mul, eisensteinSeries, ← + inv_mul_eq_iff_eq_mul₀ z2, ne_eq, one_div, smul_eq_mul] at * + simp_rw [← HE2, HE1, mul_add] + field_simp + ring + +theorem even_div_two_ne_zero {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) : k / 2 ≠ 0 := by + simp only [ne_eq, Nat.div_eq_zero_iff, OfNat.ofNat_ne_zero, false_or, not_lt] + suffices (2 : ℤ) ≤ k by + norm_cast at * + refine (Int.two_le_iff_pos_of_even (m := k) (by simpa using hk2 )).mpr (by omega) + +lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) : + (1 / (riemannZeta (k))) * ((-2 * ↑π * Complex.I) ^ k / (k - 1)!) = -((2 * k) / bernoulli k) := by + have hk0 := even_div_two_ne_zero hk2 hkn0 + have hk1 : 2 * (k / 2) = k := by apply Nat.two_mul_div_two_of_even hk2 + have hk11 : 2 * (((k / 2) : ℕ) : ℂ) = k := by norm_cast + have hpi : (π : ℂ) ≠ 0 := by + simp [Real.pi_ne_zero] + have hkf : ((k - 1)! : ℂ) ≠ 0 := by + norm_cast + apply Nat.factorial_ne_zero + have h3 : (-2 * ↑π * Complex.I) ^ k = (-1) ^ k * 2 ^ k * π ^ k * (-1) ^ (k / 2) := by + simp_rw [mul_pow] + nth_rw 3 [← hk1] + rw [neg_pow, pow_mul] + simp + have := riemannZeta_two_mul_nat hk0 + rw [hk1, hk11] at this + rw [h3, this, (Nat.mul_factorial_pred hkn0).symm] + field_simp + have : (k : ℂ) * ↑(k - 1)! * (2 ^ k * ↑π ^ k * (-1) ^ (k / 2)) / + ((-1) ^ (k / 2 + 1) * 2 ^ (k - 1) * ↑π ^ k * ↑(bernoulli k) * ↑(k - 1)!) = + (↑k * ↑(k - 1)! * (2 ^ k * ↑π ^ k * (-1) ^ (k / 2)) / + ((-1) ^ (k / 2 + 1) * 2 ^ (k - 1) * ↑π ^ k * ↑(k - 1)!)) * 1 / (bernoulli k) := by + ring + rw [this] + congr + field_simp + have h2k : (2 : ℂ) ^ k = 2 * 2 ^ (k - 1) := by + rw [show k = 1 + (k - 1) by omega, pow_add] + simp + rw [h2k] + ring + +lemma EisensteinSeries.q_expansion_bernoulli {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : + (E k hk) z = 1 + -((2 * k) / bernoulli k) * + ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * ↑π * Complex.I * z) ^ (n : ℤ) := by + have h2 := EisensteinSeries.q_expansion hk hk2 z + rw [eisensteinSeries_coeff_identity hk2 (by omega)] at h2 + apply h2 diff --git a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean index 45980196002550..c553de40d401d3 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean @@ -534,17 +534,67 @@ lemma multipliable_int_iff_multipliable_nat_and_neg {f : ℤ → G} : end IsUniformGroup +theorem tsum_int_eq_tsum_neg {α : Type*} [AddCommMonoid α] [TopologicalSpace α] (f : ℤ → α) : + ∑' d, f (-d) = ∑' d, f d := by + rw [show (fun d => f (-d)) = (fun d => f d) ∘ (Equiv.neg ℤ) by ext; simp] + apply (Equiv.neg ℤ).tsum_eq + end Int section pnat +variable {α R : Type*} [TopologicalSpace α] [CommMonoid α] [AddMonoidWithOne R] + @[to_additive] -theorem pnat_multipliable_iff_multipliable_succ {α : Type*} [TopologicalSpace α] [CommMonoid α] +theorem pnat_multipliable_iff_multipliable_succ {f : ℕ → α} : Multipliable (fun x : ℕ+ => f x) ↔ Multipliable fun x : ℕ => f (x + 1) := Equiv.pnatEquivNat.symm.multipliable_iff.symm @[to_additive] -theorem tprod_pnat_eq_tprod_succ {α : Type*} [TopologicalSpace α] [CommMonoid α] (f : ℕ → α) : +theorem tprod_pnat_eq_tprod_succ (f : ℕ → α) : ∏' n : ℕ+, f n = ∏' n, f (n + 1) := (Equiv.pnatEquivNat.symm.tprod_eq _).symm +@[to_additive] +lemma tprod_zero_pnat_eq_tprod_nat {α : Type*} [TopologicalSpace α] [CommGroup α] + [IsTopologicalGroup α] [T2Space α] (f : ℕ → α) (hf : Multipliable f) : + f 0 * ∏' (n : ℕ+), f ↑n = ∏' (n : ℕ), f n := by + simp [Multipliable.tprod_eq_zero_mul hf, tprod_pnat_eq_tprod_succ f] + +theorem pnat_multipliable_iff_multipliable_succ' {f : R → α} : + Multipliable (fun x : ℕ+ => f x) ↔ Multipliable fun x : ℕ => f (x + 1) := by + convert Equiv.pnatEquivNat.symm.multipliable_iff.symm + simp + +theorem pnat_summable_iff_summable_succ' {α : Type*} [TopologicalSpace α] + [AddCommMonoid α] {f : R → α} : + Summable (fun x : ℕ+ => f x) ↔ Summable fun x : ℕ => f (x + 1) := by + convert Equiv.pnatEquivNat.symm.summable_iff.symm + simp + +theorem tprod_pnat_eq_tprod_succ' + (f : R → α) : ∏' n : ℕ+, f n = ∏' (n : ℕ), f (n + 1) := by + convert (Equiv.pnatEquivNat.symm.tprod_eq _).symm + simp + +theorem tsum_pnat_eq_tsum_succ' {α : Type*} + [TopologicalSpace α] [AddCommMonoid α] + (f : R → α) : ∑' n : ℕ+, f n = ∑' (n : ℕ), f (n + 1) := by + convert (Equiv.pnatEquivNat.symm.tsum_eq _).symm + simp + +theorem tsum_nat_eq_zero_two_pnat {α : Type*} [UniformSpace α] [Ring α] [IsUniformAddGroup α] + [CompleteSpace α] [T2Space α] {f : ℤ → α} (hf : ∀ n : ℤ, f n = f (-n)) (hf2 : Summable f) : + ∑' n, f n = f 0 + 2 * ∑' n : ℕ+, f n := by + rw [tsum_of_add_one_of_neg_add_one] + · conv => + enter [1,2,1] + ext n + rw [hf] + simp only [neg_add_rev, Int.reduceNeg, neg_neg, tsum_pnat_eq_tsum_succ', two_mul] + abel + · simpa using ((summable_nat_add_iff (k := 1)).mpr + (summable_int_iff_summable_nat_and_neg.mp hf2).1) + · exact (summable_nat_add_iff (k := 1)).mpr (summable_int_iff_summable_nat_and_neg.mp hf2).2 + + end pnat From 3e5f7fd57354319ece9d626082f94f32e2b2d3e3 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 17:21:18 +0100 Subject: [PATCH 036/128] open pr --- Mathlib/NumberTheory/Divisors.lean | 778 +++++++++++++++++++++++++++++ 1 file changed, 778 insertions(+) diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 577a50530a35f9..142c2ebc533416 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -742,3 +742,781 @@ lemma mul_mem_zero_one_two_three_four_iff {a b : ℤ} (h₀ : a = 0 ↔ b = 0) : aesop end Int + +/- +Copyright (c) 2020 Aaron Anderson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Aaron Anderson +-/ +import Mathlib.Algebra.IsPrimePow +import Mathlib.Algebra.Order.BigOperators.Group.Finset +import Mathlib.Algebra.Order.Interval.Finset.SuccPred +import Mathlib.Algebra.Order.Ring.Int +import Mathlib.Algebra.Ring.CharZero +import Mathlib.Data.Nat.Cast.Order.Ring +import Mathlib.Data.Nat.PrimeFin +import Mathlib.Data.Nat.SuccPred +import Mathlib.Order.Interval.Finset.Nat +import Mathlib.Data.PNat.Defs + +/-! +# Divisor Finsets + +This file defines sets of divisors of a natural number. This is particularly useful as background +for defining Dirichlet convolution. + +## Main Definitions +Let `n : ℕ`. All of the following definitions are in the `Nat` namespace: +* `divisors n` is the `Finset` of natural numbers that divide `n`. +* `properDivisors n` is the `Finset` of natural numbers that divide `n`, other than `n`. +* `divisorsAntidiagonal n` is the `Finset` of pairs `(x,y)` such that `x * y = n`. +* `Perfect n` is true when `n` is positive and the sum of `properDivisors n` is `n`. + +## Conventions + +Since `0` has infinitely many divisors, none of the definitions in this file make sense for it. +Therefore we adopt the convention that `Nat.divisors 0`, `Nat.properDivisors 0`, +`Nat.divisorsAntidiagonal 0` and `Int.divisorsAntidiag 0` are all `∅`. + +## Tags +divisors, perfect numbers + +-/ + +open Finset + +namespace Nat + +variable (n : ℕ) + +/-- `divisors n` is the `Finset` of divisors of `n`. By convention, we set `divisors 0 = ∅`. -/ +def divisors : Finset ℕ := {d ∈ Ico 1 (n + 1) | d ∣ n} + +/-- `properDivisors n` is the `Finset` of divisors of `n`, other than `n`. +By convention, we set `properDivisors 0 = ∅`. -/ +def properDivisors : Finset ℕ := {d ∈ Ico 1 n | d ∣ n} + +/-- Pairs of divisors of a natural number as a finset. + +`n.divisorsAntidiagonal` is the finset of pairs `(a, b) : ℕ × ℕ` such that `a * b = n`. +By convention, we set `Nat.divisorsAntidiagonal 0 = ∅`. + +O(n). -/ +def divisorsAntidiagonal : Finset (ℕ × ℕ) := + (Icc 1 n).filterMap (fun x ↦ let y := n / x; if x * y = n then some (x, y) else none) + fun x₁ x₂ (x, y) hx₁ hx₂ ↦ by aesop + +/-- Pairs of divisors of a natural number, as a list. + +`n.divisorsAntidiagonalList` is the list of pairs `(a, b) : ℕ × ℕ` such that `a * b = n`, ordered +by increasing `a`. By convention, we set `Nat.divisorsAntidiagonalList 0 = []`. +-/ +def divisorsAntidiagonalList (n : ℕ) : List (ℕ × ℕ) := + (List.range' 1 n).filterMap + (fun x ↦ let y := n / x; if x * y = n then some (x, y) else none) + +variable {n} + +@[simp] +theorem filter_dvd_eq_divisors (h : n ≠ 0) : {d ∈ range n.succ | d ∣ n} = n.divisors := by + ext + simp only [divisors, mem_filter, mem_range, mem_Ico, and_congr_left_iff, iff_and_self] + exact fun ha _ => succ_le_iff.mpr (pos_of_dvd_of_pos ha h.bot_lt) + +@[simp] +theorem filter_dvd_eq_properDivisors (h : n ≠ 0) : {d ∈ range n | d ∣ n} = n.properDivisors := by + ext + simp only [properDivisors, mem_filter, mem_range, mem_Ico, and_congr_left_iff, iff_and_self] + exact fun ha _ => succ_le_iff.mpr (pos_of_dvd_of_pos ha h.bot_lt) + +theorem self_notMem_properDivisors : n ∉ properDivisors n := by simp [properDivisors] + +@[deprecated (since := "2025-05-23")] +alias properDivisors.not_self_mem := self_notMem_properDivisors + +@[simp] +theorem mem_properDivisors {m : ℕ} : n ∈ properDivisors m ↔ n ∣ m ∧ n < m := by + rcases eq_or_ne m 0 with (rfl | hm); · simp [properDivisors] + simp only [and_comm, ← filter_dvd_eq_properDivisors hm, mem_filter, mem_range] + +theorem insert_self_properDivisors (h : n ≠ 0) : insert n (properDivisors n) = divisors n := by + rw [divisors, properDivisors, + ← Finset.insert_Ico_right_eq_Ico_add_one (one_le_iff_ne_zero.2 h), + Finset.filter_insert, if_pos (dvd_refl n)] + +theorem cons_self_properDivisors (h : n ≠ 0) : + cons n (properDivisors n) self_notMem_properDivisors = divisors n := by + rw [cons_eq_insert, insert_self_properDivisors h] + +@[simp] +theorem mem_divisors {m : ℕ} : n ∈ divisors m ↔ n ∣ m ∧ m ≠ 0 := by + rcases eq_or_ne m 0 with (rfl | hm); · simp [divisors] + simp only [hm, Ne, not_false_iff, and_true, ← filter_dvd_eq_divisors hm, mem_filter, + mem_range, and_iff_right_iff_imp, Nat.lt_succ_iff] + exact le_of_dvd hm.bot_lt + +theorem dvd_of_mem_divisors {m : ℕ} (h : n ∈ divisors m) : n ∣ m := (mem_divisors.mp h).1 + +theorem ne_zero_of_mem_divisors {m : ℕ} (h : n ∈ divisors m) : m ≠ 0 := (mem_divisors.mp h).2 + +theorem one_mem_divisors : 1 ∈ divisors n ↔ n ≠ 0 := by simp + +theorem mem_divisors_self (n : ℕ) (h : n ≠ 0) : n ∈ n.divisors := + mem_divisors.2 ⟨dvd_rfl, h⟩ + +@[simp] +theorem mem_divisorsAntidiagonal {x : ℕ × ℕ} : + x ∈ divisorsAntidiagonal n ↔ x.fst * x.snd = n ∧ n ≠ 0 := by + obtain ⟨a, b⟩ := x + simp only [divisorsAntidiagonal, mul_div_eq_iff_dvd, mem_filterMap, mem_Icc, one_le_iff_ne_zero, + Option.ite_none_right_eq_some, Option.some.injEq, Prod.ext_iff, and_left_comm, exists_eq_left] + constructor + · rintro ⟨han, ⟨ha, han'⟩, rfl⟩ + simp [Nat.mul_div_eq_iff_dvd, han] + omega + · rintro ⟨rfl, hab⟩ + rw [mul_ne_zero_iff] at hab + simpa [hab.1, hab.2] using Nat.le_mul_of_pos_right _ hab.2.bot_lt + +@[simp] lemma divisorsAntidiagonalList_zero : divisorsAntidiagonalList 0 = [] := rfl +@[simp] lemma divisorsAntidiagonalList_one : divisorsAntidiagonalList 1 = [(1, 1)] := rfl + +@[simp] +lemma toFinset_divisorsAntidiagonalList {n : ℕ} : + n.divisorsAntidiagonalList.toFinset = n.divisorsAntidiagonal := by + rw [divisorsAntidiagonalList, divisorsAntidiagonal, List.toFinset_filterMap (f_inj := by aesop), + List.toFinset_range'_1_1] + +lemma sorted_divisorsAntidiagonalList_fst {n : ℕ} : + n.divisorsAntidiagonalList.Sorted (·.fst < ·.fst) := by + refine (List.sorted_lt_range' _ _ Nat.one_ne_zero).filterMap fun a b c d h h' ha => ?_ + rw [Option.ite_none_right_eq_some, Option.some.injEq] at h h' + simpa [← h.right, ← h'.right] + +lemma sorted_divisorsAntidiagonalList_snd {n : ℕ} : + n.divisorsAntidiagonalList.Sorted (·.snd > ·.snd) := by + obtain rfl | hn := eq_or_ne n 0 + · simp + refine (List.sorted_lt_range' _ _ Nat.one_ne_zero).filterMap ?_ + simp only [Option.ite_none_right_eq_some, Option.some.injEq, gt_iff_lt, and_imp, Prod.forall, + Prod.mk.injEq] + rintro a b _ _ _ _ ha rfl rfl hb rfl rfl hab + rwa [Nat.div_lt_div_left hn ⟨_, hb.symm⟩ ⟨_, ha.symm⟩] + +lemma nodup_divisorsAntidiagonalList {n : ℕ} : n.divisorsAntidiagonalList.Nodup := + have : IsIrrefl (ℕ × ℕ) (·.fst < ·.fst) := ⟨by simp⟩ + sorted_divisorsAntidiagonalList_fst.nodup + +/-- The `Finset` and `List` versions agree by definition. -/ +@[simp] +theorem val_divisorsAntidiagonal (n : ℕ) : + (divisorsAntidiagonal n).val = divisorsAntidiagonalList n := + rfl + +@[simp] +lemma mem_divisorsAntidiagonalList {n : ℕ} {a : ℕ × ℕ} : + a ∈ n.divisorsAntidiagonalList ↔ a.1 * a.2 = n ∧ n ≠ 0 := by + rw [← List.mem_toFinset, toFinset_divisorsAntidiagonalList, mem_divisorsAntidiagonal] + +@[simp high] +lemma swap_mem_divisorsAntidiagonalList {a : ℕ × ℕ} : + a.swap ∈ n.divisorsAntidiagonalList ↔ a ∈ n.divisorsAntidiagonalList := by simp [mul_comm] + +lemma reverse_divisorsAntidiagonalList (n : ℕ) : + n.divisorsAntidiagonalList.reverse = n.divisorsAntidiagonalList.map .swap := by + have : IsAsymm (ℕ × ℕ) (·.snd < ·.snd) := ⟨fun _ _ ↦ lt_asymm⟩ + refine List.eq_of_perm_of_sorted ?_ sorted_divisorsAntidiagonalList_snd.reverse <| + sorted_divisorsAntidiagonalList_fst.map _ fun _ _ ↦ id + simp [List.reverse_perm', List.perm_ext_iff_of_nodup nodup_divisorsAntidiagonalList + (nodup_divisorsAntidiagonalList.map Prod.swap_injective), mul_comm] + +lemma ne_zero_of_mem_divisorsAntidiagonal {p : ℕ × ℕ} (hp : p ∈ n.divisorsAntidiagonal) : + p.1 ≠ 0 ∧ p.2 ≠ 0 := by + obtain ⟨hp₁, hp₂⟩ := Nat.mem_divisorsAntidiagonal.mp hp + exact mul_ne_zero_iff.mp (hp₁.symm ▸ hp₂) + +lemma left_ne_zero_of_mem_divisorsAntidiagonal {p : ℕ × ℕ} (hp : p ∈ n.divisorsAntidiagonal) : + p.1 ≠ 0 := + (ne_zero_of_mem_divisorsAntidiagonal hp).1 + +lemma right_ne_zero_of_mem_divisorsAntidiagonal {p : ℕ × ℕ} (hp : p ∈ n.divisorsAntidiagonal) : + p.2 ≠ 0 := + (ne_zero_of_mem_divisorsAntidiagonal hp).2 + +theorem divisor_le {m : ℕ} : n ∈ divisors m → n ≤ m := by + rcases m with - | m + · simp + · simp only [mem_divisors, Nat.succ_ne_zero m, and_true, Ne, not_false_iff] + exact Nat.le_of_dvd (Nat.succ_pos m) + +theorem divisors_subset_of_dvd {m : ℕ} (hzero : n ≠ 0) (h : m ∣ n) : divisors m ⊆ divisors n := + Finset.subset_iff.2 fun _x hx => Nat.mem_divisors.mpr ⟨(Nat.mem_divisors.mp hx).1.trans h, hzero⟩ + +theorem card_divisors_le_self (n : ℕ) : #n.divisors ≤ n := calc + _ ≤ #(Ico 1 (n + 1)) := by + apply card_le_card + simp only [divisors, filter_subset] + _ = n := by rw [card_Ico, add_tsub_cancel_right] + +theorem divisors_subset_properDivisors {m : ℕ} (hzero : n ≠ 0) (h : m ∣ n) (hdiff : m ≠ n) : + divisors m ⊆ properDivisors n := by + apply Finset.subset_iff.2 + intro x hx + exact + Nat.mem_properDivisors.2 + ⟨(Nat.mem_divisors.1 hx).1.trans h, + lt_of_le_of_lt (divisor_le hx) + (lt_of_le_of_ne (divisor_le (Nat.mem_divisors.2 ⟨h, hzero⟩)) hdiff)⟩ + +lemma divisors_filter_dvd_of_dvd {n m : ℕ} (hn : n ≠ 0) (hm : m ∣ n) : + {d ∈ n.divisors | d ∣ m} = m.divisors := by + ext k + simp_rw [mem_filter, mem_divisors] + exact ⟨fun ⟨_, hkm⟩ ↦ ⟨hkm, ne_zero_of_dvd_ne_zero hn hm⟩, fun ⟨hk, _⟩ ↦ ⟨⟨hk.trans hm, hn⟩, hk⟩⟩ + +@[simp] +theorem divisors_zero : divisors 0 = ∅ := by + ext + simp + +@[simp] +theorem properDivisors_zero : properDivisors 0 = ∅ := by + ext + simp + +@[simp] +lemma nonempty_divisors : (divisors n).Nonempty ↔ n ≠ 0 := + ⟨fun ⟨m, hm⟩ hn ↦ by simp [hn] at hm, fun hn ↦ ⟨1, one_mem_divisors.2 hn⟩⟩ + +@[simp] +lemma divisors_eq_empty : divisors n = ∅ ↔ n = 0 := + not_nonempty_iff_eq_empty.symm.trans nonempty_divisors.not_left + +theorem properDivisors_subset_divisors : properDivisors n ⊆ divisors n := + filter_subset_filter _ <| Ico_subset_Ico_right n.le_succ + +@[simp] +theorem divisors_one : divisors 1 = {1} := by + ext + simp + +@[simp] +theorem properDivisors_one : properDivisors 1 = ∅ := by rw [properDivisors, Ico_self, filter_empty] + +theorem pos_of_mem_divisors {m : ℕ} (h : m ∈ n.divisors) : 0 < m := by + cases m + · rw [mem_divisors, zero_dvd_iff (a := n)] at h + cases h.2 h.1 + apply Nat.succ_pos + +theorem pos_of_mem_properDivisors {m : ℕ} (h : m ∈ n.properDivisors) : 0 < m := + pos_of_mem_divisors (properDivisors_subset_divisors h) + +theorem one_mem_properDivisors_iff_one_lt : 1 ∈ n.properDivisors ↔ 1 < n := by + rw [mem_properDivisors, and_iff_right (one_dvd _)] + +@[simp] +lemma sup_divisors_id (n : ℕ) : n.divisors.sup id = n := by + refine le_antisymm (Finset.sup_le fun _ ↦ divisor_le) ?_ + rcases Decidable.eq_or_ne n 0 with rfl | hn + · apply zero_le + · exact Finset.le_sup (f := id) <| mem_divisors_self n hn + +lemma one_lt_of_mem_properDivisors {m n : ℕ} (h : m ∈ n.properDivisors) : 1 < n := + lt_of_le_of_lt (pos_of_mem_properDivisors h) (mem_properDivisors.1 h).2 + +lemma one_lt_div_of_mem_properDivisors {m n : ℕ} (h : m ∈ n.properDivisors) : + 1 < n / m := by + obtain ⟨h_dvd, h_lt⟩ := mem_properDivisors.mp h + rwa [Nat.lt_div_iff_mul_lt' h_dvd, mul_one] + +/-- See also `Nat.mem_properDivisors`. -/ +lemma mem_properDivisors_iff_exists {m n : ℕ} (hn : n ≠ 0) : + m ∈ n.properDivisors ↔ ∃ k > 1, n = m * k := by + refine ⟨fun h ↦ ⟨n / m, one_lt_div_of_mem_properDivisors h, ?_⟩, ?_⟩ + · exact (Nat.mul_div_cancel' (mem_properDivisors.mp h).1).symm + · rintro ⟨k, hk, rfl⟩ + rw [mul_ne_zero_iff] at hn + exact mem_properDivisors.mpr ⟨⟨k, rfl⟩, lt_mul_of_one_lt_right (Nat.pos_of_ne_zero hn.1) hk⟩ + +@[simp] +lemma nonempty_properDivisors : n.properDivisors.Nonempty ↔ 1 < n := + ⟨fun ⟨_m, hm⟩ ↦ one_lt_of_mem_properDivisors hm, fun hn ↦ + ⟨1, one_mem_properDivisors_iff_one_lt.2 hn⟩⟩ + +@[simp] +lemma properDivisors_eq_empty : n.properDivisors = ∅ ↔ n ≤ 1 := by + rw [← not_nonempty_iff_eq_empty, nonempty_properDivisors, not_lt] + +@[simp] +theorem divisorsAntidiagonal_zero : divisorsAntidiagonal 0 = ∅ := by + ext + simp + +@[simp] +theorem divisorsAntidiagonal_one : divisorsAntidiagonal 1 = {(1, 1)} := by + ext + simp [mul_eq_one, Prod.ext_iff] + +@[simp high] +theorem swap_mem_divisorsAntidiagonal {x : ℕ × ℕ} : + x.swap ∈ divisorsAntidiagonal n ↔ x ∈ divisorsAntidiagonal n := by + rw [mem_divisorsAntidiagonal, mem_divisorsAntidiagonal, mul_comm, Prod.swap] + +/-- `Nat.swap_mem_divisorsAntidiagonal` with the LHS in simp normal form. -/ +@[deprecated swap_mem_divisorsAntidiagonal (since := "2025-02-17")] +theorem swap_mem_divisorsAntidiagonal_aux {x : ℕ × ℕ} : + x.snd * x.fst = n ∧ ¬n = 0 ↔ x ∈ divisorsAntidiagonal n := by + rw [mem_divisorsAntidiagonal, mul_comm] + +lemma prodMk_mem_divisorsAntidiag {x y : ℕ} (hn : n ≠ 0) : + (x, y) ∈ n.divisorsAntidiagonal ↔ x * y = n := by simp [hn] + +theorem fst_mem_divisors_of_mem_antidiagonal {x : ℕ × ℕ} (h : x ∈ divisorsAntidiagonal n) : + x.fst ∈ divisors n := by + rw [mem_divisorsAntidiagonal] at h + simp [Dvd.intro _ h.1, h.2] + +theorem snd_mem_divisors_of_mem_antidiagonal {x : ℕ × ℕ} (h : x ∈ divisorsAntidiagonal n) : + x.snd ∈ divisors n := by + rw [mem_divisorsAntidiagonal] at h + simp [Dvd.intro_left _ h.1, h.2] + +@[simp] +theorem map_swap_divisorsAntidiagonal : + (divisorsAntidiagonal n).map (Equiv.prodComm _ _).toEmbedding = divisorsAntidiagonal n := by + rw [← coe_inj, coe_map, Equiv.coe_toEmbedding, Equiv.coe_prodComm, + Set.image_swap_eq_preimage_swap] + ext + exact swap_mem_divisorsAntidiagonal + +@[simp] +theorem image_fst_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.fst = divisors n := by + ext + simp [Dvd.dvd, @eq_comm _ n (_ * _)] + +@[simp] +theorem image_snd_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.snd = divisors n := by + rw [← map_swap_divisorsAntidiagonal, map_eq_image, image_image] + exact image_fst_divisorsAntidiagonal + +theorem map_div_right_divisors : + n.divisors.map ⟨fun d => (d, n / d), fun _ _ => congr_arg Prod.fst⟩ = + n.divisorsAntidiagonal := by + ext ⟨d, nd⟩ + simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors, + Prod.ext_iff, and_left_comm, exists_eq_left] + constructor + · rintro ⟨⟨⟨k, rfl⟩, hn⟩, rfl⟩ + rw [Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt] + exact ⟨rfl, hn⟩ + · rintro ⟨rfl, hn⟩ + exact ⟨⟨dvd_mul_right _ _, hn⟩, Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt⟩ + +theorem map_div_left_divisors : + n.divisors.map ⟨fun d => (n / d, d), fun _ _ => congr_arg Prod.snd⟩ = + n.divisorsAntidiagonal := by + apply Finset.map_injective (Equiv.prodComm _ _).toEmbedding + ext + rw [map_swap_divisorsAntidiagonal, ← map_div_right_divisors, Finset.map_map] + simp + +theorem sum_divisors_eq_sum_properDivisors_add_self : + ∑ i ∈ divisors n, i = (∑ i ∈ properDivisors n, i) + n := by + rcases Decidable.eq_or_ne n 0 with (rfl | hn) + · simp + · rw [← cons_self_properDivisors hn, Finset.sum_cons, add_comm] + +/-- `n : ℕ` is perfect if and only the sum of the proper divisors of `n` is `n` and `n` + is positive. -/ +def Perfect (n : ℕ) : Prop := + ∑ i ∈ properDivisors n, i = n ∧ 0 < n + +theorem perfect_iff_sum_properDivisors (h : 0 < n) : Perfect n ↔ ∑ i ∈ properDivisors n, i = n := + and_iff_left h + +theorem perfect_iff_sum_divisors_eq_two_mul (h : 0 < n) : + Perfect n ↔ ∑ i ∈ divisors n, i = 2 * n := by + rw [perfect_iff_sum_properDivisors h, sum_divisors_eq_sum_properDivisors_add_self, two_mul] + constructor <;> intro h + · rw [h] + · apply add_right_cancel h + +theorem mem_divisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} : + x ∈ divisors (p ^ k) ↔ ∃ j ≤ k, x = p ^ j := by + rw [mem_divisors, Nat.dvd_prime_pow pp, and_iff_left (ne_of_gt (pow_pos pp.pos k))] + +theorem Prime.divisors {p : ℕ} (pp : p.Prime) : divisors p = {1, p} := by + ext + rw [mem_divisors, dvd_prime pp, and_iff_left pp.ne_zero, Finset.mem_insert, Finset.mem_singleton] + +theorem Prime.properDivisors {p : ℕ} (pp : p.Prime) : properDivisors p = {1} := by + rw [← erase_insert self_notMem_properDivisors, insert_self_properDivisors pp.ne_zero, + pp.divisors, pair_comm, erase_insert fun con => pp.ne_one (mem_singleton.1 con)] + +theorem divisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) : + divisors (p ^ k) = (Finset.range (k + 1)).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by + ext a + rw [mem_divisors_prime_pow pp] + simp [Nat.lt_succ, eq_comm] + +theorem divisors_injective : Function.Injective divisors := + Function.LeftInverse.injective sup_divisors_id + +@[simp] +theorem divisors_inj {a b : ℕ} : a.divisors = b.divisors ↔ a = b := + divisors_injective.eq_iff + +theorem eq_properDivisors_of_subset_of_sum_eq_sum {s : Finset ℕ} (hsub : s ⊆ n.properDivisors) : + ((∑ x ∈ s, x) = ∑ x ∈ n.properDivisors, x) → s = n.properDivisors := by + cases n + · rw [properDivisors_zero, subset_empty] at hsub + simp [hsub] + classical + rw [← sum_sdiff hsub] + intro h + apply Subset.antisymm hsub + rw [← sdiff_eq_empty_iff_subset] + contrapose h + rw [← Ne, ← nonempty_iff_ne_empty] at h + apply ne_of_lt + rw [← zero_add (∑ x ∈ s, x), ← add_assoc, add_zero] + apply add_lt_add_right + have hlt := + sum_lt_sum_of_nonempty h fun x hx => pos_of_mem_properDivisors (sdiff_subset hx) + simp only [sum_const_zero] at hlt + apply hlt + +theorem sum_properDivisors_dvd (h : (∑ x ∈ n.properDivisors, x) ∣ n) : + ∑ x ∈ n.properDivisors, x = 1 ∨ ∑ x ∈ n.properDivisors, x = n := by + rcases n with - | n + · simp + · rcases n with - | n + · simp at h + · rw [or_iff_not_imp_right] + intro ne_n + have hlt : ∑ x ∈ n.succ.succ.properDivisors, x < n.succ.succ := + lt_of_le_of_ne (Nat.le_of_dvd (Nat.succ_pos _) h) ne_n + symm + rw [← mem_singleton, eq_properDivisors_of_subset_of_sum_eq_sum (singleton_subset_iff.2 + (mem_properDivisors.2 ⟨h, hlt⟩)) (sum_singleton _ _), mem_properDivisors] + exact ⟨one_dvd _, Nat.succ_lt_succ (Nat.succ_pos _)⟩ + +@[to_additive (attr := simp)] +theorem Prime.prod_properDivisors {α : Type*} [CommMonoid α] {p : ℕ} {f : ℕ → α} (h : p.Prime) : + ∏ x ∈ p.properDivisors, f x = f 1 := by simp [h.properDivisors] + +@[to_additive (attr := simp)] +theorem Prime.prod_divisors {α : Type*} [CommMonoid α] {p : ℕ} {f : ℕ → α} (h : p.Prime) : + ∏ x ∈ p.divisors, f x = f p * f 1 := by + rw [← cons_self_properDivisors h.ne_zero, prod_cons, h.prod_properDivisors] + +theorem properDivisors_eq_singleton_one_iff_prime : n.properDivisors = {1} ↔ n.Prime := by + refine ⟨?_, ?_⟩ + · intro h + refine Nat.prime_def.mpr ⟨?_, fun m hdvd => ?_⟩ + · match n with + | 0 => contradiction + | 1 => contradiction + | Nat.succ (Nat.succ n) => simp + · rw [← mem_singleton, ← h, mem_properDivisors] + have := Nat.le_of_dvd ?_ hdvd + · simpa [hdvd, this] using (le_iff_eq_or_lt.mp this).symm + · by_contra! + simp only [nonpos_iff_eq_zero.mp this] at h + contradiction + · exact fun h => Prime.properDivisors h + +theorem sum_properDivisors_eq_one_iff_prime : ∑ x ∈ n.properDivisors, x = 1 ↔ n.Prime := by + rcases n with - | n + · simp [Nat.not_prime_zero] + · cases n + · simp [Nat.not_prime_one] + · rw [← properDivisors_eq_singleton_one_iff_prime] + refine ⟨fun h => ?_, fun h => h.symm ▸ sum_singleton _ _⟩ + rw [@eq_comm (Finset ℕ) _ _] + apply + eq_properDivisors_of_subset_of_sum_eq_sum + (singleton_subset_iff.2 + (one_mem_properDivisors_iff_one_lt.2 (succ_lt_succ (Nat.succ_pos _)))) + ((sum_singleton _ _).trans h.symm) + +theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} : + x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by + rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right] + simp only [exists_prop, and_assoc] + apply exists_congr + intro a + constructor <;> intro h + · rcases h with ⟨_h_left, rfl, h_right⟩ + rw [Nat.pow_lt_pow_iff_right pp.one_lt] at h_right + exact ⟨h_right, rfl⟩ + · rcases h with ⟨h_left, rfl⟩ + rw [Nat.pow_lt_pow_iff_right pp.one_lt] + simp [h_left, le_of_lt] + +theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) : + properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by + ext a + simp only [mem_properDivisors, mem_map, mem_range, Function.Embedding.coeFn_mk] + have := mem_properDivisors_prime_pow pp k (x := a) + rw [mem_properDivisors] at this + grind + +@[to_additive (attr := simp)] +theorem prod_properDivisors_prime_pow {α : Type*} [CommMonoid α] {k p : ℕ} {f : ℕ → α} + (h : p.Prime) : (∏ x ∈ (p ^ k).properDivisors, f x) = ∏ x ∈ range k, f (p ^ x) := by + simp [h, properDivisors_prime_pow] + +@[to_additive (attr := simp) sum_divisors_prime_pow] +theorem prod_divisors_prime_pow {α : Type*} [CommMonoid α] {k p : ℕ} {f : ℕ → α} (h : p.Prime) : + (∏ x ∈ (p ^ k).divisors, f x) = ∏ x ∈ range (k + 1), f (p ^ x) := by + simp [h, divisors_prime_pow] + +@[to_additive] +theorem prod_divisorsAntidiagonal {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) {n : ℕ} : + ∏ i ∈ n.divisorsAntidiagonal, f i.1 i.2 = ∏ i ∈ n.divisors, f i (n / i) := by + rw [← map_div_right_divisors, Finset.prod_map] + rfl + +@[to_additive] +theorem prod_divisorsAntidiagonal' {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) {n : ℕ} : + ∏ i ∈ n.divisorsAntidiagonal, f i.1 i.2 = ∏ i ∈ n.divisors, f (n / i) i := by + rw [← map_swap_divisorsAntidiagonal, Finset.prod_map] + exact prod_divisorsAntidiagonal fun i j => f j i + +/-- The factors of `n` are the prime divisors -/ +theorem primeFactors_eq_to_filter_divisors_prime (n : ℕ) : + n.primeFactors = {p ∈ divisors n | p.Prime} := by + rcases n.eq_zero_or_pos with (rfl | hn) + · simp + · ext q + simpa [hn, hn.ne', mem_primeFactorsList] using and_comm + +lemma primeFactors_filter_dvd_of_dvd {m n : ℕ} (hn : n ≠ 0) (hmn : m ∣ n) : + {p ∈ n.primeFactors | p ∣ m} = m.primeFactors := by + simp_rw [primeFactors_eq_to_filter_divisors_prime, filter_comm, + divisors_filter_dvd_of_dvd hn hmn] + +@[simp] +theorem image_div_divisors_eq_divisors (n : ℕ) : + image (fun x : ℕ => n / x) n.divisors = n.divisors := by + by_cases hn : n = 0 + · simp [hn] + ext a + constructor + · rw [mem_image] + rintro ⟨x, hx1, hx2⟩ + rw [mem_divisors] at * + refine ⟨?_, hn⟩ + rw [← hx2] + exact div_dvd_of_dvd hx1.1 + · rw [mem_divisors, mem_image] + rintro ⟨h1, -⟩ + exact ⟨n / a, mem_divisors.mpr ⟨div_dvd_of_dvd h1, hn⟩, Nat.div_div_self h1 hn⟩ + +/- Porting note: Removed simp; simp_nf linter: +Left-hand side does not simplify, when using the simp lemma on itself. +This usually means that it will never apply. -/ +@[to_additive sum_div_divisors] +theorem prod_div_divisors {α : Type*} [CommMonoid α] (n : ℕ) (f : ℕ → α) : + (∏ d ∈ n.divisors, f (n / d)) = n.divisors.prod f := by + by_cases hn : n = 0; · simp [hn] + rw [← prod_image] + · exact prod_congr (image_div_divisors_eq_divisors n) (by simp) + · intro x hx y hy h + rw [mem_coe, mem_divisors] at hx hy + exact (div_eq_iff_eq_of_dvd_dvd hn hx.1 hy.1).mp h + +theorem disjoint_divisors_filter_isPrimePow {a b : ℕ} (hab : a.Coprime b) : + Disjoint (a.divisors.filter IsPrimePow) (b.divisors.filter IsPrimePow) := by + simp only [Finset.disjoint_left, Finset.mem_filter, and_imp, Nat.mem_divisors, not_and] + rintro n han _ha hn hbn _hb - + exact hn.ne_one (Nat.eq_one_of_dvd_coprimes hab han hbn) + +end Nat + +namespace Int +variable {xy : ℤ × ℤ} {x y z : ℤ} + +-- Local notation for the embeddings `n ↦ n, n ↦ -n : ℕ → ℤ` +local notation "natCast" => Nat.castEmbedding (R := ℤ) +local notation "negNatCast" => + Function.Embedding.trans Nat.castEmbedding (Equiv.toEmbedding (Equiv.neg ℤ)) + +/-- Pairs of divisors of an integer as a finset. + +`z.divisorsAntidiag` is the finset of pairs `(a, b) : ℤ × ℤ` such that `a * b = z`. +By convention, we set `Int.divisorsAntidiag 0 = ∅`. + +O(|z|). Computed from `Nat.divisorsAntidiagonal`. -/ +def divisorsAntidiag : (z : ℤ) → Finset (ℤ × ℤ) + | (n : ℕ) => + let s : Finset (ℕ × ℕ) := n.divisorsAntidiagonal + (s.map <| .prodMap natCast natCast).disjUnion (s.map <| .prodMap negNatCast negNatCast) <| by + simp +contextual [s, disjoint_left, eq_comm] + | negSucc n => + let s : Finset (ℕ × ℕ) := (n + 1).divisorsAntidiagonal + (s.map <| .prodMap natCast negNatCast).disjUnion (s.map <| .prodMap negNatCast natCast) <| by + simp +contextual [s, disjoint_left, eq_comm, forall_swap (α := _ * _ = _)] + +@[simp] +lemma mem_divisorsAntidiag : + ∀ {z} {xy : ℤ × ℤ}, xy ∈ divisorsAntidiag z ↔ xy.fst * xy.snd = z ∧ z ≠ 0 + | (n : ℕ), ((x : ℕ), (y : ℕ)) => by + simp [divisorsAntidiag] + norm_cast + simp +contextual [eq_comm] + | (n : ℕ), (negSucc x, negSucc y) => by + simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] + norm_cast + simp +contextual [eq_comm] + | (n : ℕ), ((x : ℕ), negSucc y) => by + simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] + norm_cast + aesop + | (n : ℕ), (negSucc x, (y : ℕ)) => by + suffices (∃ a, (n = a * y ∧ ¬n = 0) ∧ (a:ℤ) = -1 + -↑x) ↔ (n:ℤ) = (-1 + -↑x) * ↑y ∧ ¬n = 0 by + simpa [divisorsAntidiag, eq_comm, negSucc_eq] + simp only [← Int.neg_add, Int.add_comm 1, Int.neg_mul, Int.add_mul] + norm_cast + match n with + | 0 => simp + | n + 1 => simp + | .negSucc n, ((x : ℕ), (y : ℕ)) => by + simp [divisorsAntidiag] + norm_cast + | .negSucc n, (negSucc x, negSucc y) => by + simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] + norm_cast + simp +contextual + | .negSucc n, ((x : ℕ), negSucc y) => by + simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] + norm_cast + aesop + | .negSucc n, (negSucc x, (y : ℕ)) => by + simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] + norm_cast + simp +contextual [eq_comm] + +@[simp] lemma divisorsAntidiag_zero : divisorsAntidiag 0 = ∅ := rfl + +-- TODO Write a simproc instead of `divisorsAntidiagonal_one`, ..., `divisorsAntidiagonal_four` ... + +@[simp] +theorem divisorsAntidiagonal_one : + Int.divisorsAntidiag 1 = {(1, 1), (-1, -1)} := + rfl + +@[simp] +theorem divisorsAntidiagonal_two : + Int.divisorsAntidiag 2 = {(1, 2), (2, 1), (-1, -2), (-2, -1)} := + rfl + +@[simp] +theorem divisorsAntidiagonal_three : + Int.divisorsAntidiag 3 = {(1, 3), (3, 1), (-1, -3), (-3, -1)} := + rfl + +@[simp] +theorem divisorsAntidiagonal_four : + Int.divisorsAntidiag 4 = {(1, 4), (2, 2), (4, 1), (-1, -4), (-2, -2), (-4, -1)} := + rfl + +lemma prodMk_mem_divisorsAntidiag (hz : z ≠ 0) : (x, y) ∈ z.divisorsAntidiag ↔ x * y = z := by + simp [hz] + +@[simp high] +lemma swap_mem_divisorsAntidiag : xy.swap ∈ z.divisorsAntidiag ↔ xy ∈ z.divisorsAntidiag := by + simp [mul_comm] + +lemma neg_mem_divisorsAntidiag : -xy ∈ z.divisorsAntidiag ↔ xy ∈ z.divisorsAntidiag := by simp + +@[simp] +lemma map_prodComm_divisorsAntidiag : + z.divisorsAntidiag.map (Equiv.prodComm _ _).toEmbedding = z.divisorsAntidiag := by + ext; simp [mem_divisorsAntidiag] + +@[simp] +lemma map_neg_divisorsAntidiag : + z.divisorsAntidiag.map (Equiv.neg _).toEmbedding = z.divisorsAntidiag := by + ext; simp [mem_divisorsAntidiag, mul_comm] + +lemma divisorsAntidiag_neg : + (-z).divisorsAntidiag = + z.divisorsAntidiag.map (.prodMap (.refl _) (Equiv.neg _).toEmbedding) := by + ext; simp [mem_divisorsAntidiag, Prod.ext_iff, neg_eq_iff_eq_neg] + +lemma divisorsAntidiag_natCast (n : ℕ) : + divisorsAntidiag n = + (n.divisorsAntidiagonal.map <| .prodMap natCast natCast).disjUnion + (n.divisorsAntidiagonal.map <| .prodMap negNatCast negNatCast) (by + simp +contextual [disjoint_left, eq_comm]) := rfl + +lemma divisorsAntidiag_neg_natCast (n : ℕ) : + divisorsAntidiag (-n) = + (n.divisorsAntidiagonal.map <| .prodMap natCast negNatCast).disjUnion + (n.divisorsAntidiagonal.map <| .prodMap negNatCast natCast) (by + simp +contextual [disjoint_left, eq_comm]) := by cases n <;> rfl + +lemma divisorsAntidiag_ofNat (n : ℕ) : + divisorsAntidiag ofNat(n) = + (n.divisorsAntidiagonal.map <| .prodMap natCast natCast).disjUnion + (n.divisorsAntidiagonal.map <| .prodMap negNatCast negNatCast) (by + simp +contextual [disjoint_left, eq_comm]) := rfl + +/-- This lemma justifies its existence from its utility in crystallographic root system theory. -/ +lemma mul_mem_one_two_three_iff {a b : ℤ} : + a * b ∈ ({1, 2, 3} : Set ℤ) ↔ (a, b) ∈ ({ + (1, 1), (-1, -1), + (1, 2), (2, 1), (-1, -2), (-2, -1), + (1, 3), (3, 1), (-1, -3), (-3, -1)} : Set (ℤ × ℤ)) := by + simp only [← Int.prodMk_mem_divisorsAntidiag, Set.mem_insert_iff, Set.mem_singleton_iff, ne_eq, + one_ne_zero, not_false_eq_true, OfNat.ofNat_ne_zero] + aesop + +/-- This lemma justifies its existence from its utility in crystallographic root system theory. -/ +lemma mul_mem_zero_one_two_three_four_iff {a b : ℤ} (h₀ : a = 0 ↔ b = 0) : + a * b ∈ ({0, 1, 2, 3, 4} : Set ℤ) ↔ (a, b) ∈ ({ + (0, 0), + (1, 1), (-1, -1), + (1, 2), (2, 1), (-1, -2), (-2, -1), + (1, 3), (3, 1), (-1, -3), (-3, -1), + (4, 1), (1, 4), (-4, -1), (-1, -4), (2, 2), (-2, -2)} : Set (ℤ × ℤ)) := by + simp only [← Int.prodMk_mem_divisorsAntidiag, Set.mem_insert_iff, Set.mem_singleton_iff, ne_eq, + one_ne_zero, not_false_eq_true, OfNat.ofNat_ne_zero] + aesop + +end Int + +section pnat + +/-- The map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` +to `(a , b)`. -/ +def mapdiv (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := by + refine fun x => + ⟨⟨x.1.1, Nat.pos_of_mem_divisors (Nat.fst_mem_divisors_of_mem_antidiagonal x.2)⟩, + (⟨x.1.2, Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ : ℕ+), + Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ + +/-- The equivalence from the union over `n` of `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` +given by sending `n = a * b` to `(a , b)`. -/ +def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ℕ+ × ℕ+ where + toFun x := mapdiv x.1 x.2 + invFun x := + ⟨⟨x.1.1 * x.2.1, mul_pos x.1.2 x.2.2⟩, ⟨x.1, x.2⟩, by + simp only [PNat.mk_coe, Nat.mem_divisorsAntidiagonal, ne_eq, mul_eq_zero, not_or] + refine ⟨rfl, PNat.ne_zero x.1, PNat.ne_zero x.2⟩⟩ + left_inv := by + rintro ⟨n, ⟨k, l⟩, h⟩ + rw [Nat.mem_divisorsAntidiagonal] at h + simp_rw [mapdiv, PNat.mk_coe] + ext <;> simp [h] at * + rfl + right_inv := by + rintro ⟨n, ⟨k, l⟩, h⟩ + · simp_rw [mapdiv] + norm_cast + · rfl + +end pnat From 626a3c611fcf3aff22849b418d5280525709d60d Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 17:24:56 +0100 Subject: [PATCH 037/128] open pr correctly --- Mathlib/NumberTheory/Divisors.lean | 747 +---------------------------- 1 file changed, 1 insertion(+), 746 deletions(-) diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 142c2ebc533416..287b4416b327e5 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -11,753 +11,8 @@ import Mathlib.Algebra.Ring.CharZero import Mathlib.Data.Nat.Cast.Order.Ring import Mathlib.Data.Nat.PrimeFin import Mathlib.Data.Nat.SuccPred -import Mathlib.Order.Interval.Finset.Nat - -/-! -# Divisor Finsets - -This file defines sets of divisors of a natural number. This is particularly useful as background -for defining Dirichlet convolution. - -## Main Definitions -Let `n : ℕ`. All of the following definitions are in the `Nat` namespace: -* `divisors n` is the `Finset` of natural numbers that divide `n`. -* `properDivisors n` is the `Finset` of natural numbers that divide `n`, other than `n`. -* `divisorsAntidiagonal n` is the `Finset` of pairs `(x,y)` such that `x * y = n`. -* `Perfect n` is true when `n` is positive and the sum of `properDivisors n` is `n`. - -## Conventions - -Since `0` has infinitely many divisors, none of the definitions in this file make sense for it. -Therefore we adopt the convention that `Nat.divisors 0`, `Nat.properDivisors 0`, -`Nat.divisorsAntidiagonal 0` and `Int.divisorsAntidiag 0` are all `∅`. - -## Tags -divisors, perfect numbers - --/ - -open Finset - -namespace Nat - -variable (n : ℕ) - -/-- `divisors n` is the `Finset` of divisors of `n`. By convention, we set `divisors 0 = ∅`. -/ -def divisors : Finset ℕ := {d ∈ Ico 1 (n + 1) | d ∣ n} - -/-- `properDivisors n` is the `Finset` of divisors of `n`, other than `n`. -By convention, we set `properDivisors 0 = ∅`. -/ -def properDivisors : Finset ℕ := {d ∈ Ico 1 n | d ∣ n} - -/-- Pairs of divisors of a natural number as a finset. - -`n.divisorsAntidiagonal` is the finset of pairs `(a, b) : ℕ × ℕ` such that `a * b = n`. -By convention, we set `Nat.divisorsAntidiagonal 0 = ∅`. - -O(n). -/ -def divisorsAntidiagonal : Finset (ℕ × ℕ) := - (Icc 1 n).filterMap (fun x ↦ let y := n / x; if x * y = n then some (x, y) else none) - fun x₁ x₂ (x, y) hx₁ hx₂ ↦ by aesop - -/-- Pairs of divisors of a natural number, as a list. - -`n.divisorsAntidiagonalList` is the list of pairs `(a, b) : ℕ × ℕ` such that `a * b = n`, ordered -by increasing `a`. By convention, we set `Nat.divisorsAntidiagonalList 0 = []`. --/ -def divisorsAntidiagonalList (n : ℕ) : List (ℕ × ℕ) := - (List.range' 1 n).filterMap - (fun x ↦ let y := n / x; if x * y = n then some (x, y) else none) - -variable {n} - -@[simp] -theorem filter_dvd_eq_divisors (h : n ≠ 0) : {d ∈ range n.succ | d ∣ n} = n.divisors := by - ext - simp only [divisors, mem_filter, mem_range, mem_Ico, and_congr_left_iff, iff_and_self] - exact fun ha _ => succ_le_iff.mpr (pos_of_dvd_of_pos ha h.bot_lt) - -@[simp] -theorem filter_dvd_eq_properDivisors (h : n ≠ 0) : {d ∈ range n | d ∣ n} = n.properDivisors := by - ext - simp only [properDivisors, mem_filter, mem_range, mem_Ico, and_congr_left_iff, iff_and_self] - exact fun ha _ => succ_le_iff.mpr (pos_of_dvd_of_pos ha h.bot_lt) - -theorem self_notMem_properDivisors : n ∉ properDivisors n := by simp [properDivisors] - -@[deprecated (since := "2025-05-23")] -alias properDivisors.not_self_mem := self_notMem_properDivisors - -@[simp] -theorem mem_properDivisors {m : ℕ} : n ∈ properDivisors m ↔ n ∣ m ∧ n < m := by - rcases eq_or_ne m 0 with (rfl | hm); · simp [properDivisors] - simp only [and_comm, ← filter_dvd_eq_properDivisors hm, mem_filter, mem_range] - -theorem insert_self_properDivisors (h : n ≠ 0) : insert n (properDivisors n) = divisors n := by - rw [divisors, properDivisors, - ← Finset.insert_Ico_right_eq_Ico_add_one (one_le_iff_ne_zero.2 h), - Finset.filter_insert, if_pos (dvd_refl n)] - -theorem cons_self_properDivisors (h : n ≠ 0) : - cons n (properDivisors n) self_notMem_properDivisors = divisors n := by - rw [cons_eq_insert, insert_self_properDivisors h] - -@[simp] -theorem mem_divisors {m : ℕ} : n ∈ divisors m ↔ n ∣ m ∧ m ≠ 0 := by - rcases eq_or_ne m 0 with (rfl | hm); · simp [divisors] - simp only [hm, Ne, not_false_iff, and_true, ← filter_dvd_eq_divisors hm, mem_filter, - mem_range, and_iff_right_iff_imp, Nat.lt_succ_iff] - exact le_of_dvd hm.bot_lt - -theorem dvd_of_mem_divisors {m : ℕ} (h : n ∈ divisors m) : n ∣ m := (mem_divisors.mp h).1 - -theorem ne_zero_of_mem_divisors {m : ℕ} (h : n ∈ divisors m) : m ≠ 0 := (mem_divisors.mp h).2 - -theorem one_mem_divisors : 1 ∈ divisors n ↔ n ≠ 0 := by simp - -theorem mem_divisors_self (n : ℕ) (h : n ≠ 0) : n ∈ n.divisors := - mem_divisors.2 ⟨dvd_rfl, h⟩ - -@[simp] -theorem mem_divisorsAntidiagonal {x : ℕ × ℕ} : - x ∈ divisorsAntidiagonal n ↔ x.fst * x.snd = n ∧ n ≠ 0 := by - obtain ⟨a, b⟩ := x - simp only [divisorsAntidiagonal, mul_div_eq_iff_dvd, mem_filterMap, mem_Icc, one_le_iff_ne_zero, - Option.ite_none_right_eq_some, Option.some.injEq, Prod.ext_iff, and_left_comm, exists_eq_left] - constructor - · rintro ⟨han, ⟨ha, han'⟩, rfl⟩ - simp [Nat.mul_div_eq_iff_dvd, han] - omega - · rintro ⟨rfl, hab⟩ - rw [mul_ne_zero_iff] at hab - simpa [hab.1, hab.2] using Nat.le_mul_of_pos_right _ hab.2.bot_lt - -@[simp] lemma divisorsAntidiagonalList_zero : divisorsAntidiagonalList 0 = [] := rfl -@[simp] lemma divisorsAntidiagonalList_one : divisorsAntidiagonalList 1 = [(1, 1)] := rfl - -@[simp] -lemma toFinset_divisorsAntidiagonalList {n : ℕ} : - n.divisorsAntidiagonalList.toFinset = n.divisorsAntidiagonal := by - rw [divisorsAntidiagonalList, divisorsAntidiagonal, List.toFinset_filterMap (f_inj := by aesop), - List.toFinset_range'_1_1] - -lemma sorted_divisorsAntidiagonalList_fst {n : ℕ} : - n.divisorsAntidiagonalList.Sorted (·.fst < ·.fst) := by - refine (List.sorted_lt_range' _ _ Nat.one_ne_zero).filterMap fun a b c d h h' ha => ?_ - rw [Option.ite_none_right_eq_some, Option.some.injEq] at h h' - simpa [← h.right, ← h'.right] - -lemma sorted_divisorsAntidiagonalList_snd {n : ℕ} : - n.divisorsAntidiagonalList.Sorted (·.snd > ·.snd) := by - obtain rfl | hn := eq_or_ne n 0 - · simp - refine (List.sorted_lt_range' _ _ Nat.one_ne_zero).filterMap ?_ - simp only [Option.ite_none_right_eq_some, Option.some.injEq, gt_iff_lt, and_imp, Prod.forall, - Prod.mk.injEq] - rintro a b _ _ _ _ ha rfl rfl hb rfl rfl hab - rwa [Nat.div_lt_div_left hn ⟨_, hb.symm⟩ ⟨_, ha.symm⟩] - -lemma nodup_divisorsAntidiagonalList {n : ℕ} : n.divisorsAntidiagonalList.Nodup := - have : IsIrrefl (ℕ × ℕ) (·.fst < ·.fst) := ⟨by simp⟩ - sorted_divisorsAntidiagonalList_fst.nodup - -/-- The `Finset` and `List` versions agree by definition. -/ -@[simp] -theorem val_divisorsAntidiagonal (n : ℕ) : - (divisorsAntidiagonal n).val = divisorsAntidiagonalList n := - rfl - -@[simp] -lemma mem_divisorsAntidiagonalList {n : ℕ} {a : ℕ × ℕ} : - a ∈ n.divisorsAntidiagonalList ↔ a.1 * a.2 = n ∧ n ≠ 0 := by - rw [← List.mem_toFinset, toFinset_divisorsAntidiagonalList, mem_divisorsAntidiagonal] - -@[simp high] -lemma swap_mem_divisorsAntidiagonalList {a : ℕ × ℕ} : - a.swap ∈ n.divisorsAntidiagonalList ↔ a ∈ n.divisorsAntidiagonalList := by simp [mul_comm] - -lemma reverse_divisorsAntidiagonalList (n : ℕ) : - n.divisorsAntidiagonalList.reverse = n.divisorsAntidiagonalList.map .swap := by - have : IsAsymm (ℕ × ℕ) (·.snd < ·.snd) := ⟨fun _ _ ↦ lt_asymm⟩ - refine List.eq_of_perm_of_sorted ?_ sorted_divisorsAntidiagonalList_snd.reverse <| - sorted_divisorsAntidiagonalList_fst.map _ fun _ _ ↦ id - simp [List.reverse_perm', List.perm_ext_iff_of_nodup nodup_divisorsAntidiagonalList - (nodup_divisorsAntidiagonalList.map Prod.swap_injective), mul_comm] - -lemma ne_zero_of_mem_divisorsAntidiagonal {p : ℕ × ℕ} (hp : p ∈ n.divisorsAntidiagonal) : - p.1 ≠ 0 ∧ p.2 ≠ 0 := by - obtain ⟨hp₁, hp₂⟩ := Nat.mem_divisorsAntidiagonal.mp hp - exact mul_ne_zero_iff.mp (hp₁.symm ▸ hp₂) - -lemma left_ne_zero_of_mem_divisorsAntidiagonal {p : ℕ × ℕ} (hp : p ∈ n.divisorsAntidiagonal) : - p.1 ≠ 0 := - (ne_zero_of_mem_divisorsAntidiagonal hp).1 - -lemma right_ne_zero_of_mem_divisorsAntidiagonal {p : ℕ × ℕ} (hp : p ∈ n.divisorsAntidiagonal) : - p.2 ≠ 0 := - (ne_zero_of_mem_divisorsAntidiagonal hp).2 - -theorem divisor_le {m : ℕ} : n ∈ divisors m → n ≤ m := by - rcases m with - | m - · simp - · simp only [mem_divisors, Nat.succ_ne_zero m, and_true, Ne, not_false_iff] - exact Nat.le_of_dvd (Nat.succ_pos m) - -theorem divisors_subset_of_dvd {m : ℕ} (hzero : n ≠ 0) (h : m ∣ n) : divisors m ⊆ divisors n := - Finset.subset_iff.2 fun _x hx => Nat.mem_divisors.mpr ⟨(Nat.mem_divisors.mp hx).1.trans h, hzero⟩ - -theorem card_divisors_le_self (n : ℕ) : #n.divisors ≤ n := calc - _ ≤ #(Ico 1 (n + 1)) := by - apply card_le_card - simp only [divisors, filter_subset] - _ = n := by rw [card_Ico, add_tsub_cancel_right] - -theorem divisors_subset_properDivisors {m : ℕ} (hzero : n ≠ 0) (h : m ∣ n) (hdiff : m ≠ n) : - divisors m ⊆ properDivisors n := by - apply Finset.subset_iff.2 - intro x hx - exact - Nat.mem_properDivisors.2 - ⟨(Nat.mem_divisors.1 hx).1.trans h, - lt_of_le_of_lt (divisor_le hx) - (lt_of_le_of_ne (divisor_le (Nat.mem_divisors.2 ⟨h, hzero⟩)) hdiff)⟩ - -lemma divisors_filter_dvd_of_dvd {n m : ℕ} (hn : n ≠ 0) (hm : m ∣ n) : - {d ∈ n.divisors | d ∣ m} = m.divisors := by - ext k - simp_rw [mem_filter, mem_divisors] - exact ⟨fun ⟨_, hkm⟩ ↦ ⟨hkm, ne_zero_of_dvd_ne_zero hn hm⟩, fun ⟨hk, _⟩ ↦ ⟨⟨hk.trans hm, hn⟩, hk⟩⟩ - -@[simp] -theorem divisors_zero : divisors 0 = ∅ := by - ext - simp - -@[simp] -theorem properDivisors_zero : properDivisors 0 = ∅ := by - ext - simp - -@[simp] -lemma nonempty_divisors : (divisors n).Nonempty ↔ n ≠ 0 := - ⟨fun ⟨m, hm⟩ hn ↦ by simp [hn] at hm, fun hn ↦ ⟨1, one_mem_divisors.2 hn⟩⟩ - -@[simp] -lemma divisors_eq_empty : divisors n = ∅ ↔ n = 0 := - not_nonempty_iff_eq_empty.symm.trans nonempty_divisors.not_left - -theorem properDivisors_subset_divisors : properDivisors n ⊆ divisors n := - filter_subset_filter _ <| Ico_subset_Ico_right n.le_succ - -@[simp] -theorem divisors_one : divisors 1 = {1} := by - ext - simp - -@[simp] -theorem properDivisors_one : properDivisors 1 = ∅ := by rw [properDivisors, Ico_self, filter_empty] - -theorem pos_of_mem_divisors {m : ℕ} (h : m ∈ n.divisors) : 0 < m := by - cases m - · rw [mem_divisors, zero_dvd_iff (a := n)] at h - cases h.2 h.1 - apply Nat.succ_pos - -theorem pos_of_mem_properDivisors {m : ℕ} (h : m ∈ n.properDivisors) : 0 < m := - pos_of_mem_divisors (properDivisors_subset_divisors h) - -theorem one_mem_properDivisors_iff_one_lt : 1 ∈ n.properDivisors ↔ 1 < n := by - rw [mem_properDivisors, and_iff_right (one_dvd _)] - -@[simp] -lemma sup_divisors_id (n : ℕ) : n.divisors.sup id = n := by - refine le_antisymm (Finset.sup_le fun _ ↦ divisor_le) ?_ - rcases Decidable.eq_or_ne n 0 with rfl | hn - · apply zero_le - · exact Finset.le_sup (f := id) <| mem_divisors_self n hn - -lemma one_lt_of_mem_properDivisors {m n : ℕ} (h : m ∈ n.properDivisors) : 1 < n := - lt_of_le_of_lt (pos_of_mem_properDivisors h) (mem_properDivisors.1 h).2 - -lemma one_lt_div_of_mem_properDivisors {m n : ℕ} (h : m ∈ n.properDivisors) : - 1 < n / m := by - obtain ⟨h_dvd, h_lt⟩ := mem_properDivisors.mp h - rwa [Nat.lt_div_iff_mul_lt' h_dvd, mul_one] - -/-- See also `Nat.mem_properDivisors`. -/ -lemma mem_properDivisors_iff_exists {m n : ℕ} (hn : n ≠ 0) : - m ∈ n.properDivisors ↔ ∃ k > 1, n = m * k := by - refine ⟨fun h ↦ ⟨n / m, one_lt_div_of_mem_properDivisors h, ?_⟩, ?_⟩ - · exact (Nat.mul_div_cancel' (mem_properDivisors.mp h).1).symm - · rintro ⟨k, hk, rfl⟩ - rw [mul_ne_zero_iff] at hn - exact mem_properDivisors.mpr ⟨⟨k, rfl⟩, lt_mul_of_one_lt_right (Nat.pos_of_ne_zero hn.1) hk⟩ - -@[simp] -lemma nonempty_properDivisors : n.properDivisors.Nonempty ↔ 1 < n := - ⟨fun ⟨_m, hm⟩ ↦ one_lt_of_mem_properDivisors hm, fun hn ↦ - ⟨1, one_mem_properDivisors_iff_one_lt.2 hn⟩⟩ - -@[simp] -lemma properDivisors_eq_empty : n.properDivisors = ∅ ↔ n ≤ 1 := by - rw [← not_nonempty_iff_eq_empty, nonempty_properDivisors, not_lt] - -@[simp] -theorem divisorsAntidiagonal_zero : divisorsAntidiagonal 0 = ∅ := by - ext - simp - -@[simp] -theorem divisorsAntidiagonal_one : divisorsAntidiagonal 1 = {(1, 1)} := by - ext - simp [mul_eq_one, Prod.ext_iff] - -@[simp high] -theorem swap_mem_divisorsAntidiagonal {x : ℕ × ℕ} : - x.swap ∈ divisorsAntidiagonal n ↔ x ∈ divisorsAntidiagonal n := by - rw [mem_divisorsAntidiagonal, mem_divisorsAntidiagonal, mul_comm, Prod.swap] - -/-- `Nat.swap_mem_divisorsAntidiagonal` with the LHS in simp normal form. -/ -@[deprecated swap_mem_divisorsAntidiagonal (since := "2025-02-17")] -theorem swap_mem_divisorsAntidiagonal_aux {x : ℕ × ℕ} : - x.snd * x.fst = n ∧ ¬n = 0 ↔ x ∈ divisorsAntidiagonal n := by - rw [mem_divisorsAntidiagonal, mul_comm] - -lemma prodMk_mem_divisorsAntidiag {x y : ℕ} (hn : n ≠ 0) : - (x, y) ∈ n.divisorsAntidiagonal ↔ x * y = n := by simp [hn] - -theorem fst_mem_divisors_of_mem_antidiagonal {x : ℕ × ℕ} (h : x ∈ divisorsAntidiagonal n) : - x.fst ∈ divisors n := by - rw [mem_divisorsAntidiagonal] at h - simp [Dvd.intro _ h.1, h.2] - -theorem snd_mem_divisors_of_mem_antidiagonal {x : ℕ × ℕ} (h : x ∈ divisorsAntidiagonal n) : - x.snd ∈ divisors n := by - rw [mem_divisorsAntidiagonal] at h - simp [Dvd.intro_left _ h.1, h.2] - -@[simp] -theorem map_swap_divisorsAntidiagonal : - (divisorsAntidiagonal n).map (Equiv.prodComm _ _).toEmbedding = divisorsAntidiagonal n := by - rw [← coe_inj, coe_map, Equiv.coe_toEmbedding, Equiv.coe_prodComm, - Set.image_swap_eq_preimage_swap] - ext - exact swap_mem_divisorsAntidiagonal - -@[simp] -theorem image_fst_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.fst = divisors n := by - ext - simp [Dvd.dvd, @eq_comm _ n (_ * _)] - -@[simp] -theorem image_snd_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.snd = divisors n := by - rw [← map_swap_divisorsAntidiagonal, map_eq_image, image_image] - exact image_fst_divisorsAntidiagonal - -theorem map_div_right_divisors : - n.divisors.map ⟨fun d => (d, n / d), fun _ _ => congr_arg Prod.fst⟩ = - n.divisorsAntidiagonal := by - ext ⟨d, nd⟩ - simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors, - Prod.ext_iff, and_left_comm, exists_eq_left] - constructor - · rintro ⟨⟨⟨k, rfl⟩, hn⟩, rfl⟩ - rw [Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt] - exact ⟨rfl, hn⟩ - · rintro ⟨rfl, hn⟩ - exact ⟨⟨dvd_mul_right _ _, hn⟩, Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt⟩ - -theorem map_div_left_divisors : - n.divisors.map ⟨fun d => (n / d, d), fun _ _ => congr_arg Prod.snd⟩ = - n.divisorsAntidiagonal := by - apply Finset.map_injective (Equiv.prodComm _ _).toEmbedding - ext - rw [map_swap_divisorsAntidiagonal, ← map_div_right_divisors, Finset.map_map] - simp - -theorem sum_divisors_eq_sum_properDivisors_add_self : - ∑ i ∈ divisors n, i = (∑ i ∈ properDivisors n, i) + n := by - rcases Decidable.eq_or_ne n 0 with (rfl | hn) - · simp - · rw [← cons_self_properDivisors hn, Finset.sum_cons, add_comm] - -/-- `n : ℕ` is perfect if and only the sum of the proper divisors of `n` is `n` and `n` - is positive. -/ -def Perfect (n : ℕ) : Prop := - ∑ i ∈ properDivisors n, i = n ∧ 0 < n - -theorem perfect_iff_sum_properDivisors (h : 0 < n) : Perfect n ↔ ∑ i ∈ properDivisors n, i = n := - and_iff_left h - -theorem perfect_iff_sum_divisors_eq_two_mul (h : 0 < n) : - Perfect n ↔ ∑ i ∈ divisors n, i = 2 * n := by - rw [perfect_iff_sum_properDivisors h, sum_divisors_eq_sum_properDivisors_add_self, two_mul] - constructor <;> intro h - · rw [h] - · apply add_right_cancel h - -theorem mem_divisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} : - x ∈ divisors (p ^ k) ↔ ∃ j ≤ k, x = p ^ j := by - rw [mem_divisors, Nat.dvd_prime_pow pp, and_iff_left (ne_of_gt (pow_pos pp.pos k))] - -theorem Prime.divisors {p : ℕ} (pp : p.Prime) : divisors p = {1, p} := by - ext - rw [mem_divisors, dvd_prime pp, and_iff_left pp.ne_zero, Finset.mem_insert, Finset.mem_singleton] - -theorem Prime.properDivisors {p : ℕ} (pp : p.Prime) : properDivisors p = {1} := by - rw [← erase_insert self_notMem_properDivisors, insert_self_properDivisors pp.ne_zero, - pp.divisors, pair_comm, erase_insert fun con => pp.ne_one (mem_singleton.1 con)] - -theorem divisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) : - divisors (p ^ k) = (Finset.range (k + 1)).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by - ext a - rw [mem_divisors_prime_pow pp] - simp [Nat.lt_succ, eq_comm] - -theorem divisors_injective : Function.Injective divisors := - Function.LeftInverse.injective sup_divisors_id - -@[simp] -theorem divisors_inj {a b : ℕ} : a.divisors = b.divisors ↔ a = b := - divisors_injective.eq_iff - -theorem eq_properDivisors_of_subset_of_sum_eq_sum {s : Finset ℕ} (hsub : s ⊆ n.properDivisors) : - ((∑ x ∈ s, x) = ∑ x ∈ n.properDivisors, x) → s = n.properDivisors := by - cases n - · rw [properDivisors_zero, subset_empty] at hsub - simp [hsub] - classical - rw [← sum_sdiff hsub] - intro h - apply Subset.antisymm hsub - rw [← sdiff_eq_empty_iff_subset] - contrapose h - rw [← Ne, ← nonempty_iff_ne_empty] at h - apply ne_of_lt - rw [← zero_add (∑ x ∈ s, x), ← add_assoc, add_zero] - apply add_lt_add_right - have hlt := - sum_lt_sum_of_nonempty h fun x hx => pos_of_mem_properDivisors (sdiff_subset hx) - simp only [sum_const_zero] at hlt - apply hlt - -theorem sum_properDivisors_dvd (h : (∑ x ∈ n.properDivisors, x) ∣ n) : - ∑ x ∈ n.properDivisors, x = 1 ∨ ∑ x ∈ n.properDivisors, x = n := by - rcases n with - | n - · simp - · rcases n with - | n - · simp at h - · rw [or_iff_not_imp_right] - intro ne_n - have hlt : ∑ x ∈ n.succ.succ.properDivisors, x < n.succ.succ := - lt_of_le_of_ne (Nat.le_of_dvd (Nat.succ_pos _) h) ne_n - symm - rw [← mem_singleton, eq_properDivisors_of_subset_of_sum_eq_sum (singleton_subset_iff.2 - (mem_properDivisors.2 ⟨h, hlt⟩)) (sum_singleton _ _), mem_properDivisors] - exact ⟨one_dvd _, Nat.succ_lt_succ (Nat.succ_pos _)⟩ - -@[to_additive (attr := simp)] -theorem Prime.prod_properDivisors {α : Type*} [CommMonoid α] {p : ℕ} {f : ℕ → α} (h : p.Prime) : - ∏ x ∈ p.properDivisors, f x = f 1 := by simp [h.properDivisors] - -@[to_additive (attr := simp)] -theorem Prime.prod_divisors {α : Type*} [CommMonoid α] {p : ℕ} {f : ℕ → α} (h : p.Prime) : - ∏ x ∈ p.divisors, f x = f p * f 1 := by - rw [← cons_self_properDivisors h.ne_zero, prod_cons, h.prod_properDivisors] - -theorem properDivisors_eq_singleton_one_iff_prime : n.properDivisors = {1} ↔ n.Prime := by - refine ⟨?_, ?_⟩ - · intro h - refine Nat.prime_def.mpr ⟨?_, fun m hdvd => ?_⟩ - · match n with - | 0 => contradiction - | 1 => contradiction - | Nat.succ (Nat.succ n) => simp - · rw [← mem_singleton, ← h, mem_properDivisors] - have := Nat.le_of_dvd ?_ hdvd - · simpa [hdvd, this] using (le_iff_eq_or_lt.mp this).symm - · by_contra! - simp only [nonpos_iff_eq_zero.mp this] at h - contradiction - · exact fun h => Prime.properDivisors h - -theorem sum_properDivisors_eq_one_iff_prime : ∑ x ∈ n.properDivisors, x = 1 ↔ n.Prime := by - rcases n with - | n - · simp [Nat.not_prime_zero] - · cases n - · simp [Nat.not_prime_one] - · rw [← properDivisors_eq_singleton_one_iff_prime] - refine ⟨fun h => ?_, fun h => h.symm ▸ sum_singleton _ _⟩ - rw [@eq_comm (Finset ℕ) _ _] - apply - eq_properDivisors_of_subset_of_sum_eq_sum - (singleton_subset_iff.2 - (one_mem_properDivisors_iff_one_lt.2 (succ_lt_succ (Nat.succ_pos _)))) - ((sum_singleton _ _).trans h.symm) - -theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} : - x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by - rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right] - simp only [exists_prop, and_assoc] - apply exists_congr - intro a - constructor <;> intro h - · rcases h with ⟨_h_left, rfl, h_right⟩ - rw [Nat.pow_lt_pow_iff_right pp.one_lt] at h_right - exact ⟨h_right, rfl⟩ - · rcases h with ⟨h_left, rfl⟩ - rw [Nat.pow_lt_pow_iff_right pp.one_lt] - simp [h_left, le_of_lt] - -theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) : - properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by - ext a - simp only [mem_properDivisors, mem_map, mem_range, Function.Embedding.coeFn_mk] - have := mem_properDivisors_prime_pow pp k (x := a) - rw [mem_properDivisors] at this - grind - -@[to_additive (attr := simp)] -theorem prod_properDivisors_prime_pow {α : Type*} [CommMonoid α] {k p : ℕ} {f : ℕ → α} - (h : p.Prime) : (∏ x ∈ (p ^ k).properDivisors, f x) = ∏ x ∈ range k, f (p ^ x) := by - simp [h, properDivisors_prime_pow] - -@[to_additive (attr := simp) sum_divisors_prime_pow] -theorem prod_divisors_prime_pow {α : Type*} [CommMonoid α] {k p : ℕ} {f : ℕ → α} (h : p.Prime) : - (∏ x ∈ (p ^ k).divisors, f x) = ∏ x ∈ range (k + 1), f (p ^ x) := by - simp [h, divisors_prime_pow] - -@[to_additive] -theorem prod_divisorsAntidiagonal {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) {n : ℕ} : - ∏ i ∈ n.divisorsAntidiagonal, f i.1 i.2 = ∏ i ∈ n.divisors, f i (n / i) := by - rw [← map_div_right_divisors, Finset.prod_map] - rfl - -@[to_additive] -theorem prod_divisorsAntidiagonal' {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) {n : ℕ} : - ∏ i ∈ n.divisorsAntidiagonal, f i.1 i.2 = ∏ i ∈ n.divisors, f (n / i) i := by - rw [← map_swap_divisorsAntidiagonal, Finset.prod_map] - exact prod_divisorsAntidiagonal fun i j => f j i - -/-- The factors of `n` are the prime divisors -/ -theorem primeFactors_eq_to_filter_divisors_prime (n : ℕ) : - n.primeFactors = {p ∈ divisors n | p.Prime} := by - rcases n.eq_zero_or_pos with (rfl | hn) - · simp - · ext q - simpa [hn, hn.ne', mem_primeFactorsList] using and_comm - -lemma primeFactors_filter_dvd_of_dvd {m n : ℕ} (hn : n ≠ 0) (hmn : m ∣ n) : - {p ∈ n.primeFactors | p ∣ m} = m.primeFactors := by - simp_rw [primeFactors_eq_to_filter_divisors_prime, filter_comm, - divisors_filter_dvd_of_dvd hn hmn] - -@[simp] -theorem image_div_divisors_eq_divisors (n : ℕ) : - image (fun x : ℕ => n / x) n.divisors = n.divisors := by - by_cases hn : n = 0 - · simp [hn] - ext a - constructor - · rw [mem_image] - rintro ⟨x, hx1, hx2⟩ - rw [mem_divisors] at * - refine ⟨?_, hn⟩ - rw [← hx2] - exact div_dvd_of_dvd hx1.1 - · rw [mem_divisors, mem_image] - rintro ⟨h1, -⟩ - exact ⟨n / a, mem_divisors.mpr ⟨div_dvd_of_dvd h1, hn⟩, Nat.div_div_self h1 hn⟩ - -/- Porting note: Removed simp; simp_nf linter: -Left-hand side does not simplify, when using the simp lemma on itself. -This usually means that it will never apply. -/ -@[to_additive sum_div_divisors] -theorem prod_div_divisors {α : Type*} [CommMonoid α] (n : ℕ) (f : ℕ → α) : - (∏ d ∈ n.divisors, f (n / d)) = n.divisors.prod f := by - by_cases hn : n = 0; · simp [hn] - rw [← prod_image] - · exact prod_congr (image_div_divisors_eq_divisors n) (by simp) - · intro x hx y hy h - rw [mem_coe, mem_divisors] at hx hy - exact (div_eq_iff_eq_of_dvd_dvd hn hx.1 hy.1).mp h - -theorem disjoint_divisors_filter_isPrimePow {a b : ℕ} (hab : a.Coprime b) : - Disjoint (a.divisors.filter IsPrimePow) (b.divisors.filter IsPrimePow) := by - simp only [Finset.disjoint_left, Finset.mem_filter, and_imp, Nat.mem_divisors, not_and] - rintro n han _ha hn hbn _hb - - exact hn.ne_one (Nat.eq_one_of_dvd_coprimes hab han hbn) - -end Nat - -namespace Int -variable {xy : ℤ × ℤ} {x y z : ℤ} - --- Local notation for the embeddings `n ↦ n, n ↦ -n : ℕ → ℤ` -local notation "natCast" => Nat.castEmbedding (R := ℤ) -local notation "negNatCast" => - Function.Embedding.trans Nat.castEmbedding (Equiv.toEmbedding (Equiv.neg ℤ)) - -/-- Pairs of divisors of an integer as a finset. - -`z.divisorsAntidiag` is the finset of pairs `(a, b) : ℤ × ℤ` such that `a * b = z`. -By convention, we set `Int.divisorsAntidiag 0 = ∅`. - -O(|z|). Computed from `Nat.divisorsAntidiagonal`. -/ -def divisorsAntidiag : (z : ℤ) → Finset (ℤ × ℤ) - | (n : ℕ) => - let s : Finset (ℕ × ℕ) := n.divisorsAntidiagonal - (s.map <| .prodMap natCast natCast).disjUnion (s.map <| .prodMap negNatCast negNatCast) <| by - simp +contextual [s, disjoint_left, eq_comm] - | negSucc n => - let s : Finset (ℕ × ℕ) := (n + 1).divisorsAntidiagonal - (s.map <| .prodMap natCast negNatCast).disjUnion (s.map <| .prodMap negNatCast natCast) <| by - simp +contextual [s, disjoint_left, eq_comm, forall_swap (α := _ * _ = _)] - -@[simp] -lemma mem_divisorsAntidiag : - ∀ {z} {xy : ℤ × ℤ}, xy ∈ divisorsAntidiag z ↔ xy.fst * xy.snd = z ∧ z ≠ 0 - | (n : ℕ), ((x : ℕ), (y : ℕ)) => by - simp [divisorsAntidiag] - norm_cast - simp +contextual [eq_comm] - | (n : ℕ), (negSucc x, negSucc y) => by - simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] - norm_cast - simp +contextual [eq_comm] - | (n : ℕ), ((x : ℕ), negSucc y) => by - simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] - norm_cast - aesop - | (n : ℕ), (negSucc x, (y : ℕ)) => by - suffices (∃ a, (n = a * y ∧ ¬n = 0) ∧ (a:ℤ) = -1 + -↑x) ↔ (n:ℤ) = (-1 + -↑x) * ↑y ∧ ¬n = 0 by - simpa [divisorsAntidiag, eq_comm, negSucc_eq] - simp only [← Int.neg_add, Int.add_comm 1, Int.neg_mul, Int.add_mul] - norm_cast - match n with - | 0 => simp - | n + 1 => simp - | .negSucc n, ((x : ℕ), (y : ℕ)) => by - simp [divisorsAntidiag] - norm_cast - | .negSucc n, (negSucc x, negSucc y) => by - simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] - norm_cast - simp +contextual - | .negSucc n, ((x : ℕ), negSucc y) => by - simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] - norm_cast - aesop - | .negSucc n, (negSucc x, (y : ℕ)) => by - simp [divisorsAntidiag, negSucc_eq, -neg_add_rev] - norm_cast - simp +contextual [eq_comm] - -@[simp] lemma divisorsAntidiag_zero : divisorsAntidiag 0 = ∅ := rfl - --- TODO Write a simproc instead of `divisorsAntidiagonal_one`, ..., `divisorsAntidiagonal_four` ... - -@[simp] -theorem divisorsAntidiagonal_one : - Int.divisorsAntidiag 1 = {(1, 1), (-1, -1)} := - rfl - -@[simp] -theorem divisorsAntidiagonal_two : - Int.divisorsAntidiag 2 = {(1, 2), (2, 1), (-1, -2), (-2, -1)} := - rfl - -@[simp] -theorem divisorsAntidiagonal_three : - Int.divisorsAntidiag 3 = {(1, 3), (3, 1), (-1, -3), (-3, -1)} := - rfl - -@[simp] -theorem divisorsAntidiagonal_four : - Int.divisorsAntidiag 4 = {(1, 4), (2, 2), (4, 1), (-1, -4), (-2, -2), (-4, -1)} := - rfl - -lemma prodMk_mem_divisorsAntidiag (hz : z ≠ 0) : (x, y) ∈ z.divisorsAntidiag ↔ x * y = z := by - simp [hz] - -@[simp high] -lemma swap_mem_divisorsAntidiag : xy.swap ∈ z.divisorsAntidiag ↔ xy ∈ z.divisorsAntidiag := by - simp [mul_comm] - -lemma neg_mem_divisorsAntidiag : -xy ∈ z.divisorsAntidiag ↔ xy ∈ z.divisorsAntidiag := by simp - -@[simp] -lemma map_prodComm_divisorsAntidiag : - z.divisorsAntidiag.map (Equiv.prodComm _ _).toEmbedding = z.divisorsAntidiag := by - ext; simp [mem_divisorsAntidiag] - -@[simp] -lemma map_neg_divisorsAntidiag : - z.divisorsAntidiag.map (Equiv.neg _).toEmbedding = z.divisorsAntidiag := by - ext; simp [mem_divisorsAntidiag, mul_comm] - -lemma divisorsAntidiag_neg : - (-z).divisorsAntidiag = - z.divisorsAntidiag.map (.prodMap (.refl _) (Equiv.neg _).toEmbedding) := by - ext; simp [mem_divisorsAntidiag, Prod.ext_iff, neg_eq_iff_eq_neg] - -lemma divisorsAntidiag_natCast (n : ℕ) : - divisorsAntidiag n = - (n.divisorsAntidiagonal.map <| .prodMap natCast natCast).disjUnion - (n.divisorsAntidiagonal.map <| .prodMap negNatCast negNatCast) (by - simp +contextual [disjoint_left, eq_comm]) := rfl - -lemma divisorsAntidiag_neg_natCast (n : ℕ) : - divisorsAntidiag (-n) = - (n.divisorsAntidiagonal.map <| .prodMap natCast negNatCast).disjUnion - (n.divisorsAntidiagonal.map <| .prodMap negNatCast natCast) (by - simp +contextual [disjoint_left, eq_comm]) := by cases n <;> rfl - -lemma divisorsAntidiag_ofNat (n : ℕ) : - divisorsAntidiag ofNat(n) = - (n.divisorsAntidiagonal.map <| .prodMap natCast natCast).disjUnion - (n.divisorsAntidiagonal.map <| .prodMap negNatCast negNatCast) (by - simp +contextual [disjoint_left, eq_comm]) := rfl - -/-- This lemma justifies its existence from its utility in crystallographic root system theory. -/ -lemma mul_mem_one_two_three_iff {a b : ℤ} : - a * b ∈ ({1, 2, 3} : Set ℤ) ↔ (a, b) ∈ ({ - (1, 1), (-1, -1), - (1, 2), (2, 1), (-1, -2), (-2, -1), - (1, 3), (3, 1), (-1, -3), (-3, -1)} : Set (ℤ × ℤ)) := by - simp only [← Int.prodMk_mem_divisorsAntidiag, Set.mem_insert_iff, Set.mem_singleton_iff, ne_eq, - one_ne_zero, not_false_eq_true, OfNat.ofNat_ne_zero] - aesop - -/-- This lemma justifies its existence from its utility in crystallographic root system theory. -/ -lemma mul_mem_zero_one_two_three_four_iff {a b : ℤ} (h₀ : a = 0 ↔ b = 0) : - a * b ∈ ({0, 1, 2, 3, 4} : Set ℤ) ↔ (a, b) ∈ ({ - (0, 0), - (1, 1), (-1, -1), - (1, 2), (2, 1), (-1, -2), (-2, -1), - (1, 3), (3, 1), (-1, -3), (-3, -1), - (4, 1), (1, 4), (-4, -1), (-1, -4), (2, 2), (-2, -2)} : Set (ℤ × ℤ)) := by - simp only [← Int.prodMk_mem_divisorsAntidiag, Set.mem_insert_iff, Set.mem_singleton_iff, ne_eq, - one_ne_zero, not_false_eq_true, OfNat.ofNat_ne_zero] - aesop - -end Int - -/- -Copyright (c) 2020 Aaron Anderson. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Aaron Anderson --/ -import Mathlib.Algebra.IsPrimePow -import Mathlib.Algebra.Order.BigOperators.Group.Finset -import Mathlib.Algebra.Order.Interval.Finset.SuccPred -import Mathlib.Algebra.Order.Ring.Int -import Mathlib.Algebra.Ring.CharZero -import Mathlib.Data.Nat.Cast.Order.Ring -import Mathlib.Data.Nat.PrimeFin -import Mathlib.Data.Nat.SuccPred -import Mathlib.Order.Interval.Finset.Nat import Mathlib.Data.PNat.Defs +import Mathlib.Order.Interval.Finset.Nat /-! # Divisor Finsets From 970ef6b4d4be46f1ceeb786571498c91373c0afa Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 17:40:47 +0100 Subject: [PATCH 038/128] docstrings --- .../NumberTheory/ModularForms/EisensteinSeries/Defs.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean index 8665dd1c25cc49..f3477985b5c454 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean @@ -54,8 +54,12 @@ def gammaSet_one_equiv (a a' : Fin 2 → ZMod 1) : gammaSet 1 a ≃ gammaSet 1 a Equiv.setCongr (gammaSet_one_eq a a') open Pointwise +/-- The set of pairs of integers with gcd 1 scaled by a natural number `N`, making them have gcd +equal to N. -/ def gammaSetN (N : ℕ) : Set (Fin 2 → ℤ) := ({N} : Set ℕ) • gammaSet 1 0 +/-- The map from `gammaSetN` to `gammaSet` given by forgetting the scalar multiple in +`gammaSetN`. -/ noncomputable def gammaSetN_map (N : ℕ) (v : gammaSetN N) : gammaSet 1 0 := by have hv2 := v.2 simp only [gammaSetN, singleton_smul, mem_smul_set, nsmul_eq_mul] at hv2 @@ -89,6 +93,7 @@ noncomputable def gammaSetN_Equiv {N : ℕ} (hN : N ≠ 0) : gammaSetN N ≃ gam simpa [hN] using (congr_fun H.choose_spec.2 i) simp_all only [gammaSetN_map] +/-- The map from `Fin 2 → ℤ` to the union of `gammaSetN` given by dividing out by the gcd. -/ private def fin_to_GammaSetN (v : Fin 2 → ℤ) : Σ n : ℕ, gammaSetN n := by refine ⟨(v 0).gcd (v 1), ⟨(v 0).gcd (v 1) • ![(v 0)/(v 0).gcd (v 1), (v 1)/(v 0).gcd (v 1)], ?_⟩⟩ by_cases hn : 0 < (v 0).gcd (v 1) @@ -99,6 +104,8 @@ private def fin_to_GammaSetN (v : Fin 2 → ℤ) : Σ n : ℕ, gammaSetN n := by Nat.succ_eq_add_one, Nat.reduceAdd, CharP.cast_eq_zero, zero_nsmul] refine ⟨![1,1], by simpa [gammaSet_top_mem] using Int.isCoprime_iff_gcd_eq_one.mpr rfl⟩ +/-- The equivalence between `Fin 2 → ℤ` and the union of `gammaSetN` given by +dividing out by the gcd. -/ def GammaSet_one_Equiv : (Fin 2 → ℤ) ≃ (Σ n : ℕ, gammaSetN n) where toFun v := fin_to_GammaSetN v invFun v := v.2 From 1874f542966620138fbcae02f79ed62478bc06c6 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 17:45:35 +0100 Subject: [PATCH 039/128] space --- Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean index c553de40d401d3..d26790d2208539 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean @@ -596,5 +596,4 @@ theorem tsum_nat_eq_zero_two_pnat {α : Type*} [UniformSpace α] [Ring α] [IsUn (summable_int_iff_summable_nat_and_neg.mp hf2).1) · exact (summable_nat_add_iff (k := 1)).mpr (summable_int_iff_summable_nat_and_neg.mp hf2).2 - end pnat From ae866f9ad46be9d90b63e615ae311e17dbb1c830 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 17:53:36 +0100 Subject: [PATCH 040/128] doc string --- Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean index f3477985b5c454..1fd8903c0f17ba 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean @@ -73,6 +73,7 @@ lemma gammaSetN_map_eq {N : ℕ} (v : gammaSetN N) : v.1 = N • gammaSetN_map N simp only [gammaSetN, singleton_smul, mem_smul_set, nsmul_eq_mul] at hv2 exact (hv2.choose_spec.2).symm +/-- The equivalence between `gammaSetN` and `gammaSet` for non-zero `N`. -/ noncomputable def gammaSetN_Equiv {N : ℕ} (hN : N ≠ 0) : gammaSetN N ≃ gammaSet 1 0 where toFun v := gammaSetN_map N v invFun v := by From 62a78b1f77019a3d64652c1f2dc9c33926bc7f8e Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 18:02:45 +0100 Subject: [PATCH 041/128] docstring --- Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean index e7dae0844ca1cf..92f07b5d4a3dc3 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean @@ -37,6 +37,7 @@ def eisensteinSeries_MF {k : ℤ} {N : ℕ+} (hk : 3 ≤ k) (a : Fin 2 → ZMod /-- The trivial congruence condition at level 1. -/ def standardcongruencecondition : Fin 2 → ZMod ((1 : ℕ+) : ℕ) := 0 +/-- Notation for the `standardcongruencecondition`. -/ scoped notation "𝟙" => standardcongruencecondition /-- Normalised Eisenstein series of level 1 and weight `k`, From f686b78ac53988274d63ff19f6d7eb0cccda13e2 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 18:38:25 +0100 Subject: [PATCH 042/128] implicit --- Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean | 2 +- .../NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean index 92f07b5d4a3dc3..21ed73410729fb 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Basic.lean @@ -42,7 +42,7 @@ scoped notation "𝟙" => standardcongruencecondition /-- Normalised Eisenstein series of level 1 and weight `k`, here they need `1/2` since we sum over coprime pairs. -/ -noncomputable def E (k : ℕ) (hk : 3 ≤ k) : ModularForm Γ(1) k := +noncomputable def E {k : ℕ} (hk : 3 ≤ k) : ModularForm Γ(1) k := (1/2 : ℂ) • eisensteinSeries_MF (by omega) 𝟙 end ModularForm diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index f8b41b85feaa46..69ee5d8921dc5f 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -394,7 +394,7 @@ lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) ring lemma EisensteinSeries.q_expansion_bernoulli {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : - (E k hk) z = 1 + -((2 * k) / bernoulli k) * + (E hk) z = 1 + -((2 * k) / bernoulli k) * ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * ↑π * Complex.I * z) ^ (n : ℤ) := by have h2 := EisensteinSeries.q_expansion hk hk2 z rw [eisensteinSeries_coeff_identity hk2 (by omega)] at h2 From 7297e0141696ecc7584426a9be98a0f80535bb52 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 18:39:13 +0100 Subject: [PATCH 043/128] fix --- .../NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index 69ee5d8921dc5f..ee13b006f34a30 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -335,7 +335,7 @@ lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ simp lemma EisensteinSeries.q_expansion {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : - (E k hk) z = 1 + (1 / (riemannZeta (k))) * ((-2 * ↑π * Complex.I) ^ k / (k - 1)!) * + (E hk) z = 1 + (1 / (riemannZeta (k))) * ((-2 * ↑π * Complex.I) ^ k / (k - 1)!) * ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * ↑π * Complex.I * z) ^ (n : ℤ) := by have : (eisensteinSeries_MF (k := k) (by omega) standardcongruencecondition) z = (eisensteinSeries_SIF standardcongruencecondition k) z := rfl From 9a3aed390b9890af4e25f099201e98d1ffde6d64 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 18:46:36 +0100 Subject: [PATCH 044/128] tidy --- .../EisensteinSeries/QExpansion.lean | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index ee13b006f34a30..ab03d6902a7d30 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -29,8 +29,8 @@ open scoped Topology Real Nat Complex Pointwise local notation "ℍₒ" => complexUpperHalfPlane lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (p : ℝ) {S : Set ℂ} (hs : IsOpen S) : - EqOn (iteratedDerivWithin k (fun s : ℂ => cexp (2 * ↑π * Complex.I * m * s / p)) S) - (fun s => (2 * ↑π * Complex.I * m / p) ^ k * cexp (2 * ↑π * Complex.I * m * s / p)) S := by + EqOn (iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * Complex.I * m * s / p)) S) + (fun s ↦ (2 * ↑π * Complex.I * m / p) ^ k * cexp (2 * ↑π * Complex.I * m * s / p)) S := by apply EqOn.trans (iteratedDerivWithin_of_isOpen hs) intro x hx have : (fun s ↦ cexp (2 * ↑π * Complex.I * ↑m * s / ↑p)) = @@ -41,13 +41,13 @@ lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (p : ℝ) {S : Set ℂ} (hs ring_nf private lemma aux_IsBigO_mul (k l : ℕ) (p : ℝ) {f : ℕ → ℂ} - (hf : f =O[atTop] (fun n => (↑(n ^ l) : ℝ))) : - (fun n => f n * (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] - (fun n => (↑(n ^ (l + k)) : ℝ)) := by - have h0 : (fun n : ℕ => (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] - (fun n => (↑(n ^ (k)) : ℝ)) := by - have h1 : (fun n : ℕ => (2 * ↑π * Complex.I * ↑n / p) ^ k) = - (fun n : ℕ => ((2 * ↑π * Complex.I / p) ^ k) * ↑n ^ k) := by + (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : + (fun n ↦ f n * (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] + (fun n ↦ (↑(n ^ (l + k)) : ℝ)) := by + have h0 : (fun n : ℕ ↦ (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] + (fun n ↦ (↑(n ^ (k)) : ℝ)) := by + have h1 : (fun n : ℕ ↦ (2 * ↑π * Complex.I * ↑n / p) ^ k) = + (fun n : ℕ ↦ ((2 * ↑π * Complex.I / p) ^ k) * ↑n ^ k) := by ext z ring simpa [h1] using (Complex.isBigO_ofReal_right.mp (Asymptotics.isBigO_const_mul_self @@ -58,13 +58,13 @@ private lemma aux_IsBigO_mul (k l : ℕ) (p : ℝ) {f : ℕ → ℂ} open BoundedContinuousFunction in theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f : ℕ → ℂ} {p : ℝ} - (hp : 0 < p) (hf : f =O[atTop] (fun n => (↑(n ^ l) : ℝ))) : + (hp : 0 < p) (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : SummableLocallyUniformlyOn (fun n ↦ (f n) • iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z / p) ^ n) ℍₒ) ℍₒ := by apply SummableLocallyUniformlyOn_of_locally_bounded complexUpperHalPlane_isOpen intro K hK hKc haveI : CompactSpace K := isCompact_univ_iff.mp (isCompact_iff_isCompact_univ.mp hKc) - let c : ContinuousMap K ℂ := ⟨fun r : K => Complex.exp (2 * ↑π * Complex.I * r / p), by fun_prop⟩ + let c : ContinuousMap K ℂ := ⟨fun r : K ↦ Complex.exp (2 * ↑π * Complex.I * r / p), by fun_prop⟩ let r : ℝ := ‖mkOfCompact c‖ have hr : ‖r‖ < 1 := by simp only [norm_norm, r, norm_lt_iff_of_compact Real.zero_lt_one, mkOfCompact_apply, @@ -78,12 +78,11 @@ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f (Asymptotics.isBigO_norm_left.mpr (aux_IsBigO_mul k l p hf))), ?_⟩ intro n z hz have h0 := pow_le_pow_left₀ (by apply norm_nonneg _) (norm_coe_le_norm (mkOfCompact c) ⟨z, hz⟩) n - simp - simp only [Nat.cast_pow, norm_mkOfCompact, mkOfCompact_apply, ContinuousMap.coe_mk, ← - exp_nsmul', iteratedDerivWithin_cexp_mul_const k n p complexUpperHalPlane_isOpen (hK hz), - norm_mul, norm_pow, norm_div, - RCLike.norm_ofNat, norm_real, norm_I, mul_one, RCLike.norm_natCast, abs_norm, r, - c] at * + simp only [norm_mkOfCompact, mkOfCompact_apply, ContinuousMap.coe_mk, ← + exp_nsmul', Pi.smul_apply, + iteratedDerivWithin_cexp_mul_const k n p complexUpperHalPlane_isOpen (hK hz), smul_eq_mul, + norm_mul, norm_pow, Complex.norm_div, norm_ofNat, norm_real, Real.norm_eq_abs, norm_I, mul_one, + norm_natCast, abs_norm, ge_iff_le, r, c] at * rw [← mul_assoc] gcongr convert h0 @@ -94,8 +93,8 @@ and q-expansion coefficients all `1`. -/ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' (k : ℕ) : SummableLocallyUniformlyOn (fun n ↦ iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ) ℍₒ := by - have h0 : (fun n : ℕ => (1 : ℂ)) =O[atTop] (fun n => (↑(n ^ 1) : ℝ)) := by - simp only [Nat.cast_pow, Asymptotics.isBigO_iff, norm_one, norm_pow, Real.norm_natCast, + have h0 : (fun n : ℕ ↦ (1 : ℂ)) =O[atTop] (fun n ↦ ((n ^ 1) : ℝ)) := by + simp only [Asymptotics.isBigO_iff, norm_one, norm_pow, Real.norm_natCast, eventually_atTop, ge_iff_le] refine ⟨1, 1, fun b hb => by norm_cast; simp [hb]⟩ simpa using summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion k 1 (p := 1) @@ -109,7 +108,7 @@ theorem differnetiableAt_iteratedDerivWithin_cexp (n a : ℕ) {s : Set ℂ} (hs apply this.congr (iteratedDerivWithin_of_isOpen hs) fun_prop -lemma iteratedDerivWithin_tsum_exp_eq (k : ℕ) (z : ℍ) : iteratedDerivWithin k (fun z => +lemma iteratedDerivWithin_tsum_exp_eq (k : ℕ) (z : ℍ) : iteratedDerivWithin k (fun z ↦ ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n) ℍₒ z = ∑' n : ℕ, iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * Complex.I * s) ^ n) ℍₒ z := by rw [iteratedDerivWithin_tsum k complexUpperHalPlane_isOpen (by simpa using z.2)] @@ -120,7 +119,7 @@ lemma iteratedDerivWithin_tsum_exp_eq (k : ℕ) (z : ℍ) : iteratedDerivWithin complexUpperHalPlane_isOpen hz theorem contDiffOn_tsum_cexp (k : ℕ∞) : - ContDiffOn ℂ k (fun z : ℂ => ∑' n : ℕ, cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ := + ContDiffOn ℂ k (fun z : ℂ ↦ ∑' n : ℕ, cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ := contDiffOn_of_differentiableOn_deriv fun m _ z hz ↦ ((summableUniformlyOn_differentiableOn complexUpperHalPlane_isOpen (summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' m) @@ -129,14 +128,14 @@ theorem contDiffOn_tsum_cexp (k : ℕ∞) : iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) (iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : - iteratedDerivWithin k (fun z => (((π : ℂ) * Complex.I) - + iteratedDerivWithin k (fun z ↦ (((π : ℂ) * Complex.I) - (2 * π * Complex.I) * ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n)) ℍₒ z = -(2 * π * Complex.I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by suffices iteratedDerivWithin k (fun z ↦ ((↑π * Complex.I) - (2 * π * Complex.I) * ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n)) ℍₒ z = -(2 * π * Complex.I) * ∑' n : ℕ, iteratedDerivWithin k - (fun s : ℂ => cexp (2 * ↑π * Complex.I * s) ^ n) ℍₒ z by + (fun s : ℂ ↦ cexp (2 * ↑π * Complex.I * s) ^ n) ℍₒ z by have h : -(2 * ↑π * Complex.I * (2 * ↑π * Complex.I) ^ k) * ∑' (n : ℕ), ↑n ^ k * cexp (2 * ↑π * Complex.I * ↑z) ^ n = -(2 * π * Complex.I) * ∑' n : ℕ, (2 * ↑π * Complex.I * n) ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by @@ -182,11 +181,11 @@ theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) · simpa using z.2 theorem summable_pow_mul_cexp (k : ℕ) (e : ℕ+) (z : ℍ) : - Summable fun c : ℕ => (c : ℂ) ^ k * cexp (2 * ↑π * Complex.I * e * ↑z) ^ c := by + Summable fun c : ℕ ↦ (c : ℂ) ^ k * cexp (2 * ↑π * Complex.I * e * ↑z) ^ c := by have he : 0 < (e * (z : ℂ)).im := by simpa using z.2 apply ((summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion 0 k (p := 1) - (f := fun n => (n ^ k : ℂ)) (by norm_num) + (f := fun n ↦ (n ^ k : ℂ)) (by norm_num) (by simp [← Complex.isBigO_ofReal_right, Asymptotics.isBigO_refl])).summable he).congr intro b simp only [ofReal_one, div_one, ← Complex.exp_nsmul, nsmul_eq_mul, iteratedDerivWithin_zero, @@ -214,13 +213,13 @@ theorem summable_divisorsAntidiagonal_aux (k : ℕ) (z : ℍ) : · simp only [Complex.norm_mul, norm_pow, Complex.norm_natCast, tsum_fintype, Finset.univ_eq_attach] · apply Summable.of_nonneg_of_le (fun b => Finset.sum_nonneg (by simp)) ?_ ((summable_norm_iff - (f := fun c : ℕ+ => (c : ℂ) ^ (k + 1) * exp (2 * ↑π * Complex.I * (1: ℕ+) * ↑z) ^ (c : ℕ)).mpr + (f := fun c : ℕ+ ↦ (c : ℂ) ^ (k + 1) * exp (2 * ↑π * Complex.I * (1: ℕ+) * ↑z) ^ (c : ℕ)).mpr (by apply (summable_pow_mul_cexp (k+1) 1 z).subtype))) intro b apply le_trans (b := ∑ _ ∈ (b : ℕ).divisors, b ^ k * ‖exp (2 * ↑π * Complex.I * z) ^ (b : ℕ)‖) - · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun (x : ℕ × ℕ) => + · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun (x : ℕ × ℕ) ↦ (x.1 : ℝ) ^ (k : ℕ) * ‖Complex.exp (2 * ↑π * Complex.I * x.2 * z)‖ ^ x.1), - Nat.sum_divisorsAntidiagonal ((fun x y => + Nat.sum_divisorsAntidiagonal ((fun x y ↦ (x : ℝ) ^ (k : ℕ) * ‖Complex.exp (2 * ↑π * Complex.I * y * z)‖ ^ x))] gcongr <;> rename_i i hi <;> simp at hi · exact Nat.le_of_dvd b.2 hi @@ -235,7 +234,7 @@ theorem summable_divisorsAntidiagonal_aux (k : ℕ) (z : ℍ) : theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ ↦ (c.1 ^ k : ℂ) * Complex.exp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) := by rw [sigmaAntidiagonalEquivProd.summable_iff.symm] - simp [sigmaAntidiagonalEquivProd, mapdiv] + simp only [sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, Equiv.coe_fn_mk] apply summable_divisorsAntidiagonal_aux k z theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : @@ -253,10 +252,10 @@ theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : apply tsum_congr intro n simp only [tsum_fintype, Finset.univ_eq_attach,Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) - (fun (x : ℕ × ℕ) => (x.1 : ℂ) ^ k * cexp (2 * ↑π * Complex.I * x.2 * z) ^ x.1), - Nat.sum_divisorsAntidiagonal' (fun x y => (x : ℂ) ^ k * cexp (2 * ↑π * Complex.I * y * z) ^ x), + (fun (x : ℕ × ℕ) ↦ (x.1 : ℂ) ^ k * cexp (2 * ↑π * Complex.I * x.2 * z) ^ x.1), + Nat.sum_divisorsAntidiagonal' (fun x y ↦ (x : ℂ) ^ k * cexp (2 * ↑π * Complex.I * y * z) ^ x), Finset.sum_mul] - refine Finset.sum_congr (rfl) fun i hi => ?_ + refine Finset.sum_congr (rfl) fun i hi ↦ ?_ have hni : (n / i : ℕ) * (i : ℂ) = n := by norm_cast simp only [Nat.mem_divisors, ne_eq, PNat.ne_zero, not_false_eq_true, and_true] at * @@ -266,18 +265,19 @@ theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : left ring_nf -theorem summable_prod_eisSummand (k : ℕ) (hk : 3 ≤ k) (z : ℍ) : +theorem summable_prod_eisSummand {k : ℕ} (hk : 3 ≤ k) (z : ℍ) : Summable fun x : ℤ × ℤ ↦ eisSummand k ![x.1, x.2] z := by - simp [← (piFinTwoEquiv fun _ => ℤ).summable_iff, ← summable_norm_iff] + simp only [← (piFinTwoEquiv fun _ ↦ ℤ).summable_iff, piFinTwoEquiv_apply, Fin.isValue, ← + summable_norm_iff, comp_apply, norm_norm] apply (EisensteinSeries.summable_norm_eisSummand (by linarith) z).congr simp [EisensteinSeries.eisSummand] -lemma tsum_prod_eisSummand_eq_sigma_cexp (k : ℕ) (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : +lemma tsum_prod_eisSummand_eq_sigma_cexp {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : ∑' (x : Fin 2 → ℤ), eisSummand k x z = 2 * riemannZeta ↑k + 2 * ((-2 * ↑π * Complex.I) ^ k / ↑(k - 1)!) * ∑' (n : ℕ+), ↑((σ (k - 1)) ↑n) * cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ) := by - rw [← (piFinTwoEquiv fun _ => ℤ).symm.tsum_eq, Summable.tsum_prod - (by apply summable_prod_eisSummand k hk), tsum_nat_eq_zero_two_pnat] + rw [← (piFinTwoEquiv fun _ ↦ ℤ).symm.tsum_eq, Summable.tsum_prod + (by apply summable_prod_eisSummand hk), tsum_nat_eq_zero_two_pnat] · have (b : ℕ+) := EisensteinSeries.qExpansion_identity_pnat (k := k - 1) (by omega) ⟨b * z , by simpa using z.2⟩ have hk1 : k - 1 + 1 = k := by omega @@ -300,8 +300,8 @@ lemma tsum_prod_eisSummand_eq_sigma_cexp (k : ℕ) (hk : 3 ≤ k) (hk2 : Even k) zpow_neg, zpow_natCast, ← Even.neg_pow hk2 (n * (z : ℂ) + y), neg_add_rev, Int.cast_neg, neg_mul, inv_inj] ring - · simpa using Summable.prod (f := fun x : ℤ × ℤ => eisSummand k ![x.1, x.2] z) - (by apply summable_prod_eisSummand k hk) + · simpa using Summable.prod (f := fun x : ℤ × ℤ ↦ eisSummand k ![x.1, x.2] z) + (by apply summable_prod_eisSummand hk) lemma gammaSetN_eisSummand (k : ℤ) (z : ℍ) {n : ℕ} (v : gammaSetN n) : eisSummand k v z = ((n : ℂ) ^ k)⁻¹ * eisSummand k (gammaSetN_map n v) z := by @@ -323,14 +323,14 @@ lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ by_cases hb : b = 0 · simp [hb, CharP.cast_eq_zero, gammaSetN_eisSummand k z, show ((0 : ℂ) ^ k)⁻¹ = 0 by aesop] · simpa [gammaSetN_eisSummand k z, zpow_natCast, tsum_mul_left, hb] using - (gammaSetN_Equiv hb).tsum_eq (fun v => eisSummand k v z) - · apply summable_mul_of_summable_norm (f:= fun (n : ℕ)=> ((n : ℂ) ^ k)⁻¹) - (g := fun (v : gammaSet 1 0) => eisSummand k v z) (by simp [hk1]) + (gammaSetN_Equiv hb).tsum_eq (fun v ↦ eisSummand k v z) + · apply summable_mul_of_summable_norm (f:= fun (n : ℕ) ↦ ((n : ℂ) ^ k)⁻¹) + (g := fun (v : gammaSet 1 0) ↦ eisSummand k v z) (by simp [hk1]) apply (EisensteinSeries.summable_norm_eisSummand (by omega) z).subtype · intro b simpa using (Summable.of_norm (by apply (EisensteinSeries.summable_norm_eisSummand (by omega) z).subtype)).mul_left (a := ((b : ℂ) ^ k)⁻¹) - · apply ((GammaSet_one_Equiv.symm.summable_iff (f := fun v => eisSummand k v z)).mpr + · apply ((GammaSet_one_Equiv.symm.summable_iff (f := fun v ↦ eisSummand k v z)).mpr (EisensteinSeries.summable_norm_eisSummand (by omega) z).of_norm).congr simp @@ -341,7 +341,7 @@ lemma EisensteinSeries.q_expansion {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : (eisensteinSeries_SIF standardcongruencecondition k) z := rfl rw [E, ModularForm.smul_apply, this, eisensteinSeries_SIF_apply standardcongruencecondition k z, eisensteinSeries, standardcongruencecondition] - have HE1 := tsum_prod_eisSummand_eq_sigma_cexp k (by omega) hk2 z + have HE1 := tsum_prod_eisSummand_eq_sigma_cexp (by omega) hk2 z have HE2 := tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries (by omega) z have z2 : (riemannZeta (k)) ≠ 0 := by refine riemannZeta_ne_zero_of_one_lt_re ?_ From 4845a6e9425f0336f7ae6d862b17cd5a5a7c438a Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Fri, 1 Aug 2025 18:50:07 +0100 Subject: [PATCH 045/128] save --- .../ModularForms/EisensteinSeries/QExpansion.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index ab03d6902a7d30..d5101be59e2cd7 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -42,8 +42,7 @@ lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (p : ℝ) {S : Set ℂ} (hs private lemma aux_IsBigO_mul (k l : ℕ) (p : ℝ) {f : ℕ → ℂ} (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : - (fun n ↦ f n * (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] - (fun n ↦ (↑(n ^ (l + k)) : ℝ)) := by + (fun n ↦ f n * (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] (fun n ↦ (↑(n ^ (l + k)) : ℝ)) := by have h0 : (fun n : ℕ ↦ (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] (fun n ↦ (↑(n ^ (k)) : ℝ)) := by have h1 : (fun n : ℕ ↦ (2 * ↑π * Complex.I * ↑n / p) ^ k) = @@ -60,7 +59,7 @@ open BoundedContinuousFunction in theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f : ℕ → ℂ} {p : ℝ} (hp : 0 < p) (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : SummableLocallyUniformlyOn (fun n ↦ (f n) • - iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z / p) ^ n) ℍₒ) ℍₒ := by + iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z / p) ^ n) ℍₒ) ℍₒ := by apply SummableLocallyUniformlyOn_of_locally_bounded complexUpperHalPlane_isOpen intro K hK hKc haveI : CompactSpace K := isCompact_univ_iff.mp (isCompact_iff_isCompact_univ.mp hKc) @@ -241,7 +240,7 @@ theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : ℂ) * cexp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) = - ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) by + ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) by rw [Summable.tsum_prod (summable_prod_aux k z), Summable.tsum_comm] at this · simpa using this · apply (summable_prod_aux k z).prod_symm.congr From ec590ca300f5df162dd95541288bae1e6b66efac Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Sat, 2 Aug 2025 09:30:05 +0100 Subject: [PATCH 046/128] save --- Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean index d26790d2208539..dbf6d14bd8001c 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/NatInt.lean @@ -543,7 +543,7 @@ end Int section pnat -variable {α R : Type*} [TopologicalSpace α] [CommMonoid α] [AddMonoidWithOne R] +variable {R : Type*} {α : Type*} [AddMonoidWithOne R] [TopologicalSpace α] [CommMonoid α] @[to_additive] theorem pnat_multipliable_iff_multipliable_succ @@ -565,20 +565,17 @@ theorem pnat_multipliable_iff_multipliable_succ' {f : R → α} : convert Equiv.pnatEquivNat.symm.multipliable_iff.symm simp -theorem pnat_summable_iff_summable_succ' {α : Type*} [TopologicalSpace α] - [AddCommMonoid α] {f : R → α} : - Summable (fun x : ℕ+ => f x) ↔ Summable fun x : ℕ => f (x + 1) := by +theorem pnat_summable_iff_summable_succ' {α : Type*} [TopologicalSpace α] [AddCommMonoid α] + {f : R → α} : Summable (fun x : ℕ+ => f x) ↔ Summable fun x : ℕ => f (x + 1) := by convert Equiv.pnatEquivNat.symm.summable_iff.symm simp -theorem tprod_pnat_eq_tprod_succ' - (f : R → α) : ∏' n : ℕ+, f n = ∏' (n : ℕ), f (n + 1) := by +theorem tprod_pnat_eq_tprod_succ' (f : R → α) : ∏' n : ℕ+, f n = ∏' (n : ℕ), f (n + 1) := by convert (Equiv.pnatEquivNat.symm.tprod_eq _).symm simp -theorem tsum_pnat_eq_tsum_succ' {α : Type*} - [TopologicalSpace α] [AddCommMonoid α] - (f : R → α) : ∑' n : ℕ+, f n = ∑' (n : ℕ), f (n + 1) := by +theorem tsum_pnat_eq_tsum_succ' {α : Type*} [TopologicalSpace α] [AddCommMonoid α] (f : R → α) : + ∑' n : ℕ+, f n = ∑' (n : ℕ), f (n + 1) := by convert (Equiv.pnatEquivNat.symm.tsum_eq _).symm simp From 8bdec7cb157267beaa2644ecb0075e83ce280a0e Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 11 Aug 2025 15:19:54 +0100 Subject: [PATCH 047/128] rev updates --- Mathlib/NumberTheory/Divisors.lean | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 287b4416b327e5..735651715541e2 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -748,8 +748,8 @@ section pnat /-- The map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` to `(a , b)`. -/ -def mapdiv (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := by - refine fun x => +def divisorsAntidiagonal_factors (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := + fun x ↦ ⟨⟨x.1.1, Nat.pos_of_mem_divisors (Nat.fst_mem_divisors_of_mem_antidiagonal x.2)⟩, (⟨x.1.2, Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ : ℕ+), Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ @@ -757,21 +757,13 @@ def mapdiv (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := by /-- The equivalence from the union over `n` of `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` to `(a , b)`. -/ def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ℕ+ × ℕ+ where - toFun x := mapdiv x.1 x.2 + toFun x := divisorsAntidiagonal_factors x.1 x.2 invFun x := - ⟨⟨x.1.1 * x.2.1, mul_pos x.1.2 x.2.2⟩, ⟨x.1, x.2⟩, by - simp only [PNat.mk_coe, Nat.mem_divisorsAntidiagonal, ne_eq, mul_eq_zero, not_or] - refine ⟨rfl, PNat.ne_zero x.1, PNat.ne_zero x.2⟩⟩ + ⟨⟨x.1.val * x.2.val, mul_pos x.1.2 x.2.2⟩, ⟨x.1, x.2⟩, by simp [Nat.mem_divisorsAntidiagonal]⟩ left_inv := by rintro ⟨n, ⟨k, l⟩, h⟩ rw [Nat.mem_divisorsAntidiagonal] at h - simp_rw [mapdiv, PNat.mk_coe] - ext <;> simp [h] at * - rfl - right_inv := by - rintro ⟨n, ⟨k, l⟩, h⟩ - · simp_rw [mapdiv] - norm_cast - · rfl + ext <;> simp [divisorsAntidiagonal_factors, ← PNat.coe_injective.eq_iff, h.1] + right_inv _ := rfl end pnat From f85293c3ba8e7ea333071c17870b36496e412226 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 11 Aug 2025 17:59:49 +0100 Subject: [PATCH 048/128] test --- .../ModularForms/EisensteinSeries/Defs.lean | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean index 1fd8903c0f17ba..6c58f1b692ef8f 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean @@ -3,8 +3,9 @@ Copyright (c) 2024 Chris Birkbeck. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck, David Loeffler -/ +import Mathlib.Algebra.EuclideanDomain.Int import Mathlib.NumberTheory.ModularForms.SlashInvariantForms -import Mathlib.NumberTheory.ModularForms.CongruenceSubgroups +import Mathlib.RingTheory.EuclideanDomain /-! # Eisenstein Series @@ -58,6 +59,17 @@ open Pointwise equal to N. -/ def gammaSetN (N : ℕ) : Set (Fin 2 → ℤ) := ({N} : Set ℕ) • gammaSet 1 0 +def fin_to_gcd_map (v : Fin 2 → ℤ) : ℕ := (v 0).gcd (v 1) + +def gammaSetN' (N : ℕ) : Set (Fin 2 → ℤ) := fin_to_gcd_map ⁻¹' {N} + +lemma test (v : Fin 2 → ℤ) : + v ∈ gammaSetN' N ↔ (v 0).gcd (v 1) = N := by + simp [gammaSetN', fin_to_gcd_map] + +def div_N_map (N : ℤ) (v : Fin 2 → ℤ) : Fin 2 → ℤ := fun i => v i / N + + /-- The map from `gammaSetN` to `gammaSet` given by forgetting the scalar multiple in `gammaSetN`. -/ noncomputable def gammaSetN_map (N : ℕ) (v : gammaSetN N) : gammaSet 1 0 := by @@ -68,6 +80,52 @@ noncomputable def gammaSetN_map (N : ℕ) (v : gammaSetN N) : gammaSet 1 0 := by lemma gammaSet_top_mem (v : Fin 2 → ℤ) : v ∈ gammaSet 1 0 ↔ IsCoprime (v 0) (v 1) := by simpa [gammaSet] using fun h ↦ Subsingleton.eq_zero (Int.cast ∘ v) +lemma bij (N : ℕ) (hN : N ≠ 0) : Set.BijOn (fun (v : Fin 2 → ℤ) i => v i / N) + (gammaSetN' N) (gammaSet 1 0) := by + refine ⟨?_, ?_, ?_⟩ + · intro x hx + simp [gammaSetN', fin_to_gcd_map] at * + rw [gammaSet_top_mem] + rw [← hx] + rw [← hx] at hN + apply isCoprime_div_gcd_div_gcd' + simpa using hN + · intro x hx v hv hv2 + simp [gammaSetN', fin_to_gcd_map] at * + ext i + fin_cases i + · simp + have hi1 := congr_fun hv2 0 + rw [Int.ediv_left_inj] at hi1 + · apply hi1 + · rw [← hx] + exact Int.gcd_dvd_left (x 0) (x 1) + · rw [← hv] + exact Int.gcd_dvd_left (v 0) (v 1) + simp + have hi1 := congr_fun hv2 1 + rw [Int.ediv_left_inj] at hi1 + · apply hi1 + · rw [← hx] + exact Int.gcd_dvd_right (x 0) (x 1) + rw [← hv] + exact Int.gcd_dvd_right (v 0) (v 1) + · intro x hx + simp [gammaSetN'] + use N • x + simp [fin_to_gcd_map] + constructor + · rw [Int.gcd_mul_left] + rw [gammaSet_top_mem] at hx + rw [Int.isCoprime_iff_gcd_eq_one] at hx + rw [hx] + simp + · ext i + aesop + + + + lemma gammaSetN_map_eq {N : ℕ} (v : gammaSetN N) : v.1 = N • gammaSetN_map N v := by have hv2 := v.2 simp only [gammaSetN, singleton_smul, mem_smul_set, nsmul_eq_mul] at hv2 @@ -94,6 +152,11 @@ noncomputable def gammaSetN_Equiv {N : ℕ} (hN : N ≠ 0) : gammaSetN N ≃ gam simpa [hN] using (congr_fun H.choose_spec.2 i) simp_all only [gammaSetN_map] +/-- The equivalence between `gammaSetN` and `gammaSet` for non-zero `N`. -/ +noncomputable def gammaSetN_Equiv' {N : ℕ} (hN : N ≠ 0) : gammaSetN' N ≃ gammaSet 1 0 := by + apply Set.BijOn.equiv _ (bij N hN) + + /-- The map from `Fin 2 → ℤ` to the union of `gammaSetN` given by dividing out by the gcd. -/ private def fin_to_GammaSetN (v : Fin 2 → ℤ) : Σ n : ℕ, gammaSetN n := by refine ⟨(v 0).gcd (v 1), ⟨(v 0).gcd (v 1) • ![(v 0)/(v 0).gcd (v 1), (v 1)/(v 0).gcd (v 1)], ?_⟩⟩ @@ -126,6 +189,9 @@ def GammaSet_one_Equiv : (Fin 2 → ℤ) ≃ (Σ n : ℕ, gammaSetN n) where · exact Int.mul_ediv_cancel' (Int.gcd_dvd_left _ _) · exact Int.mul_ediv_cancel' (Int.gcd_dvd_right _ _) +def GammaSet_top_Equiv'' : (Fin 2 → ℤ) ≃ (Σ n : ℕ, gammaSetN' n) := by + apply Equiv.symm + apply Equiv.sigmaFiberEquiv end gammaSet_def @@ -200,3 +266,5 @@ lemma eisensteinSeries_SIF_apply (k : ℤ) (z : ℍ) : eisensteinSeries_SIF a k z = eisensteinSeries a k z := rfl end EisensteinSeries + +#min_imports From 5e63b971c12db6c7ab81a015adbee4cd2664e819 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 11 Aug 2025 19:59:05 +0100 Subject: [PATCH 049/128] updates --- .../ModularForms/EisensteinSeries/Defs.lean | 162 +++++------------- .../EisensteinSeries/QExpansion.lean | 21 ++- Mathlib/RingTheory/EuclideanDomain.lean | 7 + 3 files changed, 67 insertions(+), 123 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean index 6c58f1b692ef8f..f3411c5ca34986 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean @@ -54,144 +54,74 @@ lemma gammaSet_one_eq (a a' : Fin 2 → ZMod 1) : gammaSet 1 a = gammaSet 1 a' : def gammaSet_one_equiv (a a' : Fin 2 → ZMod 1) : gammaSet 1 a ≃ gammaSet 1 a' := Equiv.setCongr (gammaSet_one_eq a a') -open Pointwise -/-- The set of pairs of integers with gcd 1 scaled by a natural number `N`, making them have gcd -equal to N. -/ -def gammaSetN (N : ℕ) : Set (Fin 2 → ℤ) := ({N} : Set ℕ) • gammaSet 1 0 - +/-- The map from `Fin 2 → ℤ` sending `![a,b]` to `a.gcd b`. -/ def fin_to_gcd_map (v : Fin 2 → ℤ) : ℕ := (v 0).gcd (v 1) -def gammaSetN' (N : ℕ) : Set (Fin 2 → ℤ) := fin_to_gcd_map ⁻¹' {N} - -lemma test (v : Fin 2 → ℤ) : - v ∈ gammaSetN' N ↔ (v 0).gcd (v 1) = N := by - simp [gammaSetN', fin_to_gcd_map] - -def div_N_map (N : ℤ) (v : Fin 2 → ℤ) : Fin 2 → ℤ := fun i => v i / N +/-- The set of pairs of integers whose gcd is `N`, defined as the fiber of +`fin_to_gcd_map` at `N`. -/ +def gammaSetN (N : ℕ) : Set (Fin 2 → ℤ) := fin_to_gcd_map ⁻¹' {N} - -/-- The map from `gammaSetN` to `gammaSet` given by forgetting the scalar multiple in -`gammaSetN`. -/ -noncomputable def gammaSetN_map (N : ℕ) (v : gammaSetN N) : gammaSet 1 0 := by - have hv2 := v.2 - simp only [gammaSetN, singleton_smul, mem_smul_set, nsmul_eq_mul] at hv2 - refine ⟨hv2.choose, hv2.choose_spec.1⟩ +/-- An abbreviation of the map which divides a integer vector by an integer. -/ +abbrev div_N_map (N : ℤ) {m : ℕ} (v : Fin m → ℤ) : Fin m → ℤ := fun i => v i / N lemma gammaSet_top_mem (v : Fin 2 → ℤ) : v ∈ gammaSet 1 0 ↔ IsCoprime (v 0) (v 1) := by simpa [gammaSet] using fun h ↦ Subsingleton.eq_zero (Int.cast ∘ v) -lemma bij (N : ℕ) (hN : N ≠ 0) : Set.BijOn (fun (v : Fin 2 → ℤ) i => v i / N) - (gammaSetN' N) (gammaSet 1 0) := by +lemma gammaSetN_to_gammaSet10_bijection {N : ℕ} (hN : N ≠ 0) : + Set.BijOn (div_N_map N) (gammaSetN N) (gammaSet 1 0) := by refine ⟨?_, ?_, ?_⟩ · intro x hx - simp [gammaSetN', fin_to_gcd_map] at * - rw [gammaSet_top_mem] - rw [← hx] - rw [← hx] at hN - apply isCoprime_div_gcd_div_gcd' - simpa using hN + simp only [ne_eq, gammaSetN, mem_preimage, fin_to_gcd_map, Fin.isValue, mem_singleton_iff, + gammaSet_top_mem] at * + rw [← hx] at hN ⊢ + apply isCoprime_div_gcd_div_gcd' (by simpa using hN) · intro x hx v hv hv2 - simp [gammaSetN', fin_to_gcd_map] at * + simp only [ne_eq, gammaSetN, mem_preimage, fin_to_gcd_map, Fin.isValue, mem_singleton_iff] at * ext i - fin_cases i - · simp - have hi1 := congr_fun hv2 0 + · have hi1 := congr_fun hv2 i rw [Int.ediv_left_inj] at hi1 · apply hi1 - · rw [← hx] - exact Int.gcd_dvd_left (x 0) (x 1) - · rw [← hv] - exact Int.gcd_dvd_left (v 0) (v 1) - simp - have hi1 := congr_fun hv2 1 - rw [Int.ediv_left_inj] at hi1 - · apply hi1 - · rw [← hx] - exact Int.gcd_dvd_right (x 0) (x 1) - rw [← hv] - exact Int.gcd_dvd_right (v 0) (v 1) + · fin_cases i <;> rw [← hx] <;> simp [Int.gcd_dvd_left, Int.gcd_dvd_right] + · fin_cases i <;> rw [← hv] <;> simp [Int.gcd_dvd_left, Int.gcd_dvd_right] · intro x hx - simp [gammaSetN'] use N • x - simp [fin_to_gcd_map] + simp only [gammaSetN, nsmul_eq_mul, mem_preimage, fin_to_gcd_map, Fin.isValue, Pi.mul_apply, + Pi.natCast_apply, mem_singleton_iff] constructor - · rw [Int.gcd_mul_left] - rw [gammaSet_top_mem] at hx - rw [Int.isCoprime_iff_gcd_eq_one] at hx - rw [hx] - simp + · rw [gammaSet_top_mem, Int.isCoprime_iff_gcd_eq_one] at hx + simp [Int.gcd_mul_left, hx] · ext i + rw [div_N_map] aesop - - - -lemma gammaSetN_map_eq {N : ℕ} (v : gammaSetN N) : v.1 = N • gammaSetN_map N v := by - have hv2 := v.2 - simp only [gammaSetN, singleton_smul, mem_smul_set, nsmul_eq_mul] at hv2 - exact (hv2.choose_spec.2).symm +lemma gammaSetN_map_eq {N : ℕ} (v : gammaSetN N) : v.1 = N • (div_N_map N v) := by + by_cases hN : N = 0 + · have hv := v.2 + simp [hN, gammaSetN, fin_to_gcd_map] at * + ext i + fin_cases i <;> simp [hv] + · have hnz : (N : ℤ) ≠ 0 := by + norm_cast + have hN2 : (v.1 0).gcd (v.1 1) = N := by + aesop + ext i + · simp [div_N_map] + rw [← Int.mul_ediv_assoc ] + · aesop + · simp_rw [← hN2] + fin_cases i <;> simp [Int.gcd_dvd_left, Int.gcd_dvd_right] /-- The equivalence between `gammaSetN` and `gammaSet` for non-zero `N`. -/ -noncomputable def gammaSetN_Equiv {N : ℕ} (hN : N ≠ 0) : gammaSetN N ≃ gammaSet 1 0 where - toFun v := gammaSetN_map N v - invFun v := by - use N • v - simp only [gammaSetN, singleton_smul, nsmul_eq_mul, mem_smul_set] - refine ⟨v, by simp⟩ - left_inv v := by - simp_rw [← gammaSetN_map_eq v] - right_inv v := by - have H : N • v.1 ∈ gammaSetN N := by - simp only [gammaSetN, singleton_smul, nsmul_eq_mul, mem_smul_set] - refine ⟨v.1, by simp⟩ - simp [gammaSetN, mem_smul_set] at * - let x := H.choose - have hx := H.choose_spec - have hxv : ⟨H.choose, H.choose_spec.1⟩ = v := by - ext i - simpa [hN] using (congr_fun H.choose_spec.2 i) - simp_all only [gammaSetN_map] +def gammaSetN_Equiv {N : ℕ} (hN : N ≠ 0) : gammaSetN N ≃ gammaSet 1 0 := by + apply Set.BijOn.equiv _ (gammaSetN_to_gammaSet10_bijection hN) -/-- The equivalence between `gammaSetN` and `gammaSet` for non-zero `N`. -/ -noncomputable def gammaSetN_Equiv' {N : ℕ} (hN : N ≠ 0) : gammaSetN' N ≃ gammaSet 1 0 := by - apply Set.BijOn.equiv _ (bij N hN) - - -/-- The map from `Fin 2 → ℤ` to the union of `gammaSetN` given by dividing out by the gcd. -/ -private def fin_to_GammaSetN (v : Fin 2 → ℤ) : Σ n : ℕ, gammaSetN n := by - refine ⟨(v 0).gcd (v 1), ⟨(v 0).gcd (v 1) • ![(v 0)/(v 0).gcd (v 1), (v 1)/(v 0).gcd (v 1)], ?_⟩⟩ - by_cases hn : 0 < (v 0).gcd (v 1) - · apply Set.smul_mem_smul (by aesop) - rw [gammaSet_top_mem, Int.isCoprime_iff_gcd_eq_one] - apply Int.gcd_div_gcd_div_gcd hn - · simp only [gammaSetN, Fin.isValue, (nonpos_iff_eq_zero.mp (not_lt.mp hn)), singleton_smul, - Nat.succ_eq_add_one, Nat.reduceAdd, CharP.cast_eq_zero, zero_nsmul] - refine ⟨![1,1], by simpa [gammaSet_top_mem] using Int.isCoprime_iff_gcd_eq_one.mpr rfl⟩ - -/-- The equivalence between `Fin 2 → ℤ` and the union of `gammaSetN` given by -dividing out by the gcd. -/ -def GammaSet_one_Equiv : (Fin 2 → ℤ) ≃ (Σ n : ℕ, gammaSetN n) where - toFun v := fin_to_GammaSetN v - invFun v := v.2 - left_inv v := by - ext i - fin_cases i - · exact Int.mul_ediv_cancel' (Int.gcd_dvd_left _ _) - · exact Int.mul_ediv_cancel' (Int.gcd_dvd_right _ _) - right_inv v := by - ext i - · have hv2 := v.2.2 - simp only [gammaSetN, singleton_smul, mem_smul_set, nsmul_eq_mul] at hv2 - obtain ⟨x, hx⟩ := hv2 - simp [← hx.2, fin_to_GammaSetN, Fin.isValue, Int.gcd_mul_left, - Int.isCoprime_iff_gcd_eq_one.mp hx.1.2] - · fin_cases i - · exact Int.mul_ediv_cancel' (Int.gcd_dvd_left _ _) - · exact Int.mul_ediv_cancel' (Int.gcd_dvd_right _ _) - -def GammaSet_top_Equiv'' : (Fin 2 → ℤ) ≃ (Σ n : ℕ, gammaSetN' n) := by - apply Equiv.symm - apply Equiv.sigmaFiberEquiv +def GammaSet_top_Equiv : (Fin 2 → ℤ) ≃ (Σ n : ℕ, gammaSetN n) := + (Equiv.sigmaFiberEquiv fin_to_gcd_map).symm + +@[simp] +lemma GammaSet_top_Equiv_symm_eq (v : Σ n : ℕ, gammaSetN n) : + (GammaSet_top_Equiv.symm v) = v.2 := by + simp [GammaSet_top_Equiv, fin_to_gcd_map, Equiv.sigmaFiberEquiv] end gammaSet_def diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index d5101be59e2cd7..08744962c469e8 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -303,19 +303,26 @@ lemma tsum_prod_eisSummand_eq_sigma_cexp {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (by apply summable_prod_eisSummand hk) lemma gammaSetN_eisSummand (k : ℤ) (z : ℍ) {n : ℕ} (v : gammaSetN n) : eisSummand k v z = - ((n : ℂ) ^ k)⁻¹ * eisSummand k (gammaSetN_map n v) z := by - simp only [eisSummand, gammaSetN_map_eq v, Fin.isValue, Pi.smul_apply, nsmul_eq_mul, - Int.cast_mul, Int.cast_natCast, zpow_neg, ← mul_inv, ← mul_zpow] + ((n : ℂ) ^ k)⁻¹ * eisSummand k (div_N_map n v) z := by + have := gammaSetN_map_eq v + simp_rw [eisSummand] + nth_rw 1 2 [this] + simp only [Fin.isValue, Pi.smul_apply, nsmul_eq_mul, Int.cast_mul, Int.cast_natCast, zpow_neg, ← + mul_inv, ← mul_zpow, inv_inj] ring_nf lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ k) (z : ℍ) : ∑' (x : Fin 2 → ℤ), eisSummand k x z = (riemannZeta (k)) * (eisensteinSeries 𝟙 k z) := by - rw [← GammaSet_one_Equiv.symm.tsum_eq] + rw [← GammaSet_top_Equiv.symm.tsum_eq] have hk1 : 1 < k := by omega - rw [eisensteinSeries , Summable.tsum_sigma, GammaSet_one_Equiv, zeta_nat_eq_tsum_of_gt_one hk1, + conv => + enter [1,1] + ext c + rw [GammaSet_top_Equiv_symm_eq] + rw [eisensteinSeries , Summable.tsum_sigma, zeta_nat_eq_tsum_of_gt_one hk1, tsum_mul_tsum_of_summable_norm (by simp [hk1]) (by apply (summable_norm_eisSummand (by omega) z).subtype)] - · simp only [Equiv.coe_fn_symm_mk, one_div] + · simp only [one_div] rw [Summable.tsum_prod'] · apply tsum_congr intro b @@ -329,7 +336,7 @@ lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ · intro b simpa using (Summable.of_norm (by apply (EisensteinSeries.summable_norm_eisSummand (by omega) z).subtype)).mul_left (a := ((b : ℂ) ^ k)⁻¹) - · apply ((GammaSet_one_Equiv.symm.summable_iff (f := fun v ↦ eisSummand k v z)).mpr + · apply ((GammaSet_top_Equiv.symm.summable_iff (f := fun v ↦ eisSummand k v z)).mpr (EisensteinSeries.summable_norm_eisSummand (by omega) z).of_norm).congr simp diff --git a/Mathlib/RingTheory/EuclideanDomain.lean b/Mathlib/RingTheory/EuclideanDomain.lean index ad1c10230efb09..71d26352cec2c5 100644 --- a/Mathlib/RingTheory/EuclideanDomain.lean +++ b/Mathlib/RingTheory/EuclideanDomain.lean @@ -51,6 +51,13 @@ theorem isCoprime_div_gcd_div_gcd (hq : q ≠ 0) : (EuclideanDomain.mul_div_cancel' (gcd_ne_zero_of_right hq) <| gcd_dvd_right _ _).symm <| gcd_ne_zero_of_right hq +theorem isCoprime_div_gcd_div_gcd' (hpq : GCDMonoid.gcd p q ≠ 0) : + IsCoprime (p / GCDMonoid.gcd p q) (q / GCDMonoid.gcd p q) := + (gcd_isUnit_iff _ _).1 <| + isUnit_gcd_of_eq_mul_gcd + (EuclideanDomain.mul_div_cancel' (hpq) <| gcd_dvd_left _ _).symm + (EuclideanDomain.mul_div_cancel' (hpq) <| gcd_dvd_right _ _).symm <| hpq + end GCDMonoid namespace EuclideanDomain From 0d564a9ea48a17ef95898961dd4de114cb9d9436 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 11 Aug 2025 20:21:56 +0100 Subject: [PATCH 050/128] fix --- Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean index f3411c5ca34986..78c794f4beda21 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean @@ -196,5 +196,3 @@ lemma eisensteinSeries_SIF_apply (k : ℤ) (z : ℍ) : eisensteinSeries_SIF a k z = eisensteinSeries a k z := rfl end EisensteinSeries - -#min_imports From 5be61ee393682c603af96c10c28b1e1d3c63f764 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 11 Aug 2025 20:30:46 +0100 Subject: [PATCH 051/128] doc string --- Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean index 78c794f4beda21..4194ff984fa492 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean @@ -115,6 +115,8 @@ lemma gammaSetN_map_eq {N : ℕ} (v : gammaSetN N) : v.1 = N • (div_N_map N v) def gammaSetN_Equiv {N : ℕ} (hN : N ≠ 0) : gammaSetN N ≃ gammaSet 1 0 := by apply Set.BijOn.equiv _ (gammaSetN_to_gammaSet10_bijection hN) + +/-- The equivalence between `(Fin 2 → ℤ)` and `Σ n : ℕ, gammaSetN n)` . -/ def GammaSet_top_Equiv : (Fin 2 → ℤ) ≃ (Σ n : ℕ, gammaSetN n) := (Equiv.sigmaFiberEquiv fin_to_gcd_map).symm From 6ef7e2b5f5f2f69d2c7389a5bb008907555505ae Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 12 Aug 2025 09:07:53 +0100 Subject: [PATCH 052/128] name update --- Mathlib/NumberTheory/Divisors.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 735651715541e2..129a41bcff8ecb 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -748,7 +748,7 @@ section pnat /-- The map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` to `(a , b)`. -/ -def divisorsAntidiagonal_factors (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := +def divisorsAntidiagonalFactors (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := fun x ↦ ⟨⟨x.1.1, Nat.pos_of_mem_divisors (Nat.fst_mem_divisors_of_mem_antidiagonal x.2)⟩, (⟨x.1.2, Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ : ℕ+), @@ -757,13 +757,13 @@ def divisorsAntidiagonal_factors (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ /-- The equivalence from the union over `n` of `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` to `(a , b)`. -/ def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ℕ+ × ℕ+ where - toFun x := divisorsAntidiagonal_factors x.1 x.2 + toFun x := divisorsAntidiagonalFactors x.1 x.2 invFun x := ⟨⟨x.1.val * x.2.val, mul_pos x.1.2 x.2.2⟩, ⟨x.1, x.2⟩, by simp [Nat.mem_divisorsAntidiagonal]⟩ left_inv := by rintro ⟨n, ⟨k, l⟩, h⟩ rw [Nat.mem_divisorsAntidiagonal] at h - ext <;> simp [divisorsAntidiagonal_factors, ← PNat.coe_injective.eq_iff, h.1] + ext <;> simp [divisorsAntidiagonalFactors, ← PNat.coe_injective.eq_iff, h.1] right_inv _ := rfl end pnat From ec398e2728d87748b2fc20a0cee0564a22f8ac03 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 12 Aug 2025 13:13:59 +0100 Subject: [PATCH 053/128] update --- .../ModularForms/EisensteinSeries/Defs.lean | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean index 4194ff984fa492..1314b9a2ce1c3c 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/Defs.lean @@ -67,6 +67,11 @@ abbrev div_N_map (N : ℤ) {m : ℕ} (v : Fin m → ℤ) : Fin m → ℤ := fun lemma gammaSet_top_mem (v : Fin 2 → ℤ) : v ∈ gammaSet 1 0 ↔ IsCoprime (v 0) (v 1) := by simpa [gammaSet] using fun h ↦ Subsingleton.eq_zero (Int.cast ∘ v) +lemma gammaSetN_div_N {N : ℕ} {v : Fin 2 → ℤ} (hv : v ∈ gammaSetN N) (i : Fin 2) : + (N : ℤ) ∣ v i := by + simp only [gammaSetN, mem_preimage, fin_to_gcd_map, Fin.isValue, mem_singleton_iff] at * + fin_cases i <;> simp [← hv, Int.gcd_dvd_left, Int.gcd_dvd_right] + lemma gammaSetN_to_gammaSet10_bijection {N : ℕ} (hN : N ≠ 0) : Set.BijOn (div_N_map N) (gammaSetN N) (gammaSet 1 0) := by refine ⟨?_, ?_, ?_⟩ @@ -76,13 +81,8 @@ lemma gammaSetN_to_gammaSet10_bijection {N : ℕ} (hN : N ≠ 0) : rw [← hx] at hN ⊢ apply isCoprime_div_gcd_div_gcd' (by simpa using hN) · intro x hx v hv hv2 - simp only [ne_eq, gammaSetN, mem_preimage, fin_to_gcd_map, Fin.isValue, mem_singleton_iff] at * ext i - · have hi1 := congr_fun hv2 i - rw [Int.ediv_left_inj] at hi1 - · apply hi1 - · fin_cases i <;> rw [← hx] <;> simp [Int.gcd_dvd_left, Int.gcd_dvd_right] - · fin_cases i <;> rw [← hv] <;> simp [Int.gcd_dvd_left, Int.gcd_dvd_right] + · apply (Int.ediv_left_inj (gammaSetN_div_N hx i) (gammaSetN_div_N hv i)).mp (congr_fun hv2 i) · intro x hx use N • x simp only [gammaSetN, nsmul_eq_mul, mem_preimage, fin_to_gcd_map, Fin.isValue, Pi.mul_apply, @@ -91,31 +91,22 @@ lemma gammaSetN_to_gammaSet10_bijection {N : ℕ} (hN : N ≠ 0) : · rw [gammaSet_top_mem, Int.isCoprime_iff_gcd_eq_one] at hx simp [Int.gcd_mul_left, hx] · ext i - rw [div_N_map] - aesop + simp_all [div_N_map] lemma gammaSetN_map_eq {N : ℕ} (v : gammaSetN N) : v.1 = N • (div_N_map N v) := by by_cases hN : N = 0 · have hv := v.2 - simp [hN, gammaSetN, fin_to_gcd_map] at * + simp only [hN, gammaSetN, mem_preimage, fin_to_gcd_map, Fin.isValue, mem_singleton_iff, + Int.gcd_eq_zero_iff, CharP.cast_eq_zero, zero_nsmul] at * ext i fin_cases i <;> simp [hv] - · have hnz : (N : ℤ) ≠ 0 := by - norm_cast - have hN2 : (v.1 0).gcd (v.1 1) = N := by - aesop - ext i - · simp [div_N_map] - rw [← Int.mul_ediv_assoc ] - · aesop - · simp_rw [← hN2] - fin_cases i <;> simp [Int.gcd_dvd_left, Int.gcd_dvd_right] + · ext i + simp_all [Pi.smul_apply, div_N_map, ← Int.mul_ediv_assoc _ (gammaSetN_div_N v.2 i)] /-- The equivalence between `gammaSetN` and `gammaSet` for non-zero `N`. -/ def gammaSetN_Equiv {N : ℕ} (hN : N ≠ 0) : gammaSetN N ≃ gammaSet 1 0 := by apply Set.BijOn.equiv _ (gammaSetN_to_gammaSet10_bijection hN) - /-- The equivalence between `(Fin 2 → ℤ)` and `Σ n : ℕ, gammaSetN n)` . -/ def GammaSet_top_Equiv : (Fin 2 → ℤ) ≃ (Σ n : ℕ, gammaSetN n) := (Equiv.sigmaFiberEquiv fin_to_gcd_map).symm From bcf0fe54fe4d7ecd27a377bf44ebf73521305395 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 12 Aug 2025 13:46:29 +0100 Subject: [PATCH 054/128] save --- .../EisensteinSeries/QExpansion.lean | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index 08744962c469e8..51192c0dd1220f 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -43,8 +43,7 @@ lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (p : ℝ) {S : Set ℂ} (hs private lemma aux_IsBigO_mul (k l : ℕ) (p : ℝ) {f : ℕ → ℂ} (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : (fun n ↦ f n * (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] (fun n ↦ (↑(n ^ (l + k)) : ℝ)) := by - have h0 : (fun n : ℕ ↦ (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] - (fun n ↦ (↑(n ^ (k)) : ℝ)) := by + have h0 : (fun n : ℕ ↦ (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] (fun n ↦ (↑(n ^ k) : ℝ)) := by have h1 : (fun n : ℕ ↦ (2 * ↑π * Complex.I * ↑n / p) ^ k) = (fun n : ℕ ↦ ((2 * ↑π * Complex.I / p) ^ k) * ↑n ^ k) := by ext z @@ -333,14 +332,14 @@ lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ · apply summable_mul_of_summable_norm (f:= fun (n : ℕ) ↦ ((n : ℂ) ^ k)⁻¹) (g := fun (v : gammaSet 1 0) ↦ eisSummand k v z) (by simp [hk1]) apply (EisensteinSeries.summable_norm_eisSummand (by omega) z).subtype - · intro b - simpa using (Summable.of_norm (by apply (EisensteinSeries.summable_norm_eisSummand - (by omega) z).subtype)).mul_left (a := ((b : ℂ) ^ k)⁻¹) + · exact fun b => by simpa using (Summable.of_norm (by apply + (summable_norm_eisSummand (by omega) z).subtype)).mul_left (a := ((b : ℂ) ^ k)⁻¹) · apply ((GammaSet_top_Equiv.symm.summable_iff (f := fun v ↦ eisSummand k v z)).mpr (EisensteinSeries.summable_norm_eisSummand (by omega) z).of_norm).congr simp -lemma EisensteinSeries.q_expansion {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : +/-- The q-Expansion of normalised Eisenstein series of level one with `riemannZeta` term. -/ +lemma EisensteinSeries.q_expansion_riemannZeta {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : (E hk) z = 1 + (1 / (riemannZeta (k))) * ((-2 * ↑π * Complex.I) ^ k / (k - 1)!) * ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * ↑π * Complex.I * z) ^ (n : ℤ) := by have : (eisensteinSeries_MF (k := k) (by omega) standardcongruencecondition) z = @@ -399,9 +398,10 @@ lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) rw [h2k] ring +/-- The q-Expansion of normalised Eisenstein series of level one with `bernoulli` term. -/ lemma EisensteinSeries.q_expansion_bernoulli {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : (E hk) z = 1 + -((2 * k) / bernoulli k) * - ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * ↑π * Complex.I * z) ^ (n : ℤ) := by - have h2 := EisensteinSeries.q_expansion hk hk2 z + ∑' n : ℕ+, σ (k - 1) n * cexp (2 * ↑π * Complex.I * z) ^ (n : ℤ) := by + have h2 := EisensteinSeries.q_expansion_riemannZeta hk hk2 z rw [eisensteinSeries_coeff_identity hk2 (by omega)] at h2 apply h2 From ba4978b57152396808ec419ffe72f33653fd8516 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 12 Aug 2025 14:27:16 +0100 Subject: [PATCH 055/128] save --- .../ModularForms/EisensteinSeries/E2.lean | 107 +++--------------- 1 file changed, 17 insertions(+), 90 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean index d243776bbad2da..93201ec8bdeb80 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean @@ -4,7 +4,13 @@ import Mathlib.Data.Int.Star import Mathlib.NumberTheory.LSeries.RiemannZeta import Mathlib.NumberTheory.ModularForms.EisensteinSeries.UniformConvergence +/-! +# Eisenstein Series E2 +We define the Eisenstein series `E2` of weight `2` and level `1` as a limit of partial sums +over non-symmetric intervals. + +-/ open ModularForm EisensteinSeries UpperHalfPlane TopologicalSpace intervalIntegral Metric Filter Function Complex MatrixGroups Finset @@ -17,6 +23,10 @@ noncomputable section /-- This is an auxilary summand used to define the Eisenstein serires `G2`. -/ def e2Summand (m : ℤ) (z : ℍ) : ℂ := ∑' (n : ℤ), eisSummand 2 ![m, n] z +lemma e2Summand_summable (m : ℤ) (z : ℍ) : Summable (fun n => eisSummand 2 ![m, n] z) := by + apply (linear_right_summable z m (k := 2) (by omega)).congr + simp [eisSummand] + /-- The Eisenstein series of weight `2` and level `1` defined as the limit as `N` tends to infinity of the partial sum of `m` in `[N,N)` of `e2Summand m`. This sum over non-symmetric intervals is handy in proofs of its transformation property. -/ @@ -26,93 +36,10 @@ def E2 : ℍ → ℂ := (1 / (2 * riemannZeta 2)) • G2 def D2 (γ : SL(2, ℤ)) : ℍ → ℂ := fun z => (2 * π * Complex.I * γ 1 0) / (denom γ z) -lemma Eis_isBigO (m : ℤ) (z : ℍ) : (fun (n : ℤ) => ((m : ℂ) * z + n)⁻¹) =O[cofinite] - (fun n => ((r z * ‖![n, m]‖))⁻¹) := by - rw [Asymptotics.isBigO_iff'] - refine ⟨1, Real.zero_lt_one, ?_⟩ - filter_upwards with n - have := EisensteinSeries.summand_bound z (k := 1) (by norm_num) ![m, n] - simp only [Fin.isValue, Matrix.cons_val_zero, Matrix.cons_val_one, Matrix.cons_val_fin_one, - Real.rpow_neg_one, norm_inv, Nat.succ_eq_add_one, Nat.reduceAdd, mul_inv_rev, norm_mul, - norm_norm, Real.norm_eq_abs, one_mul, ge_iff_le] at * - apply le_trans this - rw [abs_norm, mul_comm, show |r z| = r z by rw [abs_eq_self]; exact (r_pos z).le, norm_symm] - -lemma linear_bigO2 (m : ℤ) (z : ℍ) : (fun (n : ℤ) => ((m : ℂ) * z + n)⁻¹) =O[cofinite] - fun n => ((n : ℝ)⁻¹) := by - have h1 := Eis_isBigO m z - apply Asymptotics.IsBigO.trans h1 - rw [@Asymptotics.isBigO_iff'] - refine ⟨|(r z)|⁻¹, by simp [ne_of_gt (r_pos z)], ?_⟩ - rw [eventually_iff_exists_mem] - refine ⟨{0}ᶜ, Set.Finite.compl_mem_cofinite (Set.finite_singleton 0), ?_⟩ - simp only [Set.mem_compl_iff, Set.mem_singleton_iff, Nat.succ_eq_add_one, Nat.reduceAdd, - mul_inv_rev, norm_mul, norm_inv, norm_norm, Real.norm_eq_abs, abs_norm] - intro n hn - rw [mul_comm] - gcongr - simpa using abs_le_left_of_norm m n - -lemma linear_bigO (m : ℤ) (z : ℍ) : (fun (n : ℤ) => ((m : ℂ) * z + n)⁻¹) =O[cofinite] - fun n => (|(n : ℝ)|⁻¹) := by - have := Asymptotics.IsBigO.abs_right (linear_bigO2 m z) - simp_rw [abs_inv] at this - exact this - -lemma linear_bigO_pow (m : ℤ) (z : ℍ) (k : ℕ) : - (fun (n : ℤ) => ((((m : ℂ) * z + n)) ^ k )⁻¹) =O[cofinite] fun n => ((|(n : ℝ)| ^ k)⁻¹) := by - simp_rw [← inv_pow] - apply Asymptotics.IsBigO.pow - apply linear_bigO m z - - -lemma summable_hammerTime {α : Type} [NormedField α] [CompleteSpace α] (f : ℤ → α) (a : ℝ) - (hab : 1 < a) (hf : (fun n => (f n)⁻¹) =O[cofinite] fun n => (|(n : ℝ)| ^ (a : ℝ))⁻¹) : - Summable fun n => (f n)⁻¹ := by - apply summable_of_isBigO _ hf - have := Real.summable_abs_int_rpow hab - apply this.congr - intro b - refine Real.rpow_neg ?_ a - exact abs_nonneg (b : ℝ) - -lemma G2_summable_aux (n : ℤ) (z : ℍ) (k : ℤ) (hk : 2 ≤ k) : - Summable fun d : ℤ => ((((n : ℂ) * z) + d) ^ k)⁻¹ := by - apply summable_hammerTime _ k - · norm_cast - · lift k to ℕ using (by linarith) - have := linear_bigO_pow n z k - norm_cast at * - -lemma pnat_div_upper (n : ℕ+) (z : ℍ) : 0 < (-(n : ℂ) / z).im := by - norm_cast - rw [div_im] - simp only [Int.cast_neg, Int.cast_natCast, neg_im, natCast_im, neg_zero, coe_re, zero_mul, - zero_div, neg_re, natCast_re, coe_im, neg_mul, zero_sub, Left.neg_pos_iff, gt_iff_lt] - rw [@div_neg_iff] - right - simp only [Left.neg_neg_iff, Nat.cast_pos, PNat.pos, mul_pos_iff_of_pos_left, Complex.normSq_pos, - ne_eq] - refine ⟨z.2, ne_zero z⟩ - -lemma e2Summand_summable (z : ℍ) (n : ℤ) : Summable fun b : ℤ ↦ 1 / (((b : ℂ) * ↑z + ↑n) ^ 2) := by - have := (G2_summable_aux (-n) ⟨-1 /z, by simpa using pnat_div_upper 1 z⟩ 2 - (by norm_num)).mul_left ((z : ℂ)^2)⁻¹ - apply this.congr - intro b - simp only [UpperHalfPlane.coe, Int.cast_neg, neg_mul] - field_simp - norm_cast - congr 1 - rw [← mul_pow] - congr - have hz := ne_zero z --this come our with a coe that should be fixed - simp only [UpperHalfPlane.coe, ne_eq] at hz - field_simp - ring - -lemma Asymptotics.IsBigO.map {α β ι γ : Type*} [Norm α] [Norm β] {f : ι → α} {g : ι → β} - {p : Filter ι} (hf : f =O[p] g) (c : γ → ι) : + + +/- lemma Asymptotics.IsBigO.map {α β ι γ : Type*} [Norm α] [Norm β] {f : ι → α} {g : ι → β} + {p : Filter ι} (hf : f =O[p] g) (c : γ → ι) : (fun (n : γ) => f (c n)) =O[p.comap c] fun n => g (c n) := by rw [isBigO_iff] at * obtain ⟨C, hC⟩ := hf @@ -121,9 +48,9 @@ lemma Asymptotics.IsBigO.map {α β ι γ : Type*} [Norm α] [Norm β] {f : ι filter_upwards [hC] with n hn exact fun a ha ↦ Eq.mpr (id (congrArg (fun _a ↦ ‖f _a‖ ≤ C * ‖g _a‖) ha)) hn -lemma Asymptotics.IsBigO.nat_of_int {α β: Type*} [Norm α] [SeminormedAddCommGroup β] {f : ℤ → α} - {g : ℤ → β} (hf : f =O[cofinite] g) : (fun (n : ℕ) => f n) =O[cofinite] fun n => g n := by +lemma Asymptotics.IsBigO.nat_of_int {α β : Type*} [Norm α] [SeminormedAddCommGroup β] {f : ℤ → α} + {g : ℤ → β} (hf : f =O[cofinite] g) : (fun (n : ℕ) => f n) =O[cofinite] fun n => g n := by have := Asymptotics.IsBigO.map hf Nat.cast simp only [Int.cofinite_eq, isBigO_sup, comap_sup, Asymptotics.isBigO_sup] at * rw [Nat.cofinite_eq_atTop] - simpa using this.2 + simpa using this.2 -/ From 39f4595a2fe62a93bec59740ee25323dee9d12ca Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 12 Aug 2025 19:05:12 +0100 Subject: [PATCH 056/128] save --- .../ModularForms/EisensteinSeries/E2.lean | 138 +++++++++++++----- .../EisensteinSeries/QExpansion.lean | 2 +- 2 files changed, 100 insertions(+), 40 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean index d68d9ffa90a54a..58ec41470b39eb 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean @@ -19,7 +19,7 @@ over non-symmetric intervals. -/ open ModularForm EisensteinSeries UpperHalfPlane TopologicalSpace intervalIntegral - Metric Filter Function Complex MatrixGroups Finset + Metric Filter Function Complex MatrixGroups Finset ArithmeticFunction open scoped Interval Real Topology BigOperators Nat @@ -33,6 +33,11 @@ lemma e2Summand_summable (m : ℤ) (z : ℍ) : Summable (fun n => eisSummand 2 ! apply (linear_right_summable z m (k := 2) (by omega)).congr simp [eisSummand] +@[simp] +lemma e2Summand_zero_eq_riemannZeta_two (z : ℍ) : e2Summand 0 z = 2 * riemannZeta 2 := by + simpa [e2Summand, eisSummand] using + (two_riemannZeta_eq_tsum_int_inv_even_pow (k := 2) (by omega) (by simp)).symm + /-- The Eisenstein series of weight `2` and level `1` defined as the limit as `N` tends to infinity of the partial sum of `m` in `[N,N)` of `e2Summand m`. This sum over symmetric intervals is handy in showing it is Cauchy. -/ @@ -42,48 +47,103 @@ def E2 : ℍ → ℂ := (1 / (2 * riemannZeta 2)) • G2 def D2 (γ : SL(2, ℤ)) : ℍ → ℂ := fun z => (2 * π * Complex.I * γ 1 0) / (denom γ z) - -lemma t8 (z : ℍ) : - (fun N : ℕ => ∑ m ∈ Finset.Icc (-N : ℤ) N, (∑' (n : ℤ), (1 / ((m : ℂ) * z + n) ^ 2))) = - (fun _ : ℕ => 2*((riemannZeta 2))) + - (fun N : ℕ => ∑ m ∈ Finset.range (N), 2 * (-2 * ↑π * Complex.I) ^ 2 / (2 - 1)! * - ∑' n : ℕ+, n ^ ((2 - 1) ) * Complex.exp (2 * ↑π * Complex.I * (m + 1) * z * n)) := by - sorry - -lemma t9 (z : ℍ) : ∑' m : ℕ, - ( 2 * (-2 * ↑π * Complex.I) ^ 2 / (2 - 1)! * - ∑' n : ℕ+, n ^ ((2 - 1) ) * Complex.exp (2 * ↑π * Complex.I * (m + 1) * z * n)) = - - 8 * π ^ 2 * ∑' (n : ℕ+), (sigma 1 n) * cexp (2 * π * Complex.I * n * z) := by sorry - -theorem G2_c_tendsto (z : ℍ) : - Tendsto - (fun N ↦ - ∑ x ∈ Finset.range N, - 2 * (2 * ↑π * Complex.I) ^ 2 * ∑' (n : ℕ+), ↑↑n * cexp (2 * ↑π * Complex.I * (↑x + 1) * ↑z * ↑↑n)) - atTop (𝓝 (-8 * ↑π ^ 2 * ∑' (n : ℕ+), ↑((σ 1) ↑n) * cexp (2 * ↑π * Complex.I * ↑↑n * ↑z))) := by - rw [← t9] - have hf : Summable fun m : ℕ => ( 2 * (-2 * ↑π * Complex.I) ^ 2 / (2 - 1)! * - ∑' n : ℕ+, n ^ ((2 - 1)) * Complex.exp (2 * ↑π * Complex.I * (m + 1) * z * n)) := by - conv => - enter [1] - ext m - rw [show (m : ℂ) + 1 = (((m + 1) : ℕ) : ℂ) by simp] - have := nat_pos_tsum2' (f := fun m : ℕ => ( 2 * (-2 * ↑π * Complex.I) ^ 2 / (2 - 1)! * - ∑' n : ℕ+, n ^ ((2 - 1) ) * Complex.exp (2 * ↑π * Complex.I * (m) * z * n)) ) - rw [← this] - have := (a4 2 z).prod_symm.prod - apply Summable.mul_left - apply this.congr - intro b - congr - have := hf.hasSum - have V := this.comp tendsto_finset_range +lemma Icc_succ_succ (n : ℕ) : Finset.Icc (-(n + 1) : ℤ) (n + 1) = Finset.Icc (-n : ℤ) n ∪ + {(-(n + 1) : ℤ), (n + 1 : ℤ)} := by + refine Finset.ext_iff.mpr ?_ + intro a + simp only [neg_add_rev, Int.reduceNeg, Finset.mem_Icc, add_neg_le_iff_le_add, Finset.union_insert, + Finset.mem_insert, Finset.mem_union, Finset.mem_singleton] + omega + +lemma sum_Icc_of_even_eq_range {α : Type*} [CommRing α] (f : ℤ → α) (hf : ∀ n, f n = f (-n)) + (N : ℕ) : ∑ m ∈ Finset.Icc (-N : ℤ) N, f m = 2 * ∑ m ∈ Finset.range (N + 1), f m - f 0 := by + induction' N with N ih + · simp [two_mul] + · have := Icc_succ_succ N + simp only [neg_add_rev, Int.reduceNeg, Nat.cast_add, Nat.cast_one] at * + rw [this, Finset.sum_union (by simp), Finset.sum_pair (by omega), ih] + nth_rw 2 [Finset.sum_range_succ] + have HF := hf (N + 1) + simp only [neg_add_rev, Int.reduceNeg] at HF + rw [← HF] + ring_nf + norm_cast + +lemma G2_partial_sum_eq (z : ℍ) (N : ℕ) : (∑ m ∈ Icc (-N : ℤ) N, e2Summand m z) = + (2 * riemannZeta 2) + (∑ m ∈ Finset.range (N), 2 * (-2 * ↑π * Complex.I) ^ 2 / (2 - 1)! * + ∑' n : ℕ+, n ^ ((2 - 1) ) * cexp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) := by + rw [sum_Icc_of_even_eq_range, Finset.sum_range_succ', mul_add] + · nth_rw 2 [two_mul] + ring_nf + have (a : ℕ):= EisensteinSeries.qExpansion_identity_pnat (k := 1) (by omega) ⟨(a + 1) * z, by + have ha : 0 < a + (1 : ℝ) := by norm_cast; omega + simpa [ha] using z.2⟩ + simp only [coe_mk_subtype, add_comm, Nat.reduceAdd, one_div, mul_comm, mul_neg, even_two, + Even.neg_pow, Nat.factorial_one, Nat.cast_one, div_one, pow_one, e2Summand, eisSummand, + Nat.cast_add, Fin.isValue, Matrix.cons_val_zero, Int.cast_add, Int.cast_natCast, Int.cast_one, + Matrix.cons_val_one, Matrix.cons_val_fin_one, Int.reduceNeg, zpow_neg, mul_sum, Int.cast_zero, + zero_mul, add_zero, I_sq, neg_mul, one_mul, inv_one] at * + congr + · simpa using (two_riemannZeta_eq_tsum_int_inv_even_pow (k := 2) (by omega) (by simp)).symm + · ext a + norm_cast at * + simp_rw [this a, ← tsum_mul_left, ← tsum_neg,ofReal_mul, ofReal_ofNat, mul_pow, I_sq, neg_mul, + one_mul, Nat.cast_add, Nat.cast_one, mul_neg, ofReal_pow] + apply tsum_congr + intro b + ring_nf + · intro n + simp only [e2Summand, eisSummand, Fin.isValue, Matrix.cons_val_zero, Matrix.cons_val_one, + Matrix.cons_val_fin_one, Int.reduceNeg, zpow_neg, Int.cast_neg, neg_mul] + nth_rw 2 [← tsum_int_eq_tsum_neg] + apply tsum_congr + intro b + norm_cast + ring_nf + aesop + +private lemma aux_tsum_identity (z : ℍ) : ∑' m : ℕ, (2 * (-2 * ↑π * Complex.I) ^ 2 * + ∑' n : ℕ+, n ^ ((2 - 1) ) * cexp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) = + -8 * π ^ 2 * ∑' (n : ℕ+), (sigma 1 n) * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by + have := tsum_prod_pow_cexp_eq_tsum_sigma 1 z + rw [tsum_pnat_eq_tsum_succ (fun d => + ∑' (c : ℕ+), (c ^ 1 : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ))] at this + simp only [neg_mul, even_two, Even.neg_pow, Nat.add_one_sub_one, pow_one, ← tsum_mul_left, ← this, + Nat.cast_add, Nat.cast_one] + apply tsum_congr + intro b + apply tsum_congr + intro c + simp only [mul_pow, I_sq, mul_neg, mul_one, neg_mul, neg_inj, mul_eq_mul_right_iff, mul_eq_zero, + Nat.cast_eq_zero, PNat.ne_zero, ne_eq, not_false_eq_true, pow_eq_zero_iff, exp_ne_zero, or_self, + or_false] + ring + +theorem G2_tendsto (z : ℍ) : Tendsto (fun N ↦ ∑ x ∈ range N, 2 * (2 * ↑π * Complex.I) ^ 2 * + ∑' (n : ℕ+), n * cexp (2 * ↑π * Complex.I * (↑x + 1) * ↑z) ^ (n : ℕ)) atTop + (𝓝 (-8 * ↑π ^ 2 * ∑' (n : ℕ+), ↑((σ 1) ↑n) * cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ))) := by + rw [← aux_tsum_identity] + have hf : Summable fun m : ℕ => ( 2 * (-2 * ↑π * Complex.I) ^ 2 * + ∑' n : ℕ+, n ^ ((2 - 1)) * Complex.exp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) := by + apply Summable.mul_left + have := (summable_prod_aux 1 z).prod_symm.prod + have h0 := pnat_summable_iff_summable_succ + (f := fun b ↦ ∑' (c : ℕ+), c * cexp (2 * ↑π * Complex.I * ↑↑b * ↑z) ^ (c : ℕ)) simp at * - apply V + rw [← h0] + apply this + simpa using (hf.hasSum).comp tendsto_finset_range lemma G2_cauchy (z : ℍ) : CauchySeq (fun N : ℕ => ∑ m ∈ Icc (-N : ℤ) N, e2Summand m z) := by + conv => + enter [1] + ext n + rw [G2_partial_sum_eq] + apply CauchySeq.const_add + apply Filter.Tendsto.cauchySeq (x := + -8 * π ^ 2 * ∑' (n : ℕ+), (σ 1 n) * cexp (2 * π * Complex.I * z) ^ (n : ℕ)) + simpa using G2_tendsto z - sorry diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index 51192c0dd1220f..0568ccfe588db1 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -237,7 +237,7 @@ theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = - ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by + ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : ℂ) * cexp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) = ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) by rw [Summable.tsum_prod (summable_prod_aux k z), Summable.tsum_comm] at this From ea92785e24b66ce01635fe2ec539526ba61ea197 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 13 Aug 2025 14:02:03 +0100 Subject: [PATCH 057/128] save --- .../ModularForms/EisensteinSeries/E2.lean | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean index 58ec41470b39eb..8b50b4b651bce5 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean @@ -41,7 +41,7 @@ lemma e2Summand_zero_eq_riemannZeta_two (z : ℍ) : e2Summand 0 z = 2 * riemannZ /-- The Eisenstein series of weight `2` and level `1` defined as the limit as `N` tends to infinity of the partial sum of `m` in `[N,N)` of `e2Summand m`. This sum over symmetric intervals is handy in showing it is Cauchy. -/ -def G2 : ℍ → ℂ := fun z => limUnder (atTop) (fun N : ℕ => ∑ m ∈ Icc (-N : ℤ) N, e2Summand m z) +def G2 : ℍ → ℂ := fun z => limUnder atTop (fun N : ℕ => ∑ m ∈ Icc (-N : ℤ) N, e2Summand m z) def E2 : ℍ → ℂ := (1 / (2 * riemannZeta 2)) • G2 @@ -70,19 +70,19 @@ lemma sum_Icc_of_even_eq_range {α : Type*} [CommRing α] (f : ℤ → α) (hf : norm_cast lemma G2_partial_sum_eq (z : ℍ) (N : ℕ) : (∑ m ∈ Icc (-N : ℤ) N, e2Summand m z) = - (2 * riemannZeta 2) + (∑ m ∈ Finset.range (N), 2 * (-2 * ↑π * Complex.I) ^ 2 / (2 - 1)! * - ∑' n : ℕ+, n ^ ((2 - 1) ) * cexp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) := by + (2 * riemannZeta 2) + (∑ m ∈ Finset.range N, 2 * (-2 * ↑π * Complex.I) ^ 2 * + ∑' n : ℕ+, n * cexp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) := by rw [sum_Icc_of_even_eq_range, Finset.sum_range_succ', mul_add] · nth_rw 2 [two_mul] ring_nf have (a : ℕ):= EisensteinSeries.qExpansion_identity_pnat (k := 1) (by omega) ⟨(a + 1) * z, by - have ha : 0 < a + (1 : ℝ) := by norm_cast; omega + have ha : 0 < a + (1 : ℝ) := by linarith simpa [ha] using z.2⟩ simp only [coe_mk_subtype, add_comm, Nat.reduceAdd, one_div, mul_comm, mul_neg, even_two, Even.neg_pow, Nat.factorial_one, Nat.cast_one, div_one, pow_one, e2Summand, eisSummand, Nat.cast_add, Fin.isValue, Matrix.cons_val_zero, Int.cast_add, Int.cast_natCast, Int.cast_one, Matrix.cons_val_one, Matrix.cons_val_fin_one, Int.reduceNeg, zpow_neg, mul_sum, Int.cast_zero, - zero_mul, add_zero, I_sq, neg_mul, one_mul, inv_one] at * + zero_mul, add_zero, I_sq, neg_mul, one_mul] at * congr · simpa using (two_riemannZeta_eq_tsum_int_inv_even_pow (k := 2) (by omega) (by simp)).symm · ext a @@ -103,20 +103,17 @@ lemma G2_partial_sum_eq (z : ℍ) (N : ℕ) : (∑ m ∈ Icc (-N : ℤ) N, e2Sum aesop private lemma aux_tsum_identity (z : ℍ) : ∑' m : ℕ, (2 * (-2 * ↑π * Complex.I) ^ 2 * - ∑' n : ℕ+, n ^ ((2 - 1) ) * cexp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) = + ∑' n : ℕ+, n * cexp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) = -8 * π ^ 2 * ∑' (n : ℕ+), (sigma 1 n) * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by have := tsum_prod_pow_cexp_eq_tsum_sigma 1 z rw [tsum_pnat_eq_tsum_succ (fun d => ∑' (c : ℕ+), (c ^ 1 : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ))] at this - simp only [neg_mul, even_two, Even.neg_pow, Nat.add_one_sub_one, pow_one, ← tsum_mul_left, ← this, - Nat.cast_add, Nat.cast_one] + simp only [neg_mul, even_two, Even.neg_pow, ← tsum_mul_left, ← this, Nat.cast_add, Nat.cast_one] apply tsum_congr intro b apply tsum_congr intro c - simp only [mul_pow, I_sq, mul_neg, mul_one, neg_mul, neg_inj, mul_eq_mul_right_iff, mul_eq_zero, - Nat.cast_eq_zero, PNat.ne_zero, ne_eq, not_false_eq_true, pow_eq_zero_iff, exp_ne_zero, or_self, - or_false] + simp only [mul_pow, I_sq, mul_neg, mul_one, neg_mul, neg_inj] ring theorem G2_tendsto (z : ℍ) : Tendsto (fun N ↦ ∑ x ∈ range N, 2 * (2 * ↑π * Complex.I) ^ 2 * From e397df0c3cc072ee94629e0134996fbef4e939a0 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 13 Aug 2025 14:14:35 +0100 Subject: [PATCH 058/128] doc string --- Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean index 8b50b4b651bce5..953b852f61d5ff 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean @@ -43,8 +43,10 @@ infinity of the partial sum of `m` in `[N,N)` of `e2Summand m`. This sum over sy intervals is handy in showing it is Cauchy. -/ def G2 : ℍ → ℂ := fun z => limUnder atTop (fun N : ℕ => ∑ m ∈ Icc (-N : ℤ) N, e2Summand m z) +/-- The normalised Eisenstein series of weight `2` and level `1`. -/ def E2 : ℍ → ℂ := (1 / (2 * riemannZeta 2)) • G2 +/-- This function measures the defect in `E2` being a modular form. -/ def D2 (γ : SL(2, ℤ)) : ℍ → ℂ := fun z => (2 * π * Complex.I * γ 1 0) / (denom γ z) lemma Icc_succ_succ (n : ℕ) : Finset.Icc (-(n + 1) : ℤ) (n + 1) = Finset.Icc (-n : ℤ) n ∪ From ed2eb15b09ca5f5ecdeedf8361e55ca698370cfe Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 11:10:32 +0100 Subject: [PATCH 059/128] open --- .../ModularForms/DedekindEta.lean | 412 ++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 Mathlib/NumberTheory/ModularForms/DedekindEta.lean diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean new file mode 100644 index 00000000000000..d896d04dc92d93 --- /dev/null +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -0,0 +1,412 @@ +import Mathlib.Algebra.Order.Ring.Star +import Mathlib.Analysis.CStarAlgebra.Classes +import Mathlib.Analysis.Complex.LocallyUniformLimit +import Mathlib.Analysis.Complex.UpperHalfPlane.Exp +import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn +import Mathlib.Data.Complex.FiniteDimensional + + +open UpperHalfPlane TopologicalSpace Set MeasureTheory intervalIntegral + Metric Filter Function Complex + +open scoped Interval Real NNReal ENNReal Topology BigOperators Nat Classical + + + +local notation "𝕢" => Periodic.qParam + +local notation "𝕢₁" => Periodic.qParam 1 + +noncomputable abbrev eta_q (n : ℕ) (z : ℂ) := (𝕢₁ z) ^ (n + 1) + +lemma eta_q_eq_exp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * (n + 1) * z) := by + simp [eta_q, Periodic.qParam, ← Complex.exp_nsmul] + ring_nf + +lemma eta_q_eq_pow (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * z) ^ (n + 1) := by + simp [eta_q, Periodic.qParam] + +theorem qParam_lt_one (z : ℍ) (r : ℝ) (hr : 0 < r) : + ‖𝕢 r z‖ < 1 := by + simp [Periodic.qParam, norm_exp, mul_re, re_ofNat, ofReal_re, im_ofNat, ofReal_im, mul_zero, + sub_zero, Complex.I_re, mul_im, zero_mul, add_zero, Complex.I_im, mul_one, sub_self, coe_re, + coe_im, zero_sub, Real.exp_lt_one_iff] + rw [neg_div, neg_lt_zero] + positivity + +lemma one_sub_qParam_ne_zero (r : ℝ) (hr : 0 < r) (z : ℍ) : 1 - 𝕢 r z ≠ 0 := by + rw [sub_ne_zero] + intro h + have := qParam_lt_one z r + rw [← h] at this + simp [lt_self_iff_false] at * + linarith + +lemma one_add_eta_q_ne_zero (n : ℕ) (z : ℍ) : 1 - eta_q n z ≠ 0 := by + rw [eta_q_eq_exp, sub_ne_zero] + intro h + have := UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨(n + 1) • z, by + have : 0 < (n + 1 : ℝ) := by linarith + simpa [this] using z.2⟩ + simp [← mul_assoc] at this + rw [← h] at this + simp only [norm_one, lt_self_iff_false] at * + +noncomputable abbrev etaProdTerm (z : ℂ) := ∏' (n : ℕ), (1 - eta_q n z) + +local notation "ηₚ" => etaProdTerm + +/- The eta function. Best to define it on all of ℂ since we want to take its logDeriv. -/ +noncomputable def ModularForm.eta (z : ℂ) := (𝕢 24 z) * ηₚ z + +local notation "η" => ModularForm.eta + +theorem Summable_eta_q (z : ℍ) : Summable fun n : ℕ ↦ ‖-eta_q n z‖ := by + simp_rw [eta_q, eta_q_eq_pow, norm_neg, norm_pow, summable_nat_add_iff 1] + simp only [summable_geometric_iff_norm_lt_one, norm_norm] + apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z + +@[fun_prop] +lemma qParam_differentiable (n : ℝ) : Differentiable ℂ (𝕢 n) := by + rw [show 𝕢 n = fun x => exp (2 * π * Complex.I * x / n) by rfl] + fun_prop + +@[fun_prop] +lemma qParam_ContDiff (n : ℝ) (m : WithTop ℕ∞) : ContDiff ℂ m (𝕢 n) := by + rw [show 𝕢 n = fun x => exp (2 * π * Complex.I * x / n) by rfl] + fun_prop + +lemma hasProdLocallyUniformlyOn_eta : + HasProdLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ηₚ {x | 0 < x.im} := by + simp_rw [sub_eq_add_neg] + apply hasProdLocallyUniformlyOn_of_forall_compact (isOpen_lt continuous_const Complex.continuous_im) + intro K hK hcK + by_cases hN : ¬ Nonempty K + · rw [hasProdUniformlyOn_iff_tendstoUniformlyOn] + simpa [not_nonempty_iff_eq_empty'.mp hN] using tendstoUniformlyOn_empty + have hc : ContinuousOn (fun x ↦ ‖cexp (2 * ↑π * Complex.I * x)‖) K := by fun_prop + obtain ⟨z, hz, hB, HB⟩ := IsCompact.exists_sSup_image_eq_and_ge hcK (by simpa using hN) hc + apply Summable.hasProdUniformlyOn_nat_one_add hcK (Summable_eta_q ⟨z, by simpa using (hK hz)⟩) + · filter_upwards with n x hx + simpa only [eta_q, eta_q_eq_pow n x, norm_neg, norm_pow, coe_mk_subtype, + eta_q_eq_pow n (⟨z, hK hz⟩ : ℍ)] using + pow_le_pow_left₀ (by simp [norm_nonneg]) (HB x hx) (n + 1) + · simp_rw [eta_q, Periodic.qParam] + fun_prop + +lemma tprod_ne_zero' {ι α : Type*} (x : α) (f : ι → α → ℂ) (hf : ∀ i x, 1 + f i x ≠ 0) + (hu : ∀ x : α, Summable fun n => f n x) : (∏' i : ι, (1 + f i) x) ≠ 0 := by + simp only [Pi.add_apply, Pi.one_apply, ne_eq] + rw [← Complex.cexp_tsum_eq_tprod (f := fun n => 1 + f n x) (fun n => hf n x)] + · simp only [exp_ne_zero, not_false_eq_true] + · exact Complex.summable_log_one_add_of_summable (hu x) + +theorem etaProdTerm_ne_zero (z : ℍ) : ηₚ z ≠ 0 := by + simp only [etaProdTerm, eta_q, ne_eq] + refine tprod_ne_zero' z (fun n x => -eta_q n x) ?_ ?_ + · refine fun i x => by simpa using one_add_eta_q_ne_zero i x + · intro x + simpa [eta_q, ←summable_norm_iff] using Summable_eta_q x + +/--Eta is non-vanishing!-/ +lemma eta_nonzero_on_UpperHalfPlane (z : ℍ) : η z ≠ 0 := by + simpa [ModularForm.eta, Periodic.qParam] using etaProdTerm_ne_zero z + +/- +lemma differentiable_eta_q (n : ℕ) : Differentiable ℂ (eta_q n) := by + rw [show eta_q n = fun x => -exp (2 * π * Complex.I * x) ^ (n + 1) by + ext z; exact eta_q_eq_pow n z] + fun_prop -/ + +lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = + fun z ↦ -r * cexp z / (1 - r * cexp ( z)) := by + ext z + simp [logDeriv] + +lemma logDeriv_one_sub_mul_cexp_comp (r : ℂ) {g : ℂ → ℂ} (hg : Differentiable ℂ g) : + logDeriv ((fun z ↦ 1 - r * cexp z) ∘ g) = + fun z ↦ -r * (deriv g z) * cexp (g z) / (1 - r * cexp (g z)) := by + ext y + rw [logDeriv_comp (by fun_prop) (hg y), logDeriv_one_sub_cexp] + ring + + +theorem one_add_eta_logDeriv_eq (z : ℂ) (i : ℕ) : + logDeriv (fun x ↦ 1 - eta_q i x) z = 2 * ↑π * Complex.I * (↑i + 1) * -eta_q i z / (1 - eta_q i z) := by + have h2 : (fun x ↦ 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) = + ((fun z ↦ 1 - 1 * cexp z) ∘ fun x ↦ 2 * ↑π * Complex.I * (↑i + 1) * x) := by aesop + have h3 : deriv (fun x : ℂ ↦ (2 * π * Complex.I * (i + 1) * x)) = + fun _ ↦ 2 * π * Complex.I * (i + 1) := by + ext y + simpa using deriv_const_mul (2 * π * Complex.I * (i + 1)) (d := fun (x : ℂ) => x) (x := y) + simp_rw [eta_q_eq_exp, h2, logDeriv_one_sub_mul_cexp_comp 1 + (g := fun x => (2 * π * Complex.I * (i + 1) * x)) (by fun_prop), h3] + simp + +lemma tsum_log_deriv_eta_q (z : ℂ) : + ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = + ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) := by + refine tsum_congr (fun i => ?_) + apply one_add_eta_logDeriv_eq + +lemma tsum_log_deriv_eta_q' (z : ℂ) : + ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = + (2 * ↑π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by + rw [tsum_log_deriv_eta_q z, ← tsum_mul_left] + congr 1 + ext i + ring + +lemma logDeriv_q (n : ℝ) (z : ℂ) : logDeriv (𝕢 n) z = 2 * ↑π * Complex.I / n := by + have : (𝕢 n) = (fun z ↦ cexp (z)) ∘ (fun z => (2 * ↑π * Complex.I / n) * z) := by + ext y + simp only [Periodic.qParam, comp_apply] + ring_nf + rw [this, logDeriv_comp (by fun_prop) (by fun_prop), deriv_const_mul _ (by fun_prop)] + simp [LogDeriv_exp] + +lemma logDeriv_z_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * Complex.I / 24 := by + have : (𝕢 24) = (fun z ↦ cexp (z)) ∘ (fun z => (2 * ↑π * Complex.I / 24) * z) := by + ext y + simp only [Periodic.qParam, ofReal_ofNat, comp_apply] + ring_nf + rw [this, logDeriv_comp (by fun_prop) (by fun_prop), deriv_const_mul _ (by fun_prop)] + simp [LogDeriv_exp] + + +theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ ↑z := by + have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ + (isOpen_lt continuous_const Complex.continuous_im) + · rw [DifferentiableOn] at hD + apply (hD z (by apply z.2)).differentiableAt + · apply IsOpen.mem_nhds (isOpen_lt continuous_const Complex.continuous_im) z.2 + · filter_upwards with b y + apply (DifferentiableOn.finset_prod (u := Finset.range b) + (f := fun i x => 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) + (by fun_prop)).congr + intro x hx + simp [sub_eq_add_neg, eta_q_eq_exp] + +lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta ↑z := by + apply DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) + +theorem logDeriv_tprod_eq_tsum {ι : Type*} {s : Set ℂ} (hs : IsOpen s) (x : s) {f : ι → ℂ → ℂ} + (hf : ∀ i, f i x ≠ 0) (hd : ∀ i : ι, DifferentiableOn ℂ (f i) s) + (hm : Summable fun i ↦ logDeriv (f i) ↑x) (htend : MultipliableLocallyUniformlyOn f s) + (hnez : ∏' (i : ι), f i x ≠ 0) : logDeriv (∏' i : ι, f i ·) x = ∑' i : ι, logDeriv (f i) x := by + apply symm + rw [← Summable.hasSum_iff hm, HasSum] + have := logDeriv_tendsto (f := fun (n : Finset ι) ↦ ∏ i ∈ n, (f i)) + (g := (∏' i : ι, f i ·)) (s := s) hs (p := atTop) + simp only [eventually_atTop, ge_iff_le, ne_eq, forall_exists_index, Subtype.forall] at this + conv => + enter [1] + ext n + rw [← logDeriv_prod _ _ _ (by intro i hi; apply hf i) + (by intro i hi; apply (hd i x x.2).differentiableAt; exact IsOpen.mem_nhds hs x.2)] + apply (this x x.2 ?_ ⊥ ?_ hnez).congr + · intro m + congr + aesop + · convert hasProdLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp + htend.hasProdLocallyUniformlyOn + simp + · intro b hb z hz + apply DifferentiableAt.differentiableWithinAt + have hp : ∀ (i : ι), i ∈ b → DifferentiableAt ℂ (f i) z := by + exact fun i hi ↦ (hd i z hz).differentiableAt (IsOpen.mem_nhds hs hz) + simpa using DifferentiableAt.finset_prod hp + +/- lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E₂ z := by + unfold ModularForm.eta etaProdTerm + rw [logDeriv_mul (UpperHalfPlane.coe z) _ (etaProdTerm_ne_zero z) _ + (etaProdTerm_differentiableAt z)] + · have HG := logDeriv_tprod_eq_tsum (isOpen_lt continuous_const Complex.continuous_im) z + (fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) ?_ ?_ ?_ (etaProdTerm_ne_zero z) + rw [show z.1 = UpperHalfPlane.coe z by rfl] at HG + rw [HG] + · simp only [tsum_log_deriv_eta_q' z, E₂, logDeriv_z_term z, mul_neg, one_div, mul_inv_rev, Pi.smul_apply, smul_eq_mul] + rw [G2_q_exp'', riemannZeta_two, ← (tsum_eq_tsum_sigma_pos'' z), mul_sub, sub_eq_add_neg, mul_add] + conv => + enter [1,2,2,1] + ext n + rw [neg_div, neg_eq_neg_one_mul] + rw [tsum_mul_left] + have hpi : (π : ℂ) ≠ 0 := by simpa using Real.pi_ne_zero + congr 1 + · ring_nf + field_simp + ring + · field_simp + ring_nf + congr + ext n + ring_nf + · intro i x hx + simp_rw [eta_q_eq_exp] + fun_prop + · simp only [mem_setOf_eq, one_add_eta_logDeriv_eq] + apply ((summable_nat_add_iff 1).mpr ((logDeriv_q_expo_summable (𝕢₁ z) + (by simpa [Periodic.qParam] using exp_upperHalfPlane_lt_one z)).mul_left (-2 * π * Complex.I))).congr + intro b + have := one_add_eta_q_ne_zero b z + simp only [UpperHalfPlane.coe, ne_eq, neg_mul, Nat.cast_add, Nat.cast_one, mul_neg] at * + field_simp + left + ring + · use ηₚ + apply (hasProdLocallyUniformlyOn_eta).congr + exact fun n ⦃x⦄ hx ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, (fun n a ↦ 1 - eta_q n a) i b) x) + · simp [ne_eq, exp_ne_zero, not_false_eq_true, Periodic.qParam] + · fun_prop -/ + +/- lemma eta_logDeriv_eql (z : ℍ) : (logDeriv (η ∘ (fun z : ℂ => -1/z))) z = + (logDeriv ((csqrt) * η)) z := by + have h0 : (logDeriv (η ∘ (fun z : ℂ => -1/z))) z = ((z :ℂ)^(2 : ℤ))⁻¹ * (logDeriv η) (⟨-1 / z, by simpa using pnat_div_upper 1 z⟩ : ℍ) := by + rw [logDeriv_comp, mul_comm] + congr + conv => + enter [1,1] + intro z + rw [neg_div] + simp + simp only [deriv.fun_neg', deriv_inv', neg_neg, inv_inj] + norm_cast + · simpa only using + eta_DifferentiableAt_UpperHalfPlane (⟨-1 / z, by simpa using pnat_div_upper 1 z⟩ : ℍ) + conv => + enter [2] + ext z + rw [neg_div] + simp + apply DifferentiableAt.neg + apply DifferentiableAt.inv + simp only [differentiableAt_fun_id] + exact ne_zero z + rw [h0, show ((csqrt) * η) = (fun x => (csqrt) x * η x) by rfl, logDeriv_mul] + nth_rw 2 [logDeriv_apply] + unfold csqrt + have := csqrt_deriv z + rw [this] + simp only [one_div, neg_mul, smul_eq_mul] + nth_rw 2 [div_eq_mul_inv] + rw [← Complex.exp_neg, show 2⁻¹ * cexp (-(2⁻¹ * Complex.log ↑z)) * cexp (-(2⁻¹ * Complex.log ↑z)) = + (cexp (-(2⁻¹ * Complex.log ↑z)) * cexp (-(2⁻¹ * Complex.log ↑z)))* 2⁻¹ by ring, ← Complex.exp_add, + ← sub_eq_add_neg, show -(2⁻¹ * Complex.log ↑z) - 2⁻¹ * Complex.log ↑z = -Complex.log ↑z by ring, Complex.exp_neg, Complex.exp_log, eta_logDeriv z] + have Rb := eta_logDeriv (⟨-1 / z, by simpa using pnat_div_upper 1 z⟩ : ℍ) + simp only [coe_mk_subtype] at Rb + rw [Rb] + have E := E₂_transform z + simp only [one_div, neg_mul, smul_eq_mul, SL_slash_def, + modular_S_smul, + ModularGroup.denom_S, Int.reduceNeg, zpow_neg] at * + have h00 : (UpperHalfPlane.mk (-z : ℂ)⁻¹ z.im_inv_neg_coe_pos) = (⟨-1 / z, by simpa using pnat_div_upper 1 z⟩ : ℍ) := by + simp [UpperHalfPlane.mk] + ring_nf + rw [h00] at E + rw [← mul_assoc, mul_comm, ← mul_assoc] + simp only [UpperHalfPlane.coe] at * + rw [E, add_mul, add_comm] + congr 1 + have hzne := ne_zero z + have hI : Complex.I ≠ 0 := by + exact I_ne_zero + have hpi : (π : ℂ) ≠ 0 := by + simp only [ne_eq, ofReal_eq_zero] + exact Real.pi_ne_zero + simp [UpperHalfPlane.coe] at hzne ⊢ + field_simp + ring + rw [mul_comm] + · simpa only [UpperHalfPlane.coe, ne_eq] using (ne_zero z) + · simp only [csqrt, one_div, ne_eq, Complex.exp_ne_zero, not_false_eq_true] + · apply eta_nonzero_on_UpperHalfPlane z + · unfold csqrt + rw [show (fun a ↦ cexp (1 / 2 * Complex.log a)) = cexp ∘ (fun a ↦ 1 / 2 * Complex.log a) by rfl] + apply DifferentiableAt.comp + simp + apply DifferentiableAt.const_mul + apply Complex.differentiableAt_log + rw [@mem_slitPlane_iff] + right + have hz := z.2 + simp at hz + exact Ne.symm (ne_of_lt hz) + · apply eta_DifferentiableAt_UpperHalfPlane z + +lemma eta_logderivs : {z : ℂ | 0 < z.im}.EqOn (logDeriv (η ∘ (fun z : ℂ => -1/z))) + (logDeriv ((csqrt) * η)) := by + intro z hz + have := eta_logDeriv_eql ⟨z, hz⟩ + exact this + +lemma eta_logderivs_const : ∃ z : ℂ, z ≠ 0 ∧ {z : ℂ | 0 < z.im}.EqOn ((η ∘ (fun z : ℂ => -1/z))) + (z • ((csqrt) * η)) := by + have h := eta_logderivs + rw [logDeriv_eqOn_iff] at h + · exact h + · apply DifferentiableOn.comp + pick_goal 4 + · use ({z : ℂ | 0 < z.im}) + · rw [DifferentiableOn] + intro x hx + apply DifferentiableAt.differentiableWithinAt + apply eta_DifferentiableAt_UpperHalfPlane ⟨x, hx⟩ + · apply DifferentiableOn.div + fun_prop + fun_prop + intro x hx + have hx2 := ne_zero (⟨x, hx⟩ : ℍ) + norm_cast at * + · intro y hy + simp + have := UpperHalfPlane.im_inv_neg_coe_pos (⟨y, hy⟩ : ℍ) + conv => + enter [2,1] + rw [neg_div] + rw [div_eq_mul_inv] + simp + simp at * + exact this + · apply DifferentiableOn.mul + simp only [DifferentiableOn, mem_setOf_eq] + intro x hx + apply (csqrt_differentiableAt ⟨x, hx⟩).differentiableWithinAt + simp only [DifferentiableOn, mem_setOf_eq] + intro x hx + apply (eta_DifferentiableAt_UpperHalfPlane ⟨x, hx⟩).differentiableWithinAt + · use UpperHalfPlane.I + simp only [coe_I, mem_setOf_eq, Complex.I_im, zero_lt_one] + · exact isOpen_lt continuous_const Complex.continuous_im + · exact convex_halfSpace_im_gt 0 + · intro x hx + simp only [Pi.mul_apply, ne_eq, mul_eq_zero, not_or] + refine ⟨ ?_ , by apply eta_nonzero_on_UpperHalfPlane ⟨x, hx⟩⟩ + unfold csqrt + simp only [one_div, Complex.exp_ne_zero, not_false_eq_true] + · intro x hx + simp only [comp_apply, ne_eq] + have := eta_nonzero_on_UpperHalfPlane ⟨-1 / x, by simpa using pnat_div_upper 1 ⟨x, hx⟩⟩ + simpa only [ne_eq, coe_mk_subtype] using this + +lemma eta_equality : {z : ℂ | 0 < z.im}.EqOn ((η ∘ (fun z : ℂ => -1/z))) + ((csqrt (Complex.I))⁻¹ • ((csqrt) * η)) := by + have h := eta_logderivs_const + obtain ⟨z, hz, h⟩ := h + intro x hx + have h2 := h hx + have hI : (Complex.I) ∈ {z : ℂ | 0 < z.im} := by + simp only [mem_setOf_eq, Complex.I_im, zero_lt_one] + have h3 := h hI + simp at h3 + conv at h3 => + enter [2] + rw [← mul_assoc] + have he : η Complex.I ≠ 0 := by + have h:= eta_nonzero_on_UpperHalfPlane UpperHalfPlane.I + convert h + have hcd := (mul_eq_right₀ he).mp (_root_.id (Eq.symm h3)) + rw [mul_eq_one_iff_inv_eq₀ hz] at hcd + rw [@inv_eq_iff_eq_inv] at hcd + rw [hcd] at h2 + exact h2 -/ From dc50298c73cad957bec8290c6d631b68e3d39b32 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 12:40:53 +0100 Subject: [PATCH 060/128] save --- .../SpecialFunctions/Log/Summable.lean | 8 +++ .../ModularForms/DedekindEta.lean | 64 ++++++++----------- 2 files changed, 33 insertions(+), 39 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean b/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean index d3619781f90f29..d87f8eb76b514c 100644 --- a/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean +++ b/Mathlib/Analysis/SpecialFunctions/Log/Summable.lean @@ -42,6 +42,14 @@ lemma summable_log_one_add_of_summable {f : ι → ℂ} (hf : Summable f) : filter_upwards [hf.norm.tendsto_cofinite_zero.eventually_le_const one_half_pos] with i hi using norm_log_one_add_half_le_self hi +lemma tprod_one_add_ne_zero_of_summable {α : Type*} (x : α) {f : ι → α → ℂ} + (hf : ∀ i x, 1 + f i x ≠ 0) (hu : ∀ x : α, Summable fun n => f n x) : + (∏' i : ι, (1 + f i) x) ≠ 0 := by + simp only [Pi.add_apply, Pi.one_apply, ne_eq] + rw [← Complex.cexp_tsum_eq_tprod (f := fun n => 1 + f n x) (fun n => hf n x)] + · simp only [exp_ne_zero, not_false_eq_true] + · exact Complex.summable_log_one_add_of_summable (hu x) + protected lemma multipliable_one_add_of_summable (hf : Summable f) : Multipliable (fun i ↦ 1 + f i) := multipliable_of_summable_log (summable_log_one_add_of_summable hf) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index d896d04dc92d93..8742bcaffa936c 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -9,15 +9,12 @@ import Mathlib.Data.Complex.FiniteDimensional open UpperHalfPlane TopologicalSpace Set MeasureTheory intervalIntegral Metric Filter Function Complex -open scoped Interval Real NNReal ENNReal Topology BigOperators Nat Classical - +open scoped Interval Real NNReal ENNReal Topology BigOperators Nat local notation "𝕢" => Periodic.qParam -local notation "𝕢₁" => Periodic.qParam 1 - -noncomputable abbrev eta_q (n : ℕ) (z : ℂ) := (𝕢₁ z) ^ (n + 1) +noncomputable abbrev eta_q (n : ℕ) (z : ℂ) := (𝕢 1 z) ^ (n + 1) lemma eta_q_eq_exp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * (n + 1) * z) := by simp [eta_q, Periodic.qParam, ← Complex.exp_nsmul] @@ -61,6 +58,8 @@ noncomputable def ModularForm.eta (z : ℂ) := (𝕢 24 z) * ηₚ z local notation "η" => ModularForm.eta +open ModularForm + theorem Summable_eta_q (z : ℍ) : Summable fun n : ℕ ↦ ‖-eta_q n z‖ := by simp_rw [eta_q, eta_q_eq_pow, norm_neg, norm_pow, summable_nat_add_iff 1] simp only [summable_geometric_iff_norm_lt_one, norm_norm] @@ -79,44 +78,32 @@ lemma qParam_ContDiff (n : ℝ) (m : WithTop ℕ∞) : ContDiff ℂ m (𝕢 n) : lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ηₚ {x | 0 < x.im} := by simp_rw [sub_eq_add_neg] - apply hasProdLocallyUniformlyOn_of_forall_compact (isOpen_lt continuous_const Complex.continuous_im) + apply hasProdLocallyUniformlyOn_of_forall_compact (isOpen_lt continuous_const continuous_im) intro K hK hcK by_cases hN : ¬ Nonempty K · rw [hasProdUniformlyOn_iff_tendstoUniformlyOn] simpa [not_nonempty_iff_eq_empty'.mp hN] using tendstoUniformlyOn_empty - have hc : ContinuousOn (fun x ↦ ‖cexp (2 * ↑π * Complex.I * x)‖) K := by fun_prop - obtain ⟨z, hz, hB, HB⟩ := IsCompact.exists_sSup_image_eq_and_ge hcK (by simpa using hN) hc - apply Summable.hasProdUniformlyOn_nat_one_add hcK (Summable_eta_q ⟨z, by simpa using (hK hz)⟩) - · filter_upwards with n x hx - simpa only [eta_q, eta_q_eq_pow n x, norm_neg, norm_pow, coe_mk_subtype, - eta_q_eq_pow n (⟨z, hK hz⟩ : ℍ)] using - pow_le_pow_left₀ (by simp [norm_nonneg]) (HB x hx) (n + 1) - · simp_rw [eta_q, Periodic.qParam] - fun_prop - -lemma tprod_ne_zero' {ι α : Type*} (x : α) (f : ι → α → ℂ) (hf : ∀ i x, 1 + f i x ≠ 0) - (hu : ∀ x : α, Summable fun n => f n x) : (∏' i : ι, (1 + f i) x) ≠ 0 := by - simp only [Pi.add_apply, Pi.one_apply, ne_eq] - rw [← Complex.cexp_tsum_eq_tprod (f := fun n => 1 + f n x) (fun n => hf n x)] - · simp only [exp_ne_zero, not_false_eq_true] - · exact Complex.summable_log_one_add_of_summable (hu x) + · have hc : ContinuousOn (fun x ↦ ‖cexp (2 * ↑π * Complex.I * x)‖) K := by fun_prop + obtain ⟨z, hz, hB, HB⟩ := IsCompact.exists_sSup_image_eq_and_ge hcK (by simpa using hN) hc + apply Summable.hasProdUniformlyOn_nat_one_add hcK (Summable_eta_q ⟨z, by simpa using (hK hz)⟩) + · filter_upwards with n x hx + simpa only [eta_q, eta_q_eq_pow n x, norm_neg, norm_pow, coe_mk_subtype, + eta_q_eq_pow n (⟨z, hK hz⟩ : ℍ)] using + pow_le_pow_left₀ (by simp [norm_nonneg]) (HB x hx) (n + 1) + · simp_rw [eta_q, Periodic.qParam] + fun_prop theorem etaProdTerm_ne_zero (z : ℍ) : ηₚ z ≠ 0 := by simp only [etaProdTerm, eta_q, ne_eq] - refine tprod_ne_zero' z (fun n x => -eta_q n x) ?_ ?_ + refine tprod_one_add_ne_zero_of_summable z (f := fun n x => -eta_q n x) ?_ ?_ · refine fun i x => by simpa using one_add_eta_q_ne_zero i x · intro x simpa [eta_q, ←summable_norm_iff] using Summable_eta_q x -/--Eta is non-vanishing!-/ -lemma eta_nonzero_on_UpperHalfPlane (z : ℍ) : η z ≠ 0 := by +/-- Eta is non-vanishing. -/ +lemma eta_ne_zero_on_UpperHalfPlane (z : ℍ) : η z ≠ 0 := by simpa [ModularForm.eta, Periodic.qParam] using etaProdTerm_ne_zero z -/- -lemma differentiable_eta_q (n : ℕ) : Differentiable ℂ (eta_q n) := by - rw [show eta_q n = fun x => -exp (2 * π * Complex.I * x) ^ (n + 1) by - ext z; exact eta_q_eq_pow n z] - fun_prop -/ lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = fun z ↦ -r * cexp z / (1 - r * cexp ( z)) := by @@ -131,20 +118,19 @@ lemma logDeriv_one_sub_mul_cexp_comp (r : ℂ) {g : ℂ → ℂ} (hg : Different ring -theorem one_add_eta_logDeriv_eq (z : ℂ) (i : ℕ) : - logDeriv (fun x ↦ 1 - eta_q i x) z = 2 * ↑π * Complex.I * (↑i + 1) * -eta_q i z / (1 - eta_q i z) := by +theorem one_add_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ↦ 1 - eta_q i x) z = + 2 * ↑π * Complex.I * (↑i + 1) * -eta_q i z / (1 - eta_q i z) := by have h2 : (fun x ↦ 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) = ((fun z ↦ 1 - 1 * cexp z) ∘ fun x ↦ 2 * ↑π * Complex.I * (↑i + 1) * x) := by aesop have h3 : deriv (fun x : ℂ ↦ (2 * π * Complex.I * (i + 1) * x)) = - fun _ ↦ 2 * π * Complex.I * (i + 1) := by - ext y - simpa using deriv_const_mul (2 * π * Complex.I * (i + 1)) (d := fun (x : ℂ) => x) (x := y) + fun _ ↦ 2 * π * Complex.I * (i + 1) := by + ext y + simpa using deriv_const_mul (2 * π * Complex.I * (i + 1)) (d := fun (x : ℂ) ↦ x) (x := y) simp_rw [eta_q_eq_exp, h2, logDeriv_one_sub_mul_cexp_comp 1 (g := fun x => (2 * π * Complex.I * (i + 1) * x)) (by fun_prop), h3] simp -lemma tsum_log_deriv_eta_q (z : ℂ) : - ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = +lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) := by refine tsum_congr (fun i => ?_) apply one_add_eta_logDeriv_eq @@ -174,7 +160,7 @@ lemma logDeriv_z_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * Comple simp [LogDeriv_exp] -theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ ↑z := by +theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ (isOpen_lt continuous_const Complex.continuous_im) · rw [DifferentiableOn] at hD @@ -187,7 +173,7 @@ theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ ↑z intro x hx simp [sub_eq_add_neg, eta_q_eq_exp] -lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta ↑z := by +lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := by apply DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) theorem logDeriv_tprod_eq_tsum {ι : Type*} {s : Set ℂ} (hs : IsOpen s) (x : s) {f : ι → ℂ → ℂ} From 64bf79fd36c10dafa463e9636ae1eb113b833c33 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 17:03:36 +0100 Subject: [PATCH 061/128] update --- Mathlib.lean | 2 + Mathlib/Analysis/Calculus/Deriv/Basic.lean | 6 +++ Mathlib/Analysis/Calculus/LogDeriv.lean | 47 ++++++++++++++++++- .../InfiniteSum/LogDerivUniformlyOn.lean | 33 +++++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4ba0541c1997a8..75ad952262ae43 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4721,6 +4721,7 @@ import Mathlib.NumberTheory.MaricaSchoenheim import Mathlib.NumberTheory.Modular import Mathlib.NumberTheory.ModularForms.Basic import Mathlib.NumberTheory.ModularForms.CongruenceSubgroups +import Mathlib.NumberTheory.ModularForms.DedekindEta import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Basic import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Defs import Mathlib.NumberTheory.ModularForms.EisensteinSeries.IsBoundedAtImInfty @@ -6170,6 +6171,7 @@ import Mathlib.Topology.Algebra.InfiniteSum.ENNReal import Mathlib.Topology.Algebra.InfiniteSum.Field import Mathlib.Topology.Algebra.InfiniteSum.Group import Mathlib.Topology.Algebra.InfiniteSum.GroupCompletion +import Mathlib.Topology.Algebra.InfiniteSum.LogDerivUniformlyOn import Mathlib.Topology.Algebra.InfiniteSum.Module import Mathlib.Topology.Algebra.InfiniteSum.NatInt import Mathlib.Topology.Algebra.InfiniteSum.Nonarchimedean diff --git a/Mathlib/Analysis/Calculus/Deriv/Basic.lean b/Mathlib/Analysis/Calculus/Deriv/Basic.lean index c47a1fa48f676d..a05a47c53c25b0 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Basic.lean @@ -593,6 +593,12 @@ theorem derivWithin_congr (hs : EqOn f₁ f s) (hx : f₁ x = f x) : unfold derivWithin rw [fderivWithin_congr hs hx] +lemma deriv_eqOn_congr {𝕜'} [NontriviallyNormedField 𝕜'] [NormedSpace 𝕜 𝕜'] {f g : 𝕜 → 𝕜'} + {s : Set 𝕜} (hfg : s.EqOn f g) (hs : IsOpen s) : s.EqOn (deriv f) ( deriv g) := by + intro x hx + rw [← derivWithin_of_isOpen hs hx, ← derivWithin_of_isOpen hs hx] + exact derivWithin_congr hfg (hfg hx) + theorem Filter.EventuallyEq.deriv_eq (hL : f₁ =ᶠ[𝓝 x] f) : deriv f₁ x = deriv f x := by unfold deriv rwa [Filter.EventuallyEq.fderiv_eq] diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index 79a2316decfc72..e4c1fba1cb69bd 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -4,6 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ import Mathlib.Analysis.Calculus.Deriv.ZPow +import Mathlib.Analysis.RCLike.Basic +import Mathlib.Analysis.Calculus.MeanValue /-! # Logarithmic Derivatives @@ -15,7 +17,7 @@ facts about this, including how it changes under multiplication and composition. noncomputable section -open Filter Function +open Filter Function Set open scoped Topology @@ -109,3 +111,46 @@ theorem logDeriv_comp {f : 𝕜' → 𝕜'} {g : 𝕜 → 𝕜'} {x : 𝕜} (hf (hg : DifferentiableAt 𝕜 g x) : logDeriv (f ∘ g) x = logDeriv f (g x) * deriv g x := by simp only [logDeriv, Pi.div_apply, deriv_comp _ hf hg, comp_apply] ring + +lemma logDeriv_eqOn_iff {E 𝕜 : Type*} [NontriviallyNormedField E] + [NontriviallyNormedField 𝕜] [IsRCLikeNormedField 𝕜] [NormedAlgebra 𝕜 E] [NormedSpace ℝ 𝕜] + {f g : 𝕜 → E} {s : Set 𝕜} (hf : DifferentiableOn 𝕜 f s) (hg : DifferentiableOn 𝕜 g s) + (hs2 : IsOpen s) (hsc : Convex ℝ s) (hgn : ∀ x, x ∈ s → g x ≠ 0) (hfn : ∀ x, x ∈ s → f x ≠ 0) : + EqOn (logDeriv f) (logDeriv g) s ↔ ∃ (z : E), z ≠ 0 ∧ s.EqOn f (z • g) := by + by_cases hs : s.Nonempty + constructor + · simp_rw [logDeriv] + intro h + obtain ⟨t, ht⟩ := hs + refine ⟨(f t) * (g t)⁻¹, mul_ne_zero (hfn t ht) (by simpa using (hgn t ht)), fun y hy => ?_⟩ + · have hderiv : s.EqOn (deriv (f * g⁻¹)) (deriv f * g⁻¹ - f * deriv g / g ^ 2) := by + intro z hz + rw [deriv_mul (hf.differentiableAt (hs2.mem_nhds hz)) ((hg.differentiableAt + (hs2.mem_nhds hz)).inv (hgn z hz))] + simp only [Pi.inv_apply, show g⁻¹ = (fun x => x⁻¹) ∘ g by rfl, deriv_inv, neg_mul, + deriv_comp z (differentiableAt_inv (hgn z hz)) (hg.differentiableAt (hs2.mem_nhds hz)), + mul_neg, Pi.sub_apply, Pi.mul_apply, comp_apply, Pi.div_apply, Pi.pow_apply] + ring + have H3 := Convex.is_const_of_fderivWithin_eq_zero (f := f * g⁻¹) (s := s) hsc + (hf.mul (DifferentiableOn.inv hg hgn)) ?_ hy ht + · simp only [Pi.mul_apply, Pi.inv_apply] at H3 + rw [← H3] + field_simp [hgn y hy] + · have he : s.EqOn (deriv f * g⁻¹ - f * deriv g / g ^ 2) 0 := by + intro z hz + field_simp [hgn z hz] + rw [pow_two, mul_comm, mul_assoc, ← mul_sub, mul_eq_zero] + right + have H := h hz + simp_rw [Pi.div_apply, div_eq_div_iff (hfn z hz) (hgn z hz), mul_comm] at H + simp [H] + intro v hv + have ha := he hv ▸ (hderiv hv) + simpa [fderivWithin_of_isOpen hs2 hv] using (ContinuousLinearMap.ext_ring ha) + · intro h + obtain ⟨z, hz0, hz⟩ := h + intro x hx + simp [logDeriv_apply, deriv_eqOn_congr hz hs2 hx, hz hx, deriv_const_smul _ + (hg.differentiableAt (hs2.mem_nhds hx)), mul_div_mul_left (deriv g x) (g x) hz0] + · simp only [not_nonempty_iff_eq_empty.mp hs, eqOn_empty, ne_eq, and_true, true_iff] + refine ⟨1, one_ne_zero⟩ diff --git a/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean new file mode 100644 index 00000000000000..a02c55d6fc059a --- /dev/null +++ b/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean @@ -0,0 +1,33 @@ +import Mathlib.Analysis.CStarAlgebra.Classes +import Mathlib.Analysis.Complex.LocallyUniformLimit +import Mathlib.Topology.Algebra.InfiniteSum.UniformOn + + +open TopologicalSpace Filter Complex Set Function + +theorem logDeriv_tprod_eq_tsum {ι : Type*} {s : Set ℂ} (hs : IsOpen s) {x : s} {f : ι → ℂ → ℂ} + (hf : ∀ i, f i x ≠ 0) (hd : ∀ i : ι, DifferentiableOn ℂ (f i) s) + (hm : Summable fun i ↦ logDeriv (f i) x) (htend : MultipliableLocallyUniformlyOn f s) + (hnez : ∏' (i : ι), f i x ≠ 0) : logDeriv (∏' i : ι, f i ·) x = ∑' i : ι, logDeriv (f i) x := by + apply symm + rw [← Summable.hasSum_iff hm, HasSum] + have := logDeriv_tendsto (f := fun (n : Finset ι) ↦ ∏ i ∈ n, (f i)) + (g := (∏' i : ι, f i ·)) (s := s) hs (p := atTop) + simp only [eventually_atTop, ge_iff_le, ne_eq, forall_exists_index, Subtype.forall] at this + conv => + enter [1] + ext n + rw [← logDeriv_prod _ _ _ (by intro i hi; apply hf i) + (by intro i hi; apply (hd i x x.2).differentiableAt; exact IsOpen.mem_nhds hs x.2)] + apply (this x x.2 ?_ ⊥ ?_ hnez).congr + · intro m + congr + aesop + · convert hasProdLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp + htend.hasProdLocallyUniformlyOn + simp + · intro b hb z hz + apply DifferentiableAt.differentiableWithinAt + have hp : ∀ (i : ι), i ∈ b → DifferentiableAt ℂ (f i) z := by + exact fun i hi ↦ (hd i z hz).differentiableAt (IsOpen.mem_nhds hs hz) + simpa using DifferentiableAt.finset_prod hp From f80072abb160270e88271956a29024e03fa67041 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 17:12:29 +0100 Subject: [PATCH 062/128] save --- .../ModularForms/DedekindEta.lean | 32 ++----------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 8742bcaffa936c..95af5b26243917 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -159,13 +159,12 @@ lemma logDeriv_z_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * Comple rw [this, logDeriv_comp (by fun_prop) (by fun_prop), deriv_const_mul _ (by fun_prop)] simp [LogDeriv_exp] - theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ (isOpen_lt continuous_const Complex.continuous_im) · rw [DifferentiableOn] at hD - apply (hD z (by apply z.2)).differentiableAt - · apply IsOpen.mem_nhds (isOpen_lt continuous_const Complex.continuous_im) z.2 + apply (hD z z.2).differentiableAt + · apply (isOpen_lt continuous_const Complex.continuous_im).mem_nhds z.2 · filter_upwards with b y apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x => 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) @@ -176,33 +175,6 @@ theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := by apply DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) -theorem logDeriv_tprod_eq_tsum {ι : Type*} {s : Set ℂ} (hs : IsOpen s) (x : s) {f : ι → ℂ → ℂ} - (hf : ∀ i, f i x ≠ 0) (hd : ∀ i : ι, DifferentiableOn ℂ (f i) s) - (hm : Summable fun i ↦ logDeriv (f i) ↑x) (htend : MultipliableLocallyUniformlyOn f s) - (hnez : ∏' (i : ι), f i x ≠ 0) : logDeriv (∏' i : ι, f i ·) x = ∑' i : ι, logDeriv (f i) x := by - apply symm - rw [← Summable.hasSum_iff hm, HasSum] - have := logDeriv_tendsto (f := fun (n : Finset ι) ↦ ∏ i ∈ n, (f i)) - (g := (∏' i : ι, f i ·)) (s := s) hs (p := atTop) - simp only [eventually_atTop, ge_iff_le, ne_eq, forall_exists_index, Subtype.forall] at this - conv => - enter [1] - ext n - rw [← logDeriv_prod _ _ _ (by intro i hi; apply hf i) - (by intro i hi; apply (hd i x x.2).differentiableAt; exact IsOpen.mem_nhds hs x.2)] - apply (this x x.2 ?_ ⊥ ?_ hnez).congr - · intro m - congr - aesop - · convert hasProdLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp - htend.hasProdLocallyUniformlyOn - simp - · intro b hb z hz - apply DifferentiableAt.differentiableWithinAt - have hp : ∀ (i : ι), i ∈ b → DifferentiableAt ℂ (f i) z := by - exact fun i hi ↦ (hd i z hz).differentiableAt (IsOpen.mem_nhds hs hz) - simpa using DifferentiableAt.finset_prod hp - /- lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E₂ z := by unfold ModularForm.eta etaProdTerm rw [logDeriv_mul (UpperHalfPlane.coe z) _ (etaProdTerm_ne_zero z) _ From c006f611d96927106594448b0ab6ac82432f9a68 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 17:16:01 +0100 Subject: [PATCH 063/128] open --- .../InfiniteSum/LogDerivUniformlyOn.lean | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean diff --git a/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean new file mode 100644 index 00000000000000..a02c55d6fc059a --- /dev/null +++ b/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean @@ -0,0 +1,33 @@ +import Mathlib.Analysis.CStarAlgebra.Classes +import Mathlib.Analysis.Complex.LocallyUniformLimit +import Mathlib.Topology.Algebra.InfiniteSum.UniformOn + + +open TopologicalSpace Filter Complex Set Function + +theorem logDeriv_tprod_eq_tsum {ι : Type*} {s : Set ℂ} (hs : IsOpen s) {x : s} {f : ι → ℂ → ℂ} + (hf : ∀ i, f i x ≠ 0) (hd : ∀ i : ι, DifferentiableOn ℂ (f i) s) + (hm : Summable fun i ↦ logDeriv (f i) x) (htend : MultipliableLocallyUniformlyOn f s) + (hnez : ∏' (i : ι), f i x ≠ 0) : logDeriv (∏' i : ι, f i ·) x = ∑' i : ι, logDeriv (f i) x := by + apply symm + rw [← Summable.hasSum_iff hm, HasSum] + have := logDeriv_tendsto (f := fun (n : Finset ι) ↦ ∏ i ∈ n, (f i)) + (g := (∏' i : ι, f i ·)) (s := s) hs (p := atTop) + simp only [eventually_atTop, ge_iff_le, ne_eq, forall_exists_index, Subtype.forall] at this + conv => + enter [1] + ext n + rw [← logDeriv_prod _ _ _ (by intro i hi; apply hf i) + (by intro i hi; apply (hd i x x.2).differentiableAt; exact IsOpen.mem_nhds hs x.2)] + apply (this x x.2 ?_ ⊥ ?_ hnez).congr + · intro m + congr + aesop + · convert hasProdLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp + htend.hasProdLocallyUniformlyOn + simp + · intro b hb z hz + apply DifferentiableAt.differentiableWithinAt + have hp : ∀ (i : ι), i ∈ b → DifferentiableAt ℂ (f i) z := by + exact fun i hi ↦ (hd i z hz).differentiableAt (IsOpen.mem_nhds hs hz) + simpa using DifferentiableAt.finset_prod hp From c35e7a3c343365b431b317580020841126f2f642 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 17:16:25 +0100 Subject: [PATCH 064/128] open --- Mathlib/Analysis/Calculus/LogDeriv.lean | 47 ++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index 79a2316decfc72..e4c1fba1cb69bd 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -4,6 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ import Mathlib.Analysis.Calculus.Deriv.ZPow +import Mathlib.Analysis.RCLike.Basic +import Mathlib.Analysis.Calculus.MeanValue /-! # Logarithmic Derivatives @@ -15,7 +17,7 @@ facts about this, including how it changes under multiplication and composition. noncomputable section -open Filter Function +open Filter Function Set open scoped Topology @@ -109,3 +111,46 @@ theorem logDeriv_comp {f : 𝕜' → 𝕜'} {g : 𝕜 → 𝕜'} {x : 𝕜} (hf (hg : DifferentiableAt 𝕜 g x) : logDeriv (f ∘ g) x = logDeriv f (g x) * deriv g x := by simp only [logDeriv, Pi.div_apply, deriv_comp _ hf hg, comp_apply] ring + +lemma logDeriv_eqOn_iff {E 𝕜 : Type*} [NontriviallyNormedField E] + [NontriviallyNormedField 𝕜] [IsRCLikeNormedField 𝕜] [NormedAlgebra 𝕜 E] [NormedSpace ℝ 𝕜] + {f g : 𝕜 → E} {s : Set 𝕜} (hf : DifferentiableOn 𝕜 f s) (hg : DifferentiableOn 𝕜 g s) + (hs2 : IsOpen s) (hsc : Convex ℝ s) (hgn : ∀ x, x ∈ s → g x ≠ 0) (hfn : ∀ x, x ∈ s → f x ≠ 0) : + EqOn (logDeriv f) (logDeriv g) s ↔ ∃ (z : E), z ≠ 0 ∧ s.EqOn f (z • g) := by + by_cases hs : s.Nonempty + constructor + · simp_rw [logDeriv] + intro h + obtain ⟨t, ht⟩ := hs + refine ⟨(f t) * (g t)⁻¹, mul_ne_zero (hfn t ht) (by simpa using (hgn t ht)), fun y hy => ?_⟩ + · have hderiv : s.EqOn (deriv (f * g⁻¹)) (deriv f * g⁻¹ - f * deriv g / g ^ 2) := by + intro z hz + rw [deriv_mul (hf.differentiableAt (hs2.mem_nhds hz)) ((hg.differentiableAt + (hs2.mem_nhds hz)).inv (hgn z hz))] + simp only [Pi.inv_apply, show g⁻¹ = (fun x => x⁻¹) ∘ g by rfl, deriv_inv, neg_mul, + deriv_comp z (differentiableAt_inv (hgn z hz)) (hg.differentiableAt (hs2.mem_nhds hz)), + mul_neg, Pi.sub_apply, Pi.mul_apply, comp_apply, Pi.div_apply, Pi.pow_apply] + ring + have H3 := Convex.is_const_of_fderivWithin_eq_zero (f := f * g⁻¹) (s := s) hsc + (hf.mul (DifferentiableOn.inv hg hgn)) ?_ hy ht + · simp only [Pi.mul_apply, Pi.inv_apply] at H3 + rw [← H3] + field_simp [hgn y hy] + · have he : s.EqOn (deriv f * g⁻¹ - f * deriv g / g ^ 2) 0 := by + intro z hz + field_simp [hgn z hz] + rw [pow_two, mul_comm, mul_assoc, ← mul_sub, mul_eq_zero] + right + have H := h hz + simp_rw [Pi.div_apply, div_eq_div_iff (hfn z hz) (hgn z hz), mul_comm] at H + simp [H] + intro v hv + have ha := he hv ▸ (hderiv hv) + simpa [fderivWithin_of_isOpen hs2 hv] using (ContinuousLinearMap.ext_ring ha) + · intro h + obtain ⟨z, hz0, hz⟩ := h + intro x hx + simp [logDeriv_apply, deriv_eqOn_congr hz hs2 hx, hz hx, deriv_const_smul _ + (hg.differentiableAt (hs2.mem_nhds hx)), mul_div_mul_left (deriv g x) (g x) hz0] + · simp only [not_nonempty_iff_eq_empty.mp hs, eqOn_empty, ne_eq, and_true, true_iff] + refine ⟨1, one_ne_zero⟩ From 62bae65dcabd5b39aff1cfe209bd394d6548f344 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 17:16:48 +0100 Subject: [PATCH 065/128] open --- Mathlib/Analysis/Calculus/Deriv/Basic.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/Analysis/Calculus/Deriv/Basic.lean b/Mathlib/Analysis/Calculus/Deriv/Basic.lean index c47a1fa48f676d..a05a47c53c25b0 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Basic.lean @@ -593,6 +593,12 @@ theorem derivWithin_congr (hs : EqOn f₁ f s) (hx : f₁ x = f x) : unfold derivWithin rw [fderivWithin_congr hs hx] +lemma deriv_eqOn_congr {𝕜'} [NontriviallyNormedField 𝕜'] [NormedSpace 𝕜 𝕜'] {f g : 𝕜 → 𝕜'} + {s : Set 𝕜} (hfg : s.EqOn f g) (hs : IsOpen s) : s.EqOn (deriv f) ( deriv g) := by + intro x hx + rw [← derivWithin_of_isOpen hs hx, ← derivWithin_of_isOpen hs hx] + exact derivWithin_congr hfg (hfg hx) + theorem Filter.EventuallyEq.deriv_eq (hL : f₁ =ᶠ[𝓝 x] f) : deriv f₁ x = deriv f x := by unfold deriv rwa [Filter.EventuallyEq.fderiv_eq] From 6c8f169796a92fc156a61930ff6f3c922f69e8d4 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 17:22:47 +0100 Subject: [PATCH 066/128] remove logderiv stuff --- Mathlib.lean | 1 - Mathlib/Analysis/Calculus/Deriv/Basic.lean | 6 --- Mathlib/Analysis/Calculus/LogDeriv.lean | 43 ------------------- .../InfiniteSum/LogDerivUniformlyOn.lean | 33 -------------- 4 files changed, 83 deletions(-) delete mode 100644 Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean diff --git a/Mathlib.lean b/Mathlib.lean index 75ad952262ae43..62850b9f33fd53 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6171,7 +6171,6 @@ import Mathlib.Topology.Algebra.InfiniteSum.ENNReal import Mathlib.Topology.Algebra.InfiniteSum.Field import Mathlib.Topology.Algebra.InfiniteSum.Group import Mathlib.Topology.Algebra.InfiniteSum.GroupCompletion -import Mathlib.Topology.Algebra.InfiniteSum.LogDerivUniformlyOn import Mathlib.Topology.Algebra.InfiniteSum.Module import Mathlib.Topology.Algebra.InfiniteSum.NatInt import Mathlib.Topology.Algebra.InfiniteSum.Nonarchimedean diff --git a/Mathlib/Analysis/Calculus/Deriv/Basic.lean b/Mathlib/Analysis/Calculus/Deriv/Basic.lean index a05a47c53c25b0..c47a1fa48f676d 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Basic.lean @@ -593,12 +593,6 @@ theorem derivWithin_congr (hs : EqOn f₁ f s) (hx : f₁ x = f x) : unfold derivWithin rw [fderivWithin_congr hs hx] -lemma deriv_eqOn_congr {𝕜'} [NontriviallyNormedField 𝕜'] [NormedSpace 𝕜 𝕜'] {f g : 𝕜 → 𝕜'} - {s : Set 𝕜} (hfg : s.EqOn f g) (hs : IsOpen s) : s.EqOn (deriv f) ( deriv g) := by - intro x hx - rw [← derivWithin_of_isOpen hs hx, ← derivWithin_of_isOpen hs hx] - exact derivWithin_congr hfg (hfg hx) - theorem Filter.EventuallyEq.deriv_eq (hL : f₁ =ᶠ[𝓝 x] f) : deriv f₁ x = deriv f x := by unfold deriv rwa [Filter.EventuallyEq.fderiv_eq] diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index e4c1fba1cb69bd..d065528de2cea3 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -111,46 +111,3 @@ theorem logDeriv_comp {f : 𝕜' → 𝕜'} {g : 𝕜 → 𝕜'} {x : 𝕜} (hf (hg : DifferentiableAt 𝕜 g x) : logDeriv (f ∘ g) x = logDeriv f (g x) * deriv g x := by simp only [logDeriv, Pi.div_apply, deriv_comp _ hf hg, comp_apply] ring - -lemma logDeriv_eqOn_iff {E 𝕜 : Type*} [NontriviallyNormedField E] - [NontriviallyNormedField 𝕜] [IsRCLikeNormedField 𝕜] [NormedAlgebra 𝕜 E] [NormedSpace ℝ 𝕜] - {f g : 𝕜 → E} {s : Set 𝕜} (hf : DifferentiableOn 𝕜 f s) (hg : DifferentiableOn 𝕜 g s) - (hs2 : IsOpen s) (hsc : Convex ℝ s) (hgn : ∀ x, x ∈ s → g x ≠ 0) (hfn : ∀ x, x ∈ s → f x ≠ 0) : - EqOn (logDeriv f) (logDeriv g) s ↔ ∃ (z : E), z ≠ 0 ∧ s.EqOn f (z • g) := by - by_cases hs : s.Nonempty - constructor - · simp_rw [logDeriv] - intro h - obtain ⟨t, ht⟩ := hs - refine ⟨(f t) * (g t)⁻¹, mul_ne_zero (hfn t ht) (by simpa using (hgn t ht)), fun y hy => ?_⟩ - · have hderiv : s.EqOn (deriv (f * g⁻¹)) (deriv f * g⁻¹ - f * deriv g / g ^ 2) := by - intro z hz - rw [deriv_mul (hf.differentiableAt (hs2.mem_nhds hz)) ((hg.differentiableAt - (hs2.mem_nhds hz)).inv (hgn z hz))] - simp only [Pi.inv_apply, show g⁻¹ = (fun x => x⁻¹) ∘ g by rfl, deriv_inv, neg_mul, - deriv_comp z (differentiableAt_inv (hgn z hz)) (hg.differentiableAt (hs2.mem_nhds hz)), - mul_neg, Pi.sub_apply, Pi.mul_apply, comp_apply, Pi.div_apply, Pi.pow_apply] - ring - have H3 := Convex.is_const_of_fderivWithin_eq_zero (f := f * g⁻¹) (s := s) hsc - (hf.mul (DifferentiableOn.inv hg hgn)) ?_ hy ht - · simp only [Pi.mul_apply, Pi.inv_apply] at H3 - rw [← H3] - field_simp [hgn y hy] - · have he : s.EqOn (deriv f * g⁻¹ - f * deriv g / g ^ 2) 0 := by - intro z hz - field_simp [hgn z hz] - rw [pow_two, mul_comm, mul_assoc, ← mul_sub, mul_eq_zero] - right - have H := h hz - simp_rw [Pi.div_apply, div_eq_div_iff (hfn z hz) (hgn z hz), mul_comm] at H - simp [H] - intro v hv - have ha := he hv ▸ (hderiv hv) - simpa [fderivWithin_of_isOpen hs2 hv] using (ContinuousLinearMap.ext_ring ha) - · intro h - obtain ⟨z, hz0, hz⟩ := h - intro x hx - simp [logDeriv_apply, deriv_eqOn_congr hz hs2 hx, hz hx, deriv_const_smul _ - (hg.differentiableAt (hs2.mem_nhds hx)), mul_div_mul_left (deriv g x) (g x) hz0] - · simp only [not_nonempty_iff_eq_empty.mp hs, eqOn_empty, ne_eq, and_true, true_iff] - refine ⟨1, one_ne_zero⟩ diff --git a/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean deleted file mode 100644 index a02c55d6fc059a..00000000000000 --- a/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean +++ /dev/null @@ -1,33 +0,0 @@ -import Mathlib.Analysis.CStarAlgebra.Classes -import Mathlib.Analysis.Complex.LocallyUniformLimit -import Mathlib.Topology.Algebra.InfiniteSum.UniformOn - - -open TopologicalSpace Filter Complex Set Function - -theorem logDeriv_tprod_eq_tsum {ι : Type*} {s : Set ℂ} (hs : IsOpen s) {x : s} {f : ι → ℂ → ℂ} - (hf : ∀ i, f i x ≠ 0) (hd : ∀ i : ι, DifferentiableOn ℂ (f i) s) - (hm : Summable fun i ↦ logDeriv (f i) x) (htend : MultipliableLocallyUniformlyOn f s) - (hnez : ∏' (i : ι), f i x ≠ 0) : logDeriv (∏' i : ι, f i ·) x = ∑' i : ι, logDeriv (f i) x := by - apply symm - rw [← Summable.hasSum_iff hm, HasSum] - have := logDeriv_tendsto (f := fun (n : Finset ι) ↦ ∏ i ∈ n, (f i)) - (g := (∏' i : ι, f i ·)) (s := s) hs (p := atTop) - simp only [eventually_atTop, ge_iff_le, ne_eq, forall_exists_index, Subtype.forall] at this - conv => - enter [1] - ext n - rw [← logDeriv_prod _ _ _ (by intro i hi; apply hf i) - (by intro i hi; apply (hd i x x.2).differentiableAt; exact IsOpen.mem_nhds hs x.2)] - apply (this x x.2 ?_ ⊥ ?_ hnez).congr - · intro m - congr - aesop - · convert hasProdLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp - htend.hasProdLocallyUniformlyOn - simp - · intro b hb z hz - apply DifferentiableAt.differentiableWithinAt - have hp : ∀ (i : ι), i ∈ b → DifferentiableAt ℂ (f i) z := by - exact fun i hi ↦ (hd i z hz).differentiableAt (IsOpen.mem_nhds hs hz) - simpa using DifferentiableAt.finset_prod hp From d0416ab8e1285fafa707effbc40f6ebad6eec143 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 17:23:28 +0100 Subject: [PATCH 067/128] remove logderiv stuff --- Mathlib/Analysis/Calculus/LogDeriv.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index d065528de2cea3..0fde1dc87234fd 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -17,7 +17,7 @@ facts about this, including how it changes under multiplication and composition. noncomputable section -open Filter Function Set +open Filter Function open scoped Topology From e7eed9123acece98b45e5692de55ed61eb773152 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 17:24:12 +0100 Subject: [PATCH 068/128] remove logderiv stuff --- Mathlib/Analysis/Calculus/LogDeriv.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index 0fde1dc87234fd..79a2316decfc72 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -4,8 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ import Mathlib.Analysis.Calculus.Deriv.ZPow -import Mathlib.Analysis.RCLike.Basic -import Mathlib.Analysis.Calculus.MeanValue /-! # Logarithmic Derivatives From abb1bf663c9e907a81aa3b55e993b94e601ee9ad Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 17:32:00 +0100 Subject: [PATCH 069/128] docs --- Mathlib/Analysis/Calculus/LogDeriv.lean | 1 - .../Algebra/InfiniteSum/LogDerivUniformlyOn.lean | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index e4c1fba1cb69bd..afa188861515f0 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ import Mathlib.Analysis.Calculus.Deriv.ZPow -import Mathlib.Analysis.RCLike.Basic import Mathlib.Analysis.Calculus.MeanValue /-! diff --git a/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean index a02c55d6fc059a..e18d851b6fd0d2 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean @@ -1,7 +1,21 @@ +/- +Copyright (c) 2025 Chris Birkbeck. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Birkbeck +-/ import Mathlib.Analysis.CStarAlgebra.Classes import Mathlib.Analysis.Complex.LocallyUniformLimit import Mathlib.Topology.Algebra.InfiniteSum.UniformOn +/-! +# The Logarithmic derivative of an infinite product + +We show that if we have an infinite product of functions `f` that is locally uniformly convergent, +then the logarithmic derivative of the product is the sum of the logarithmic derivatives of the +individual functions. + +-/ + open TopologicalSpace Filter Complex Set Function From 46f2afae9982361b20c9a81e8bb804dba12b69fa Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 18:31:28 +0100 Subject: [PATCH 070/128] remove stuff --- Mathlib/Analysis/Complex/Periodic.lean | 10 + .../ModularForms/DedekindEta.lean | 293 +++--------------- 2 files changed, 48 insertions(+), 255 deletions(-) diff --git a/Mathlib/Analysis/Complex/Periodic.lean b/Mathlib/Analysis/Complex/Periodic.lean index 89b4a25870dced..9ef59af5b1cb3e 100644 --- a/Mathlib/Analysis/Complex/Periodic.lean +++ b/Mathlib/Analysis/Complex/Periodic.lean @@ -72,6 +72,16 @@ theorem norm_qParam_lt_iff (hh : 0 < h) (A : ℝ) (z : ℂ) : rw [norm_qParam, Real.exp_lt_exp, div_lt_div_iff_of_pos_right hh, mul_lt_mul_left_of_neg] simpa using Real.pi_pos +@[fun_prop] +lemma qParam_differentiable (n : ℝ) : Differentiable ℂ (𝕢 n) := by + rw [show 𝕢 n = fun x => exp (2 * π * Complex.I * x / n) by rfl] + fun_prop + +@[fun_prop] +lemma qParam_ContDiff (n : ℝ) (m : WithTop ℕ∞) : ContDiff ℂ m (𝕢 n) := by + rw [show 𝕢 n = fun x => exp (2 * π * Complex.I * x / n) by rfl] + fun_prop + @[deprecated (since := "2025-02-17")] alias abs_qParam_lt_iff := norm_qParam_lt_iff theorem qParam_tendsto (hh : 0 < h) : Tendsto (qParam h) I∞ (𝓝[≠] 0) := by diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 95af5b26243917..d00bbfe6df2311 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -1,3 +1,9 @@ +/- +Copyright (c) 2024 Chris Birkbeck. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Birkbeck, David Loeffler +-/ + import Mathlib.Algebra.Order.Ring.Star import Mathlib.Analysis.CStarAlgebra.Classes import Mathlib.Analysis.Complex.LocallyUniformLimit @@ -5,6 +11,20 @@ import Mathlib.Analysis.Complex.UpperHalfPlane.Exp import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn import Mathlib.Data.Complex.FiniteDimensional +/-! +# Dedekind eta function + +## Main definitions + +* We define the Dedekind eta function as the infinite product + `η(z) = q^1/24 * ∏' (1 - q^n)` where `q = e^(2πiz)` and `z` is in the upper half-plane. + The product is taken over all non-negative integers `n`. We then show it is non-vanishing and + differentiable on the upper half-plane. + +## References +* [F. Diamond and J. Shurman, *A First Course in Modular Forms*][diamondshurman2005] +-/ + open UpperHalfPlane TopologicalSpace Set MeasureTheory intervalIntegral Metric Filter Function Complex @@ -14,33 +34,19 @@ open scoped Interval Real NNReal ENNReal Topology BigOperators Nat local notation "𝕢" => Periodic.qParam +/-- The q term inside the product defining the eta function. It is defined as +`eta_q n z = e ^ (2 π i (n + 1) z)`. -/ noncomputable abbrev eta_q (n : ℕ) (z : ℂ) := (𝕢 1 z) ^ (n + 1) -lemma eta_q_eq_exp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * (n + 1) * z) := by +lemma eta_q_eq_cexp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * (n + 1) * z) := by simp [eta_q, Periodic.qParam, ← Complex.exp_nsmul] ring_nf lemma eta_q_eq_pow (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * z) ^ (n + 1) := by simp [eta_q, Periodic.qParam] -theorem qParam_lt_one (z : ℍ) (r : ℝ) (hr : 0 < r) : - ‖𝕢 r z‖ < 1 := by - simp [Periodic.qParam, norm_exp, mul_re, re_ofNat, ofReal_re, im_ofNat, ofReal_im, mul_zero, - sub_zero, Complex.I_re, mul_im, zero_mul, add_zero, Complex.I_im, mul_one, sub_self, coe_re, - coe_im, zero_sub, Real.exp_lt_one_iff] - rw [neg_div, neg_lt_zero] - positivity - -lemma one_sub_qParam_ne_zero (r : ℝ) (hr : 0 < r) (z : ℍ) : 1 - 𝕢 r z ≠ 0 := by - rw [sub_ne_zero] - intro h - have := qParam_lt_one z r - rw [← h] at this - simp [lt_self_iff_false] at * - linarith - lemma one_add_eta_q_ne_zero (n : ℕ) (z : ℍ) : 1 - eta_q n z ≠ 0 := by - rw [eta_q_eq_exp, sub_ne_zero] + rw [eta_q_eq_cexp, sub_ne_zero] intro h have := UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨(n + 1) • z, by have : 0 < (n + 1 : ℝ) := by linarith @@ -49,11 +55,12 @@ lemma one_add_eta_q_ne_zero (n : ℕ) (z : ℍ) : 1 - eta_q n z ≠ 0 := by rw [← h] at this simp only [norm_one, lt_self_iff_false] at * +/-- The product term in the eta function, defined as `∏' 1 - q ^ n` for `q = e ^ 2 π i z`. -/ noncomputable abbrev etaProdTerm (z : ℂ) := ∏' (n : ℕ), (1 - eta_q n z) local notation "ηₚ" => etaProdTerm -/- The eta function. Best to define it on all of ℂ since we want to take its logDeriv. -/ +/- The eta function, whose value at z is `q^1/24 * ∏' 1 - q ^ n` for `q = e ^ 2 π i z`. -/ noncomputable def ModularForm.eta (z : ℂ) := (𝕢 24 z) * ηₚ z local notation "η" => ModularForm.eta @@ -65,18 +72,8 @@ theorem Summable_eta_q (z : ℍ) : Summable fun n : ℕ ↦ ‖-eta_q n z‖ := simp only [summable_geometric_iff_norm_lt_one, norm_norm] apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z -@[fun_prop] -lemma qParam_differentiable (n : ℝ) : Differentiable ℂ (𝕢 n) := by - rw [show 𝕢 n = fun x => exp (2 * π * Complex.I * x / n) by rfl] - fun_prop - -@[fun_prop] -lemma qParam_ContDiff (n : ℝ) (m : WithTop ℕ∞) : ContDiff ℂ m (𝕢 n) := by - rw [show 𝕢 n = fun x => exp (2 * π * Complex.I * x / n) by rfl] - fun_prop - -lemma hasProdLocallyUniformlyOn_eta : - HasProdLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ηₚ {x | 0 < x.im} := by +lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ηₚ + {x | 0 < x.im} := by simp_rw [sub_eq_add_neg] apply hasProdLocallyUniformlyOn_of_forall_compact (isOpen_lt continuous_const continuous_im) intro K hK hcK @@ -104,7 +101,6 @@ theorem etaProdTerm_ne_zero (z : ℍ) : ηₚ z ≠ 0 := by lemma eta_ne_zero_on_UpperHalfPlane (z : ℍ) : η z ≠ 0 := by simpa [ModularForm.eta, Periodic.qParam] using etaProdTerm_ne_zero z - lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = fun z ↦ -r * cexp z / (1 - r * cexp ( z)) := by ext z @@ -117,7 +113,6 @@ lemma logDeriv_one_sub_mul_cexp_comp (r : ℂ) {g : ℂ → ℂ} (hg : Different rw [logDeriv_comp (by fun_prop) (hg y), logDeriv_one_sub_cexp] ring - theorem one_add_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ↦ 1 - eta_q i x) z = 2 * ↑π * Complex.I * (↑i + 1) * -eta_q i z / (1 - eta_q i z) := by have h2 : (fun x ↦ 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) = @@ -126,245 +121,33 @@ theorem one_add_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ↦ 1 - et fun _ ↦ 2 * π * Complex.I * (i + 1) := by ext y simpa using deriv_const_mul (2 * π * Complex.I * (i + 1)) (d := fun (x : ℂ) ↦ x) (x := y) - simp_rw [eta_q_eq_exp, h2, logDeriv_one_sub_mul_cexp_comp 1 + simp_rw [eta_q_eq_cexp, h2, logDeriv_one_sub_mul_cexp_comp 1 (g := fun x => (2 * π * Complex.I * (i + 1) * x)) (by fun_prop), h3] simp lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) := by + (2 * ↑π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by + suffices ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = + ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by + rw [this, ← tsum_mul_left] + congr 1 + ext i + ring refine tsum_congr (fun i => ?_) apply one_add_eta_logDeriv_eq -lemma tsum_log_deriv_eta_q' (z : ℂ) : - ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - (2 * ↑π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by - rw [tsum_log_deriv_eta_q z, ← tsum_mul_left] - congr 1 - ext i - ring - -lemma logDeriv_q (n : ℝ) (z : ℂ) : logDeriv (𝕢 n) z = 2 * ↑π * Complex.I / n := by - have : (𝕢 n) = (fun z ↦ cexp (z)) ∘ (fun z => (2 * ↑π * Complex.I / n) * z) := by - ext y - simp only [Periodic.qParam, comp_apply] - ring_nf - rw [this, logDeriv_comp (by fun_prop) (by fun_prop), deriv_const_mul _ (by fun_prop)] - simp [LogDeriv_exp] - -lemma logDeriv_z_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * Complex.I / 24 := by - have : (𝕢 24) = (fun z ↦ cexp (z)) ∘ (fun z => (2 * ↑π * Complex.I / 24) * z) := by - ext y - simp only [Periodic.qParam, ofReal_ofNat, comp_apply] - ring_nf - rw [this, logDeriv_comp (by fun_prop) (by fun_prop), deriv_const_mul _ (by fun_prop)] - simp [LogDeriv_exp] - theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ (isOpen_lt continuous_const Complex.continuous_im) · rw [DifferentiableOn] at hD apply (hD z z.2).differentiableAt - · apply (isOpen_lt continuous_const Complex.continuous_im).mem_nhds z.2 + exact (isOpen_lt continuous_const Complex.continuous_im).mem_nhds z.2 · filter_upwards with b y apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x => 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) (by fun_prop)).congr intro x hx - simp [sub_eq_add_neg, eta_q_eq_exp] + simp [sub_eq_add_neg, eta_q_eq_cexp] lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := by apply DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) - -/- lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E₂ z := by - unfold ModularForm.eta etaProdTerm - rw [logDeriv_mul (UpperHalfPlane.coe z) _ (etaProdTerm_ne_zero z) _ - (etaProdTerm_differentiableAt z)] - · have HG := logDeriv_tprod_eq_tsum (isOpen_lt continuous_const Complex.continuous_im) z - (fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) ?_ ?_ ?_ (etaProdTerm_ne_zero z) - rw [show z.1 = UpperHalfPlane.coe z by rfl] at HG - rw [HG] - · simp only [tsum_log_deriv_eta_q' z, E₂, logDeriv_z_term z, mul_neg, one_div, mul_inv_rev, Pi.smul_apply, smul_eq_mul] - rw [G2_q_exp'', riemannZeta_two, ← (tsum_eq_tsum_sigma_pos'' z), mul_sub, sub_eq_add_neg, mul_add] - conv => - enter [1,2,2,1] - ext n - rw [neg_div, neg_eq_neg_one_mul] - rw [tsum_mul_left] - have hpi : (π : ℂ) ≠ 0 := by simpa using Real.pi_ne_zero - congr 1 - · ring_nf - field_simp - ring - · field_simp - ring_nf - congr - ext n - ring_nf - · intro i x hx - simp_rw [eta_q_eq_exp] - fun_prop - · simp only [mem_setOf_eq, one_add_eta_logDeriv_eq] - apply ((summable_nat_add_iff 1).mpr ((logDeriv_q_expo_summable (𝕢₁ z) - (by simpa [Periodic.qParam] using exp_upperHalfPlane_lt_one z)).mul_left (-2 * π * Complex.I))).congr - intro b - have := one_add_eta_q_ne_zero b z - simp only [UpperHalfPlane.coe, ne_eq, neg_mul, Nat.cast_add, Nat.cast_one, mul_neg] at * - field_simp - left - ring - · use ηₚ - apply (hasProdLocallyUniformlyOn_eta).congr - exact fun n ⦃x⦄ hx ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, (fun n a ↦ 1 - eta_q n a) i b) x) - · simp [ne_eq, exp_ne_zero, not_false_eq_true, Periodic.qParam] - · fun_prop -/ - -/- lemma eta_logDeriv_eql (z : ℍ) : (logDeriv (η ∘ (fun z : ℂ => -1/z))) z = - (logDeriv ((csqrt) * η)) z := by - have h0 : (logDeriv (η ∘ (fun z : ℂ => -1/z))) z = ((z :ℂ)^(2 : ℤ))⁻¹ * (logDeriv η) (⟨-1 / z, by simpa using pnat_div_upper 1 z⟩ : ℍ) := by - rw [logDeriv_comp, mul_comm] - congr - conv => - enter [1,1] - intro z - rw [neg_div] - simp - simp only [deriv.fun_neg', deriv_inv', neg_neg, inv_inj] - norm_cast - · simpa only using - eta_DifferentiableAt_UpperHalfPlane (⟨-1 / z, by simpa using pnat_div_upper 1 z⟩ : ℍ) - conv => - enter [2] - ext z - rw [neg_div] - simp - apply DifferentiableAt.neg - apply DifferentiableAt.inv - simp only [differentiableAt_fun_id] - exact ne_zero z - rw [h0, show ((csqrt) * η) = (fun x => (csqrt) x * η x) by rfl, logDeriv_mul] - nth_rw 2 [logDeriv_apply] - unfold csqrt - have := csqrt_deriv z - rw [this] - simp only [one_div, neg_mul, smul_eq_mul] - nth_rw 2 [div_eq_mul_inv] - rw [← Complex.exp_neg, show 2⁻¹ * cexp (-(2⁻¹ * Complex.log ↑z)) * cexp (-(2⁻¹ * Complex.log ↑z)) = - (cexp (-(2⁻¹ * Complex.log ↑z)) * cexp (-(2⁻¹ * Complex.log ↑z)))* 2⁻¹ by ring, ← Complex.exp_add, - ← sub_eq_add_neg, show -(2⁻¹ * Complex.log ↑z) - 2⁻¹ * Complex.log ↑z = -Complex.log ↑z by ring, Complex.exp_neg, Complex.exp_log, eta_logDeriv z] - have Rb := eta_logDeriv (⟨-1 / z, by simpa using pnat_div_upper 1 z⟩ : ℍ) - simp only [coe_mk_subtype] at Rb - rw [Rb] - have E := E₂_transform z - simp only [one_div, neg_mul, smul_eq_mul, SL_slash_def, - modular_S_smul, - ModularGroup.denom_S, Int.reduceNeg, zpow_neg] at * - have h00 : (UpperHalfPlane.mk (-z : ℂ)⁻¹ z.im_inv_neg_coe_pos) = (⟨-1 / z, by simpa using pnat_div_upper 1 z⟩ : ℍ) := by - simp [UpperHalfPlane.mk] - ring_nf - rw [h00] at E - rw [← mul_assoc, mul_comm, ← mul_assoc] - simp only [UpperHalfPlane.coe] at * - rw [E, add_mul, add_comm] - congr 1 - have hzne := ne_zero z - have hI : Complex.I ≠ 0 := by - exact I_ne_zero - have hpi : (π : ℂ) ≠ 0 := by - simp only [ne_eq, ofReal_eq_zero] - exact Real.pi_ne_zero - simp [UpperHalfPlane.coe] at hzne ⊢ - field_simp - ring - rw [mul_comm] - · simpa only [UpperHalfPlane.coe, ne_eq] using (ne_zero z) - · simp only [csqrt, one_div, ne_eq, Complex.exp_ne_zero, not_false_eq_true] - · apply eta_nonzero_on_UpperHalfPlane z - · unfold csqrt - rw [show (fun a ↦ cexp (1 / 2 * Complex.log a)) = cexp ∘ (fun a ↦ 1 / 2 * Complex.log a) by rfl] - apply DifferentiableAt.comp - simp - apply DifferentiableAt.const_mul - apply Complex.differentiableAt_log - rw [@mem_slitPlane_iff] - right - have hz := z.2 - simp at hz - exact Ne.symm (ne_of_lt hz) - · apply eta_DifferentiableAt_UpperHalfPlane z - -lemma eta_logderivs : {z : ℂ | 0 < z.im}.EqOn (logDeriv (η ∘ (fun z : ℂ => -1/z))) - (logDeriv ((csqrt) * η)) := by - intro z hz - have := eta_logDeriv_eql ⟨z, hz⟩ - exact this - -lemma eta_logderivs_const : ∃ z : ℂ, z ≠ 0 ∧ {z : ℂ | 0 < z.im}.EqOn ((η ∘ (fun z : ℂ => -1/z))) - (z • ((csqrt) * η)) := by - have h := eta_logderivs - rw [logDeriv_eqOn_iff] at h - · exact h - · apply DifferentiableOn.comp - pick_goal 4 - · use ({z : ℂ | 0 < z.im}) - · rw [DifferentiableOn] - intro x hx - apply DifferentiableAt.differentiableWithinAt - apply eta_DifferentiableAt_UpperHalfPlane ⟨x, hx⟩ - · apply DifferentiableOn.div - fun_prop - fun_prop - intro x hx - have hx2 := ne_zero (⟨x, hx⟩ : ℍ) - norm_cast at * - · intro y hy - simp - have := UpperHalfPlane.im_inv_neg_coe_pos (⟨y, hy⟩ : ℍ) - conv => - enter [2,1] - rw [neg_div] - rw [div_eq_mul_inv] - simp - simp at * - exact this - · apply DifferentiableOn.mul - simp only [DifferentiableOn, mem_setOf_eq] - intro x hx - apply (csqrt_differentiableAt ⟨x, hx⟩).differentiableWithinAt - simp only [DifferentiableOn, mem_setOf_eq] - intro x hx - apply (eta_DifferentiableAt_UpperHalfPlane ⟨x, hx⟩).differentiableWithinAt - · use UpperHalfPlane.I - simp only [coe_I, mem_setOf_eq, Complex.I_im, zero_lt_one] - · exact isOpen_lt continuous_const Complex.continuous_im - · exact convex_halfSpace_im_gt 0 - · intro x hx - simp only [Pi.mul_apply, ne_eq, mul_eq_zero, not_or] - refine ⟨ ?_ , by apply eta_nonzero_on_UpperHalfPlane ⟨x, hx⟩⟩ - unfold csqrt - simp only [one_div, Complex.exp_ne_zero, not_false_eq_true] - · intro x hx - simp only [comp_apply, ne_eq] - have := eta_nonzero_on_UpperHalfPlane ⟨-1 / x, by simpa using pnat_div_upper 1 ⟨x, hx⟩⟩ - simpa only [ne_eq, coe_mk_subtype] using this - -lemma eta_equality : {z : ℂ | 0 < z.im}.EqOn ((η ∘ (fun z : ℂ => -1/z))) - ((csqrt (Complex.I))⁻¹ • ((csqrt) * η)) := by - have h := eta_logderivs_const - obtain ⟨z, hz, h⟩ := h - intro x hx - have h2 := h hx - have hI : (Complex.I) ∈ {z : ℂ | 0 < z.im} := by - simp only [mem_setOf_eq, Complex.I_im, zero_lt_one] - have h3 := h hI - simp at h3 - conv at h3 => - enter [2] - rw [← mul_assoc] - have he : η Complex.I ≠ 0 := by - have h:= eta_nonzero_on_UpperHalfPlane UpperHalfPlane.I - convert h - have hcd := (mul_eq_right₀ he).mp (_root_.id (Eq.symm h3)) - rw [mul_eq_one_iff_inv_eq₀ hz] at hcd - rw [@inv_eq_iff_eq_inv] at hcd - rw [hcd] at h2 - exact h2 -/ From 4ed6485322298f42831bec514bbaf68ba018630e Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 18:45:36 +0100 Subject: [PATCH 071/128] save --- .../ModularForms/DedekindEta.lean | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index d00bbfe6df2311..9a71bbd5633823 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -51,17 +51,15 @@ lemma one_add_eta_q_ne_zero (n : ℕ) (z : ℍ) : 1 - eta_q n z ≠ 0 := by have := UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨(n + 1) • z, by have : 0 < (n + 1 : ℝ) := by linarith simpa [this] using z.2⟩ - simp [← mul_assoc] at this - rw [← h] at this - simp only [norm_one, lt_self_iff_false] at * + simp [← mul_assoc, ← h] at * -/-- The product term in the eta function, defined as `∏' 1 - q ^ n` for `q = e ^ 2 π i z`. -/ +/-- The product term in the eta function, defined as `∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. -/ noncomputable abbrev etaProdTerm (z : ℂ) := ∏' (n : ℕ), (1 - eta_q n z) local notation "ηₚ" => etaProdTerm -/- The eta function, whose value at z is `q^1/24 * ∏' 1 - q ^ n` for `q = e ^ 2 π i z`. -/ -noncomputable def ModularForm.eta (z : ℂ) := (𝕢 24 z) * ηₚ z +/- The eta function, whose value at z is `q^1/24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. -/ +noncomputable def ModularForm.eta (z : ℂ) := 𝕢 24 z * ηₚ z local notation "η" => ModularForm.eta @@ -95,7 +93,7 @@ theorem etaProdTerm_ne_zero (z : ℍ) : ηₚ z ≠ 0 := by refine tprod_one_add_ne_zero_of_summable z (f := fun n x => -eta_q n x) ?_ ?_ · refine fun i x => by simpa using one_add_eta_q_ne_zero i x · intro x - simpa [eta_q, ←summable_norm_iff] using Summable_eta_q x + simpa [eta_q, ← summable_norm_iff] using Summable_eta_q x /-- Eta is non-vanishing. -/ lemma eta_ne_zero_on_UpperHalfPlane (z : ℍ) : η z ≠ 0 := by @@ -139,8 +137,7 @@ lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - e theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ (isOpen_lt continuous_const Complex.continuous_im) - · rw [DifferentiableOn] at hD - apply (hD z z.2).differentiableAt + · apply (hD z z.2).differentiableAt exact (isOpen_lt continuous_const Complex.continuous_im).mem_nhds z.2 · filter_upwards with b y apply (DifferentiableOn.finset_prod (u := Finset.range b) @@ -149,5 +146,5 @@ theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := intro x hx simp [sub_eq_add_neg, eta_q_eq_cexp] -lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := by - apply DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) +lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := + DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) From 07bb88d435a9007fe270156b4d92fbcece47affe Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 18:56:43 +0100 Subject: [PATCH 072/128] update with complexupperhalfplane --- Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean | 11 +++++++++++ Mathlib/NumberTheory/ModularForms/DedekindEta.lean | 14 +++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index 04ea612c3dd435..f5c194a02ece9a 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -203,5 +203,16 @@ theorem vadd_im : (x +ᵥ z).im = z.im := zero_add _ end RealAddAction +section complexUpperHalfPlane + +/-- The UpperHalfPlane as a subset of `ℂ`. This is convinient for takind derivatives of functions +on the upper half plane. -/ +abbrev complexUpperHalfPlane := {z : ℂ | 0 < z.im} + +local notation "ℍₒ" => complexUpperHalfPlane + +lemma complexUpperHalPlane_isOpen : IsOpen ℍₒ := (isOpen_lt continuous_const Complex.continuous_im) + +end complexUpperHalfPlane end UpperHalfPlane diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 9a71bbd5633823..65e84015661767 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -31,9 +31,10 @@ open UpperHalfPlane TopologicalSpace Set MeasureTheory intervalIntegral open scoped Interval Real NNReal ENNReal Topology BigOperators Nat - local notation "𝕢" => Periodic.qParam +local notation "ℍₒ" => complexUpperHalfPlane + /-- The q term inside the product defining the eta function. It is defined as `eta_q n z = e ^ (2 π i (n + 1) z)`. -/ noncomputable abbrev eta_q (n : ℕ) (z : ℂ) := (𝕢 1 z) ^ (n + 1) @@ -68,12 +69,11 @@ open ModularForm theorem Summable_eta_q (z : ℍ) : Summable fun n : ℕ ↦ ‖-eta_q n z‖ := by simp_rw [eta_q, eta_q_eq_pow, norm_neg, norm_pow, summable_nat_add_iff 1] simp only [summable_geometric_iff_norm_lt_one, norm_norm] - apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z + apply norm_exp_two_pi_I_lt_one z -lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ηₚ - {x | 0 < x.im} := by +lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ηₚ ℍₒ:= by simp_rw [sub_eq_add_neg] - apply hasProdLocallyUniformlyOn_of_forall_compact (isOpen_lt continuous_const continuous_im) + apply hasProdLocallyUniformlyOn_of_forall_compact complexUpperHalPlane_isOpen intro K hK hcK by_cases hN : ¬ Nonempty K · rw [hasProdUniformlyOn_iff_tendstoUniformlyOn] @@ -136,9 +136,9 @@ lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - e theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ - (isOpen_lt continuous_const Complex.continuous_im) + complexUpperHalPlane_isOpen · apply (hD z z.2).differentiableAt - exact (isOpen_lt continuous_const Complex.continuous_im).mem_nhds z.2 + exact (complexUpperHalPlane_isOpen).mem_nhds z.2 · filter_upwards with b y apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x => 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) From 6ed01baf64abc0d13e5d36d242d56c15cbbf98a9 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 19:09:25 +0100 Subject: [PATCH 073/128] clean --- .../ModularForms/DedekindEta.lean | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 65e84015661767..9543d46d0b74e8 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -17,15 +17,14 @@ import Mathlib.Data.Complex.FiniteDimensional ## Main definitions * We define the Dedekind eta function as the infinite product - `η(z) = q^1/24 * ∏' (1 - q^n)` where `q = e^(2πiz)` and `z` is in the upper half-plane. - The product is taken over all non-negative integers `n`. We then show it is non-vanishing and - differentiable on the upper half-plane. +`η(z) = q ^ 1/24 * ∏' (1 - q ^ (n + 1))` where `q = e ^ (2πiz)` and `z` is in the upper half-plane. +The product is taken over all non-negative integers `n`. We then show it is non-vanishing and +differentiable on the upper half-plane. ## References * [F. Diamond and J. Shurman, *A First Course in Modular Forms*][diamondshurman2005] -/ - open UpperHalfPlane TopologicalSpace Set MeasureTheory intervalIntegral Metric Filter Function Complex @@ -49,7 +48,7 @@ lemma eta_q_eq_pow (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * lemma one_add_eta_q_ne_zero (n : ℕ) (z : ℍ) : 1 - eta_q n z ≠ 0 := by rw [eta_q_eq_cexp, sub_ne_zero] intro h - have := UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨(n + 1) • z, by + have := norm_exp_two_pi_I_lt_one ⟨(n + 1) • z, by have : 0 < (n + 1 : ℝ) := by linarith simpa [this] using z.2⟩ simp [← mul_assoc, ← h] at * @@ -59,14 +58,14 @@ noncomputable abbrev etaProdTerm (z : ℂ) := ∏' (n : ℕ), (1 - eta_q n z) local notation "ηₚ" => etaProdTerm -/- The eta function, whose value at z is `q^1/24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. -/ +/-- The eta function, whose value at z is `q^1/24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. -/ noncomputable def ModularForm.eta (z : ℂ) := 𝕢 24 z * ηₚ z local notation "η" => ModularForm.eta open ModularForm -theorem Summable_eta_q (z : ℍ) : Summable fun n : ℕ ↦ ‖-eta_q n z‖ := by +theorem Summable_eta_q (z : ℍ) : Summable fun n ↦ ‖-eta_q n z‖ := by simp_rw [eta_q, eta_q_eq_pow, norm_neg, norm_pow, summable_nat_add_iff 1] simp only [summable_geometric_iff_norm_lt_one, norm_norm] apply norm_exp_two_pi_I_lt_one z @@ -78,9 +77,9 @@ lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - by_cases hN : ¬ Nonempty K · rw [hasProdUniformlyOn_iff_tendstoUniformlyOn] simpa [not_nonempty_iff_eq_empty'.mp hN] using tendstoUniformlyOn_empty - · have hc : ContinuousOn (fun x ↦ ‖cexp (2 * ↑π * Complex.I * x)‖) K := by fun_prop - obtain ⟨z, hz, hB, HB⟩ := IsCompact.exists_sSup_image_eq_and_ge hcK (by simpa using hN) hc - apply Summable.hasProdUniformlyOn_nat_one_add hcK (Summable_eta_q ⟨z, by simpa using (hK hz)⟩) + · have hc : ContinuousOn (fun x ↦ ‖cexp (2 * π * Complex.I * x)‖) K := by fun_prop + obtain ⟨z, hz, hB, HB⟩ := hcK.exists_sSup_image_eq_and_ge (by simpa using hN) hc + apply (Summable_eta_q ⟨z, by simpa using (hK hz)⟩).hasProdUniformlyOn_nat_one_add hcK · filter_upwards with n x hx simpa only [eta_q, eta_q_eq_pow n x, norm_neg, norm_pow, coe_mk_subtype, eta_q_eq_pow n (⟨z, hK hz⟩ : ℍ)] using @@ -95,7 +94,7 @@ theorem etaProdTerm_ne_zero (z : ℍ) : ηₚ z ≠ 0 := by · intro x simpa [eta_q, ← summable_norm_iff] using Summable_eta_q x -/-- Eta is non-vanishing. -/ +/-- Eta is non-vanishing on the upper half plane. -/ lemma eta_ne_zero_on_UpperHalfPlane (z : ℍ) : η z ≠ 0 := by simpa [ModularForm.eta, Periodic.qParam] using etaProdTerm_ne_zero z @@ -111,8 +110,8 @@ lemma logDeriv_one_sub_mul_cexp_comp (r : ℂ) {g : ℂ → ℂ} (hg : Different rw [logDeriv_comp (by fun_prop) (hg y), logDeriv_one_sub_cexp] ring -theorem one_add_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ↦ 1 - eta_q i x) z = - 2 * ↑π * Complex.I * (↑i + 1) * -eta_q i z / (1 - eta_q i z) := by +private theorem one_sub_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ↦ 1 - eta_q i x) z = + 2 * π * Complex.I * (i + 1) * -eta_q i z / (1 - eta_q i z) := by have h2 : (fun x ↦ 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) = ((fun z ↦ 1 - 1 * cexp z) ∘ fun x ↦ 2 * ↑π * Complex.I * (↑i + 1) * x) := by aesop have h3 : deriv (fun x : ℂ ↦ (2 * π * Complex.I * (i + 1) * x)) = @@ -124,27 +123,23 @@ theorem one_add_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ↦ 1 - et simp lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - (2 * ↑π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by + (2 * π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by suffices ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by rw [this, ← tsum_mul_left] congr 1 ext i ring - refine tsum_congr (fun i => ?_) - apply one_add_eta_logDeriv_eq + exact tsum_congr (fun i => one_sub_eta_logDeriv_eq z i) theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ complexUpperHalPlane_isOpen - · apply (hD z z.2).differentiableAt - exact (complexUpperHalPlane_isOpen).mem_nhds z.2 + · exact (hD z z.2).differentiableAt (complexUpperHalPlane_isOpen.mem_nhds z.2) · filter_upwards with b y - apply (DifferentiableOn.finset_prod (u := Finset.range b) - (f := fun i x => 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) + apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x => 1 - eta_q i x) (by fun_prop)).congr - intro x hx - simp [sub_eq_add_neg, eta_q_eq_cexp] + simp lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) From 0804f629aa77a1c9b3ab721d67177745a11c8549 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 19:13:28 +0100 Subject: [PATCH 074/128] clean more --- Mathlib/NumberTheory/ModularForms/DedekindEta.lean | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 9543d46d0b74e8..cc1e920ce8908c 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -74,11 +74,9 @@ lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - simp_rw [sub_eq_add_neg] apply hasProdLocallyUniformlyOn_of_forall_compact complexUpperHalPlane_isOpen intro K hK hcK - by_cases hN : ¬ Nonempty K - · rw [hasProdUniformlyOn_iff_tendstoUniformlyOn] - simpa [not_nonempty_iff_eq_empty'.mp hN] using tendstoUniformlyOn_empty + by_cases hN : K.Nonempty · have hc : ContinuousOn (fun x ↦ ‖cexp (2 * π * Complex.I * x)‖) K := by fun_prop - obtain ⟨z, hz, hB, HB⟩ := hcK.exists_sSup_image_eq_and_ge (by simpa using hN) hc + obtain ⟨z, hz, hB, HB⟩ := hcK.exists_sSup_image_eq_and_ge hN hc apply (Summable_eta_q ⟨z, by simpa using (hK hz)⟩).hasProdUniformlyOn_nat_one_add hcK · filter_upwards with n x hx simpa only [eta_q, eta_q_eq_pow n x, norm_neg, norm_pow, coe_mk_subtype, @@ -86,6 +84,8 @@ lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - pow_le_pow_left₀ (by simp [norm_nonneg]) (HB x hx) (n + 1) · simp_rw [eta_q, Periodic.qParam] fun_prop + · rw [hasProdUniformlyOn_iff_tendstoUniformlyOn] + simpa [not_nonempty_iff_eq_empty.mp hN] using tendstoUniformlyOn_empty theorem etaProdTerm_ne_zero (z : ℍ) : ηₚ z ≠ 0 := by simp only [etaProdTerm, eta_q, ne_eq] @@ -123,9 +123,9 @@ private theorem one_sub_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x simp lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - (2 * π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by + (2 * π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by suffices ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by + ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by rw [this, ← tsum_mul_left] congr 1 ext i From 7266763893ebde34d9ac21764a946ef46ea18d1c Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 19:13:37 +0100 Subject: [PATCH 075/128] clean more --- Mathlib/NumberTheory/ModularForms/DedekindEta.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index cc1e920ce8908c..271aa4147b51cf 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -25,8 +25,8 @@ differentiable on the upper half-plane. * [F. Diamond and J. Shurman, *A First Course in Modular Forms*][diamondshurman2005] -/ -open UpperHalfPlane TopologicalSpace Set MeasureTheory intervalIntegral - Metric Filter Function Complex +open UpperHalfPlane TopologicalSpace Set MeasureTheory intervalIntegral + Metric Filter Function Complex open scoped Interval Real NNReal ENNReal Topology BigOperators Nat From 8a1fb213b8d82e51f257680d04d112c5e847045e Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 19:16:05 +0100 Subject: [PATCH 076/128] mk_all --- Mathlib.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib.lean b/Mathlib.lean index 4ba0541c1997a8..91ec3ec0cb80c3 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -6170,6 +6170,7 @@ import Mathlib.Topology.Algebra.InfiniteSum.ENNReal import Mathlib.Topology.Algebra.InfiniteSum.Field import Mathlib.Topology.Algebra.InfiniteSum.Group import Mathlib.Topology.Algebra.InfiniteSum.GroupCompletion +import Mathlib.Topology.Algebra.InfiniteSum.LogDerivUniformlyOn import Mathlib.Topology.Algebra.InfiniteSum.Module import Mathlib.Topology.Algebra.InfiniteSum.NatInt import Mathlib.Topology.Algebra.InfiniteSum.Nonarchimedean From d31078110f7aa75ad7ab3bdab4fe532f8c7b7f78 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 19:20:46 +0100 Subject: [PATCH 077/128] arrows --- Mathlib/NumberTheory/ModularForms/DedekindEta.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 271aa4147b51cf..4a7c4b280dec0b 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -89,8 +89,8 @@ lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - theorem etaProdTerm_ne_zero (z : ℍ) : ηₚ z ≠ 0 := by simp only [etaProdTerm, eta_q, ne_eq] - refine tprod_one_add_ne_zero_of_summable z (f := fun n x => -eta_q n x) ?_ ?_ - · refine fun i x => by simpa using one_add_eta_q_ne_zero i x + refine tprod_one_add_ne_zero_of_summable z (f := fun n x ↦ -eta_q n x) ?_ ?_ + · refine fun i x ↦ by simpa using one_add_eta_q_ne_zero i x · intro x simpa [eta_q, ← summable_norm_iff] using Summable_eta_q x @@ -119,7 +119,7 @@ private theorem one_sub_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ext y simpa using deriv_const_mul (2 * π * Complex.I * (i + 1)) (d := fun (x : ℂ) ↦ x) (x := y) simp_rw [eta_q_eq_cexp, h2, logDeriv_one_sub_mul_cexp_comp 1 - (g := fun x => (2 * π * Complex.I * (i + 1) * x)) (by fun_prop), h3] + (g := fun x ↦ (2 * π * Complex.I * (i + 1) * x)) (by fun_prop), h3] simp lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = @@ -130,14 +130,14 @@ lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - e congr 1 ext i ring - exact tsum_congr (fun i => one_sub_eta_logDeriv_eq z i) + exact tsum_congr (fun i ↦ one_sub_eta_logDeriv_eq z i) theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ complexUpperHalPlane_isOpen · exact (hD z z.2).differentiableAt (complexUpperHalPlane_isOpen.mem_nhds z.2) · filter_upwards with b y - apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x => 1 - eta_q i x) + apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x ↦ 1 - eta_q i x) (by fun_prop)).congr simp From e9066a70b5b9a58166d3d840f6153bd868611069 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 19:24:23 +0100 Subject: [PATCH 078/128] arrows --- Mathlib.lean | 2 +- .../InfiniteSum/LogDerivUniformlyOn.lean | 47 ------------------- 2 files changed, 1 insertion(+), 48 deletions(-) delete mode 100644 Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean diff --git a/Mathlib.lean b/Mathlib.lean index 91ec3ec0cb80c3..f7d2ebc047e3ef 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1492,6 +1492,7 @@ import Mathlib.Analysis.Calculus.LocalExtr.LineDeriv import Mathlib.Analysis.Calculus.LocalExtr.Polynomial import Mathlib.Analysis.Calculus.LocalExtr.Rolle import Mathlib.Analysis.Calculus.LogDeriv +import Mathlib.Analysis.Calculus.LogDerivUniformlyOn import Mathlib.Analysis.Calculus.MeanValue import Mathlib.Analysis.Calculus.Monotone import Mathlib.Analysis.Calculus.ParametricIntegral @@ -6170,7 +6171,6 @@ import Mathlib.Topology.Algebra.InfiniteSum.ENNReal import Mathlib.Topology.Algebra.InfiniteSum.Field import Mathlib.Topology.Algebra.InfiniteSum.Group import Mathlib.Topology.Algebra.InfiniteSum.GroupCompletion -import Mathlib.Topology.Algebra.InfiniteSum.LogDerivUniformlyOn import Mathlib.Topology.Algebra.InfiniteSum.Module import Mathlib.Topology.Algebra.InfiniteSum.NatInt import Mathlib.Topology.Algebra.InfiniteSum.Nonarchimedean diff --git a/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean b/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean deleted file mode 100644 index e18d851b6fd0d2..00000000000000 --- a/Mathlib/Topology/Algebra/InfiniteSum/LogDerivUniformlyOn.lean +++ /dev/null @@ -1,47 +0,0 @@ -/- -Copyright (c) 2025 Chris Birkbeck. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Chris Birkbeck --/ -import Mathlib.Analysis.CStarAlgebra.Classes -import Mathlib.Analysis.Complex.LocallyUniformLimit -import Mathlib.Topology.Algebra.InfiniteSum.UniformOn - -/-! -# The Logarithmic derivative of an infinite product - -We show that if we have an infinite product of functions `f` that is locally uniformly convergent, -then the logarithmic derivative of the product is the sum of the logarithmic derivatives of the -individual functions. - --/ - - -open TopologicalSpace Filter Complex Set Function - -theorem logDeriv_tprod_eq_tsum {ι : Type*} {s : Set ℂ} (hs : IsOpen s) {x : s} {f : ι → ℂ → ℂ} - (hf : ∀ i, f i x ≠ 0) (hd : ∀ i : ι, DifferentiableOn ℂ (f i) s) - (hm : Summable fun i ↦ logDeriv (f i) x) (htend : MultipliableLocallyUniformlyOn f s) - (hnez : ∏' (i : ι), f i x ≠ 0) : logDeriv (∏' i : ι, f i ·) x = ∑' i : ι, logDeriv (f i) x := by - apply symm - rw [← Summable.hasSum_iff hm, HasSum] - have := logDeriv_tendsto (f := fun (n : Finset ι) ↦ ∏ i ∈ n, (f i)) - (g := (∏' i : ι, f i ·)) (s := s) hs (p := atTop) - simp only [eventually_atTop, ge_iff_le, ne_eq, forall_exists_index, Subtype.forall] at this - conv => - enter [1] - ext n - rw [← logDeriv_prod _ _ _ (by intro i hi; apply hf i) - (by intro i hi; apply (hd i x x.2).differentiableAt; exact IsOpen.mem_nhds hs x.2)] - apply (this x x.2 ?_ ⊥ ?_ hnez).congr - · intro m - congr - aesop - · convert hasProdLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp - htend.hasProdLocallyUniformlyOn - simp - · intro b hb z hz - apply DifferentiableAt.differentiableWithinAt - have hp : ∀ (i : ι), i ∈ b → DifferentiableAt ℂ (f i) z := by - exact fun i hi ↦ (hd i z hz).differentiableAt (IsOpen.mem_nhds hs hz) - simpa using DifferentiableAt.finset_prod hp From 2c159e1f00cfb623dd5abd9b881c87efc679e787 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 14 Aug 2025 19:24:46 +0100 Subject: [PATCH 079/128] add file --- .../Calculus/LogDerivUniformlyOn.lean | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Mathlib/Analysis/Calculus/LogDerivUniformlyOn.lean diff --git a/Mathlib/Analysis/Calculus/LogDerivUniformlyOn.lean b/Mathlib/Analysis/Calculus/LogDerivUniformlyOn.lean new file mode 100644 index 00000000000000..e18d851b6fd0d2 --- /dev/null +++ b/Mathlib/Analysis/Calculus/LogDerivUniformlyOn.lean @@ -0,0 +1,47 @@ +/- +Copyright (c) 2025 Chris Birkbeck. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Birkbeck +-/ +import Mathlib.Analysis.CStarAlgebra.Classes +import Mathlib.Analysis.Complex.LocallyUniformLimit +import Mathlib.Topology.Algebra.InfiniteSum.UniformOn + +/-! +# The Logarithmic derivative of an infinite product + +We show that if we have an infinite product of functions `f` that is locally uniformly convergent, +then the logarithmic derivative of the product is the sum of the logarithmic derivatives of the +individual functions. + +-/ + + +open TopologicalSpace Filter Complex Set Function + +theorem logDeriv_tprod_eq_tsum {ι : Type*} {s : Set ℂ} (hs : IsOpen s) {x : s} {f : ι → ℂ → ℂ} + (hf : ∀ i, f i x ≠ 0) (hd : ∀ i : ι, DifferentiableOn ℂ (f i) s) + (hm : Summable fun i ↦ logDeriv (f i) x) (htend : MultipliableLocallyUniformlyOn f s) + (hnez : ∏' (i : ι), f i x ≠ 0) : logDeriv (∏' i : ι, f i ·) x = ∑' i : ι, logDeriv (f i) x := by + apply symm + rw [← Summable.hasSum_iff hm, HasSum] + have := logDeriv_tendsto (f := fun (n : Finset ι) ↦ ∏ i ∈ n, (f i)) + (g := (∏' i : ι, f i ·)) (s := s) hs (p := atTop) + simp only [eventually_atTop, ge_iff_le, ne_eq, forall_exists_index, Subtype.forall] at this + conv => + enter [1] + ext n + rw [← logDeriv_prod _ _ _ (by intro i hi; apply hf i) + (by intro i hi; apply (hd i x x.2).differentiableAt; exact IsOpen.mem_nhds hs x.2)] + apply (this x x.2 ?_ ⊥ ?_ hnez).congr + · intro m + congr + aesop + · convert hasProdLocallyUniformlyOn_iff_tendstoLocallyUniformlyOn.mp + htend.hasProdLocallyUniformlyOn + simp + · intro b hb z hz + apply DifferentiableAt.differentiableWithinAt + have hp : ∀ (i : ι), i ∈ b → DifferentiableAt ℂ (f i) z := by + exact fun i hi ↦ (hd i z hz).differentiableAt (IsOpen.mem_nhds hs hz) + simpa using DifferentiableAt.finset_prod hp From 2155c2e8eaff049bdb9ba177251e2f043cc42099 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 18 Aug 2025 09:57:33 +0100 Subject: [PATCH 080/128] save --- Mathlib/Analysis/Calculus/LogDerivUniformlyOn.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Analysis/Calculus/LogDerivUniformlyOn.lean b/Mathlib/Analysis/Calculus/LogDerivUniformlyOn.lean index e18d851b6fd0d2..df65a33728791e 100644 --- a/Mathlib/Analysis/Calculus/LogDerivUniformlyOn.lean +++ b/Mathlib/Analysis/Calculus/LogDerivUniformlyOn.lean @@ -16,7 +16,6 @@ individual functions. -/ - open TopologicalSpace Filter Complex Set Function theorem logDeriv_tprod_eq_tsum {ι : Type*} {s : Set ℂ} (hs : IsOpen s) {x : s} {f : ι → ℂ → ℂ} From 87ed893d84975ddf6fd6e20692d93afefe35e180 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 18 Aug 2025 11:08:42 +0100 Subject: [PATCH 081/128] some api --- Mathlib/NumberTheory/Divisors.lean | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 129a41bcff8ecb..aa2af726f6047b 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -754,6 +754,16 @@ def divisorsAntidiagonalFactors (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ (⟨x.1.2, Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ : ℕ+), Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ +lemma divisorsAntidiagonalFactors_eq (n : ℕ+) (x : Nat.divisorsAntidiagonal n) : + (divisorsAntidiagonalFactors n x).1.1 * (divisorsAntidiagonalFactors n x).2.1 = n := by + simp [divisorsAntidiagonalFactors, (Nat.mem_divisorsAntidiagonal.mp x.2).1] + +lemma divisorsAntidiagonalFactors_one (x : Nat.divisorsAntidiagonal 1) : + (divisorsAntidiagonalFactors 1 x) = (1, 1) := by + have h := Nat.mem_divisorsAntidiagonal.mp x.2 + simp only [mul_eq_one, ne_eq, one_ne_zero, not_false_eq_true, and_true] at h + simp [divisorsAntidiagonalFactors, h.1, h.2] + /-- The equivalence from the union over `n` of `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` to `(a , b)`. -/ def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ℕ+ × ℕ+ where @@ -766,4 +776,8 @@ def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ext <;> simp [divisorsAntidiagonalFactors, ← PNat.coe_injective.eq_iff, h.1] right_inv _ := rfl +lemma sigmaAntidiagonalEquivProd_symm_apply (x : ℕ+ × ℕ+) : + sigmaAntidiagonalEquivProd.symm x = ⟨⟨x.1 * x.2, mul_pos x.1.2 x.2.2⟩, + ⟨x.1, x.2⟩, by simp [Nat.mem_divisorsAntidiagonal]⟩ := rfl + end pnat From a533427a3874eb1fa57330c0e4e91cdedcec42a7 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 18 Aug 2025 11:15:21 +0100 Subject: [PATCH 082/128] more api --- Mathlib/NumberTheory/Divisors.lean | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index aa2af726f6047b..16bf3828b15ec1 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -776,8 +776,10 @@ def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ext <;> simp [divisorsAntidiagonalFactors, ← PNat.coe_injective.eq_iff, h.1] right_inv _ := rfl -lemma sigmaAntidiagonalEquivProd_symm_apply (x : ℕ+ × ℕ+) : - sigmaAntidiagonalEquivProd.symm x = ⟨⟨x.1 * x.2, mul_pos x.1.2 x.2.2⟩, - ⟨x.1, x.2⟩, by simp [Nat.mem_divisorsAntidiagonal]⟩ := rfl +lemma sigmaAntidiagonalEquivProd_symm_apply_fst (x : ℕ+ × ℕ+) : + (sigmaAntidiagonalEquivProd.symm x).1 = x.1.1 * x.2.1 := rfl + +lemma sigmaAntidiagonalEquivProd_symm_apply_snd (x : ℕ+ × ℕ+) : + (sigmaAntidiagonalEquivProd.symm x).2 = (x.1.1, x.2.1) := rfl end pnat From c7bfd978e84208a3c804d04b4afecc2cd6ab42dd Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 18 Aug 2025 11:19:12 +0100 Subject: [PATCH 083/128] fix --- Mathlib/NumberTheory/Divisors.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 16bf3828b15ec1..326baea55b78a9 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -754,7 +754,7 @@ def divisorsAntidiagonalFactors (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ (⟨x.1.2, Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ : ℕ+), Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ -lemma divisorsAntidiagonalFactors_eq (n : ℕ+) (x : Nat.divisorsAntidiagonal n) : +lemma divisorsAntidiagonalFactors_eq {n : ℕ+} (x : Nat.divisorsAntidiagonal n) : (divisorsAntidiagonalFactors n x).1.1 * (divisorsAntidiagonalFactors n x).2.1 = n := by simp [divisorsAntidiagonalFactors, (Nat.mem_divisorsAntidiagonal.mp x.2).1] From 5e81cc0787b38fde9b6578b588dbfc8f986370d7 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 18 Aug 2025 13:07:06 +0100 Subject: [PATCH 084/128] golf --- Mathlib/NumberTheory/ModularForms/DedekindEta.lean | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 4a7c4b280dec0b..a76e07182a364c 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -58,7 +58,7 @@ noncomputable abbrev etaProdTerm (z : ℂ) := ∏' (n : ℕ), (1 - eta_q n z) local notation "ηₚ" => etaProdTerm -/-- The eta function, whose value at z is `q^1/24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. -/ +/-- The eta function, whose value at z is `q^ 1 / 24 * ∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. -/ noncomputable def ModularForm.eta (z : ℂ) := 𝕢 24 z * ηₚ z local notation "η" => ModularForm.eta @@ -66,9 +66,7 @@ local notation "η" => ModularForm.eta open ModularForm theorem Summable_eta_q (z : ℍ) : Summable fun n ↦ ‖-eta_q n z‖ := by - simp_rw [eta_q, eta_q_eq_pow, norm_neg, norm_pow, summable_nat_add_iff 1] - simp only [summable_geometric_iff_norm_lt_one, norm_norm] - apply norm_exp_two_pi_I_lt_one z + simp [eta_q, eta_q_eq_pow, summable_nat_add_iff 1, norm_exp_two_pi_I_lt_one z] lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ηₚ ℍₒ:= by simp_rw [sub_eq_add_neg] @@ -99,7 +97,7 @@ lemma eta_ne_zero_on_UpperHalfPlane (z : ℍ) : η z ≠ 0 := by simpa [ModularForm.eta, Periodic.qParam] using etaProdTerm_ne_zero z lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = - fun z ↦ -r * cexp z / (1 - r * cexp ( z)) := by + fun z ↦ -r * cexp z / (1 - r * cexp z) := by ext z simp [logDeriv] From 14ee63557b054fe4be025843de05fa2baa717e69 Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Mon, 18 Aug 2025 11:37:21 +0000 Subject: [PATCH 085/128] feat(RingTheory): `IsTensorProduct` versions of the lemmas about tensoring with a flat module preserves injections (#27757) Add some lemmas about `IsTensorProduct` and the `IsTensorProduct` versions of the lemmas about tensoring with a flat module preserves injections. Co-authored-by: Yongle Hu <140475041+mbkybky@users.noreply.github.com> Co-authored-by: Thmoas-Guan <150537269+Thmoas-Guan@users.noreply.github.com> --- Mathlib/RingTheory/Flat/Basic.lean | 51 +++++++++++++++++--- Mathlib/RingTheory/IsTensorProduct.lean | 64 ++++++++++++++++++++----- 2 files changed, 96 insertions(+), 19 deletions(-) diff --git a/Mathlib/RingTheory/Flat/Basic.lean b/Mathlib/RingTheory/Flat/Basic.lean index b8cd66791dd018..69e8672da84a04 100644 --- a/Mathlib/RingTheory/Flat/Basic.lean +++ b/Mathlib/RingTheory/Flat/Basic.lean @@ -4,16 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin, Jujian Zhang, Yongle Hu -/ import Mathlib.Algebra.Colimit.TensorProduct -import Mathlib.Algebra.DirectSum.Finsupp -import Mathlib.Algebra.DirectSum.Module -import Mathlib.Algebra.Exact import Mathlib.Algebra.Module.CharacterModule -import Mathlib.Algebra.Module.Injective import Mathlib.Algebra.Module.Projective -import Mathlib.LinearAlgebra.DirectSum.TensorProduct -import Mathlib.LinearAlgebra.FreeModule.Basic import Mathlib.LinearAlgebra.TensorProduct.RightExactness import Mathlib.RingTheory.Finiteness.Small +import Mathlib.RingTheory.IsTensorProduct import Mathlib.RingTheory.TensorProduct.Finite /-! @@ -585,3 +580,47 @@ theorem nontrivial_of_algebraMap_injective_of_flat_right (h : Function.Injective end Algebra.TensorProduct end Nontrivial + +namespace IsTensorProduct + +variable {R M N P : Type*} [CommSemiring R] [AddCommMonoid M] [AddCommMonoid N] [AddCommMonoid P] + [Module R M] [Module R N] [Module R P] {M₁ M₂ N₁ N₂ : Type*} [AddCommMonoid M₁] [AddCommMonoid M₂] + [Module R M₁] [Module R M₂] [AddCommMonoid N₁] [AddCommMonoid N₂] [Module R N₁] [Module R N₂] + {f : M₁ →ₗ[R] M₂ →ₗ[R] M} {g : N₁ →ₗ[R] N₂ →ₗ[R] N} + (hf : IsTensorProduct f) (hg : IsTensorProduct g) (i₁ : M₁ →ₗ[R] N₁) (i₂ : M₂ →ₗ[R] N₂) + +theorem map_id_injective_of_flat_left {g : M₁ →ₗ[R] N₂ →ₗ[R] N} (hg : IsTensorProduct g) + (i : M₂ →ₗ[R] N₂) (hi : Function.Injective i) [Module.Flat R M₁] : + Function.Injective (hf.map hg LinearMap.id i) := by + have h : hf.map hg LinearMap.id i = hg.equiv ∘ i.lTensor M₁ ∘ hf.equiv.symm := + funext fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ hx hy ↦ by simp [hx, hy]) + simpa [h] using Module.Flat.lTensor_preserves_injective_linearMap i hi + +theorem map_id_injective_of_flat_right {g : N₁ →ₗ[R] M₂ →ₗ[R] N} (hg : IsTensorProduct g) + (i : M₁ →ₗ[R] N₁) (hi : Function.Injective i) [Module.Flat R M₂] : + Function.Injective (hf.map hg i LinearMap.id) := by + have h : hf.map hg i LinearMap.id = hg.equiv ∘ i.rTensor M₂ ∘ hf.equiv.symm := + funext fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ hx hy ↦ by simp [hx, hy]) + simpa [h] using Module.Flat.rTensor_preserves_injective_linearMap i hi + +/-- If `M₂` and `N₁` are flat `R`-modules, `i₁ : M₁ →ₗ[R] N₁` and `i₂ : M₂ →ₗ[R] N₂` are injective + linear maps, then the linear map `i : M ≅ M₁ ⊗[R] M₂ →ₗ[R] N₁ ⊗[R] N₂ ≅ N` induced by `i₁` + and `i₂` is injective. + See `IsTensorProduct.map_injective_of_flat'` for different flatness conditions. -/ +theorem map_injective_of_flat_right_left (h₁ : Function.Injective i₁) (h₂ : Function.Injective i₂) + [Module.Flat R M₂] [Module.Flat R N₁] : Function.Injective (hf.map hg i₁ i₂) := by + have h : hf.map hg i₁ i₂ = hg.equiv ∘ TensorProduct.map i₁ i₂ ∘ hf.equiv.symm := + funext fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ hx hy ↦ by simp [hx, hy]) + simpa [h] using map_injective_of_flat_flat i₁ i₂ h₁ h₂ + +/-- If `M₁` and `N₂` are flat `R`-modules, `i₁ : M₁ →ₗ[R] N₁` and `i₂ : M₂ →ₗ[R] N₂` are injective + linear maps, then the linear map `i : M ≅ M₁ ⊗[R] M₂ →ₗ[R] N₁ ⊗[R] N₂ ≅ N` induced by `i₁` + and `i₂` is injective. + See `IsTensorProduct.map_injective_of_flat` for different flatness conditions. -/ +theorem map_injective_of_flat_left_right (h₁ : Function.Injective i₁) (h₂ : Function.Injective i₂) + [Module.Flat R M₁] [Module.Flat R N₂] : Function.Injective (hf.map hg i₁ i₂) := by + have h : hf.map hg i₁ i₂ = hg.equiv ∘ TensorProduct.map i₁ i₂ ∘ hf.equiv.symm := + funext fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ hx hy ↦ by simp [hx, hy]) + simpa [h] using map_injective_of_flat_flat' i₁ i₂ h₁ h₂ + +end IsTensorProduct diff --git a/Mathlib/RingTheory/IsTensorProduct.lean b/Mathlib/RingTheory/IsTensorProduct.lean index bac8076ef656f0..8a28a06bbbcea8 100644 --- a/Mathlib/RingTheory/IsTensorProduct.lean +++ b/Mathlib/RingTheory/IsTensorProduct.lean @@ -60,20 +60,22 @@ theorem TensorProduct.isTensorProduct : IsTensorProduct (TensorProduct.mk R M N) simp · exact Function.bijective_id +namespace IsTensorProduct + variable {R M N} /-- If `M` is the tensor product of `M₁` and `M₂`, it is linearly equivalent to `M₁ ⊗[R] M₂`. -/ @[simps! apply] -noncomputable def IsTensorProduct.equiv (h : IsTensorProduct f) : M₁ ⊗[R] M₂ ≃ₗ[R] M := +noncomputable def equiv (h : IsTensorProduct f) : M₁ ⊗[R] M₂ ≃ₗ[R] M := LinearEquiv.ofBijective _ h @[simp] -theorem IsTensorProduct.equiv_toLinearMap (h : IsTensorProduct f) : +theorem equiv_toLinearMap (h : IsTensorProduct f) : h.equiv.toLinearMap = TensorProduct.lift f := rfl @[simp] -theorem IsTensorProduct.equiv_symm_apply (h : IsTensorProduct f) (x₁ : M₁) (x₂ : M₂) : +theorem equiv_symm_apply (h : IsTensorProduct f) (x₁ : M₁) (x₂ : M₂) : h.equiv.symm (f x₁ x₂) = x₁ ⊗ₜ x₂ := by apply h.equiv.injective refine (h.equiv.apply_symm_apply _).trans ?_ @@ -81,27 +83,26 @@ theorem IsTensorProduct.equiv_symm_apply (h : IsTensorProduct f) (x₁ : M₁) ( /-- If `M` is the tensor product of `M₁` and `M₂`, we may lift a bilinear map `M₁ →ₗ[R] M₂ →ₗ[R] M'` to a `M →ₗ[R] M'`. -/ -noncomputable def IsTensorProduct.lift (h : IsTensorProduct f) (f' : M₁ →ₗ[R] M₂ →ₗ[R] M') : +noncomputable def lift (h : IsTensorProduct f) (f' : M₁ →ₗ[R] M₂ →ₗ[R] M') : M →ₗ[R] M' := (TensorProduct.lift f').comp h.equiv.symm.toLinearMap -theorem IsTensorProduct.lift_eq (h : IsTensorProduct f) (f' : M₁ →ₗ[R] M₂ →ₗ[R] M') (x₁ : M₁) +theorem lift_eq (h : IsTensorProduct f) (f' : M₁ →ₗ[R] M₂ →ₗ[R] M') (x₁ : M₁) (x₂ : M₂) : h.lift f' (f x₁ x₂) = f' x₁ x₂ := by - delta IsTensorProduct.lift - simp + simp [lift] /-- The tensor product of a pair of linear maps between modules. -/ -noncomputable def IsTensorProduct.map (hf : IsTensorProduct f) (hg : IsTensorProduct g) +noncomputable def map (hf : IsTensorProduct f) (hg : IsTensorProduct g) (i₁ : M₁ →ₗ[R] N₁) (i₂ : M₂ →ₗ[R] N₂) : M →ₗ[R] N := hg.equiv.toLinearMap.comp ((TensorProduct.map i₁ i₂).comp hf.equiv.symm.toLinearMap) -theorem IsTensorProduct.map_eq (hf : IsTensorProduct f) (hg : IsTensorProduct g) (i₁ : M₁ →ₗ[R] N₁) +@[simp] +theorem map_eq (hf : IsTensorProduct f) (hg : IsTensorProduct g) (i₁ : M₁ →ₗ[R] N₁) (i₂ : M₂ →ₗ[R] N₂) (x₁ : M₁) (x₂ : M₂) : hf.map hg i₁ i₂ (f x₁ x₂) = g (i₁ x₁) (i₂ x₂) := by - delta IsTensorProduct.map - simp + simp [map] @[elab_as_elim] -theorem IsTensorProduct.inductionOn (h : IsTensorProduct f) {motive : M → Prop} (m : M) +theorem inductionOn (h : IsTensorProduct f) {motive : M → Prop} (m : M) (zero : motive 0) (tmul : ∀ x y, motive (f x y)) (add : ∀ x y, motive x → motive y → motive (x + y)) : motive m := by rw [← h.equiv.right_inv m] @@ -116,13 +117,50 @@ theorem IsTensorProduct.inductionOn (h : IsTensorProduct f) {motive : M → Prop rw [map_add] apply add <;> assumption -lemma IsTensorProduct.of_equiv (e : M₁ ⊗[R] M₂ ≃ₗ[R] M) (he : ∀ x y, e (x ⊗ₜ y) = f x y) : +lemma of_equiv (e : M₁ ⊗[R] M₂ ≃ₗ[R] M) (he : ∀ x y, e (x ⊗ₜ y) = f x y) : IsTensorProduct f := by have : TensorProduct.lift f = e := by ext x y simp [he] simpa [IsTensorProduct, this] using e.bijective +section map + +variable {P₁ P₂ P : Type*} [AddCommMonoid P₁] [AddCommMonoid P₂] + [AddCommMonoid P] [Module R P₁] [Module R P₂] [Module R P] {p : P₁ →ₗ[R] P₂ →ₗ[R] P} + (hf : IsTensorProduct f) (hg : IsTensorProduct g) (hp : IsTensorProduct p) + (i₁ : N₁ →ₗ[R] P₁) (j₁ : M₁ →ₗ[R] N₁) (i₂ : N₂ →ₗ[R] P₂) (j₂ : M₂ →ₗ[R] N₂) + +theorem map_comp : hf.map hp (i₁ ∘ₗ j₁) (i₂ ∘ₗ j₂) = hg.map hp i₁ i₂ ∘ₗ hf.map hg j₁ j₂ := + LinearMap.ext <| fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ h₁ h₂ ↦ by simp [h₁, h₂]) + +theorem map_map (x : M) : + hg.map hp i₁ i₂ ((hf.map hg j₁ j₂) x) = hf.map hp (i₁ ∘ₗ j₁) (i₂ ∘ₗ j₂) x := + DFunLike.congr_fun (hf.map_comp hg hp i₁ j₁ i₂ j₂).symm x + +@[simp] +theorem map_id : + hf.map hf (LinearMap.id : M₁ →ₗ[R] M₁) (LinearMap.id : M₂ →ₗ[R] M₂) = LinearMap.id := + LinearMap.ext <| fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ h₁ h₂ ↦ by simp [h₁, h₂]) + +@[simp] +protected theorem map_one : hf.map hf (1 : M₁ →ₗ[R] M₁) (1 : M₂ →ₗ[R] M₂) = 1 := + hf.map_id + +protected theorem map_mul (i₁ i₂ : M₁ →ₗ[R] M₁) (j₁ j₂ : M₂ →ₗ[R] M₂) : + hf.map hf (i₁ * i₂) (j₁ * j₂) = hf.map hf i₁ j₁ * hf.map hf i₂ j₂ := + hf.map_comp hf hf i₁ i₂ j₁ j₂ + +protected theorem map_pow (i : M₁ →ₗ[R] M₁) (j : M₂ →ₗ[R] M₂) (n : ℕ) : + hf.map hf i j ^ n = hf.map hf (i ^ n) (j ^ n) := by + induction n with + | zero => simp + | succ n ih => simp only [pow_succ, ih, hf.map_mul] + +end map + +end IsTensorProduct + end IsTensorProduct section IsBaseChange From 138c026a6f9797adfdd4d0c083826e39928cb4c3 Mon Sep 17 00:00:00 2001 From: themathqueen <2497250a@research.gla.ac.uk> Date: Mon, 18 Aug 2025 11:37:23 +0000 Subject: [PATCH 086/128] =?UTF-8?q?feat(Analysis/NormedSpace/...):=20`Alge?= =?UTF-8?q?bra.IsCentral=20R=20(V=20=E2=86=92L[R]=20V)`=20(#28209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The center of continuous linear maps on a topological vector space with separating dual is trivial, in other words, it is a central algebra. Co-authored-by: themathqueen <23701951+themathqueen@users.noreply.github.com> --- .../NormedSpace/HahnBanach/SeparatingDual.lean | 13 +++++++++++++ Mathlib/Data/SetLike/Basic.lean | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean b/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean index 9da502f7619ffb..3d418623113ddd 100644 --- a/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean +++ b/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean @@ -3,6 +3,7 @@ Copyright (c) 2023 Sébastien Gouëzel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ +import Mathlib.Algebra.Central.Defs import Mathlib.Analysis.NormedSpace.HahnBanach.Extension import Mathlib.Analysis.NormedSpace.HahnBanach.Separation import Mathlib.Analysis.NormedSpace.Multilinear.Basic @@ -115,6 +116,18 @@ theorem exists_eq_one_ne_zero_of_ne_zero_pair {x y : V} (hx : x ≠ 0) (hy : y variable [IsTopologicalAddGroup V] +/-- The center of continuous linear maps on a topological vector space +with separating dual is trivial, in other words, it is a central algebra. -/ +instance _root_.Algebra.IsCentral.continuousLinearMap [ContinuousSMul R V] : + Algebra.IsCentral R (V →L[R] V) where + out T hT := by + have h' (f : V →L[R] R) (y v : V) : f (T v) • y = f v • T y := by + simpa using congr($(Subalgebra.mem_center_iff.mp hT <| f.smulRight y) v) + nontriviality V + obtain ⟨x, hx⟩ := exists_ne (0 : V) + obtain ⟨f, hf⟩ := exists_eq_one (R := R) hx + exact ⟨f (T x), ContinuousLinearMap.ext fun _ => by simp [h', hf]⟩ + /-- In a topological vector space with separating dual, the group of continuous linear equivalences acts transitively on the set of nonzero vectors: given two nonzero vectors `x` and `y`, there exists `A : V ≃L[R] V` mapping `x` to `y`. -/ diff --git a/Mathlib/Data/SetLike/Basic.lean b/Mathlib/Data/SetLike/Basic.lean index 12a94653436ec4..8b46e053074fd3 100644 --- a/Mathlib/Data/SetLike/Basic.lean +++ b/Mathlib/Data/SetLike/Basic.lean @@ -237,4 +237,10 @@ attribute [local instance] instSubtypeSet instSubtype end +@[nontriviality] +lemma mem_of_subsingleton {A F} [Subsingleton A] [SetLike F A] (S : F) [h : Nonempty S] {a : A} : + a ∈ S := by + obtain ⟨s, hs⟩ := nonempty_subtype.mp h + simpa [Subsingleton.elim a s] + end SetLike From 2b3e07d1cb13de239315f574935283e02a67e8fc Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 18 Aug 2025 13:24:59 +0100 Subject: [PATCH 087/128] merge --- .../ModularForms/DedekindEta.lean | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index a76e07182a364c..d5fa7096d4a020 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -10,6 +10,8 @@ import Mathlib.Analysis.Complex.LocallyUniformLimit import Mathlib.Analysis.Complex.UpperHalfPlane.Exp import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn import Mathlib.Data.Complex.FiniteDimensional +import MAthlib.Analysis.Calculus.LogDerivUniformlyOn +import Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2 /-! # Dedekind eta function @@ -141,3 +143,47 @@ theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) + + +lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E₂ z := by + unfold ModularForm.eta etaProdTerm + rw [logDeriv_mul (UpperHalfPlane.coe z) _ (etaProdTerm_ne_zero z) _ + (etaProdTerm_differentiableAt z)] + · have HG := logDeriv_tprod_eq_tsum (isOpen_lt continuous_const Complex.continuous_im) z + (fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) ?_ ?_ ?_ (etaProdTerm_ne_zero z) + rw [show z.1 = UpperHalfPlane.coe z by rfl] at HG + rw [HG] + · simp only [tsum_log_deriv_eta_q' z, E₂, logDeriv_z_term z, mul_neg, one_div, mul_inv_rev, Pi.smul_apply, smul_eq_mul] + rw [G2_q_exp'', riemannZeta_two, ← (tsum_eq_tsum_sigma_pos'' z), mul_sub, sub_eq_add_neg, mul_add] + conv => + enter [1,2,2,1] + ext n + rw [neg_div, neg_eq_neg_one_mul] + rw [tsum_mul_left] + have hpi : (π : ℂ) ≠ 0 := by simp + congr 1 + · ring_nf + field_simp + ring + · field_simp + ring_nf + congr + ext n + ring_nf + · intro i x hx + simp_rw [eta_q_eq_exp] + fun_prop + · simp only [mem_setOf_eq, one_add_eta_logDeriv_eq] + apply ((summable_nat_add_iff 1).mpr ((logDeriv_q_expo_summable (𝕢₁ z) + (by simpa [Periodic.qParam] using exp_upperHalfPlane_lt_one z)).mul_left (-2 * π * Complex.I))).congr + intro b + have := one_add_eta_q_ne_zero b z + simp only [UpperHalfPlane.coe, ne_eq, neg_mul, Nat.cast_add, Nat.cast_one, mul_neg] at * + field_simp + left + ring + · use ηₚ + apply (hasProdLocallyUniformlyOn_eta).congr + exact fun n ⦃x⦄ hx ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, (fun n a ↦ 1 - eta_q n a) i b) x) + · simp [ne_eq, exp_ne_zero, not_false_eq_true, Periodic.qParam] + · fun_prop From 5fa040a8ba9bfa3990958b525808789efdf413ce Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 18 Aug 2025 18:56:51 +0100 Subject: [PATCH 088/128] some cleanup --- .../Trigonometric/Cotangent.lean | 17 +- Mathlib/Analysis/SpecificLimits/Normed.lean | 22 +++ .../ModularForms/DedekindEta.lean | 146 +++++++++++++----- .../ModularForms/EisensteinSeries/E2.lean | 11 ++ 4 files changed, 143 insertions(+), 53 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index f0c8c2a6a16d96..83099627e4775e 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -27,17 +27,10 @@ open Real Complex open scoped UpperHalfPlane -/-- The UpperHalfPlane as a subset of `ℂ`. This is convinient for takind derivatives of functions -on the upper half plane. -/ -abbrev complexUpperHalfPlane := {z : ℂ | 0 < z.im} - -local notation "ℍₒ" => complexUpperHalfPlane - -lemma complexUpperHalPlane_isOpen : IsOpen ℍₒ := by - exact (isOpen_lt continuous_const Complex.continuous_im) - local notation "ℂ_ℤ" => integerComplement +local notation "ℍₒ" => UpperHalfPlane.complexUpperHalfPlane + lemma Complex.cot_eq_exp_ratio (z : ℂ) : cot z = (Complex.exp (2 * I * z) + 1) / (I * (1 - Complex.exp (2 * I * z))) := by rw [Complex.cot, Complex.sin, Complex.cos] @@ -405,7 +398,7 @@ theorem iteratedDerivWithin_cot_sub_inv_eq_series_rep {k : ℕ} (hk : 1 ≤ k) ( theorem iteratedDerivWithin_cot_pi_z_sub_inv (k : ℕ) (z : ℍ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x) - 1 / x) ℍₒ z = (iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z) - - (-1) ^ k * (k !) * ((z : ℂ) ^ (-1 - k : ℤ)) := by + (-1) ^ k * k ! * ((z : ℂ) ^ (-1 - k : ℤ)) := by simp_rw [sub_eq_add_neg] rw [iteratedDerivWithin_fun_add (by apply z.2) complexUpperHalPlane_isOpen.uniqueDiffOn] · simpa [iteratedDerivWithin_fun_neg] using iteratedDerivWithin_one_div k @@ -417,7 +410,7 @@ theorem iteratedDerivWithin_cot_pi_z_sub_inv (k : ℕ) (z : ℍ) : theorem iteratedDerivWithin_cot_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z = - (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, ((z : ℂ) + n) ^ (-1 - k : ℤ):= by + (-1) ^ k * k ! * ∑' n : ℤ, ((z : ℂ) + n) ^ (-1 - k : ℤ):= by have h0 := iteratedDerivWithin_cot_pi_z_sub_inv k z rw [iteratedDerivWithin_cot_sub_inv_eq_series_rep hk z, add_comm] at h0 rw [← add_left_inj (-(-1) ^ k * ↑k ! * (z : ℂ) ^ (-1 - k : ℤ)), h0] @@ -425,7 +418,7 @@ theorem iteratedDerivWithin_cot_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : theorem iteratedDerivWithin_cot_series_rep_one_div {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z = - (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) := by + (-1) ^ k * k ! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) := by simp only [iteratedDerivWithin_cot_series_rep hk z, Int.reduceNeg, one_div, mul_eq_mul_left_iff, mul_eq_zero, pow_eq_zero_iff', neg_eq_zero, one_ne_zero, ne_eq, Nat.cast_eq_zero, show -1 - (k : ℤ) = -(k + 1) by ring] diff --git a/Mathlib/Analysis/SpecificLimits/Normed.lean b/Mathlib/Analysis/SpecificLimits/Normed.lean index 10b4ac34b0f12a..6e1056c0f04504 100644 --- a/Mathlib/Analysis/SpecificLimits/Normed.lean +++ b/Mathlib/Analysis/SpecificLimits/Normed.lean @@ -407,6 +407,28 @@ theorem summable_norm_pow_mul_geometric_of_norm_lt_one (k : ℕ) {r : R} exact summable_norm_mul_geometric_of_norm_lt_one (k := k) (u := fun n ↦ n ^ k) hr (isBigO_refl _ _) +lemma logDeriv_q_expo_summable {F : Type*} [NontriviallyNormedField F] [CompleteSpace F] + {r : F} (hr : ‖r‖ < 1) : Summable fun n : ℕ ↦ (n * r ^ n / (1 - r ^ n)) := by + have : Tendsto (fun n : ℕ => 1 - r ^ n) atTop (𝓝 1) := by + rw [show (1 : F) = 1 - 0 by ring] + apply Filter.Tendsto.sub (by simp) (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hr) + have h1 : Tendsto (fun n : ℕ => (1 : F)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] + have h2 := Filter.Tendsto.div h1 this (by simp) + simp only [ne_eq, one_ne_zero, not_false_eq_true, div_self, Metric.tendsto_atTop, gt_iff_lt, + ge_iff_le, Pi.div_apply, one_div, dist_eq_norm] at h2 + apply Summable.of_norm_bounded_eventually_nat (g := fun n => 2 * ‖n * r ^ n‖) + · apply Summable.mul_left + simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one 1 hr) + · simp only [norm_div, norm_mul, norm_pow, eventually_atTop, ge_iff_le] + obtain ⟨N, hN⟩ := h2 1 (by norm_num) + refine ⟨N, fun n hn ↦ ?_⟩ + have := norm_lt_of_mem_ball (by rw [mem_ball_iff_norm]; apply hN n hn) (E := F) + simp only [tendsto_const_nhds_iff, norm_inv, norm_one, mul_comm, div_eq_mul_inv, ge_iff_le] at * + gcongr + apply le_trans this.le (by linarith) + + + theorem summable_norm_geometric_of_norm_lt_one {r : R} (hr : ‖r‖ < 1) : Summable fun n : ℕ ↦ ‖(r ^ n : R)‖ := by simpa using summable_norm_pow_mul_geometric_of_norm_lt_one 0 hr diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index d5fa7096d4a020..6ddb594ff1d11b 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -10,7 +10,7 @@ import Mathlib.Analysis.Complex.LocallyUniformLimit import Mathlib.Analysis.Complex.UpperHalfPlane.Exp import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn import Mathlib.Data.Complex.FiniteDimensional -import MAthlib.Analysis.Calculus.LogDerivUniformlyOn +import Mathlib.Analysis.Calculus.LogDerivUniformlyOn import Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2 /-! @@ -28,7 +28,7 @@ differentiable on the upper half-plane. -/ open UpperHalfPlane TopologicalSpace Set MeasureTheory intervalIntegral - Metric Filter Function Complex + Metric Filter Function Complex ArithmeticFunction open scoped Interval Real NNReal ENNReal Topology BigOperators Nat @@ -103,6 +103,14 @@ lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = ext z simp [logDeriv] +lemma logDeriv_z_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * Complex.I / 24 := by + have : (𝕢 24) = (fun z ↦ cexp (z)) ∘ (fun z => (2 * ↑π * Complex.I / 24) * z) := by + ext y + simp only [Periodic.qParam, ofReal_ofNat, comp_apply] + ring_nf + rw [this, logDeriv_comp (by fun_prop) (by fun_prop), deriv_const_mul _ (by fun_prop)] + simp only [LogDeriv_exp, Pi.one_apply, deriv_id'', mul_one, one_mul] + lemma logDeriv_one_sub_mul_cexp_comp (r : ℂ) {g : ℂ → ℂ} (hg : Differentiable ℂ g) : logDeriv ((fun z ↦ 1 - r * cexp z) ∘ g) = fun z ↦ -r * (deriv g z) * cexp (g z) / (1 - r * cexp (g z)) := by @@ -144,46 +152,102 @@ theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) +lemma tsum_eq_tsum_sigma (z : ℍ) : ∑' n : ℕ+, + n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) / (1 - cexp (2 * π * Complex.I * z) ^ (n : ℕ)) = + ∑' n : ℕ+, sigma 1 n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by + have := fun m : ℕ+ => tsum_choose_mul_geometric_of_norm_lt_one + (r := (cexp (2 * ↑π * Complex.I * z))^(m : ℕ)) 0 ?_ + · simp only [add_zero, Nat.choose_zero_right, Nat.cast_one, one_mul, zero_add, pow_one, + one_div] at this + conv => + enter [1,1] + ext n + rw [div_eq_mul_one_div] + simp only [one_div, ← this n, ← tsum_mul_left] + conv => + enter [1] + ext m + rw [mul_assoc, ← pow_succ' (cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ)) m ] + have h00 := tsum_prod_pow_cexp_eq_tsum_sigma z (k := 1) + rw [Summable.tsum_comm (by apply summable_prod_aux (k := 1) z)] at h00 + rw [← h00] + apply tsum_congr + intro b + rw [← tsum_pnat_eq_tsum_succ + (fun n => b * (cexp (2 * π * Complex.I * z) ^ (b : ℕ)) ^ (n : ℕ))] + apply tsum_congr + intro c + simp only [← exp_nsmul, nsmul_eq_mul, pow_one, mul_eq_mul_left_iff, Nat.cast_eq_zero, + PNat.ne_zero, or_false] + ring_nf + · simpa using + pow_lt_one₀ (by simp) (UpperHalfPlane.norm_exp_two_pi_I_lt_one z) (by apply PNat.ne_zero) + +lemma summable_mul_tendsto_const {F ι : Type*} [NontriviallyNormedField F] [CompleteSpace F] + {f g : ι → F} (hf : Summable fun n => ‖f n‖) {c : F} (hg : Tendsto g cofinite (𝓝 c)) : + Summable fun n : ι ↦ f n * g n := by + apply summable_of_isBigO hf + have h0 : g =O[cofinite] fun _x ↦ (1 : F) := by + apply Filter.Tendsto.isBigO_one + exact hg + simpa using ((Asymptotics.isBigO_const_mul_self 1 f cofinite).mul h0) + +lemma logDeriv_q_expo_summable {F : Type*} [NontriviallyNormedField F] + [CompleteSpace F] {r : F} (hr : ‖r‖ < 1) : Summable fun n : ℕ => (n * r ^ n / (1 - r ^ n)) := by + rw [show (fun n : ℕ => (n * r ^ n / (1 - r ^ n))) = + fun n : ℕ => ((n * r ^ n) * (1 / (1 - r ^ n))) by grind] + apply summable_mul_tendsto_const (c := 1 / (1 - 0)) + · rw [Nat.cofinite_eq_atTop] + have : Tendsto (fun n : ℕ => 1 - r ^ n) atTop (𝓝 (1 - 0)) := + Filter.Tendsto.sub (by simp) (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hr) + have h1 : Tendsto (fun n : ℕ => (1 : F)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] + apply (Filter.Tendsto.div h1 this (by simp)).congr + simp + · simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one 1 hr) + -lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E₂ z := by +lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E2 z := by unfold ModularForm.eta etaProdTerm - rw [logDeriv_mul (UpperHalfPlane.coe z) _ (etaProdTerm_ne_zero z) _ - (etaProdTerm_differentiableAt z)] - · have HG := logDeriv_tprod_eq_tsum (isOpen_lt continuous_const Complex.continuous_im) z - (fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) ?_ ?_ ?_ (etaProdTerm_ne_zero z) - rw [show z.1 = UpperHalfPlane.coe z by rfl] at HG + rw [logDeriv_mul (UpperHalfPlane.coe z) (by simp [ne_eq, exp_ne_zero, not_false_eq_true, + Periodic.qParam]) (etaProdTerm_ne_zero z) (by fun_prop) (etaProdTerm_differentiableAt z) ] + have HG := logDeriv_tprod_eq_tsum (isOpen_lt continuous_const Complex.continuous_im) (x := z) + (f := fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) ?_ ?_ ?_ + (etaProdTerm_ne_zero z) + · rw [show z.1 = UpperHalfPlane.coe z by rfl] at HG rw [HG] - · simp only [tsum_log_deriv_eta_q' z, E₂, logDeriv_z_term z, mul_neg, one_div, mul_inv_rev, Pi.smul_apply, smul_eq_mul] - rw [G2_q_exp'', riemannZeta_two, ← (tsum_eq_tsum_sigma_pos'' z), mul_sub, sub_eq_add_neg, mul_add] - conv => - enter [1,2,2,1] - ext n - rw [neg_div, neg_eq_neg_one_mul] - rw [tsum_mul_left] - have hpi : (π : ℂ) ≠ 0 := by simp - congr 1 - · ring_nf - field_simp - ring - · field_simp - ring_nf - congr - ext n - ring_nf - · intro i x hx - simp_rw [eta_q_eq_exp] - fun_prop - · simp only [mem_setOf_eq, one_add_eta_logDeriv_eq] - apply ((summable_nat_add_iff 1).mpr ((logDeriv_q_expo_summable (𝕢₁ z) - (by simpa [Periodic.qParam] using exp_upperHalfPlane_lt_one z)).mul_left (-2 * π * Complex.I))).congr - intro b - have := one_add_eta_q_ne_zero b z - simp only [UpperHalfPlane.coe, ne_eq, neg_mul, Nat.cast_add, Nat.cast_one, mul_neg] at * - field_simp - left + simp only [logDeriv_z_term z, tsum_log_deriv_eta_q z, mul_neg, E2, one_div, mul_inv_rev, + Pi.smul_apply, smul_eq_mul] + rw [G2_q_exp, riemannZeta_two, ← (tsum_eq_tsum_sigma z), mul_sub, sub_eq_add_neg, mul_add] + conv => + enter [1,2,2,1] + ext n + rw [neg_div, neg_eq_neg_one_mul] + rw [tsum_mul_left] + congr 1 + · field_simp ring - · use ηₚ - apply (hasProdLocallyUniformlyOn_eta).congr - exact fun n ⦃x⦄ hx ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, (fun n a ↦ 1 - eta_q n a) i b) x) - · simp [ne_eq, exp_ne_zero, not_false_eq_true, Periodic.qParam] - · fun_prop + · have := tsum_pnat_eq_tsum_succ (f := fun n => ( n) * cexp (2 * ↑π * Complex.I * ↑z ) ^ (n) + / (1 - cexp (2 * ↑π * Complex.I * ↑z) ^ n )) + simp at this + rw [this] + field_simp [Periodic.qParam, eta_q_eq_pow] + ring_nf + congr + ext n + ring_nf + · intro i x hx + simp_rw [eta_q_eq_pow] + fun_prop + · simp only [mem_setOf_eq, one_sub_eta_logDeriv_eq] + apply ((summable_nat_add_iff 1).mpr ((logDeriv_q_expo_summable (r := 𝕢 1 z) + (by simpa [Periodic.qParam] using UpperHalfPlane.norm_exp_two_pi_I_lt_one z)).mul_left + (-2 * π * Complex.I))).congr + intro b + have := one_add_eta_q_ne_zero b z + simp only [UpperHalfPlane.coe, ne_eq, neg_mul, Nat.cast_add, Nat.cast_one, mul_neg] at * + field_simp + left + ring + · use ηₚ + apply (hasProdLocallyUniformlyOn_eta).congr + exact fun n x hx ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, (fun n a ↦ 1 - eta_q n a) i b) x) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean index 953b852f61d5ff..596f2cd00920f3 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean @@ -143,6 +143,17 @@ lemma G2_cauchy (z : ℍ) : CauchySeq (fun N : ℕ => ∑ m ∈ Icc (-N : ℤ) N -8 * π ^ 2 * ∑' (n : ℕ+), (σ 1 n) * cexp (2 * π * Complex.I * z) ^ (n : ℕ)) simpa using G2_tendsto z +lemma G2_q_exp (z : ℍ) : G2 z = (2 * riemannZeta 2) - 8 * π ^ 2 * + ∑' n : ℕ+, sigma 1 n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by + rw [G2, Filter.Tendsto.limUnder_eq] + conv => + enter [1] + ext N + rw [G2_partial_sum_eq z N] + rw [sub_eq_add_neg] + apply Filter.Tendsto.add + · simp + · simpa using G2_tendsto z From 437ce0397f204e8df1ff32691fc211f50dfdf64f Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Mon, 18 Aug 2025 20:02:05 +0100 Subject: [PATCH 089/128] save --- Mathlib/Analysis/Asymptotics/Lemmas.lean | 8 +++++++ Mathlib/Analysis/SpecificLimits/Normed.lean | 22 ------------------ .../ModularForms/DedekindEta.lean | 23 ++++++------------- 3 files changed, 15 insertions(+), 38 deletions(-) diff --git a/Mathlib/Analysis/Asymptotics/Lemmas.lean b/Mathlib/Analysis/Asymptotics/Lemmas.lean index 1ff1e0b3f24005..8fb8db474c5244 100644 --- a/Mathlib/Analysis/Asymptotics/Lemmas.lean +++ b/Mathlib/Analysis/Asymptotics/Lemmas.lean @@ -676,6 +676,14 @@ lemma Asymptotics.IsBigO.comp_summable_norm {ι E F : Type*} summable_of_isBigO hg <| hf.norm_norm.comp_tendsto <| tendsto_zero_iff_norm_tendsto_zero.2 hg.tendsto_cofinite_zero +lemma summable_mul_tendsto_const {F ι : Type*} [NontriviallyNormedField F] [CompleteSpace F] + {f g : ι → F} (hf : Summable fun n => ‖f n‖) {c : F} (hg : Tendsto g cofinite (𝓝 c)) : + Summable fun n : ι ↦ f n * g n := by + apply summable_of_isBigO hf + have h0 : g =O[cofinite] fun _x ↦ (1 : F) := by + apply Filter.Tendsto.isBigO_one + exact hg + simpa using ((Asymptotics.isBigO_const_mul_self 1 f cofinite).mul h0) namespace PartialHomeomorph variable {α : Type*} {β : Type*} [TopologicalSpace α] [TopologicalSpace β] diff --git a/Mathlib/Analysis/SpecificLimits/Normed.lean b/Mathlib/Analysis/SpecificLimits/Normed.lean index 6e1056c0f04504..10b4ac34b0f12a 100644 --- a/Mathlib/Analysis/SpecificLimits/Normed.lean +++ b/Mathlib/Analysis/SpecificLimits/Normed.lean @@ -407,28 +407,6 @@ theorem summable_norm_pow_mul_geometric_of_norm_lt_one (k : ℕ) {r : R} exact summable_norm_mul_geometric_of_norm_lt_one (k := k) (u := fun n ↦ n ^ k) hr (isBigO_refl _ _) -lemma logDeriv_q_expo_summable {F : Type*} [NontriviallyNormedField F] [CompleteSpace F] - {r : F} (hr : ‖r‖ < 1) : Summable fun n : ℕ ↦ (n * r ^ n / (1 - r ^ n)) := by - have : Tendsto (fun n : ℕ => 1 - r ^ n) atTop (𝓝 1) := by - rw [show (1 : F) = 1 - 0 by ring] - apply Filter.Tendsto.sub (by simp) (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hr) - have h1 : Tendsto (fun n : ℕ => (1 : F)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] - have h2 := Filter.Tendsto.div h1 this (by simp) - simp only [ne_eq, one_ne_zero, not_false_eq_true, div_self, Metric.tendsto_atTop, gt_iff_lt, - ge_iff_le, Pi.div_apply, one_div, dist_eq_norm] at h2 - apply Summable.of_norm_bounded_eventually_nat (g := fun n => 2 * ‖n * r ^ n‖) - · apply Summable.mul_left - simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one 1 hr) - · simp only [norm_div, norm_mul, norm_pow, eventually_atTop, ge_iff_le] - obtain ⟨N, hN⟩ := h2 1 (by norm_num) - refine ⟨N, fun n hn ↦ ?_⟩ - have := norm_lt_of_mem_ball (by rw [mem_ball_iff_norm]; apply hN n hn) (E := F) - simp only [tendsto_const_nhds_iff, norm_inv, norm_one, mul_comm, div_eq_mul_inv, ge_iff_le] at * - gcongr - apply le_trans this.le (by linarith) - - - theorem summable_norm_geometric_of_norm_lt_one {r : R} (hr : ‖r‖ < 1) : Summable fun n : ℕ ↦ ‖(r ^ n : R)‖ := by simpa using summable_norm_pow_mul_geometric_of_norm_lt_one 0 hr diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 6ddb594ff1d11b..57a25a418ac8f0 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -183,19 +183,11 @@ lemma tsum_eq_tsum_sigma (z : ℍ) : ∑' n : ℕ+, · simpa using pow_lt_one₀ (by simp) (UpperHalfPlane.norm_exp_two_pi_I_lt_one z) (by apply PNat.ne_zero) -lemma summable_mul_tendsto_const {F ι : Type*} [NontriviallyNormedField F] [CompleteSpace F] - {f g : ι → F} (hf : Summable fun n => ‖f n‖) {c : F} (hg : Tendsto g cofinite (𝓝 c)) : - Summable fun n : ι ↦ f n * g n := by - apply summable_of_isBigO hf - have h0 : g =O[cofinite] fun _x ↦ (1 : F) := by - apply Filter.Tendsto.isBigO_one - exact hg - simpa using ((Asymptotics.isBigO_const_mul_self 1 f cofinite).mul h0) - -lemma logDeriv_q_expo_summable {F : Type*} [NontriviallyNormedField F] - [CompleteSpace F] {r : F} (hr : ‖r‖ < 1) : Summable fun n : ℕ => (n * r ^ n / (1 - r ^ n)) := by - rw [show (fun n : ℕ => (n * r ^ n / (1 - r ^ n))) = - fun n : ℕ => ((n * r ^ n) * (1 / (1 - r ^ n))) by grind] +lemma summable_norm_pow_mul_geometric_div_one_sub {F : Type*} [NontriviallyNormedField F] + [CompleteSpace F] (k : ℕ) {r : F} (hr : ‖r‖ < 1) : + Summable fun n : ℕ => (n ^ k * r ^ n / (1 - r ^ n)) := by + rw [show (fun n : ℕ => (n ^ k * r ^ n / (1 - r ^ n))) = + fun n : ℕ => ((n ^ k * r ^ n) * (1 / (1 - r ^ n))) by grind] apply summable_mul_tendsto_const (c := 1 / (1 - 0)) · rw [Nat.cofinite_eq_atTop] have : Tendsto (fun n : ℕ => 1 - r ^ n) atTop (𝓝 (1 - 0)) := @@ -203,8 +195,7 @@ lemma logDeriv_q_expo_summable {F : Type*} [NontriviallyNormedField F] have h1 : Tendsto (fun n : ℕ => (1 : F)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] apply (Filter.Tendsto.div h1 this (by simp)).congr simp - · simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one 1 hr) - + · simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one k hr) lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E2 z := by unfold ModularForm.eta etaProdTerm @@ -239,7 +230,7 @@ lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12 simp_rw [eta_q_eq_pow] fun_prop · simp only [mem_setOf_eq, one_sub_eta_logDeriv_eq] - apply ((summable_nat_add_iff 1).mpr ((logDeriv_q_expo_summable (r := 𝕢 1 z) + apply ((summable_nat_add_iff 1).mpr ((summable_norm_pow_mul_geometric_div_one_sub (r := 𝕢 1 z) 1 (by simpa [Periodic.qParam] using UpperHalfPlane.norm_exp_two_pi_I_lt_one z)).mul_left (-2 * π * Complex.I))).congr intro b From a04f2ca8e7fc3dc571d7732b63c0643a6237bb2b Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Tue, 19 Aug 2025 18:56:41 +0100 Subject: [PATCH 090/128] save --- .../ModularForms/DedekindEta.lean | 74 +++++++------- .../EisensteinSeries/QExpansion.lean | 98 +++++++++++++++++-- 2 files changed, 127 insertions(+), 45 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 57a25a418ac8f0..4755abdad308e8 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -154,53 +154,51 @@ lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z lemma tsum_eq_tsum_sigma (z : ℍ) : ∑' n : ℕ+, n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) / (1 - cexp (2 * π * Complex.I * z) ^ (n : ℕ)) = - ∑' n : ℕ+, sigma 1 n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by - have := fun m : ℕ+ => tsum_choose_mul_geometric_of_norm_lt_one - (r := (cexp (2 * ↑π * Complex.I * z))^(m : ℕ)) 0 ?_ - · simp only [add_zero, Nat.choose_zero_right, Nat.cast_one, one_mul, zero_add, pow_one, - one_div] at this + ∑' n : ℕ+, σ 1 n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by + have := fun m : ℕ+ => tsum_choose_mul_geometric_of_norm_lt_one + (r := (cexp (2 * ↑π * Complex.I * z)) ^ (m : ℕ)) 0 (by simpa using + (pow_lt_one₀ (by simp) (UpperHalfPlane.norm_exp_two_pi_I_lt_one z) (by apply PNat.ne_zero))) + simp only [add_zero, Nat.choose_zero_right, Nat.cast_one, one_mul, zero_add, pow_one, + one_div] at this + conv => + enter [1,1] + ext n + rw [div_eq_mul_one_div] + simp only [one_div, ← this n, ← tsum_mul_left] conv => - enter [1,1] - ext n - rw [div_eq_mul_one_div] - simp only [one_div, ← this n, ← tsum_mul_left] - conv => - enter [1] - ext m - rw [mul_assoc, ← pow_succ' (cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ)) m ] - have h00 := tsum_prod_pow_cexp_eq_tsum_sigma z (k := 1) - rw [Summable.tsum_comm (by apply summable_prod_aux (k := 1) z)] at h00 - rw [← h00] - apply tsum_congr - intro b - rw [← tsum_pnat_eq_tsum_succ - (fun n => b * (cexp (2 * π * Complex.I * z) ^ (b : ℕ)) ^ (n : ℕ))] - apply tsum_congr - intro c - simp only [← exp_nsmul, nsmul_eq_mul, pow_one, mul_eq_mul_left_iff, Nat.cast_eq_zero, - PNat.ne_zero, or_false] - ring_nf - · simpa using - pow_lt_one₀ (by simp) (UpperHalfPlane.norm_exp_two_pi_I_lt_one z) (by apply PNat.ne_zero) + enter [1] + ext m + rw [mul_assoc, ← pow_succ' (cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ)) m ] + have h00 := (tsum_prod_pow_cexp_eq_tsum_sigma z (k := 1)) + rw [Summable.tsum_comm (by apply summable_prod_aux (k := 1) z)] at h00 + rw [← h00] + apply tsum_congr + intro b + rw [← tsum_pnat_eq_tsum_succ (fun n => b * (cexp (2 * π * Complex.I * z) ^ (b : ℕ)) ^ (n : ℕ))] + apply tsum_congr + intro c + simp only [← exp_nsmul, nsmul_eq_mul, pow_one, mul_eq_mul_left_iff, Nat.cast_eq_zero, + PNat.ne_zero, or_false] + ring_nf lemma summable_norm_pow_mul_geometric_div_one_sub {F : Type*} [NontriviallyNormedField F] [CompleteSpace F] (k : ℕ) {r : F} (hr : ‖r‖ < 1) : - Summable fun n : ℕ => (n ^ k * r ^ n / (1 - r ^ n)) := by - rw [show (fun n : ℕ => (n ^ k * r ^ n / (1 - r ^ n))) = - fun n : ℕ => ((n ^ k * r ^ n) * (1 / (1 - r ^ n))) by grind] + Summable fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n) := by + rw [show (fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n)) = + fun n : ℕ ↦ (n ^ k * r ^ n) * (1 / (1 - r ^ n)) by grind] apply summable_mul_tendsto_const (c := 1 / (1 - 0)) - · rw [Nat.cofinite_eq_atTop] - have : Tendsto (fun n : ℕ => 1 - r ^ n) atTop (𝓝 (1 - 0)) := - Filter.Tendsto.sub (by simp) (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hr) - have h1 : Tendsto (fun n : ℕ => (1 : F)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] - apply (Filter.Tendsto.div h1 this (by simp)).congr - simp - · simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one k hr) + (by simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one k hr)) + rw [Nat.cofinite_eq_atTop] + have : Tendsto (fun n : ℕ ↦ 1 - r ^ n) atTop (𝓝 (1 - 0)) := + Filter.Tendsto.sub (by simp) (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hr) + have h1 : Tendsto (fun n : ℕ ↦ (1 : F)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] + apply (Filter.Tendsto.div h1 this (by simp)).congr + simp lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E2 z := by unfold ModularForm.eta etaProdTerm rw [logDeriv_mul (UpperHalfPlane.coe z) (by simp [ne_eq, exp_ne_zero, not_false_eq_true, - Periodic.qParam]) (etaProdTerm_ne_zero z) (by fun_prop) (etaProdTerm_differentiableAt z) ] + Periodic.qParam]) (etaProdTerm_ne_zero z) (by fun_prop) (etaProdTerm_differentiableAt z)] have HG := logDeriv_tprod_eq_tsum (isOpen_lt continuous_const Complex.continuous_im) (x := z) (f := fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) ?_ ?_ ?_ (etaProdTerm_ne_zero z) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index 0568ccfe588db1..e9be9bd25895b1 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -201,6 +201,42 @@ theorem EisensteinSeries.qExpansion_identity_pnat {k : ℕ} (hk : 1 ≤ k) (z : · apply (summable_pow_mul_cexp k 1 z).congr simp +lemma natcast_norm {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormSMulClass ℤ 𝕜] + (a : ℕ) : ‖(a : 𝕜)‖ = a := by + have h0 := norm_natCast_eq_mul_norm_one 𝕜 a + simpa using h0 + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] + +theorem summable_divisorsAntidiagonal_aux2 (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : + Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ + (c.2.1).1 ^ k * (r ^ (c.2.1.2 * c.2.1.1)) := by + apply Summable.of_norm + rw [summable_sigma_of_nonneg] + constructor + · apply fun n => (hasSum_fintype _).summable + · simp only [norm_mul, norm_pow, tsum_fintype, Finset.univ_eq_attach] + · apply Summable.of_nonneg_of_le (f := fun c : ℕ+ ↦ ‖(c : 𝕜) ^ (k + 1) * r ^ (c : ℕ)‖) + (fun b => Finset.sum_nonneg (fun _ _ => by apply mul_nonneg (by simp) (by simp))) ?_ + (by apply (summable_norm_pow_mul_geometric_of_norm_lt_one (k + 1) hr).subtype) + intro b + apply le_trans (b := ∑ _ ∈ (b : ℕ).divisors, ‖(b : 𝕜)‖ ^ k * ‖r ^ (b : ℕ)‖) + · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun x ↦ + ‖(x.1 : 𝕜)‖ ^ (k : ℕ) * ‖r‖^ (x.2 * x.1)), Nat.sum_divisorsAntidiagonal + ((fun x y ↦ ‖(x : 𝕜)‖ ^ k * ‖r‖ ^ (y * x))) (n := b)] + gcongr <;> rename_i i hi <;> simp [natcast_norm] at * + · exact Nat.le_of_dvd b.2 hi + · apply le_of_eq + nth_rw 2 [← Nat.mul_div_cancel' hi] + ring_nf + · simp only [norm_pow, Finset.sum_const, nsmul_eq_mul, ← mul_assoc, add_comm k 1, pow_add, + pow_one, norm_mul] + gcongr + simpa [natcast_norm] using (Nat.card_divisors_le_self b) + · intro a + simpa using mul_nonneg (by simp) (by simp) + + theorem summable_divisorsAntidiagonal_aux (k : ℕ) (z : ℍ) : Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ (c.2.1).1 ^ k * cexp (2 * ↑π * Complex.I * c.2.1.2 * z) ^ c.2.1.1 := by @@ -235,6 +271,54 @@ theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ simp only [sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, Equiv.coe_fn_mk] apply summable_divisorsAntidiagonal_aux k z +theorem summable_auxerret (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : + Summable fun c : (ℕ+ × ℕ+) ↦ (c.1 : 𝕜) ^ k * (r ^ (c.2 * c.1 : ℕ)) :=by + rw [sigmaAntidiagonalEquivProd.summable_iff.symm] + simp only [sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, Equiv.coe_fn_mk] + apply summable_divisorsAntidiagonal_aux2 k r hr + +theorem tsum_prod_pow_cexp_eq_tsum_sigma2 (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : + ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : 𝕜) * (r ^ (d * c : ℕ)) = + ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) := by + suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : 𝕜) * (r ^ ((c.2 : ℕ) * (c.1 : ℕ))) = + ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) by + rw [Summable.tsum_prod (by apply summable_auxerret k r hr), Summable.tsum_comm] at this + · simpa using this + · apply (summable_auxerret k r hr).prod_symm.congr + simp + simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, + Equiv.coe_fn_mk, sigma_eq_sum_div', Nat.cast_sum, Nat.cast_pow] + rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux2 k r hr)] + apply tsum_congr + intro n + simp only [tsum_fintype, Finset.univ_eq_attach, Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) + (fun (x : ℕ × ℕ) ↦ (x.1 : 𝕜) ^ k * r ^ (x.2 * x.1)), + Nat.sum_divisorsAntidiagonal' (fun x y ↦ (x : 𝕜) ^ k * r ^ (y * x)), + Finset.sum_mul] + refine Finset.sum_congr (rfl) fun i hi ↦ ?_ + have hni : (n / i : ℕ) * (i : ℕ) = n := by + simp only [Nat.mem_divisors, ne_eq, PNat.ne_zero, not_false_eq_true, and_true] at * + have := Nat.div_mul_cancel hi + nth_rw 2 [← this] + simp + left + norm_cast at * + nth_rw 2 [← hni] + ring + +theorem tsum_prod_pow_cexp_eq_tsum_sigma3 (k : ℕ) (z : ℍ) : + ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = + ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by + have := tsum_prod_pow_cexp_eq_tsum_sigma2 k (cexp (2 * ↑π * Complex.I * z)) + (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) + simp_rw [← this, ← exp_nsmul] + congr + ext n + congr + ext m + ring_nf + + theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by @@ -249,7 +333,7 @@ theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k z)] apply tsum_congr intro n - simp only [tsum_fintype, Finset.univ_eq_attach,Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) + simp only [tsum_fintype, Finset.univ_eq_attach, Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) (fun (x : ℕ × ℕ) ↦ (x.1 : ℂ) ^ k * cexp (2 * ↑π * Complex.I * x.2 * z) ^ x.1), Nat.sum_divisorsAntidiagonal' (fun x y ↦ (x : ℂ) ^ k * cexp (2 * ↑π * Complex.I * y * z) ^ x), Finset.sum_mul] @@ -271,9 +355,9 @@ theorem summable_prod_eisSummand {k : ℕ} (hk : 3 ≤ k) (z : ℍ) : simp [EisensteinSeries.eisSummand] lemma tsum_prod_eisSummand_eq_sigma_cexp {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : - ∑' (x : Fin 2 → ℤ), eisSummand k x z = 2 * riemannZeta ↑k + - 2 * ((-2 * ↑π * Complex.I) ^ k / ↑(k - 1)!) * - ∑' (n : ℕ+), ↑((σ (k - 1)) ↑n) * cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ) := by + ∑' (x : Fin 2 → ℤ), eisSummand k x z = 2 * riemannZeta k + + 2 * ((-2 * π * Complex.I) ^ k / (k - 1)!) * + ∑' (n : ℕ+), (σ (k - 1) n) * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by rw [← (piFinTwoEquiv fun _ ↦ ℤ).symm.tsum_eq, Summable.tsum_prod (by apply summable_prod_eisSummand hk), tsum_nat_eq_zero_two_pnat] · have (b : ℕ+) := EisensteinSeries.qExpansion_identity_pnat (k := k - 1) (by omega) @@ -340,8 +424,8 @@ lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ /-- The q-Expansion of normalised Eisenstein series of level one with `riemannZeta` term. -/ lemma EisensteinSeries.q_expansion_riemannZeta {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : - (E hk) z = 1 + (1 / (riemannZeta (k))) * ((-2 * ↑π * Complex.I) ^ k / (k - 1)!) * - ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * ↑π * Complex.I * z) ^ (n : ℤ) := by + (E hk) z = 1 + (1 / (riemannZeta (k))) * ((-2 * π * Complex.I) ^ k / (k - 1)!) * + ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * π * Complex.I * z) ^ (n : ℤ) := by have : (eisensteinSeries_MF (k := k) (by omega) standardcongruencecondition) z = (eisensteinSeries_SIF standardcongruencecondition k) z := rfl rw [E, ModularForm.smul_apply, this, eisensteinSeries_SIF_apply standardcongruencecondition k z, @@ -366,7 +450,7 @@ theorem even_div_two_ne_zero {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) : k / 2 refine (Int.two_le_iff_pos_of_even (m := k) (by simpa using hk2 )).mpr (by omega) lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) : - (1 / (riemannZeta (k))) * ((-2 * ↑π * Complex.I) ^ k / (k - 1)!) = -((2 * k) / bernoulli k) := by + (1 / (riemannZeta (k))) * ((-2 * π * Complex.I) ^ k / (k - 1)!) = -((2 * k) / bernoulli k) := by have hk0 := even_div_two_ne_zero hk2 hkn0 have hk1 : 2 * (k / 2) = k := by apply Nat.two_mul_div_two_of_even hk2 have hk11 : 2 * (((k / 2) : ℕ) : ℂ) = k := by norm_cast From b1b02a0b158b9978ca19c3154e0e1bd31359699a Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 10:37:54 +0100 Subject: [PATCH 091/128] save --- .../EisensteinSeries/QExpansion.lean | 77 ++++++------------- .../Topology/Algebra/InfiniteSum/Basic.lean | 5 ++ 2 files changed, 28 insertions(+), 54 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index e9be9bd25895b1..9c8b3313774692 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -208,7 +208,13 @@ lemma natcast_norm {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormSMulClass variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] -theorem summable_divisorsAntidiagonal_aux2 (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : +@[simp] +lemma cexp_pow_aux (a b : ℕ) (z : ℍ) : + cexp (2 * ↑π * Complex.I * a * z) ^ b = Complex.exp (2 * ↑π * Complex.I * z) ^ (a * b) := by + simp [← Complex.exp_nsmul] + ring_nf + +theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ (c.2.1).1 ^ k * (r ^ (c.2.1.2 * c.2.1.1)) := by apply Summable.of_norm @@ -235,7 +241,7 @@ theorem summable_divisorsAntidiagonal_aux2 (k : ℕ) (r : 𝕜) (hr : ‖r‖ < simpa [natcast_norm] using (Nat.card_divisors_le_self b) · intro a simpa using mul_nonneg (by simp) (by simp) - +/- theorem summable_divisorsAntidiagonal_aux (k : ℕ) (z : ℍ) : Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ @@ -252,9 +258,9 @@ theorem summable_divisorsAntidiagonal_aux (k : ℕ) (z : ℍ) : intro b apply le_trans (b := ∑ _ ∈ (b : ℕ).divisors, b ^ k * ‖exp (2 * ↑π * Complex.I * z) ^ (b : ℕ)‖) · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun (x : ℕ × ℕ) ↦ - (x.1 : ℝ) ^ (k : ℕ) * ‖Complex.exp (2 * ↑π * Complex.I * x.2 * z)‖ ^ x.1), + (x.1 : ℝ) ^ (k : ℕ) * ‖cexp (2 * ↑π * Complex.I * x.2 * z)‖ ^ x.1), Nat.sum_divisorsAntidiagonal ((fun x y ↦ - (x : ℝ) ^ (k : ℕ) * ‖Complex.exp (2 * ↑π * Complex.I * y * z)‖ ^ x))] + (x : ℝ) ^ (k : ℕ) * ‖cexp (2 * ↑π * Complex.I * y * z)‖ ^ x))] gcongr <;> rename_i i hi <;> simp at hi · exact Nat.le_of_dvd b.2 hi · apply le_of_eq @@ -263,32 +269,31 @@ theorem summable_divisorsAntidiagonal_aux (k : ℕ) (z : ℍ) : simp ring_nf · simpa [← mul_assoc, add_comm k 1, pow_add] using Nat.card_divisors_le_self b - · simp - -theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ ↦ - (c.1 ^ k : ℂ) * Complex.exp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) := by - rw [sigmaAntidiagonalEquivProd.summable_iff.symm] - simp only [sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, Equiv.coe_fn_mk] - apply summable_divisorsAntidiagonal_aux k z + · simp -/ -theorem summable_auxerret (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : +theorem summable_prod_mul_pow (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : Summable fun c : (ℕ+ × ℕ+) ↦ (c.1 : 𝕜) ^ k * (r ^ (c.2 * c.1 : ℕ)) :=by rw [sigmaAntidiagonalEquivProd.summable_iff.symm] simp only [sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, Equiv.coe_fn_mk] - apply summable_divisorsAntidiagonal_aux2 k r hr + apply summable_divisorsAntidiagonal_aux k r hr -theorem tsum_prod_pow_cexp_eq_tsum_sigma2 (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : +theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ ↦ + (c.1 ^ k : ℂ) * Complex.exp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) := by + simpa using summable_prod_mul_pow k (Complex.exp (2 * ↑π * Complex.I * z)) + (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) + +theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : 𝕜) * (r ^ (d * c : ℕ)) = ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) := by suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : 𝕜) * (r ^ ((c.2 : ℕ) * (c.1 : ℕ))) = ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) by - rw [Summable.tsum_prod (by apply summable_auxerret k r hr), Summable.tsum_comm] at this + rw [Summable.tsum_prod (by apply summable_prod_mul_pow k r hr), Summable.tsum_comm] at this · simpa using this - · apply (summable_auxerret k r hr).prod_symm.congr + · apply (summable_prod_mul_pow k r hr).prod_symm.congr simp simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, Equiv.coe_fn_mk, sigma_eq_sum_div', Nat.cast_sum, Nat.cast_pow] - rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux2 k r hr)] + rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k r hr)] apply tsum_congr intro n simp only [tsum_fintype, Finset.univ_eq_attach, Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) @@ -306,46 +311,10 @@ theorem tsum_prod_pow_cexp_eq_tsum_sigma2 (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1 nth_rw 2 [← hni] ring -theorem tsum_prod_pow_cexp_eq_tsum_sigma3 (k : ℕ) (z : ℍ) : - ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = - ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by - have := tsum_prod_pow_cexp_eq_tsum_sigma2 k (cexp (2 * ↑π * Complex.I * z)) - (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) - simp_rw [← this, ← exp_nsmul] - congr - ext n - congr - ext m - ring_nf - - theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by - suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : ℂ) * cexp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) = - ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) by - rw [Summable.tsum_prod (summable_prod_aux k z), Summable.tsum_comm] at this - · simpa using this - · apply (summable_prod_aux k z).prod_symm.congr - simp - simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, - Equiv.coe_fn_mk, sigma_eq_sum_div', Nat.cast_sum, Nat.cast_pow] - rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k z)] - apply tsum_congr - intro n - simp only [tsum_fintype, Finset.univ_eq_attach, Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) - (fun (x : ℕ × ℕ) ↦ (x.1 : ℂ) ^ k * cexp (2 * ↑π * Complex.I * x.2 * z) ^ x.1), - Nat.sum_divisorsAntidiagonal' (fun x y ↦ (x : ℂ) ^ k * cexp (2 * ↑π * Complex.I * y * z) ^ x), - Finset.sum_mul] - refine Finset.sum_congr (rfl) fun i hi ↦ ?_ - have hni : (n / i : ℕ) * (i : ℂ) = n := by - norm_cast - simp only [Nat.mem_divisors, ne_eq, PNat.ne_zero, not_false_eq_true, and_true] at * - exact Nat.div_mul_cancel hi - simp only [← Complex.exp_nsmul, nsmul_eq_mul, ← hni, mul_eq_mul_left_iff, pow_eq_zero_iff', - Nat.cast_eq_zero, Nat.div_eq_zero_iff, ne_eq] - left - ring_nf + simpa using tsum_prod_pow_eq_tsum_sigma k (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) theorem summable_prod_eisSummand {k : ℕ} (hk : 3 ≤ k) (z : ℍ) : Summable fun x : ℤ × ℤ ↦ eisSummand k ![x.1, x.2] z := by diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean index 7482c2e832d259..e5080d3b6da94d 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean @@ -386,6 +386,11 @@ theorem tprod_congr {f g : β → α} (hfg : ∀ b, f b = g b) : ∏' b, f b = ∏' b, g b := congr_arg tprod (funext hfg) +@[to_additive] +theorem tprod_congr2 {f g : γ → β → α} + (hfg : ∀ b c, f b c = g b c) : ∏' c, ∏' b, f b c = ∏' c, ∏' b, g b c := by + exact tprod_congr fun c ↦ tprod_congr fun b ↦ hfg b c + @[to_additive] theorem tprod_fintype [Fintype β] (f : β → α) : ∏' b, f b = ∏ b, f b := by apply tprod_eq_prod; simp From 60c97013404ddb21bed3c88a6610755d154d4f75 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 10:43:12 +0100 Subject: [PATCH 092/128] move to sep file --- Mathlib.lean | 1 + Mathlib/NumberTheory/Divisors.lean | 40 ------------------------------ 2 files changed, 1 insertion(+), 40 deletions(-) diff --git a/Mathlib.lean b/Mathlib.lean index 2cc6d186aca25c..3e38b28089a0dd 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4823,6 +4823,7 @@ import Mathlib.NumberTheory.Zsqrtd.Basic import Mathlib.NumberTheory.Zsqrtd.GaussianInt import Mathlib.NumberTheory.Zsqrtd.QuadraticReciprocity import Mathlib.NumberTheory.Zsqrtd.ToReal +import Mathlib.NumberTheory.tsumDivsorsAntidiagonal import Mathlib.Order.Antichain import Mathlib.Order.Antisymmetrization import Mathlib.Order.Atoms diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 4d5c444e00ae62..3bd8148230337c 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -744,43 +744,3 @@ lemma mul_mem_zero_one_two_three_four_iff {a b : ℤ} (h₀ : a = 0 ↔ b = 0) : aesop end Int - -section pnat - -/-- The map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` -to `(a , b)`. -/ -def divisorsAntidiagonalFactors (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := - fun x ↦ - ⟨⟨x.1.1, Nat.pos_of_mem_divisors (Nat.fst_mem_divisors_of_mem_antidiagonal x.2)⟩, - (⟨x.1.2, Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ : ℕ+), - Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ - -lemma divisorsAntidiagonalFactors_eq {n : ℕ+} (x : Nat.divisorsAntidiagonal n) : - (divisorsAntidiagonalFactors n x).1.1 * (divisorsAntidiagonalFactors n x).2.1 = n := by - simp [divisorsAntidiagonalFactors, (Nat.mem_divisorsAntidiagonal.mp x.2).1] - -lemma divisorsAntidiagonalFactors_one (x : Nat.divisorsAntidiagonal 1) : - (divisorsAntidiagonalFactors 1 x) = (1, 1) := by - have h := Nat.mem_divisorsAntidiagonal.mp x.2 - simp only [mul_eq_one, ne_eq, one_ne_zero, not_false_eq_true, and_true] at h - simp [divisorsAntidiagonalFactors, h.1, h.2] - -/-- The equivalence from the union over `n` of `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` -given by sending `n = a * b` to `(a , b)`. -/ -def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ℕ+ × ℕ+ where - toFun x := divisorsAntidiagonalFactors x.1 x.2 - invFun x := - ⟨⟨x.1.val * x.2.val, mul_pos x.1.2 x.2.2⟩, ⟨x.1, x.2⟩, by simp [Nat.mem_divisorsAntidiagonal]⟩ - left_inv := by - rintro ⟨n, ⟨k, l⟩, h⟩ - rw [Nat.mem_divisorsAntidiagonal] at h - ext <;> simp [divisorsAntidiagonalFactors, ← PNat.coe_injective.eq_iff, h.1] - right_inv _ := rfl - -lemma sigmaAntidiagonalEquivProd_symm_apply_fst (x : ℕ+ × ℕ+) : - (sigmaAntidiagonalEquivProd.symm x).1 = x.1.1 * x.2.1 := rfl - -lemma sigmaAntidiagonalEquivProd_symm_apply_snd (x : ℕ+ × ℕ+) : - (sigmaAntidiagonalEquivProd.symm x).2 = (x.1.1, x.2.1) := rfl - -end pnat From 593940f736cd69e82e2fc926a101adacde9ca044 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 10:43:51 +0100 Subject: [PATCH 093/128] move to sep file --- .../NumberTheory/tsumDivsorsAntidiagonal.lean | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean diff --git a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean new file mode 100644 index 00000000000000..d35a9c93491d11 --- /dev/null +++ b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean @@ -0,0 +1,50 @@ +/- +Copyright (c) 2025 Chris Birkbeck. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Chris Birkbeck +-/ +import Mathlib.NumberTheory.Divisors + +/-! +# Lemmas on infinite sums over the antidiagonal of the divisors function + +This file contains lemmas about the antidiagonal of the divisors function. It defines the map from +`Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` to `(a, b)`. + +-/ + +/-- The map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` +to `(a , b)`. -/ +def divisorsAntidiagonalFactors (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := + fun x ↦ + ⟨⟨x.1.1, Nat.pos_of_mem_divisors (Nat.fst_mem_divisors_of_mem_antidiagonal x.2)⟩, + (⟨x.1.2, Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ : ℕ+), + Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ + +lemma divisorsAntidiagonalFactors_eq {n : ℕ+} (x : Nat.divisorsAntidiagonal n) : + (divisorsAntidiagonalFactors n x).1.1 * (divisorsAntidiagonalFactors n x).2.1 = n := by + simp [divisorsAntidiagonalFactors, (Nat.mem_divisorsAntidiagonal.mp x.2).1] + +lemma divisorsAntidiagonalFactors_one (x : Nat.divisorsAntidiagonal 1) : + (divisorsAntidiagonalFactors 1 x) = (1, 1) := by + have h := Nat.mem_divisorsAntidiagonal.mp x.2 + simp only [mul_eq_one, ne_eq, one_ne_zero, not_false_eq_true, and_true] at h + simp [divisorsAntidiagonalFactors, h.1, h.2] + +/-- The equivalence from the union over `n` of `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` +given by sending `n = a * b` to `(a , b)`. -/ +def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ℕ+ × ℕ+ where + toFun x := divisorsAntidiagonalFactors x.1 x.2 + invFun x := + ⟨⟨x.1.val * x.2.val, mul_pos x.1.2 x.2.2⟩, ⟨x.1, x.2⟩, by simp [Nat.mem_divisorsAntidiagonal]⟩ + left_inv := by + rintro ⟨n, ⟨k, l⟩, h⟩ + rw [Nat.mem_divisorsAntidiagonal] at h + ext <;> simp [divisorsAntidiagonalFactors, ← PNat.coe_injective.eq_iff, h.1] + right_inv _ := rfl + +lemma sigmaAntidiagonalEquivProd_symm_apply_fst (x : ℕ+ × ℕ+) : + (sigmaAntidiagonalEquivProd.symm x).1 = x.1.1 * x.2.1 := rfl + +lemma sigmaAntidiagonalEquivProd_symm_apply_snd (x : ℕ+ × ℕ+) : + (sigmaAntidiagonalEquivProd.symm x).2 = (x.1.1, x.2.1) := rfl From d2ae6f98b93908c92ad31712478ef44c2996228c Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 10:57:30 +0100 Subject: [PATCH 094/128] open --- .../NumberTheory/tsumDivsorsAntidiagonal.lean | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean index d35a9c93491d11..d6d81d1462ae65 100644 --- a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean @@ -4,6 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ import Mathlib.NumberTheory.Divisors +import Mathlib.Analysis.Complex.UpperHalfPlane.Exp +import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn /-! # Lemmas on infinite sums over the antidiagonal of the divisors function @@ -48,3 +50,125 @@ lemma sigmaAntidiagonalEquivProd_symm_apply_fst (x : ℕ+ × ℕ+) : lemma sigmaAntidiagonalEquivProd_symm_apply_snd (x : ℕ+ × ℕ+) : (sigmaAntidiagonalEquivProd.symm x).2 = (x.1.1, x.2.1) := rfl + +section tsum + +open UpperHalfPlane Real Complex ArithmeticFunctions Nat + +lemma natcast_norm {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormSMulClass ℤ 𝕜] + (a : ℕ) : ‖(a : 𝕜)‖ = a := by + have h0 := norm_natCast_eq_mul_norm_one 𝕜 a + simpa using h0 + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] + +theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : + Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ + (c.2.1).1 ^ k * (r ^ (c.2.1.2 * c.2.1.1)) := by + apply Summable.of_norm + rw [summable_sigma_of_nonneg] + constructor + · apply fun n => (hasSum_fintype _).summable + · simp only [norm_mul, norm_pow, tsum_fintype, Finset.univ_eq_attach] + · apply Summable.of_nonneg_of_le (f := fun c : ℕ+ ↦ ‖(c : 𝕜) ^ (k + 1) * r ^ (c : ℕ)‖) + (fun b => Finset.sum_nonneg (fun _ _ => by apply mul_nonneg (by simp) (by simp))) ?_ + (by apply (summable_norm_pow_mul_geometric_of_norm_lt_one (k + 1) hr).subtype) + intro b + apply le_trans (b := ∑ _ ∈ (b : ℕ).divisors, ‖(b : 𝕜)‖ ^ k * ‖r ^ (b : ℕ)‖) + · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun x ↦ + ‖(x.1 : 𝕜)‖ ^ (k : ℕ) * ‖r‖^ (x.2 * x.1)), Nat.sum_divisorsAntidiagonal + ((fun x y ↦ ‖(x : 𝕜)‖ ^ k * ‖r‖ ^ (y * x))) (n := b)] + gcongr <;> rename_i i hi <;> simp [natcast_norm] at * + · exact Nat.le_of_dvd b.2 hi + · apply le_of_eq + nth_rw 2 [← Nat.mul_div_cancel' hi] + ring_nf + · simp only [norm_pow, Finset.sum_const, nsmul_eq_mul, ← mul_assoc, add_comm k 1, pow_add, + pow_one, norm_mul] + gcongr + simpa [natcast_norm] using (Nat.card_divisors_le_self b) + · intro a + simpa using mul_nonneg (by simp) (by simp) + +theorem summable_prod_mul_pow (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : + Summable fun c : (ℕ+ × ℕ+) ↦ (c.1 : 𝕜) ^ k * (r ^ (c.2 * c.1 : ℕ)) :=by + rw [sigmaAntidiagonalEquivProd.summable_iff.symm] + simp only [sigmaAntidiagonalEquivProd, divisorsAntidiagonalFactors, PNat.mk_coe, Equiv.coe_fn_mk] + apply summable_divisorsAntidiagonal_aux k r hr + +/- theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ ↦ + (c.1 ^ k : ℂ) * Complex.exp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) := by + simpa using summable_prod_mul_pow k (Complex.exp (2 * ↑π * Complex.I * z)) + (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) -/ + +theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : + ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : 𝕜) * (r ^ (d * c : ℕ)) = + ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) := by + suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : 𝕜) * (r ^ ((c.2 : ℕ) * (c.1 : ℕ))) = + ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) by + rw [Summable.tsum_prod (by apply summable_prod_mul_pow k r hr), Summable.tsum_comm] at this + · simpa using this + · apply (summable_prod_mul_pow k r hr).prod_symm.congr + simp + simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, + Equiv.coe_fn_mk, sigma_eq_sum_div', Nat.cast_sum, Nat.cast_pow] + rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k r hr)] + apply tsum_congr + intro n + simp only [tsum_fintype, Finset.univ_eq_attach, Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) + (fun (x : ℕ × ℕ) ↦ (x.1 : 𝕜) ^ k * r ^ (x.2 * x.1)), + Nat.sum_divisorsAntidiagonal' (fun x y ↦ (x : 𝕜) ^ k * r ^ (y * x)), + Finset.sum_mul] + refine Finset.sum_congr (rfl) fun i hi ↦ ?_ + have hni : (n / i : ℕ) * (i : ℕ) = n := by + simp only [Nat.mem_divisors, ne_eq, PNat.ne_zero, not_false_eq_true, and_true] at * + have := Nat.div_mul_cancel hi + nth_rw 2 [← this] + simp + left + norm_cast at * + nth_rw 2 [← hni] + ring + +lemma tsum_eq_tsum_sigma (z : ℍ) : ∑' n : ℕ+, + n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) / (1 - cexp (2 * π * Complex.I * z) ^ (n : ℕ)) = + ∑' n : ℕ+, σ 1 n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by + have := fun m : ℕ+ => tsum_choose_mul_geometric_of_norm_lt_one + (r := (cexp (2 * ↑π * Complex.I * z)) ^ (m : ℕ)) 0 (by simpa using + (pow_lt_one₀ (by simp) (UpperHalfPlane.norm_exp_two_pi_I_lt_one z) (by apply PNat.ne_zero))) + simp only [add_zero, Nat.choose_zero_right, Nat.cast_one, one_mul, zero_add, pow_one, + one_div] at this + conv => + enter [1,1] + ext n + rw [div_eq_mul_one_div] + simp only [one_div, ← this n, ← tsum_mul_left] + conv => + enter [1] + ext m + rw [mul_assoc, ← pow_succ' (cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ)) m ] + have h00 := (tsum_prod_pow_cexp_eq_tsum_sigma z (k := 1)) + rw [Summable.tsum_comm (by apply summable_prod_aux (k := 1) z)] at h00 + rw [← h00] + apply tsum_congr + intro b + rw [← tsum_pnat_eq_tsum_succ (fun n => b * (cexp (2 * π * Complex.I * z) ^ (b : ℕ)) ^ (n : ℕ))] + apply tsum_congr + intro c + simp only [← exp_nsmul, nsmul_eq_mul, pow_one, mul_eq_mul_left_iff, Nat.cast_eq_zero, + PNat.ne_zero, or_false] + ring_nf + +lemma summable_norm_pow_mul_geometric_div_one_sub {F : Type*} [NontriviallyNormedField F] + [CompleteSpace F] (k : ℕ) {r : F} (hr : ‖r‖ < 1) : + Summable fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n) := by + rw [show (fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n)) = + fun n : ℕ ↦ (n ^ k * r ^ n) * (1 / (1 - r ^ n)) by grind] + apply summable_mul_tendsto_const (c := 1 / (1 - 0)) + (by simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one k hr)) + rw [Nat.cofinite_eq_atTop] + have : Tendsto (fun n : ℕ ↦ 1 - r ^ n) atTop (𝓝 (1 - 0)) := + Filter.Tendsto.sub (by simp) (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hr) + have h1 : Tendsto (fun n : ℕ ↦ (1 : F)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] + apply (Filter.Tendsto.div h1 this (by simp)).congr + simp From 071e81aef885f25ce44ffd2f8fc1572eb77870d6 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 11:00:37 +0100 Subject: [PATCH 095/128] open --- Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean index d6d81d1462ae65..186bc0a1463831 100644 --- a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean @@ -7,6 +7,7 @@ import Mathlib.NumberTheory.Divisors import Mathlib.Analysis.Complex.UpperHalfPlane.Exp import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn + /-! # Lemmas on infinite sums over the antidiagonal of the divisors function @@ -53,7 +54,7 @@ lemma sigmaAntidiagonalEquivProd_symm_apply_snd (x : ℕ+ × ℕ+) : section tsum -open UpperHalfPlane Real Complex ArithmeticFunctions Nat +open UpperHalfPlane Real Complex ArithmeticFunction Nat lemma natcast_norm {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormSMulClass ℤ 𝕜] (a : ℕ) : ‖(a : 𝕜)‖ = a := by @@ -62,6 +63,12 @@ lemma natcast_norm {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormSMulClass variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] +@[simp] +lemma cexp_pow_aux (a b : ℕ) (z : ℍ) : + cexp (2 * ↑π * Complex.I * a * z) ^ b = Complex.exp (2 * ↑π * Complex.I * z) ^ (a * b) := by + simp [← Complex.exp_nsmul] + ring_nf + theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ (c.2.1).1 ^ k * (r ^ (c.2.1.2 * c.2.1.1)) := by From 99658a2015fe98e4bdfb1833d2f2615129b96006 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 11:02:47 +0100 Subject: [PATCH 096/128] open2 --- Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean index 186bc0a1463831..022329bb25c8dd 100644 --- a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean @@ -6,6 +6,14 @@ Authors: Chris Birkbeck import Mathlib.NumberTheory.Divisors import Mathlib.Analysis.Complex.UpperHalfPlane.Exp import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn +import Mathlib.Algebra.Order.Ring.Star +import Mathlib.Analysis.SpecialFunctions.Trigonometric.Cotangent +import Mathlib.Data.Int.Star +import Mathlib.NumberTheory.LSeries.Dirichlet +import Mathlib.NumberTheory.LSeries.HurwitzZetaValues +import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Basic +import Mathlib.Topology.EMetricSpace.Paracompact +import Mathlib.Topology.Separation.CompletelyRegular /-! @@ -117,8 +125,8 @@ theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : · simpa using this · apply (summable_prod_mul_pow k r hr).prod_symm.congr simp - simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, - Equiv.coe_fn_mk, sigma_eq_sum_div', Nat.cast_sum, Nat.cast_pow] + simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, + divisorsAntidiagonalFactors, PNat.mk_coe, Equiv.coe_fn_mk, sigma_eq_sum_div', Nat.cast_sum, Nat.cast_pow] rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k r hr)] apply tsum_congr intro n From f86617fa8ed378a845772016b2fe05e673118a4f Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 11:22:52 +0100 Subject: [PATCH 097/128] open3 --- Mathlib/NumberTheory/ArithmeticFunction.lean | 3 ++ .../NumberTheory/tsumDivsorsAntidiagonal.lean | 50 +++++++------------ 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/Mathlib/NumberTheory/ArithmeticFunction.lean b/Mathlib/NumberTheory/ArithmeticFunction.lean index d54051c03b484f..2da7320057ddd7 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction.lean @@ -823,6 +823,9 @@ theorem sigma_one_apply_prime_pow {p i : ℕ} (hp : p.Prime) : σ 1 (p ^ i) = ∑ k ∈ .range (i + 1), p ^ k := by simp [sigma_apply_prime_pow hp] +theorem sigma_eq_sum_div' (k n : ℕ) : sigma k n = ∑ d ∈ Nat.divisors n, (n / d) ^ k := by + rw [sigma, ArithmeticFunction.coe_mk, ← Nat.sum_div_divisors] + theorem sigma_zero_apply (n : ℕ) : σ 0 n = #n.divisors := by simp [sigma_apply] theorem sigma_zero_apply_prime_pow {p i : ℕ} (hp : p.Prime) : σ 0 (p ^ i) = i + 1 := by diff --git a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean index 022329bb25c8dd..d6e43aadc992ff 100644 --- a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean @@ -9,7 +9,7 @@ import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn import Mathlib.Algebra.Order.Ring.Star import Mathlib.Analysis.SpecialFunctions.Trigonometric.Cotangent import Mathlib.Data.Int.Star -import Mathlib.NumberTheory.LSeries.Dirichlet +import Mathlib.NumberTheory.ArithmeticFunction import Mathlib.NumberTheory.LSeries.HurwitzZetaValues import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Basic import Mathlib.Topology.EMetricSpace.Paracompact @@ -71,12 +71,6 @@ lemma natcast_norm {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormSMulClass variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] -@[simp] -lemma cexp_pow_aux (a b : ℕ) (z : ℍ) : - cexp (2 * ↑π * Complex.I * a * z) ^ b = Complex.exp (2 * ↑π * Complex.I * z) ^ (a * b) := by - simp [← Complex.exp_nsmul] - ring_nf - theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ (c.2.1).1 ^ k * (r ^ (c.2.1.2 * c.2.1.1)) := by @@ -105,28 +99,23 @@ theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1 · intro a simpa using mul_nonneg (by simp) (by simp) -theorem summable_prod_mul_pow (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : +theorem summable_prod_mul_pow (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : Summable fun c : (ℕ+ × ℕ+) ↦ (c.1 : 𝕜) ^ k * (r ^ (c.2 * c.1 : ℕ)) :=by rw [sigmaAntidiagonalEquivProd.summable_iff.symm] simp only [sigmaAntidiagonalEquivProd, divisorsAntidiagonalFactors, PNat.mk_coe, Equiv.coe_fn_mk] apply summable_divisorsAntidiagonal_aux k r hr -/- theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ ↦ - (c.1 ^ k : ℂ) * Complex.exp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) := by - simpa using summable_prod_mul_pow k (Complex.exp (2 * ↑π * Complex.I * z)) - (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) -/ - theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : - ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : 𝕜) * (r ^ (d * c : ℕ)) = - ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) := by + ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : 𝕜) * (r ^ (d * c : ℕ)) = ∑' e : ℕ+, σ k e * r ^ (e : ℕ) := by suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : 𝕜) * (r ^ ((c.2 : ℕ) * (c.1 : ℕ))) = - ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) by - rw [Summable.tsum_prod (by apply summable_prod_mul_pow k r hr), Summable.tsum_comm] at this + ∑' e : ℕ+, σ k e * r ^ (e : ℕ) by + rw [Summable.tsum_prod (by apply summable_prod_mul_pow k hr), Summable.tsum_comm] at this · simpa using this - · apply (summable_prod_mul_pow k r hr).prod_symm.congr + · apply (summable_prod_mul_pow k hr).prod_symm.congr simp simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, - divisorsAntidiagonalFactors, PNat.mk_coe, Equiv.coe_fn_mk, sigma_eq_sum_div', Nat.cast_sum, Nat.cast_pow] + divisorsAntidiagonalFactors, PNat.mk_coe, Equiv.coe_fn_mk, sigma_eq_sum_div', cast_sum, + cast_pow] rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k r hr)] apply tsum_congr intro n @@ -145,12 +134,10 @@ theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : nth_rw 2 [← hni] ring -lemma tsum_eq_tsum_sigma (z : ℍ) : ∑' n : ℕ+, - n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) / (1 - cexp (2 * π * Complex.I * z) ^ (n : ℕ)) = - ∑' n : ℕ+, σ 1 n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by +lemma tsum_eq_tsum_sigma {r : 𝕜} (hr : ‖r‖ < 1) : + ∑' n : ℕ+, n * r ^ (n : ℕ) / (1 - r ^ (n : ℕ)) = ∑' n : ℕ+, σ 1 n * r ^ (n : ℕ) := by have := fun m : ℕ+ => tsum_choose_mul_geometric_of_norm_lt_one - (r := (cexp (2 * ↑π * Complex.I * z)) ^ (m : ℕ)) 0 (by simpa using - (pow_lt_one₀ (by simp) (UpperHalfPlane.norm_exp_two_pi_I_lt_one z) (by apply PNat.ne_zero))) + (r := r ^ (m : ℕ)) 0 (by simpa using (pow_lt_one₀ (by simp) hr (by apply PNat.ne_zero))) simp only [add_zero, Nat.choose_zero_right, Nat.cast_one, one_mul, zero_add, pow_one, one_div] at this conv => @@ -161,18 +148,19 @@ lemma tsum_eq_tsum_sigma (z : ℍ) : ∑' n : ℕ+, conv => enter [1] ext m - rw [mul_assoc, ← pow_succ' (cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ)) m ] - have h00 := (tsum_prod_pow_cexp_eq_tsum_sigma z (k := 1)) - rw [Summable.tsum_comm (by apply summable_prod_aux (k := 1) z)] at h00 + rw [mul_assoc, ← pow_succ' (r ^ (n : ℕ)) m ] + have h00 := (tsum_prod_pow_eq_tsum_sigma 1 hr) + rw [Summable.tsum_comm (by apply summable_prod_mul_pow 1 hr)] at h00 rw [← h00] apply tsum_congr intro b - rw [← tsum_pnat_eq_tsum_succ (fun n => b * (cexp (2 * π * Complex.I * z) ^ (b : ℕ)) ^ (n : ℕ))] + rw [← tsum_pnat_eq_tsum_succ (fun n => b * (r ^ (b : ℕ)) ^ (n : ℕ))] apply tsum_congr intro c - simp only [← exp_nsmul, nsmul_eq_mul, pow_one, mul_eq_mul_left_iff, Nat.cast_eq_zero, - PNat.ne_zero, or_false] - ring_nf + simp only [← pow_mul, pow_one, mul_eq_mul_left_iff] + left + ring + lemma summable_norm_pow_mul_geometric_div_one_sub {F : Type*} [NontriviallyNormedField F] [CompleteSpace F] (k : ℕ) {r : F} (hr : ‖r‖ < 1) : From b3dc880bc169789028716c0c1e439909a9a007d9 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 11:37:06 +0100 Subject: [PATCH 098/128] open4 --- Mathlib/Analysis/Asymptotics/Lemmas.lean | 8 ++++ .../NumberTheory/tsumDivsorsAntidiagonal.lean | 44 ++++++++++--------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Mathlib/Analysis/Asymptotics/Lemmas.lean b/Mathlib/Analysis/Asymptotics/Lemmas.lean index 1ff1e0b3f24005..8fb8db474c5244 100644 --- a/Mathlib/Analysis/Asymptotics/Lemmas.lean +++ b/Mathlib/Analysis/Asymptotics/Lemmas.lean @@ -676,6 +676,14 @@ lemma Asymptotics.IsBigO.comp_summable_norm {ι E F : Type*} summable_of_isBigO hg <| hf.norm_norm.comp_tendsto <| tendsto_zero_iff_norm_tendsto_zero.2 hg.tendsto_cofinite_zero +lemma summable_mul_tendsto_const {F ι : Type*} [NontriviallyNormedField F] [CompleteSpace F] + {f g : ι → F} (hf : Summable fun n => ‖f n‖) {c : F} (hg : Tendsto g cofinite (𝓝 c)) : + Summable fun n : ι ↦ f n * g n := by + apply summable_of_isBigO hf + have h0 : g =O[cofinite] fun _x ↦ (1 : F) := by + apply Filter.Tendsto.isBigO_one + exact hg + simpa using ((Asymptotics.isBigO_const_mul_self 1 f cofinite).mul h0) namespace PartialHomeomorph variable {α : Type*} {β : Type*} [TopologicalSpace α] [TopologicalSpace β] diff --git a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean index d6e43aadc992ff..3a134c9dbb77f9 100644 --- a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean @@ -62,14 +62,29 @@ lemma sigmaAntidiagonalEquivProd_symm_apply_snd (x : ℕ+ × ℕ+) : section tsum -open UpperHalfPlane Real Complex ArithmeticFunction Nat +open Filter Complex ArithmeticFunction Nat Topology -lemma natcast_norm {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormSMulClass ℤ 𝕜] +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + +lemma natCast_norm [NormSMulClass ℤ 𝕜] (a : ℕ) : ‖(a : 𝕜)‖ = a := by have h0 := norm_natCast_eq_mul_norm_one 𝕜 a simpa using h0 -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] +lemma summable_norm_pow_mul_geometric_div_one_sub [CompleteSpace 𝕜] (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : + Summable fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n) := by + rw [show (fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n)) = + fun n : ℕ ↦ (n ^ k * r ^ n) * (1 / (1 - r ^ n)) by grind] + apply summable_mul_tendsto_const (c := 1 / (1 - 0)) + (by simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one k hr)) + rw [Nat.cofinite_eq_atTop] + have : Tendsto (fun n : ℕ ↦ 1 - r ^ n) atTop (𝓝 (1 - 0)) := + Filter.Tendsto.sub (by simp) (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hr) + have h1 : Tendsto (fun n : ℕ ↦ (1 : 𝕜)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] + apply (Filter.Tendsto.div h1 this (by simp)).congr + simp + +variable [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ @@ -87,7 +102,7 @@ theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1 · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun x ↦ ‖(x.1 : 𝕜)‖ ^ (k : ℕ) * ‖r‖^ (x.2 * x.1)), Nat.sum_divisorsAntidiagonal ((fun x y ↦ ‖(x : 𝕜)‖ ^ k * ‖r‖ ^ (y * x))) (n := b)] - gcongr <;> rename_i i hi <;> simp [natcast_norm] at * + gcongr <;> rename_i i hi <;> simp [natCast_norm] at * · exact Nat.le_of_dvd b.2 hi · apply le_of_eq nth_rw 2 [← Nat.mul_div_cancel' hi] @@ -95,7 +110,7 @@ theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1 · simp only [norm_pow, Finset.sum_const, nsmul_eq_mul, ← mul_assoc, add_comm k 1, pow_add, pow_one, norm_mul] gcongr - simpa [natcast_norm] using (Nat.card_divisors_le_self b) + simpa [natCast_norm] using (Nat.card_divisors_le_self b) · intro a simpa using mul_nonneg (by simp) (by simp) @@ -148,30 +163,17 @@ lemma tsum_eq_tsum_sigma {r : 𝕜} (hr : ‖r‖ < 1) : conv => enter [1] ext m - rw [mul_assoc, ← pow_succ' (r ^ (n : ℕ)) m ] + rw [mul_assoc, ← pow_succ' (r ^ (n : ℕ)) m] + rw [← tsum_pnat_eq_tsum_succ (fun m => n * (r ^ (n : ℕ)) ^ (m : ℕ))] have h00 := (tsum_prod_pow_eq_tsum_sigma 1 hr) rw [Summable.tsum_comm (by apply summable_prod_mul_pow 1 hr)] at h00 rw [← h00] apply tsum_congr intro b - rw [← tsum_pnat_eq_tsum_succ (fun n => b * (r ^ (b : ℕ)) ^ (n : ℕ))] apply tsum_congr intro c simp only [← pow_mul, pow_one, mul_eq_mul_left_iff] left ring - -lemma summable_norm_pow_mul_geometric_div_one_sub {F : Type*} [NontriviallyNormedField F] - [CompleteSpace F] (k : ℕ) {r : F} (hr : ‖r‖ < 1) : - Summable fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n) := by - rw [show (fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n)) = - fun n : ℕ ↦ (n ^ k * r ^ n) * (1 / (1 - r ^ n)) by grind] - apply summable_mul_tendsto_const (c := 1 / (1 - 0)) - (by simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one k hr)) - rw [Nat.cofinite_eq_atTop] - have : Tendsto (fun n : ℕ ↦ 1 - r ^ n) atTop (𝓝 (1 - 0)) := - Filter.Tendsto.sub (by simp) (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hr) - have h1 : Tendsto (fun n : ℕ ↦ (1 : F)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] - apply (Filter.Tendsto.div h1 this (by simp)).congr - simp +end tsum From 8b71aa764ae49c30a77bdf4c4af5f635a35229c5 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 11:53:47 +0100 Subject: [PATCH 099/128] open --- Mathlib/NumberTheory/Divisors.lean | 1 - .../NumberTheory/tsumDivsorsAntidiagonal.lean | 52 ++++++++----------- .../Topology/Algebra/InfiniteSum/Basic.lean | 5 ++ 3 files changed, 26 insertions(+), 32 deletions(-) diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 3bd8148230337c..44fdd93b6ee4e8 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -11,7 +11,6 @@ import Mathlib.Algebra.Ring.CharZero import Mathlib.Data.Nat.Cast.Order.Ring import Mathlib.Data.Nat.PrimeFin import Mathlib.Data.Nat.SuccPred -import Mathlib.Data.PNat.Defs import Mathlib.Order.Interval.Finset.Nat /-! diff --git a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean index 3a134c9dbb77f9..ef1ac8689456d3 100644 --- a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean @@ -3,16 +3,13 @@ Copyright (c) 2025 Chris Birkbeck. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ -import Mathlib.NumberTheory.Divisors -import Mathlib.Analysis.Complex.UpperHalfPlane.Exp -import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn import Mathlib.Algebra.Order.Ring.Star -import Mathlib.Analysis.SpecialFunctions.Trigonometric.Cotangent -import Mathlib.Data.Int.Star +import Mathlib.Analysis.RCLike.Basic +import Mathlib.Analysis.SpecificLimits.Normed import Mathlib.NumberTheory.ArithmeticFunction -import Mathlib.NumberTheory.LSeries.HurwitzZetaValues -import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Basic +import Mathlib.RingTheory.LocalRing.Basic import Mathlib.Topology.EMetricSpace.Paracompact +import Mathlib.Topology.GDelta.MetrizableSpace import Mathlib.Topology.Separation.CompletelyRegular @@ -87,7 +84,7 @@ lemma summable_norm_pow_mul_geometric_div_one_sub [CompleteSpace 𝕜] (k : ℕ) variable [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : - Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ + Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal} ↦ (c.2.1).1 ^ k * (r ^ (c.2.1.2 * c.2.1.1)) := by apply Summable.of_norm rw [summable_sigma_of_nonneg] @@ -115,41 +112,37 @@ theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1 simpa using mul_nonneg (by simp) (by simp) theorem summable_prod_mul_pow (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : - Summable fun c : (ℕ+ × ℕ+) ↦ (c.1 : 𝕜) ^ k * (r ^ (c.2 * c.1 : ℕ)) :=by + Summable fun c : (ℕ+ × ℕ+) ↦ c.1 ^ k * (r ^ (c.2 * c.1 : ℕ)) := by rw [sigmaAntidiagonalEquivProd.summable_iff.symm] simp only [sigmaAntidiagonalEquivProd, divisorsAntidiagonalFactors, PNat.mk_coe, Equiv.coe_fn_mk] apply summable_divisorsAntidiagonal_aux k r hr theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : - ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : 𝕜) * (r ^ (d * c : ℕ)) = ∑' e : ℕ+, σ k e * r ^ (e : ℕ) := by - suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : 𝕜) * (r ^ ((c.2 : ℕ) * (c.1 : ℕ))) = + ∑' d : ℕ+, ∑' (c : ℕ+), c ^ k * (r ^ (d * c : ℕ)) = ∑' e : ℕ+, σ k e * r ^ (e : ℕ) := by + suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : 𝕜) * (r ^ ((c.2 : ℕ) * (c.1 : ℕ))) = ∑' e : ℕ+, σ k e * r ^ (e : ℕ) by - rw [Summable.tsum_prod (by apply summable_prod_mul_pow k hr), Summable.tsum_comm] at this + rw [Summable.tsum_prod (by apply summable_prod_mul_pow k hr), Summable.tsum_comm] at this · simpa using this - · apply (summable_prod_mul_pow k hr).prod_symm.congr + · apply (summable_prod_mul_pow k hr).prod_symm.congr simp simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, divisorsAntidiagonalFactors, PNat.mk_coe, Equiv.coe_fn_mk, sigma_eq_sum_div', cast_sum, - cast_pow] - rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k r hr)] + cast_pow, Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k r hr)] apply tsum_congr intro n simp only [tsum_fintype, Finset.univ_eq_attach, Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) - (fun (x : ℕ × ℕ) ↦ (x.1 : 𝕜) ^ k * r ^ (x.2 * x.1)), - Nat.sum_divisorsAntidiagonal' (fun x y ↦ (x : 𝕜) ^ k * r ^ (y * x)), - Finset.sum_mul] + (fun (x : ℕ × ℕ) ↦ (x.1 : 𝕜) ^ k * r ^ (x.2 * x.1)), Nat.sum_divisorsAntidiagonal' + (fun x y ↦ (x : 𝕜) ^ k * r ^ (y * x)), Finset.sum_mul] refine Finset.sum_congr (rfl) fun i hi ↦ ?_ have hni : (n / i : ℕ) * (i : ℕ) = n := by simp only [Nat.mem_divisors, ne_eq, PNat.ne_zero, not_false_eq_true, and_true] at * - have := Nat.div_mul_cancel hi - nth_rw 2 [← this] - simp + nth_rw 2 [← Nat.div_mul_cancel hi] + rw [mul_eq_mul_left_iff, pow_eq_zero_iff', ne_eq] left - norm_cast at * nth_rw 2 [← hni] ring -lemma tsum_eq_tsum_sigma {r : 𝕜} (hr : ‖r‖ < 1) : +lemma tsum_pow_div_one_sub_eq_tsum_sigma {r : 𝕜} (hr : ‖r‖ < 1) : ∑' n : ℕ+, n * r ^ (n : ℕ) / (1 - r ^ (n : ℕ)) = ∑' n : ℕ+, σ 1 n * r ^ (n : ℕ) := by have := fun m : ℕ+ => tsum_choose_mul_geometric_of_norm_lt_one (r := r ^ (m : ℕ)) 0 (by simpa using (pow_lt_one₀ (by simp) hr (by apply PNat.ne_zero))) @@ -158,21 +151,18 @@ lemma tsum_eq_tsum_sigma {r : 𝕜} (hr : ‖r‖ < 1) : conv => enter [1,1] ext n - rw [div_eq_mul_one_div] - simp only [one_div, ← this n, ← tsum_mul_left] + rw [div_eq_mul_one_div, one_div, ← this n, ← tsum_mul_left] conv => enter [1] ext m rw [mul_assoc, ← pow_succ' (r ^ (n : ℕ)) m] - rw [← tsum_pnat_eq_tsum_succ (fun m => n * (r ^ (n : ℕ)) ^ (m : ℕ))] + rw [← tsum_pnat_eq_tsum_succ (fun m => n * (r ^ (n : ℕ)) ^ (m : ℕ))] have h00 := (tsum_prod_pow_eq_tsum_sigma 1 hr) rw [Summable.tsum_comm (by apply summable_prod_mul_pow 1 hr)] at h00 rw [← h00] - apply tsum_congr - intro b - apply tsum_congr - intro c - simp only [← pow_mul, pow_one, mul_eq_mul_left_iff] + apply tsum_congr2 + intro b c + rw [← pow_mul, pow_one, mul_eq_mul_left_iff] left ring diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean index 7482c2e832d259..e5080d3b6da94d 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean @@ -386,6 +386,11 @@ theorem tprod_congr {f g : β → α} (hfg : ∀ b, f b = g b) : ∏' b, f b = ∏' b, g b := congr_arg tprod (funext hfg) +@[to_additive] +theorem tprod_congr2 {f g : γ → β → α} + (hfg : ∀ b c, f b c = g b c) : ∏' c, ∏' b, f b c = ∏' c, ∏' b, g b c := by + exact tprod_congr fun c ↦ tprod_congr fun b ↦ hfg b c + @[to_additive] theorem tprod_fintype [Fintype β] (f : β → α) : ∏' b, f b = ∏ b, f b := by apply tprod_eq_prod; simp From 6003544603a1dd36f7601e11ea55967ef01a25da Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 12:02:32 +0100 Subject: [PATCH 100/128] save --- Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean index ef1ac8689456d3..66b159d7984706 100644 --- a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean @@ -19,6 +19,10 @@ import Mathlib.Topology.Separation.CompletelyRegular This file contains lemmas about the antidiagonal of the divisors function. It defines the map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` to `(a, b)`. +We then prove some identities about the infinite sums over this antidiagonal, such as +`∑' n : ℕ+, n * r ^ (n : ℕ) / (1 - r ^ (n : ℕ)) = ∑' n : ℕ+, σ 1 n * r ^ (n : ℕ)` which are used for +Eisenstein series and their q-expansions. + -/ /-- The map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` @@ -63,10 +67,8 @@ open Filter Complex ArithmeticFunction Nat Topology variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] -lemma natCast_norm [NormSMulClass ℤ 𝕜] - (a : ℕ) : ‖(a : 𝕜)‖ = a := by - have h0 := norm_natCast_eq_mul_norm_one 𝕜 a - simpa using h0 +lemma natCast_norm [NormSMulClass ℤ 𝕜] (a : ℕ) : ‖(a : 𝕜)‖ = a := by + simpa using norm_natCast_eq_mul_norm_one 𝕜 a lemma summable_norm_pow_mul_geometric_div_one_sub [CompleteSpace 𝕜] (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : Summable fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n) := by @@ -119,7 +121,7 @@ theorem summable_prod_mul_pow (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : ∑' d : ℕ+, ∑' (c : ℕ+), c ^ k * (r ^ (d * c : ℕ)) = ∑' e : ℕ+, σ k e * r ^ (e : ℕ) := by - suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : 𝕜) * (r ^ ((c.2 : ℕ) * (c.1 : ℕ))) = + suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : 𝕜) * (r ^ (c.2 * c.1 : ℕ)) = ∑' e : ℕ+, σ k e * r ^ (e : ℕ) by rw [Summable.tsum_prod (by apply summable_prod_mul_pow k hr), Summable.tsum_comm] at this · simpa using this From 0f800da84a9154a8c73e72b69446cfcd56eeaf8d Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 12:19:34 +0100 Subject: [PATCH 101/128] fix name --- Mathlib.lean | 2 +- ...sumDivsorsAntidiagonal.lean => TsumDivsorsAntidiagonal.lean} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename Mathlib/NumberTheory/{tsumDivsorsAntidiagonal.lean => TsumDivsorsAntidiagonal.lean} (100%) diff --git a/Mathlib.lean b/Mathlib.lean index 3e38b28089a0dd..f013f20120f298 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4815,6 +4815,7 @@ import Mathlib.NumberTheory.Transcendental.Liouville.LiouvilleNumber import Mathlib.NumberTheory.Transcendental.Liouville.LiouvilleWith import Mathlib.NumberTheory.Transcendental.Liouville.Measure import Mathlib.NumberTheory.Transcendental.Liouville.Residual +import Mathlib.NumberTheory.TsumDivsorsAntidiagonal import Mathlib.NumberTheory.VonMangoldt import Mathlib.NumberTheory.WellApproximable import Mathlib.NumberTheory.Wilson @@ -4823,7 +4824,6 @@ import Mathlib.NumberTheory.Zsqrtd.Basic import Mathlib.NumberTheory.Zsqrtd.GaussianInt import Mathlib.NumberTheory.Zsqrtd.QuadraticReciprocity import Mathlib.NumberTheory.Zsqrtd.ToReal -import Mathlib.NumberTheory.tsumDivsorsAntidiagonal import Mathlib.Order.Antichain import Mathlib.Order.Antisymmetrization import Mathlib.Order.Atoms diff --git a/Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean similarity index 100% rename from Mathlib/NumberTheory/tsumDivsorsAntidiagonal.lean rename to Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean From 9ea51fbbb63d840b9dee1c3ccd72fb0f58ed4d43 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 12:31:36 +0100 Subject: [PATCH 102/128] fix imports --- Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean index 66b159d7984706..4e0bc7adfa1ba7 100644 --- a/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean @@ -8,7 +8,6 @@ import Mathlib.Analysis.RCLike.Basic import Mathlib.Analysis.SpecificLimits.Normed import Mathlib.NumberTheory.ArithmeticFunction import Mathlib.RingTheory.LocalRing.Basic -import Mathlib.Topology.EMetricSpace.Paracompact import Mathlib.Topology.GDelta.MetrizableSpace import Mathlib.Topology.Separation.CompletelyRegular @@ -169,3 +168,5 @@ lemma tsum_pow_div_one_sub_eq_tsum_sigma {r : 𝕜} (hr : ‖r‖ < 1) : ring end tsum + +#min_imports From bd0e958b37c21932a87c8d738bfd477c1a3a778e Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 12:42:20 +0100 Subject: [PATCH 103/128] fix --- Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean index 4e0bc7adfa1ba7..0cac65cbc8d8cc 100644 --- a/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean @@ -168,5 +168,3 @@ lemma tsum_pow_div_one_sub_eq_tsum_sigma {r : 𝕜} (hr : ‖r‖ < 1) : ring end tsum - -#min_imports From b7fe8c9a31dd5926c5f09cff244acc855c04bb92 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 13:48:00 +0100 Subject: [PATCH 104/128] fix --- Mathlib/NumberTheory/Divisors.lean | 33 ------ .../ModularForms/DedekindEta.lean | 73 +++---------- .../EisensteinSeries/QExpansion.lean | 102 +----------------- 3 files changed, 16 insertions(+), 192 deletions(-) diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index d98aa3ee8da914..44fdd93b6ee4e8 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -12,7 +12,6 @@ import Mathlib.Data.Nat.Cast.Order.Ring import Mathlib.Data.Nat.PrimeFin import Mathlib.Data.Nat.SuccPred import Mathlib.Order.Interval.Finset.Nat -import Mathlib.Data.PNat.Defs /-! # Divisor Finsets @@ -744,35 +743,3 @@ lemma mul_mem_zero_one_two_three_four_iff {a b : ℤ} (h₀ : a = 0 ↔ b = 0) : aesop end Int - -section pnat - -/-- The map from `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` given by sending `n = a * b` -to `(a , b)`. -/ -def mapdiv (n : ℕ+) : Nat.divisorsAntidiagonal n → ℕ+ × ℕ+ := by - refine fun x => - ⟨⟨x.1.1, Nat.pos_of_mem_divisors (Nat.fst_mem_divisors_of_mem_antidiagonal x.2)⟩, - (⟨x.1.2, Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ : ℕ+), - Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal x.2)⟩ - -/-- The equivalence from the union over `n` of `Nat.divisorsAntidiagonal n` to `ℕ+ × ℕ+` -given by sending `n = a * b` to `(a , b)`. -/ -def sigmaAntidiagonalEquivProd : (Σ n : ℕ+, Nat.divisorsAntidiagonal n) ≃ ℕ+ × ℕ+ where - toFun x := mapdiv x.1 x.2 - invFun x := - ⟨⟨x.1.1 * x.2.1, mul_pos x.1.2 x.2.2⟩, ⟨x.1, x.2⟩, by - simp only [PNat.mk_coe, Nat.mem_divisorsAntidiagonal, ne_eq, mul_eq_zero, not_or] - refine ⟨rfl, PNat.ne_zero x.1, PNat.ne_zero x.2⟩⟩ - left_inv := by - rintro ⟨n, ⟨k, l⟩, h⟩ - rw [Nat.mem_divisorsAntidiagonal] at h - simp_rw [mapdiv, PNat.mk_coe] - ext <;> simp [h] at * - rfl - right_inv := by - rintro ⟨n, ⟨k, l⟩, h⟩ - · simp_rw [mapdiv] - norm_cast - · rfl - -end pnat diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 4755abdad308e8..5049e2a74f2d1c 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -12,6 +12,7 @@ import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn import Mathlib.Data.Complex.FiniteDimensional import Mathlib.Analysis.Calculus.LogDerivUniformlyOn import Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2 +import Mathlib.NumberTheory.TsumDivsorsAntidiagonal /-! # Dedekind eta function @@ -103,7 +104,7 @@ lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = ext z simp [logDeriv] -lemma logDeriv_z_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * Complex.I / 24 := by +lemma logDeriv_q_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * Complex.I / 24 := by have : (𝕢 24) = (fun z ↦ cexp (z)) ∘ (fun z => (2 * ↑π * Complex.I / 24) * z) := by ext y simp only [Periodic.qParam, ofReal_ofNat, comp_apply] @@ -120,15 +121,14 @@ lemma logDeriv_one_sub_mul_cexp_comp (r : ℂ) {g : ℂ → ℂ} (hg : Different private theorem one_sub_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ↦ 1 - eta_q i x) z = 2 * π * Complex.I * (i + 1) * -eta_q i z / (1 - eta_q i z) := by - have h2 : (fun x ↦ 1 - cexp (2 * ↑π * Complex.I * (↑i + 1) * x)) = + have h2 : (fun x ↦ 1 - cexp (2 * ↑π * Complex.I * (i + 1) * x)) = ((fun z ↦ 1 - 1 * cexp z) ∘ fun x ↦ 2 * ↑π * Complex.I * (↑i + 1) * x) := by aesop have h3 : deriv (fun x : ℂ ↦ (2 * π * Complex.I * (i + 1) * x)) = fun _ ↦ 2 * π * Complex.I * (i + 1) := by ext y simpa using deriv_const_mul (2 * π * Complex.I * (i + 1)) (d := fun (x : ℂ) ↦ x) (x := y) simp_rw [eta_q_eq_cexp, h2, logDeriv_one_sub_mul_cexp_comp 1 - (g := fun x ↦ (2 * π * Complex.I * (i + 1) * x)) (by fun_prop), h3] - simp + (g := fun x ↦ (2 * π * Complex.I * (i + 1) * x)) (by fun_prop), h3, neg_mul, one_mul, mul_neg] lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = (2 * π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by @@ -140,7 +140,7 @@ lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - e ring exact tsum_congr (fun i ↦ one_sub_eta_logDeriv_eq z i) -theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by +theorem etaProdTerm_DifferentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ complexUpperHalPlane_isOpen · exact (hD z z.2).differentiableAt (complexUpperHalPlane_isOpen.mem_nhds z.2) @@ -150,63 +150,20 @@ theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := simp lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := - DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) - -lemma tsum_eq_tsum_sigma (z : ℍ) : ∑' n : ℕ+, - n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) / (1 - cexp (2 * π * Complex.I * z) ^ (n : ℕ)) = - ∑' n : ℕ+, σ 1 n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by - have := fun m : ℕ+ => tsum_choose_mul_geometric_of_norm_lt_one - (r := (cexp (2 * ↑π * Complex.I * z)) ^ (m : ℕ)) 0 (by simpa using - (pow_lt_one₀ (by simp) (UpperHalfPlane.norm_exp_two_pi_I_lt_one z) (by apply PNat.ne_zero))) - simp only [add_zero, Nat.choose_zero_right, Nat.cast_one, one_mul, zero_add, pow_one, - one_div] at this - conv => - enter [1,1] - ext n - rw [div_eq_mul_one_div] - simp only [one_div, ← this n, ← tsum_mul_left] - conv => - enter [1] - ext m - rw [mul_assoc, ← pow_succ' (cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ)) m ] - have h00 := (tsum_prod_pow_cexp_eq_tsum_sigma z (k := 1)) - rw [Summable.tsum_comm (by apply summable_prod_aux (k := 1) z)] at h00 - rw [← h00] - apply tsum_congr - intro b - rw [← tsum_pnat_eq_tsum_succ (fun n => b * (cexp (2 * π * Complex.I * z) ^ (b : ℕ)) ^ (n : ℕ))] - apply tsum_congr - intro c - simp only [← exp_nsmul, nsmul_eq_mul, pow_one, mul_eq_mul_left_iff, Nat.cast_eq_zero, - PNat.ne_zero, or_false] - ring_nf - -lemma summable_norm_pow_mul_geometric_div_one_sub {F : Type*} [NontriviallyNormedField F] - [CompleteSpace F] (k : ℕ) {r : F} (hr : ‖r‖ < 1) : - Summable fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n) := by - rw [show (fun n : ℕ ↦ n ^ k * r ^ n / (1 - r ^ n)) = - fun n : ℕ ↦ (n ^ k * r ^ n) * (1 / (1 - r ^ n)) by grind] - apply summable_mul_tendsto_const (c := 1 / (1 - 0)) - (by simpa using (summable_norm_pow_mul_geometric_of_norm_lt_one k hr)) - rw [Nat.cofinite_eq_atTop] - have : Tendsto (fun n : ℕ ↦ 1 - r ^ n) atTop (𝓝 (1 - 0)) := - Filter.Tendsto.sub (by simp) (tendsto_pow_atTop_nhds_zero_of_norm_lt_one hr) - have h1 : Tendsto (fun n : ℕ ↦ (1 : F)) atTop (𝓝 1) := by simp only [tendsto_const_nhds_iff] - apply (Filter.Tendsto.div h1 this (by simp)).congr - simp + DifferentiableAt.mul (by fun_prop) (etaProdTerm_DifferentiableAt z) lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E2 z := by unfold ModularForm.eta etaProdTerm rw [logDeriv_mul (UpperHalfPlane.coe z) (by simp [ne_eq, exp_ne_zero, not_false_eq_true, - Periodic.qParam]) (etaProdTerm_ne_zero z) (by fun_prop) (etaProdTerm_differentiableAt z)] - have HG := logDeriv_tprod_eq_tsum (isOpen_lt continuous_const Complex.continuous_im) (x := z) + Periodic.qParam]) (etaProdTerm_ne_zero z) (by fun_prop) (etaProdTerm_DifferentiableAt z)] + have HG := logDeriv_tprod_eq_tsum (complexUpperHalPlane_isOpen) (x := z) (f := fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) ?_ ?_ ?_ (etaProdTerm_ne_zero z) · rw [show z.1 = UpperHalfPlane.coe z by rfl] at HG - rw [HG] - simp only [logDeriv_z_term z, tsum_log_deriv_eta_q z, mul_neg, E2, one_div, mul_inv_rev, + simp only [HG, logDeriv_q_term z, tsum_log_deriv_eta_q z, mul_neg, E2, one_div, mul_inv_rev, Pi.smul_apply, smul_eq_mul] - rw [G2_q_exp, riemannZeta_two, ← (tsum_eq_tsum_sigma z), mul_sub, sub_eq_add_neg, mul_add] + rw [G2_q_exp, riemannZeta_two, ← tsum_pow_div_one_sub_eq_tsum_sigma + (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z), mul_sub, sub_eq_add_neg, mul_add] conv => enter [1,2,2,1] ext n @@ -215,11 +172,9 @@ lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12 congr 1 · field_simp ring - · have := tsum_pnat_eq_tsum_succ (f := fun n => ( n) * cexp (2 * ↑π * Complex.I * ↑z ) ^ (n) - / (1 - cexp (2 * ↑π * Complex.I * ↑z) ^ n )) - simp at this - rw [this] - field_simp [Periodic.qParam, eta_q_eq_pow] + · have := tsum_pnat_eq_tsum_succ (f := fun n ↦ n * cexp (2 * π * Complex.I * z) ^ n + / (1 - cexp (2 * π * Complex.I * z) ^ n )) + field_simp [this, Periodic.qParam, eta_q_eq_pow] ring_nf congr ext n diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index 9c8b3313774692..718f300bd86346 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -12,6 +12,7 @@ import Mathlib.NumberTheory.LSeries.HurwitzZetaValues import Mathlib.NumberTheory.ModularForms.EisensteinSeries.Basic import Mathlib.Topology.EMetricSpace.Paracompact import Mathlib.Topology.Separation.CompletelyRegular +import Mathlib.NumberTheory.TsumDivsorsAntidiagonal /-! # Einstein series Q-expansions @@ -201,116 +202,17 @@ theorem EisensteinSeries.qExpansion_identity_pnat {k : ℕ} (hk : 1 ≤ k) (z : · apply (summable_pow_mul_cexp k 1 z).congr simp -lemma natcast_norm {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormSMulClass ℤ 𝕜] - (a : ℕ) : ‖(a : 𝕜)‖ = a := by - have h0 := norm_natCast_eq_mul_norm_one 𝕜 a - simpa using h0 - -variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] - @[simp] lemma cexp_pow_aux (a b : ℕ) (z : ℍ) : cexp (2 * ↑π * Complex.I * a * z) ^ b = Complex.exp (2 * ↑π * Complex.I * z) ^ (a * b) := by simp [← Complex.exp_nsmul] ring_nf -theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : - Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ - (c.2.1).1 ^ k * (r ^ (c.2.1.2 * c.2.1.1)) := by - apply Summable.of_norm - rw [summable_sigma_of_nonneg] - constructor - · apply fun n => (hasSum_fintype _).summable - · simp only [norm_mul, norm_pow, tsum_fintype, Finset.univ_eq_attach] - · apply Summable.of_nonneg_of_le (f := fun c : ℕ+ ↦ ‖(c : 𝕜) ^ (k + 1) * r ^ (c : ℕ)‖) - (fun b => Finset.sum_nonneg (fun _ _ => by apply mul_nonneg (by simp) (by simp))) ?_ - (by apply (summable_norm_pow_mul_geometric_of_norm_lt_one (k + 1) hr).subtype) - intro b - apply le_trans (b := ∑ _ ∈ (b : ℕ).divisors, ‖(b : 𝕜)‖ ^ k * ‖r ^ (b : ℕ)‖) - · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun x ↦ - ‖(x.1 : 𝕜)‖ ^ (k : ℕ) * ‖r‖^ (x.2 * x.1)), Nat.sum_divisorsAntidiagonal - ((fun x y ↦ ‖(x : 𝕜)‖ ^ k * ‖r‖ ^ (y * x))) (n := b)] - gcongr <;> rename_i i hi <;> simp [natcast_norm] at * - · exact Nat.le_of_dvd b.2 hi - · apply le_of_eq - nth_rw 2 [← Nat.mul_div_cancel' hi] - ring_nf - · simp only [norm_pow, Finset.sum_const, nsmul_eq_mul, ← mul_assoc, add_comm k 1, pow_add, - pow_one, norm_mul] - gcongr - simpa [natcast_norm] using (Nat.card_divisors_le_self b) - · intro a - simpa using mul_nonneg (by simp) (by simp) -/- - -theorem summable_divisorsAntidiagonal_aux (k : ℕ) (z : ℍ) : - Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal } ↦ - (c.2.1).1 ^ k * cexp (2 * ↑π * Complex.I * c.2.1.2 * z) ^ c.2.1.1 := by - apply Summable.of_norm - rw [summable_sigma_of_nonneg] - constructor - · apply fun n => (hasSum_fintype _).summable - · simp only [Complex.norm_mul, norm_pow, Complex.norm_natCast, tsum_fintype, - Finset.univ_eq_attach] - · apply Summable.of_nonneg_of_le (fun b => Finset.sum_nonneg (by simp)) ?_ ((summable_norm_iff - (f := fun c : ℕ+ ↦ (c : ℂ) ^ (k + 1) * exp (2 * ↑π * Complex.I * (1: ℕ+) * ↑z) ^ (c : ℕ)).mpr - (by apply (summable_pow_mul_cexp (k+1) 1 z).subtype))) - intro b - apply le_trans (b := ∑ _ ∈ (b : ℕ).divisors, b ^ k * ‖exp (2 * ↑π * Complex.I * z) ^ (b : ℕ)‖) - · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun (x : ℕ × ℕ) ↦ - (x.1 : ℝ) ^ (k : ℕ) * ‖cexp (2 * ↑π * Complex.I * x.2 * z)‖ ^ x.1), - Nat.sum_divisorsAntidiagonal ((fun x y ↦ - (x : ℝ) ^ (k : ℕ) * ‖cexp (2 * ↑π * Complex.I * y * z)‖ ^ x))] - gcongr <;> rename_i i hi <;> simp at hi - · exact Nat.le_of_dvd b.2 hi - · apply le_of_eq - simp_rw [mul_assoc, ← norm_pow, ← Complex.exp_nsmul] - nth_rw 2 [← Nat.mul_div_cancel' hi] - simp - ring_nf - · simpa [← mul_assoc, add_comm k 1, pow_add] using Nat.card_divisors_le_self b - · simp -/ - -theorem summable_prod_mul_pow (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : - Summable fun c : (ℕ+ × ℕ+) ↦ (c.1 : 𝕜) ^ k * (r ^ (c.2 * c.1 : ℕ)) :=by - rw [sigmaAntidiagonalEquivProd.summable_iff.symm] - simp only [sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, Equiv.coe_fn_mk] - apply summable_divisorsAntidiagonal_aux k r hr - theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ ↦ (c.1 ^ k : ℂ) * Complex.exp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) := by - simpa using summable_prod_mul_pow k (Complex.exp (2 * ↑π * Complex.I * z)) + simpa using summable_prod_mul_pow k (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) -theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : - ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : 𝕜) * (r ^ (d * c : ℕ)) = - ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) := by - suffices ∑' (c : ℕ+ × ℕ+), (c.1 ^ k : 𝕜) * (r ^ ((c.2 : ℕ) * (c.1 : ℕ))) = - ∑' e : ℕ+, sigma k e * r ^ (e : ℕ) by - rw [Summable.tsum_prod (by apply summable_prod_mul_pow k r hr), Summable.tsum_comm] at this - · simpa using this - · apply (summable_prod_mul_pow k r hr).prod_symm.congr - simp - simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, mapdiv, PNat.mk_coe, - Equiv.coe_fn_mk, sigma_eq_sum_div', Nat.cast_sum, Nat.cast_pow] - rw [Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k r hr)] - apply tsum_congr - intro n - simp only [tsum_fintype, Finset.univ_eq_attach, Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) - (fun (x : ℕ × ℕ) ↦ (x.1 : 𝕜) ^ k * r ^ (x.2 * x.1)), - Nat.sum_divisorsAntidiagonal' (fun x y ↦ (x : 𝕜) ^ k * r ^ (y * x)), - Finset.sum_mul] - refine Finset.sum_congr (rfl) fun i hi ↦ ?_ - have hni : (n / i : ℕ) * (i : ℕ) = n := by - simp only [Nat.mem_divisors, ne_eq, PNat.ne_zero, not_false_eq_true, and_true] at * - have := Nat.div_mul_cancel hi - nth_rw 2 [← this] - simp - left - norm_cast at * - nth_rw 2 [← hni] - ring - theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by From d862dfe15e242737275ed827fe3e3cc8deea88cf Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 14:25:02 +0100 Subject: [PATCH 105/128] save --- .../EisensteinSeries/QExpansion.lean | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index 718f300bd86346..c1a5a80b674ae1 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -210,8 +210,7 @@ lemma cexp_pow_aux (a b : ℕ) (z : ℍ) : theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ ↦ (c.1 ^ k : ℂ) * Complex.exp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) := by - simpa using summable_prod_mul_pow k - (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) + simpa using summable_prod_mul_pow k (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = @@ -225,18 +224,16 @@ theorem summable_prod_eisSummand {k : ℕ} (hk : 3 ≤ k) (z : ℍ) : apply (EisensteinSeries.summable_norm_eisSummand (by linarith) z).congr simp [EisensteinSeries.eisSummand] -lemma tsum_prod_eisSummand_eq_sigma_cexp {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : - ∑' (x : Fin 2 → ℤ), eisSummand k x z = 2 * riemannZeta k + - 2 * ((-2 * π * Complex.I) ^ k / (k - 1)!) * +lemma tsum_eisSummand_eq_sigma_cexp {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : + ∑' x, eisSummand k x z = 2 * riemannZeta k + 2 * ((-2 * π * Complex.I) ^ k / (k - 1)!) * ∑' (n : ℕ+), (σ (k - 1) n) * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by rw [← (piFinTwoEquiv fun _ ↦ ℤ).symm.tsum_eq, Summable.tsum_prod (by apply summable_prod_eisSummand hk), tsum_nat_eq_zero_two_pnat] · have (b : ℕ+) := EisensteinSeries.qExpansion_identity_pnat (k := k - 1) (by omega) ⟨b * z , by simpa using z.2⟩ - have hk1 : k - 1 + 1 = k := by omega - simp only [coe_mk_subtype, hk1, one_div, neg_mul, mul_assoc, eisSummand, Fin.isValue, - piFinTwoEquiv_symm_apply, Fin.cons_zero, Int.cast_zero, zero_mul, Fin.cons_one, zero_add, - zpow_neg, zpow_natCast, Int.cast_natCast, + simp only [coe_mk_subtype, show k - 1 + 1 = k by omega, one_div, neg_mul, mul_assoc, eisSummand, + Fin.isValue, piFinTwoEquiv_symm_apply, Fin.cons_zero, Int.cast_zero, zero_mul, Fin.cons_one, + zero_add, zpow_neg, zpow_natCast, Int.cast_natCast, two_riemannZeta_eq_tsum_int_inv_even_pow (by omega) hk2, add_right_inj, mul_eq_mul_left_iff, OfNat.ofNat_ne_zero, or_false] at * conv => @@ -301,7 +298,7 @@ lemma EisensteinSeries.q_expansion_riemannZeta {k : ℕ} (hk : 3 ≤ k) (hk2 : E (eisensteinSeries_SIF standardcongruencecondition k) z := rfl rw [E, ModularForm.smul_apply, this, eisensteinSeries_SIF_apply standardcongruencecondition k z, eisensteinSeries, standardcongruencecondition] - have HE1 := tsum_prod_eisSummand_eq_sigma_cexp (by omega) hk2 z + have HE1 := tsum_eisSummand_eq_sigma_cexp (by omega) hk2 z have HE2 := tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries (by omega) z have z2 : (riemannZeta (k)) ≠ 0 := by refine riemannZeta_ne_zero_of_one_lt_re ?_ @@ -323,7 +320,7 @@ theorem even_div_two_ne_zero {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) : k / 2 lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) : (1 / (riemannZeta (k))) * ((-2 * π * Complex.I) ^ k / (k - 1)!) = -((2 * k) / bernoulli k) := by have hk0 := even_div_two_ne_zero hk2 hkn0 - have hk1 : 2 * (k / 2) = k := by apply Nat.two_mul_div_two_of_even hk2 + have hk1 : 2 * (k / 2) = k := Nat.two_mul_div_two_of_even hk2 have hk11 : 2 * (((k / 2) : ℕ) : ℂ) = k := by norm_cast have hpi : (π : ℂ) ≠ 0 := by simp [Real.pi_ne_zero] @@ -333,8 +330,7 @@ lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) have h3 : (-2 * ↑π * Complex.I) ^ k = (-1) ^ k * 2 ^ k * π ^ k * (-1) ^ (k / 2) := by simp_rw [mul_pow] nth_rw 3 [← hk1] - rw [neg_pow, pow_mul] - simp + rw [neg_pow, pow_mul, I_sq] have := riemannZeta_two_mul_nat hk0 rw [hk1, hk11] at this rw [h3, this, (Nat.mul_factorial_pred hkn0).symm] @@ -344,13 +340,9 @@ lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) (↑k * ↑(k - 1)! * (2 ^ k * ↑π ^ k * (-1) ^ (k / 2)) / ((-1) ^ (k / 2 + 1) * 2 ^ (k - 1) * ↑π ^ k * ↑(k - 1)!)) * 1 / (bernoulli k) := by ring - rw [this] + rw [this, show k = 1 + (k - 1) by omega, pow_add, pow_one, add_tsub_cancel_left] congr field_simp - have h2k : (2 : ℂ) ^ k = 2 * 2 ^ (k - 1) := by - rw [show k = 1 + (k - 1) by omega, pow_add] - simp - rw [h2k] ring /-- The q-Expansion of normalised Eisenstein series of level one with `bernoulli` term. -/ From e63f93c8c70ce4f63084d3ea16247ae7a43e0cba Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 15:53:43 +0100 Subject: [PATCH 106/128] weird mixup --- Mathlib/RingTheory/Flat/Basic.lean | 51 ++++-------------------------- 1 file changed, 6 insertions(+), 45 deletions(-) diff --git a/Mathlib/RingTheory/Flat/Basic.lean b/Mathlib/RingTheory/Flat/Basic.lean index 69e8672da84a04..b8cd66791dd018 100644 --- a/Mathlib/RingTheory/Flat/Basic.lean +++ b/Mathlib/RingTheory/Flat/Basic.lean @@ -4,11 +4,16 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin, Jujian Zhang, Yongle Hu -/ import Mathlib.Algebra.Colimit.TensorProduct +import Mathlib.Algebra.DirectSum.Finsupp +import Mathlib.Algebra.DirectSum.Module +import Mathlib.Algebra.Exact import Mathlib.Algebra.Module.CharacterModule +import Mathlib.Algebra.Module.Injective import Mathlib.Algebra.Module.Projective +import Mathlib.LinearAlgebra.DirectSum.TensorProduct +import Mathlib.LinearAlgebra.FreeModule.Basic import Mathlib.LinearAlgebra.TensorProduct.RightExactness import Mathlib.RingTheory.Finiteness.Small -import Mathlib.RingTheory.IsTensorProduct import Mathlib.RingTheory.TensorProduct.Finite /-! @@ -580,47 +585,3 @@ theorem nontrivial_of_algebraMap_injective_of_flat_right (h : Function.Injective end Algebra.TensorProduct end Nontrivial - -namespace IsTensorProduct - -variable {R M N P : Type*} [CommSemiring R] [AddCommMonoid M] [AddCommMonoid N] [AddCommMonoid P] - [Module R M] [Module R N] [Module R P] {M₁ M₂ N₁ N₂ : Type*} [AddCommMonoid M₁] [AddCommMonoid M₂] - [Module R M₁] [Module R M₂] [AddCommMonoid N₁] [AddCommMonoid N₂] [Module R N₁] [Module R N₂] - {f : M₁ →ₗ[R] M₂ →ₗ[R] M} {g : N₁ →ₗ[R] N₂ →ₗ[R] N} - (hf : IsTensorProduct f) (hg : IsTensorProduct g) (i₁ : M₁ →ₗ[R] N₁) (i₂ : M₂ →ₗ[R] N₂) - -theorem map_id_injective_of_flat_left {g : M₁ →ₗ[R] N₂ →ₗ[R] N} (hg : IsTensorProduct g) - (i : M₂ →ₗ[R] N₂) (hi : Function.Injective i) [Module.Flat R M₁] : - Function.Injective (hf.map hg LinearMap.id i) := by - have h : hf.map hg LinearMap.id i = hg.equiv ∘ i.lTensor M₁ ∘ hf.equiv.symm := - funext fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ hx hy ↦ by simp [hx, hy]) - simpa [h] using Module.Flat.lTensor_preserves_injective_linearMap i hi - -theorem map_id_injective_of_flat_right {g : N₁ →ₗ[R] M₂ →ₗ[R] N} (hg : IsTensorProduct g) - (i : M₁ →ₗ[R] N₁) (hi : Function.Injective i) [Module.Flat R M₂] : - Function.Injective (hf.map hg i LinearMap.id) := by - have h : hf.map hg i LinearMap.id = hg.equiv ∘ i.rTensor M₂ ∘ hf.equiv.symm := - funext fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ hx hy ↦ by simp [hx, hy]) - simpa [h] using Module.Flat.rTensor_preserves_injective_linearMap i hi - -/-- If `M₂` and `N₁` are flat `R`-modules, `i₁ : M₁ →ₗ[R] N₁` and `i₂ : M₂ →ₗ[R] N₂` are injective - linear maps, then the linear map `i : M ≅ M₁ ⊗[R] M₂ →ₗ[R] N₁ ⊗[R] N₂ ≅ N` induced by `i₁` - and `i₂` is injective. - See `IsTensorProduct.map_injective_of_flat'` for different flatness conditions. -/ -theorem map_injective_of_flat_right_left (h₁ : Function.Injective i₁) (h₂ : Function.Injective i₂) - [Module.Flat R M₂] [Module.Flat R N₁] : Function.Injective (hf.map hg i₁ i₂) := by - have h : hf.map hg i₁ i₂ = hg.equiv ∘ TensorProduct.map i₁ i₂ ∘ hf.equiv.symm := - funext fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ hx hy ↦ by simp [hx, hy]) - simpa [h] using map_injective_of_flat_flat i₁ i₂ h₁ h₂ - -/-- If `M₁` and `N₂` are flat `R`-modules, `i₁ : M₁ →ₗ[R] N₁` and `i₂ : M₂ →ₗ[R] N₂` are injective - linear maps, then the linear map `i : M ≅ M₁ ⊗[R] M₂ →ₗ[R] N₁ ⊗[R] N₂ ≅ N` induced by `i₁` - and `i₂` is injective. - See `IsTensorProduct.map_injective_of_flat` for different flatness conditions. -/ -theorem map_injective_of_flat_left_right (h₁ : Function.Injective i₁) (h₂ : Function.Injective i₂) - [Module.Flat R M₁] [Module.Flat R N₂] : Function.Injective (hf.map hg i₁ i₂) := by - have h : hf.map hg i₁ i₂ = hg.equiv ∘ TensorProduct.map i₁ i₂ ∘ hf.equiv.symm := - funext fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ hx hy ↦ by simp [hx, hy]) - simpa [h] using map_injective_of_flat_flat' i₁ i₂ h₁ h₂ - -end IsTensorProduct From 22157028e9c615fe5a0f7b48792f5153edc2643b Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 15:54:25 +0100 Subject: [PATCH 107/128] weird mixup2 --- Mathlib/RingTheory/IsTensorProduct.lean | 64 +++++-------------------- 1 file changed, 13 insertions(+), 51 deletions(-) diff --git a/Mathlib/RingTheory/IsTensorProduct.lean b/Mathlib/RingTheory/IsTensorProduct.lean index 8a28a06bbbcea8..bac8076ef656f0 100644 --- a/Mathlib/RingTheory/IsTensorProduct.lean +++ b/Mathlib/RingTheory/IsTensorProduct.lean @@ -60,22 +60,20 @@ theorem TensorProduct.isTensorProduct : IsTensorProduct (TensorProduct.mk R M N) simp · exact Function.bijective_id -namespace IsTensorProduct - variable {R M N} /-- If `M` is the tensor product of `M₁` and `M₂`, it is linearly equivalent to `M₁ ⊗[R] M₂`. -/ @[simps! apply] -noncomputable def equiv (h : IsTensorProduct f) : M₁ ⊗[R] M₂ ≃ₗ[R] M := +noncomputable def IsTensorProduct.equiv (h : IsTensorProduct f) : M₁ ⊗[R] M₂ ≃ₗ[R] M := LinearEquiv.ofBijective _ h @[simp] -theorem equiv_toLinearMap (h : IsTensorProduct f) : +theorem IsTensorProduct.equiv_toLinearMap (h : IsTensorProduct f) : h.equiv.toLinearMap = TensorProduct.lift f := rfl @[simp] -theorem equiv_symm_apply (h : IsTensorProduct f) (x₁ : M₁) (x₂ : M₂) : +theorem IsTensorProduct.equiv_symm_apply (h : IsTensorProduct f) (x₁ : M₁) (x₂ : M₂) : h.equiv.symm (f x₁ x₂) = x₁ ⊗ₜ x₂ := by apply h.equiv.injective refine (h.equiv.apply_symm_apply _).trans ?_ @@ -83,26 +81,27 @@ theorem equiv_symm_apply (h : IsTensorProduct f) (x₁ : M₁) (x₂ : M₂) : /-- If `M` is the tensor product of `M₁` and `M₂`, we may lift a bilinear map `M₁ →ₗ[R] M₂ →ₗ[R] M'` to a `M →ₗ[R] M'`. -/ -noncomputable def lift (h : IsTensorProduct f) (f' : M₁ →ₗ[R] M₂ →ₗ[R] M') : +noncomputable def IsTensorProduct.lift (h : IsTensorProduct f) (f' : M₁ →ₗ[R] M₂ →ₗ[R] M') : M →ₗ[R] M' := (TensorProduct.lift f').comp h.equiv.symm.toLinearMap -theorem lift_eq (h : IsTensorProduct f) (f' : M₁ →ₗ[R] M₂ →ₗ[R] M') (x₁ : M₁) +theorem IsTensorProduct.lift_eq (h : IsTensorProduct f) (f' : M₁ →ₗ[R] M₂ →ₗ[R] M') (x₁ : M₁) (x₂ : M₂) : h.lift f' (f x₁ x₂) = f' x₁ x₂ := by - simp [lift] + delta IsTensorProduct.lift + simp /-- The tensor product of a pair of linear maps between modules. -/ -noncomputable def map (hf : IsTensorProduct f) (hg : IsTensorProduct g) +noncomputable def IsTensorProduct.map (hf : IsTensorProduct f) (hg : IsTensorProduct g) (i₁ : M₁ →ₗ[R] N₁) (i₂ : M₂ →ₗ[R] N₂) : M →ₗ[R] N := hg.equiv.toLinearMap.comp ((TensorProduct.map i₁ i₂).comp hf.equiv.symm.toLinearMap) -@[simp] -theorem map_eq (hf : IsTensorProduct f) (hg : IsTensorProduct g) (i₁ : M₁ →ₗ[R] N₁) +theorem IsTensorProduct.map_eq (hf : IsTensorProduct f) (hg : IsTensorProduct g) (i₁ : M₁ →ₗ[R] N₁) (i₂ : M₂ →ₗ[R] N₂) (x₁ : M₁) (x₂ : M₂) : hf.map hg i₁ i₂ (f x₁ x₂) = g (i₁ x₁) (i₂ x₂) := by - simp [map] + delta IsTensorProduct.map + simp @[elab_as_elim] -theorem inductionOn (h : IsTensorProduct f) {motive : M → Prop} (m : M) +theorem IsTensorProduct.inductionOn (h : IsTensorProduct f) {motive : M → Prop} (m : M) (zero : motive 0) (tmul : ∀ x y, motive (f x y)) (add : ∀ x y, motive x → motive y → motive (x + y)) : motive m := by rw [← h.equiv.right_inv m] @@ -117,50 +116,13 @@ theorem inductionOn (h : IsTensorProduct f) {motive : M → Prop} (m : M) rw [map_add] apply add <;> assumption -lemma of_equiv (e : M₁ ⊗[R] M₂ ≃ₗ[R] M) (he : ∀ x y, e (x ⊗ₜ y) = f x y) : +lemma IsTensorProduct.of_equiv (e : M₁ ⊗[R] M₂ ≃ₗ[R] M) (he : ∀ x y, e (x ⊗ₜ y) = f x y) : IsTensorProduct f := by have : TensorProduct.lift f = e := by ext x y simp [he] simpa [IsTensorProduct, this] using e.bijective -section map - -variable {P₁ P₂ P : Type*} [AddCommMonoid P₁] [AddCommMonoid P₂] - [AddCommMonoid P] [Module R P₁] [Module R P₂] [Module R P] {p : P₁ →ₗ[R] P₂ →ₗ[R] P} - (hf : IsTensorProduct f) (hg : IsTensorProduct g) (hp : IsTensorProduct p) - (i₁ : N₁ →ₗ[R] P₁) (j₁ : M₁ →ₗ[R] N₁) (i₂ : N₂ →ₗ[R] P₂) (j₂ : M₂ →ₗ[R] N₂) - -theorem map_comp : hf.map hp (i₁ ∘ₗ j₁) (i₂ ∘ₗ j₂) = hg.map hp i₁ i₂ ∘ₗ hf.map hg j₁ j₂ := - LinearMap.ext <| fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ h₁ h₂ ↦ by simp [h₁, h₂]) - -theorem map_map (x : M) : - hg.map hp i₁ i₂ ((hf.map hg j₁ j₂) x) = hf.map hp (i₁ ∘ₗ j₁) (i₂ ∘ₗ j₂) x := - DFunLike.congr_fun (hf.map_comp hg hp i₁ j₁ i₂ j₂).symm x - -@[simp] -theorem map_id : - hf.map hf (LinearMap.id : M₁ →ₗ[R] M₁) (LinearMap.id : M₂ →ₗ[R] M₂) = LinearMap.id := - LinearMap.ext <| fun x ↦ hf.inductionOn x (by simp) (by simp) (fun _ _ h₁ h₂ ↦ by simp [h₁, h₂]) - -@[simp] -protected theorem map_one : hf.map hf (1 : M₁ →ₗ[R] M₁) (1 : M₂ →ₗ[R] M₂) = 1 := - hf.map_id - -protected theorem map_mul (i₁ i₂ : M₁ →ₗ[R] M₁) (j₁ j₂ : M₂ →ₗ[R] M₂) : - hf.map hf (i₁ * i₂) (j₁ * j₂) = hf.map hf i₁ j₁ * hf.map hf i₂ j₂ := - hf.map_comp hf hf i₁ i₂ j₁ j₂ - -protected theorem map_pow (i : M₁ →ₗ[R] M₁) (j : M₂ →ₗ[R] M₂) (n : ℕ) : - hf.map hf i j ^ n = hf.map hf (i ^ n) (j ^ n) := by - induction n with - | zero => simp - | succ n ih => simp only [pow_succ, ih, hf.map_mul] - -end map - -end IsTensorProduct - end IsTensorProduct section IsBaseChange From 5b9de1a1757f9cc30b98f6fd58ae66f2cc3e3eba Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 15:58:41 +0100 Subject: [PATCH 108/128] weird mixup3 --- .../NormedSpace/HahnBanach/SeparatingDual.lean | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean b/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean index 3d418623113ddd..9da502f7619ffb 100644 --- a/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean +++ b/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean @@ -3,7 +3,6 @@ Copyright (c) 2023 Sébastien Gouëzel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ -import Mathlib.Algebra.Central.Defs import Mathlib.Analysis.NormedSpace.HahnBanach.Extension import Mathlib.Analysis.NormedSpace.HahnBanach.Separation import Mathlib.Analysis.NormedSpace.Multilinear.Basic @@ -116,18 +115,6 @@ theorem exists_eq_one_ne_zero_of_ne_zero_pair {x y : V} (hx : x ≠ 0) (hy : y variable [IsTopologicalAddGroup V] -/-- The center of continuous linear maps on a topological vector space -with separating dual is trivial, in other words, it is a central algebra. -/ -instance _root_.Algebra.IsCentral.continuousLinearMap [ContinuousSMul R V] : - Algebra.IsCentral R (V →L[R] V) where - out T hT := by - have h' (f : V →L[R] R) (y v : V) : f (T v) • y = f v • T y := by - simpa using congr($(Subalgebra.mem_center_iff.mp hT <| f.smulRight y) v) - nontriviality V - obtain ⟨x, hx⟩ := exists_ne (0 : V) - obtain ⟨f, hf⟩ := exists_eq_one (R := R) hx - exact ⟨f (T x), ContinuousLinearMap.ext fun _ => by simp [h', hf]⟩ - /-- In a topological vector space with separating dual, the group of continuous linear equivalences acts transitively on the set of nonzero vectors: given two nonzero vectors `x` and `y`, there exists `A : V ≃L[R] V` mapping `x` to `y`. -/ From 3044c07f161451cb004493f6bee6a75f8f67bd43 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 15:59:25 +0100 Subject: [PATCH 109/128] weird mixup4 --- Mathlib/Data/SetLike/Basic.lean | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Mathlib/Data/SetLike/Basic.lean b/Mathlib/Data/SetLike/Basic.lean index 8b46e053074fd3..12a94653436ec4 100644 --- a/Mathlib/Data/SetLike/Basic.lean +++ b/Mathlib/Data/SetLike/Basic.lean @@ -237,10 +237,4 @@ attribute [local instance] instSubtypeSet instSubtype end -@[nontriviality] -lemma mem_of_subsingleton {A F} [Subsingleton A] [SetLike F A] (S : F) [h : Nonempty S] {a : A} : - a ∈ S := by - obtain ⟨s, hs⟩ := nonempty_subtype.mp h - simpa [Subsingleton.elim a s] - end SetLike From 67200a982b7b5a227065a03e97a306bbcaaf7680 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 16:49:44 +0100 Subject: [PATCH 110/128] cleanup --- .../ModularForms/DedekindEta.lean | 77 +++++++++---------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 5049e2a74f2d1c..892f773c343a95 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -130,16 +130,34 @@ private theorem one_sub_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x simp_rw [eta_q_eq_cexp, h2, logDeriv_one_sub_mul_cexp_comp 1 (g := fun x ↦ (2 * π * Complex.I * (i + 1) * x)) (by fun_prop), h3, neg_mul, one_mul, mul_neg] -lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - (2 * π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by +lemma tsum_log_deriv_one_sub_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = + -(2 * π * Complex.I) * ∑' n : ℕ, (n + 1) * (eta_q n z) / (1 - eta_q n z) := by suffices ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by + ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by rw [this, ← tsum_mul_left] congr 1 ext i ring exact tsum_congr (fun i ↦ one_sub_eta_logDeriv_eq z i) +lemma summable_log_deriv_one_sub_eta_q (z : ℍ) : + Summable fun i ↦ logDeriv (fun x ↦ 1 - eta_q i x) z := by + simp only [one_sub_eta_logDeriv_eq] + apply ((summable_nat_add_iff 1).mpr ((summable_norm_pow_mul_geometric_div_one_sub (r := 𝕢 1 z) 1 + (by simpa [Periodic.qParam] using UpperHalfPlane.norm_exp_two_pi_I_lt_one z)).mul_left + (-2 * π * Complex.I))).congr + intro b + have := one_add_eta_q_ne_zero b z + simp only [UpperHalfPlane.coe, ne_eq, neg_mul, Nat.cast_add, Nat.cast_one, mul_neg] at * + field_simp + left + ring + +lemma multipliableLocallyUniformlyOn_one_sub_eta_q : + MultipliableLocallyUniformlyOn (fun n x ↦ 1 - eta_q n x) ℍₒ := + ⟨ηₚ, (hasProdLocallyUniformlyOn_eta).congr fun n x _ ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, + (fun n a ↦ 1 - eta_q n a) i b) x)⟩ + theorem etaProdTerm_DifferentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ complexUpperHalPlane_isOpen @@ -157,41 +175,20 @@ lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12 rw [logDeriv_mul (UpperHalfPlane.coe z) (by simp [ne_eq, exp_ne_zero, not_false_eq_true, Periodic.qParam]) (etaProdTerm_ne_zero z) (by fun_prop) (etaProdTerm_DifferentiableAt z)] have HG := logDeriv_tprod_eq_tsum (complexUpperHalPlane_isOpen) (x := z) - (f := fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) ?_ ?_ ?_ - (etaProdTerm_ne_zero z) - · rw [show z.1 = UpperHalfPlane.coe z by rfl] at HG - simp only [HG, logDeriv_q_term z, tsum_log_deriv_eta_q z, mul_neg, E2, one_div, mul_inv_rev, - Pi.smul_apply, smul_eq_mul] - rw [G2_q_exp, riemannZeta_two, ← tsum_pow_div_one_sub_eq_tsum_sigma - (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z), mul_sub, sub_eq_add_neg, mul_add] - conv => - enter [1,2,2,1] - ext n - rw [neg_div, neg_eq_neg_one_mul] - rw [tsum_mul_left] - congr 1 - · field_simp - ring - · have := tsum_pnat_eq_tsum_succ (f := fun n ↦ n * cexp (2 * π * Complex.I * z) ^ n - / (1 - cexp (2 * π * Complex.I * z) ^ n )) - field_simp [this, Periodic.qParam, eta_q_eq_pow] - ring_nf - congr - ext n - ring_nf - · intro i x hx - simp_rw [eta_q_eq_pow] - fun_prop - · simp only [mem_setOf_eq, one_sub_eta_logDeriv_eq] - apply ((summable_nat_add_iff 1).mpr ((summable_norm_pow_mul_geometric_div_one_sub (r := 𝕢 1 z) 1 - (by simpa [Periodic.qParam] using UpperHalfPlane.norm_exp_two_pi_I_lt_one z)).mul_left - (-2 * π * Complex.I))).congr - intro b - have := one_add_eta_q_ne_zero b z - simp only [UpperHalfPlane.coe, ne_eq, neg_mul, Nat.cast_add, Nat.cast_one, mul_neg] at * - field_simp - left + (f := fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) + (by simp_rw [eta_q_eq_pow]; fun_prop) (summable_log_deriv_one_sub_eta_q z) + (multipliableLocallyUniformlyOn_one_sub_eta_q) (etaProdTerm_ne_zero z) + rw [show z.1 = UpperHalfPlane.coe z by rfl] at HG + simp only [logDeriv_q_term z, HG, tsum_log_deriv_one_sub_eta_q z, E2, one_div, + mul_inv_rev, Pi.smul_apply, smul_eq_mul] + rw [G2_q_exp, riemannZeta_two, ← tsum_pow_div_one_sub_eq_tsum_sigma + (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z), mul_sub, sub_eq_add_neg, mul_add] + congr 1 + · field_simp ring - · use ηₚ - apply (hasProdLocallyUniformlyOn_eta).congr - exact fun n x hx ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, (fun n a ↦ 1 - eta_q n a) i b) x) + · field_simp [tsum_pnat_eq_tsum_succ (f := fun n ↦ n * cexp (2 * π * Complex.I * z) ^ n + / (1 - cexp (2 * π * Complex.I * z) ^ n )), Periodic.qParam, eta_q_eq_pow] + ring_nf + congr + ext n + ring_nf From 21ac9cb146c7acc40c6ef1e8a9f8db906ef33e8d Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 17:30:09 +0100 Subject: [PATCH 111/128] updates --- .../Trigonometric/Cotangent.lean | 100 +++++++++--------- 1 file changed, 49 insertions(+), 51 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index 83099627e4775e..9874ff354d122c 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -243,38 +243,38 @@ open Set Complex UpperHalfPlane open scoped Nat -theorem contDiffOn_inv_linear (d : ℤ) (k : ℕ) : ContDiffOn ℂ k (fun z : ℂ ↦ 1 / (z + d)) ℂ_ℤ := by +variable (k : ℕ) + +theorem contDiffOn_inv_linear (d : ℤ) : ContDiffOn ℂ k (fun z : ℂ ↦ 1 / (z + d)) ℂ_ℤ := by simpa using ContDiffOn.inv (by fun_prop) (fun x hx ↦ Complex.integerComplement_add_ne_zero hx d) -theorem contDiffOn_inv_linear_sub (d : ℤ) (k : ℕ) : - ContDiffOn ℂ k (fun z : ℂ ↦ 1 / (z - d)) ℂ_ℤ := by - simpa [sub_eq_add_neg] using contDiffOn_inv_linear (-d) k +theorem contDiffOn_inv_linear_sub (d : ℤ) : ContDiffOn ℂ k (fun z : ℂ ↦ 1 / (z - d)) ℂ_ℤ := by + simpa [sub_eq_add_neg] using contDiffOn_inv_linear k (-d) -lemma cotTerm_iteratedDeriv (d k : ℕ) : EqOn (iteratedDeriv k (fun (z : ℂ) ↦ cotTerm z d)) - (fun z : ℂ ↦ (-1) ^ k * k ! * ((z + (d + 1)) ^ (-1 - k : ℤ) + - (z - (d + 1)) ^ (-1 - k : ℤ))) ℂ_ℤ := by +lemma cotTerm_iteratedDeriv_eqOn (d : ℕ) : EqOn (iteratedDeriv k (fun (z : ℂ) ↦ cotTerm z d)) + (fun z ↦ (-1)^ k * k ! * ((z + (d + 1))^ (-1 - k : ℤ) + (z - (d + 1)) ^ (-1 - k : ℤ))) ℂ_ℤ := by intro z hz have h1 : (fun z : ℂ ↦ 1 / (z - (d + 1)) + 1 / (z + (d + 1))) = - (fun z : ℂ ↦ 1 / (z - (d + 1))) + fun z : ℂ ↦ 1 / (z + (d +1)) := by rfl + (fun z : ℂ ↦ 1 / (z - (d + 1))) + fun z : ℂ ↦ 1 / (z + (d + 1)) := by rfl rw [h1, iteratedDeriv_add ?_] · have h2 := iter_deriv_inv_linear_sub k 1 ((d + 1 : ℂ)) have h3 := iter_deriv_inv_linear k 1 (d + 1 : ℂ) simp only [one_div, one_mul, one_pow, mul_one, Int.reduceNeg, iteratedDeriv_eq_iterate] at * rw [h2, h3] ring - · simpa using (contDiffOn_inv_linear (d + 1) k).contDiffAt - (IsOpen.mem_nhds (by apply Complex.isOpen_compl_range_intCast) hz) - · simpa using (contDiffOn_inv_linear_sub (d + 1) k).contDiffAt - (IsOpen.mem_nhds (by apply Complex.isOpen_compl_range_intCast) hz) + · simpa using (contDiffOn_inv_linear k (d + 1)).contDiffAt + ((Complex.isOpen_compl_range_intCast).mem_nhds hz) + · simpa using (contDiffOn_inv_linear_sub k (d + 1)).contDiffAt + ((Complex.isOpen_compl_range_intCast).mem_nhds hz) -lemma cotTerm_iteratedDerivWith (d k : ℕ) : +lemma cotTerm_iteratedDerivWithin_eqOn (d : ℕ) : EqOn (iteratedDerivWithin k (fun (z : ℂ) ↦ cotTerm z d) ℂ_ℤ) (fun z : ℂ ↦ (-1) ^ k * k ! * ((z + (d + 1)) ^ (-1 - k : ℤ) + (z - (d + 1)) ^ (-1 - k : ℤ))) ℂ_ℤ := by apply Set.EqOn.trans (iteratedDerivWithin_of_isOpen Complex.isOpen_compl_range_intCast) - apply cotTerm_iteratedDeriv + apply cotTerm_iteratedDeriv_eqOn -lemma cotTerm_iteratedDerivWith' (d k : ℕ) : +lemma cotTerm_iteratedDerivWithin_eqOn' (d : ℕ) : EqOn (iteratedDerivWithin k (fun (z : ℂ) ↦ cotTerm z d) ℍₒ) (fun z : ℂ ↦ (-1) ^ k * k ! * ((z + (d + 1)) ^ (-1 - k : ℤ) + (z - (d + 1)) ^ (-1 - k : ℤ))) ℍₒ := by @@ -282,14 +282,14 @@ lemma cotTerm_iteratedDerivWith' (d k : ℕ) : iteratedDerivWithin_congr_right_of_isOpen (fun (z : ℂ) ↦ cotTerm z d) k complexUpperHalPlane_isOpen (Complex.isOpen_compl_range_intCast)) intro z hz - simpa using cotTerm_iteratedDerivWith d k (UpperHalfPlane.coe_mem_integerComplement ⟨z, hz⟩) + simpa using cotTerm_iteratedDerivWithin_eqOn k d (coe_mem_integerComplement ⟨z, hz⟩) open EisensteinSeries in -private noncomputable abbrev cotTermUpperBound (A B : ℝ) (hB : 0 < B) (k a : ℕ) := +private noncomputable abbrev cotTermUpperBound (A B : ℝ) (hB : 0 < B) (a : ℕ) := k ! * (2 * (r (⟨⟨A, B⟩, by simp [hB]⟩) ^ (-1 - (k : ℤ))) * ‖ ((a + 1) ^ (-1 - (k : ℤ)) : ℝ)‖) private lemma Summable_cotTermUpperBound (A B : ℝ) (hB : 0 < B) {k : ℕ} (hk : 1 ≤ k) : - Summable fun a : ℕ ↦ cotTermUpperBound A B hB k a := by + Summable fun a : ℕ ↦ cotTermUpperBound k A B hB a := by simp_rw [← mul_assoc] apply Summable.mul_left apply ((summable_nat_add_iff 1).mpr (summable_int_iff_summable_nat_and_neg.mp @@ -300,18 +300,17 @@ private lemma Summable_cotTermUpperBound (A B : ℝ) (hB : 0 < B) {k : ℕ} (hk exact fun n ↦ rfl open EisensteinSeries in -private lemma iteratedDerivWithin_cotTerm_bounded_uniformly {k : ℕ} (hk : 1 ≤ k) (K : Set ℂ) - (hK : K ⊆ ℍₒ) (A B : ℝ) (hB : 0 < B) +private lemma iteratedDerivWithin_cotTerm_bounded_uniformly + {k : ℕ} (hk : 1 ≤ k) {K : Set ℂ} (hK : K ⊆ ℍₒ) (A B : ℝ) (hB : 0 < B) (HABK : inclusion hK '' univ ⊆ verticalStrip A B) (n : ℕ) {a : ℂ} (ha : a ∈ K) : - ‖iteratedDerivWithin k (fun z ↦ cotTerm z n) ℍₒ a‖ ≤ - cotTermUpperBound A B hB k n := by - simp only [cotTerm_iteratedDerivWith' n k (hK ha), Complex.norm_mul, norm_pow, norm_neg, + ‖iteratedDerivWithin k (fun z ↦ cotTerm z n) ℍₒ a‖ ≤ cotTermUpperBound k A B hB n := by + simp only [cotTerm_iteratedDerivWithin_eqOn' k n (hK ha), Complex.norm_mul, norm_pow, norm_neg, norm_one, one_pow, Complex.norm_natCast, one_mul, cotTermUpperBound, Int.reduceNeg, norm_zpow, Real.norm_eq_abs, two_mul, add_mul] gcongr apply le_trans (norm_add_le _ _) apply add_le_add - · have := summand_bound_of_mem_verticalStrip (k := (k + 1)) (by norm_cast; omega) ![1, n+1] hB + · have := summand_bound_of_mem_verticalStrip (k := (k + 1)) (by norm_cast; omega) ![1, n + 1] hB (z := ⟨a, (hK ha)⟩) (A := A) (by aesop) simp only [coe_setOf, image_univ, Fin.isValue, Matrix.cons_val_zero, Int.cast_one, coe_mk_subtype, one_mul, Matrix.cons_val_one, Matrix.cons_val_fin_one, Int.cast_add, @@ -326,39 +325,38 @@ private lemma iteratedDerivWithin_cotTerm_bounded_uniformly {k : ℕ} (hk : 1 Int.cast_add, Int.cast_neg, Int.cast_natCast, sub_eq_add_neg, norm_zpow, ge_iff_le] at * norm_cast at * -lemma summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm (k : ℕ) (hk : 1 ≤ k) : - SummableLocallyUniformlyOn - (fun n : ℕ ↦ iteratedDerivWithin k (fun z : ℂ ↦ cotTerm z n) ℍₒ) ℍₒ := by +lemma summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm {k : ℕ} (hk : 1 ≤ k) : + SummableLocallyUniformlyOn (fun n : ℕ ↦ iteratedDerivWithin k (fun z ↦ cotTerm z n) ℍₒ) ℍₒ := by apply SummableLocallyUniformlyOn_of_locally_bounded (complexUpperHalPlane_isOpen) intro K hK hKc have hKK2 : IsCompact (Set.image (inclusion hK) univ) := by exact (isCompact_iff_isCompact_univ.mp hKc).image_of_continuousOn (continuous_inclusion hK |>.continuousOn) obtain ⟨A, B, hB, HABK⟩ := subset_verticalStrip_of_isCompact hKK2 - exact ⟨cotTermUpperBound A B hB k, Summable_cotTermUpperBound A B hB hk, - iteratedDerivWithin_cotTerm_bounded_uniformly hk K hK A B hB HABK⟩ + exact ⟨cotTermUpperBound k A B hB, Summable_cotTermUpperBound A B hB hk, + iteratedDerivWithin_cotTerm_bounded_uniformly hk hK A B hB HABK⟩ -theorem DifferentiableOn_iteratedDeriv_cotTerm (n l : ℕ) : +theorem DifferentiableOn_iteratedDerivWithin_cotTerm (n l : ℕ) : DifferentiableOn ℂ (iteratedDerivWithin l (fun z ↦ cotTerm z n) ℍₒ) ℍₒ := by suffices DifferentiableOn ℂ (fun z : ℂ ↦ (-1) ^ l * l ! * ((z + (n + 1)) ^ (-1 - l : ℤ) + (z - (n + 1)) ^ (-1 - l : ℤ))) ℍₒ by apply this.congr intro z hz - simpa using (cotTerm_iteratedDerivWith' n l hz) + simpa using (cotTerm_iteratedDerivWithin_eqOn' l n hz) apply DifferentiableOn.const_mul apply DifferentiableOn.add <;> apply DifferentiableOn.zpow any_goals try {fun_prop} <;> left <;> intro x hx · simpa [add_eq_zero_iff_neg_eq'] using (UpperHalfPlane.ne_int ⟨x, hx⟩ (-(n+1))).symm · simpa [sub_eq_zero] using (UpperHalfPlane.ne_int ⟨x, hx⟩ ((n+1))) -private theorem aux_summable_add (k : ℕ) (hk : 1 ≤ k) (x : ℍ) : +private theorem aux_summable_add {k : ℕ} (hk : 1 ≤ k) (x : ℍ) : Summable fun (n : ℕ) ↦ ((x : ℂ) + (n + 1)) ^ (-1 - k : ℤ) := by apply ((summable_nat_add_iff 1).mpr (summable_int_iff_summable_nat_and_neg.mp (EisensteinSeries.linear_right_summable x 1 (k := k + 1) (by omega))).1).congr simp [← zpow_neg, sub_eq_add_neg] -private theorem aux_summable_neg (k : ℕ) (hk : 1 ≤ k) (x : ℍ) : +private theorem aux_summable_neg {k : ℕ} (hk : 1 ≤ k) (x : ℍ) : Summable fun (n : ℕ) ↦ ((x : ℂ) - (n + 1)) ^ (-1 - k : ℤ) := by apply ((summable_nat_add_iff 1).mpr (summable_int_iff_summable_nat_and_neg.mp (EisensteinSeries.linear_right_summable x 1 (k := k + 1) (by omega))).2).congr @@ -367,23 +365,23 @@ private theorem aux_summable_neg (k : ℕ) (hk : 1 ≤ k) (x : ℍ) : -- We have this auxilary ugly version on the lhs so the the rhs looks nicer. private theorem aux_iteratedDeriv_tsum_cotTerm {k : ℕ} (hk : 1 ≤ k) (x : ℍ) : (-1) ^ k * (k !) * (x : ℂ) ^ (-1 - k : ℤ) + iteratedDerivWithin k - (fun z : ℂ ↦ ∑' n : ℕ, cotTerm z n) ℍₒ x = - (-1) ^ (k : ℕ) * (k : ℕ)! * ∑' n : ℤ, ((x : ℂ) + n) ^ (-1 - k : ℤ) := by - rw [iteratedDerivWithin_tsum k complexUpperHalPlane_isOpen - (by simpa using x.2) (fun t ht ↦ Summable_cotTerm (coe_mem_integerComplement ⟨t, ht⟩)) - (fun l hl hl2 ↦ summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm l hl) - (fun n l z hl hz ↦ ((DifferentiableOn_iteratedDeriv_cotTerm n l)).differentiableAt - ((IsOpen.mem_nhds (complexUpperHalPlane_isOpen) hz)))] - conv => - enter [1,2,1] - ext n - rw [cotTerm_iteratedDerivWith' n k (by simp [UpperHalfPlane.coe])] - rw [tsum_of_add_one_of_neg_add_one (by simpa using aux_summable_add k hk x) - (by simpa [sub_eq_add_neg] using aux_summable_neg k hk x), - tsum_mul_left, Summable.tsum_add (aux_summable_add k hk x) (aux_summable_neg k hk x )] - simp only [Int.reduceNeg, sub_eq_add_neg, neg_add_rev, Int.cast_add, Int.cast_natCast, - Int.cast_one, Int.cast_zero, add_zero, Int.cast_neg] - ring + (fun z : ℂ ↦ ∑' n : ℕ, cotTerm z n) ℍₒ x = + (-1) ^ (k : ℕ) * (k : ℕ)! * ∑' n : ℤ, ((x : ℂ) + n) ^ (-1 - k : ℤ) := by + rw [iteratedDerivWithin_tsum k complexUpperHalPlane_isOpen + (by simpa using x.2) (fun t ht ↦ Summable_cotTerm (coe_mem_integerComplement ⟨t, ht⟩)) + (fun l hl hl2 ↦ summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm hl) + (fun n l z hl hz ↦ ((DifferentiableOn_iteratedDerivWithin_cotTerm n l)).differentiableAt + ((IsOpen.mem_nhds (complexUpperHalPlane_isOpen) hz)))] + conv => + enter [1,2,1] + ext n + rw [cotTerm_iteratedDerivWithin_eqOn' k n (by simp [UpperHalfPlane.coe])] + rw [tsum_of_add_one_of_neg_add_one (by simpa using aux_summable_add hk x) + (by simpa [sub_eq_add_neg] using aux_summable_neg hk x), + tsum_mul_left, Summable.tsum_add (aux_summable_add hk x) (aux_summable_neg hk x )] + simp only [Int.reduceNeg, sub_eq_add_neg, neg_add_rev, Int.cast_add, Int.cast_natCast, + Int.cast_one, Int.cast_zero, add_zero, Int.cast_neg] + ring theorem iteratedDerivWithin_cot_sub_inv_eq_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x) - 1 / x) ℍₒ z = @@ -395,7 +393,7 @@ theorem iteratedDerivWithin_cot_sub_inv_eq_series_rep {k : ℕ} (hk : 1 ≤ k) ( intro x hx simpa [cotTerm] using (cot_series_rep' (UpperHalfPlane.coe_mem_integerComplement ⟨x, hx⟩)) -theorem iteratedDerivWithin_cot_pi_z_sub_inv (k : ℕ) (z : ℍ) : +theorem iteratedDerivWithin_cot_pi_z_sub_inv (z : ℍ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x) - 1 / x) ℍₒ z = (iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z) - (-1) ^ k * k ! * ((z : ℂ) ^ (-1 - k : ℤ)) := by From 4501ce684a3696b7e733bb44532dcc844092d45d Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 17:41:14 +0100 Subject: [PATCH 112/128] name updates --- .../Trigonometric/Cotangent.lean | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index 9874ff354d122c..1c670b7798a51b 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -263,18 +263,18 @@ lemma cotTerm_iteratedDeriv_eqOn (d : ℕ) : EqOn (iteratedDeriv k (fun (z : ℂ rw [h2, h3] ring · simpa using (contDiffOn_inv_linear k (d + 1)).contDiffAt - ((Complex.isOpen_compl_range_intCast).mem_nhds hz) + ((isOpen_compl_range_intCast).mem_nhds hz) · simpa using (contDiffOn_inv_linear_sub k (d + 1)).contDiffAt - ((Complex.isOpen_compl_range_intCast).mem_nhds hz) + ((isOpen_compl_range_intCast).mem_nhds hz) -lemma cotTerm_iteratedDerivWithin_eqOn (d : ℕ) : +lemma cotTerm_iteratedDerivWithin_eqOn_intergerCompliment (d : ℕ) : EqOn (iteratedDerivWithin k (fun (z : ℂ) ↦ cotTerm z d) ℂ_ℤ) (fun z : ℂ ↦ (-1) ^ k * k ! * ((z + (d + 1)) ^ (-1 - k : ℤ) + (z - (d + 1)) ^ (-1 - k : ℤ))) ℂ_ℤ := by apply Set.EqOn.trans (iteratedDerivWithin_of_isOpen Complex.isOpen_compl_range_intCast) apply cotTerm_iteratedDeriv_eqOn -lemma cotTerm_iteratedDerivWithin_eqOn' (d : ℕ) : +lemma cotTerm_iteratedDerivWithin_eqOn_complexUpperHalfPlane (d : ℕ) : EqOn (iteratedDerivWithin k (fun (z : ℂ) ↦ cotTerm z d) ℍₒ) (fun z : ℂ ↦ (-1) ^ k * k ! * ((z + (d + 1)) ^ (-1 - k : ℤ) + (z - (d + 1)) ^ (-1 - k : ℤ))) ℍₒ := by @@ -282,11 +282,12 @@ lemma cotTerm_iteratedDerivWithin_eqOn' (d : ℕ) : iteratedDerivWithin_congr_right_of_isOpen (fun (z : ℂ) ↦ cotTerm z d) k complexUpperHalPlane_isOpen (Complex.isOpen_compl_range_intCast)) intro z hz - simpa using cotTerm_iteratedDerivWithin_eqOn k d (coe_mem_integerComplement ⟨z, hz⟩) + simpa using cotTerm_iteratedDerivWithin_eqOn_intergerCompliment k d + (coe_mem_integerComplement ⟨z, hz⟩) open EisensteinSeries in private noncomputable abbrev cotTermUpperBound (A B : ℝ) (hB : 0 < B) (a : ℕ) := - k ! * (2 * (r (⟨⟨A, B⟩, by simp [hB]⟩) ^ (-1 - (k : ℤ))) * ‖ ((a + 1) ^ (-1 - (k : ℤ)) : ℝ)‖) + k ! * (2 * (r (⟨⟨A, B⟩, by simp [hB]⟩) ^ (-1 - k : ℤ)) * ‖((a + 1) ^ (-1 - k : ℤ) : ℝ)‖) private lemma Summable_cotTermUpperBound (A B : ℝ) (hB : 0 < B) {k : ℕ} (hk : 1 ≤ k) : Summable fun a : ℕ ↦ cotTermUpperBound k A B hB a := by @@ -304,12 +305,11 @@ private lemma iteratedDerivWithin_cotTerm_bounded_uniformly {k : ℕ} (hk : 1 ≤ k) {K : Set ℂ} (hK : K ⊆ ℍₒ) (A B : ℝ) (hB : 0 < B) (HABK : inclusion hK '' univ ⊆ verticalStrip A B) (n : ℕ) {a : ℂ} (ha : a ∈ K) : ‖iteratedDerivWithin k (fun z ↦ cotTerm z n) ℍₒ a‖ ≤ cotTermUpperBound k A B hB n := by - simp only [cotTerm_iteratedDerivWithin_eqOn' k n (hK ha), Complex.norm_mul, norm_pow, norm_neg, - norm_one, one_pow, Complex.norm_natCast, one_mul, cotTermUpperBound, Int.reduceNeg, norm_zpow, - Real.norm_eq_abs, two_mul, add_mul] + simp only [cotTerm_iteratedDerivWithin_eqOn_complexUpperHalfPlane k n (hK ha), Complex.norm_mul, + norm_pow, norm_neg,norm_one, one_pow, Complex.norm_natCast, one_mul, cotTermUpperBound, + Int.reduceNeg, norm_zpow, Real.norm_eq_abs, two_mul, add_mul] gcongr - apply le_trans (norm_add_le _ _) - apply add_le_add + apply le_trans (norm_add_le _ _) (add_le_add ?_ ?_) · have := summand_bound_of_mem_verticalStrip (k := (k + 1)) (by norm_cast; omega) ![1, n + 1] hB (z := ⟨a, (hK ha)⟩) (A := A) (by aesop) simp only [coe_setOf, image_univ, Fin.isValue, Matrix.cons_val_zero, Int.cast_one, @@ -343,7 +343,7 @@ theorem DifferentiableOn_iteratedDerivWithin_cotTerm (n l : ℕ) : (z - (n + 1)) ^ (-1 - l : ℤ))) ℍₒ by apply this.congr intro z hz - simpa using (cotTerm_iteratedDerivWithin_eqOn' l n hz) + simpa using (cotTerm_iteratedDerivWithin_eqOn_complexUpperHalfPlane l n hz) apply DifferentiableOn.const_mul apply DifferentiableOn.add <;> apply DifferentiableOn.zpow any_goals try {fun_prop} <;> left <;> intro x hx @@ -375,7 +375,7 @@ private theorem aux_iteratedDeriv_tsum_cotTerm {k : ℕ} (hk : 1 ≤ k) (x : ℍ conv => enter [1,2,1] ext n - rw [cotTerm_iteratedDerivWithin_eqOn' k n (by simp [UpperHalfPlane.coe])] + rw [cotTerm_iteratedDerivWithin_eqOn_complexUpperHalfPlane k n (by simp [UpperHalfPlane.coe])] rw [tsum_of_add_one_of_neg_add_one (by simpa using aux_summable_add hk x) (by simpa [sub_eq_add_neg] using aux_summable_neg hk x), tsum_mul_left, Summable.tsum_add (aux_summable_add hk x) (aux_summable_neg hk x )] From a145d41c4decdd9c3c01f5897a96689c45e18e71 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 17:54:56 +0100 Subject: [PATCH 113/128] rev updates --- .../Complex/UpperHalfPlane/Basic.lean | 6 +-- .../ModularForms/DedekindEta.lean | 41 ++++++++++--------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index f5c194a02ece9a..d1f50582955012 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -207,11 +207,11 @@ section complexUpperHalfPlane /-- The UpperHalfPlane as a subset of `ℂ`. This is convinient for takind derivatives of functions on the upper half plane. -/ -abbrev complexUpperHalfPlane := {z : ℂ | 0 < z.im} +abbrev upperHalfPlaneSet := {z : ℂ | 0 < z.im} -local notation "ℍₒ" => complexUpperHalfPlane +local notation "ℍₒ" => upperHalfPlaneSet -lemma complexUpperHalPlane_isOpen : IsOpen ℍₒ := (isOpen_lt continuous_const Complex.continuous_im) +lemma upperHalfPlaneSet_isOpen : IsOpen ℍₒ := (isOpen_lt continuous_const Complex.continuous_im) end complexUpperHalfPlane diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index a76e07182a364c..dbe0e82405770e 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -32,11 +32,13 @@ open scoped Interval Real NNReal ENNReal Topology BigOperators Nat local notation "𝕢" => Periodic.qParam -local notation "ℍₒ" => complexUpperHalfPlane +local notation "ℍₒ" => upperHalfPlaneSet /-- The q term inside the product defining the eta function. It is defined as `eta_q n z = e ^ (2 π i (n + 1) z)`. -/ -noncomputable abbrev eta_q (n : ℕ) (z : ℂ) := (𝕢 1 z) ^ (n + 1) +noncomputable abbrev ModularForm.eta_q (n : ℕ) (z : ℂ) := (𝕢 1 z) ^ (n + 1) + +open ModularForm lemma eta_q_eq_cexp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * (n + 1) * z) := by simp [eta_q, Periodic.qParam, ← Complex.exp_nsmul] @@ -45,16 +47,16 @@ lemma eta_q_eq_cexp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * lemma eta_q_eq_pow (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * z) ^ (n + 1) := by simp [eta_q, Periodic.qParam] -lemma one_add_eta_q_ne_zero (n : ℕ) (z : ℍ) : 1 - eta_q n z ≠ 0 := by +lemma one_sub_eta_q_ne_zero (n : ℕ) (z : ℍ) : 1 - eta_q n z ≠ 0 := by rw [eta_q_eq_cexp, sub_ne_zero] intro h have := norm_exp_two_pi_I_lt_one ⟨(n + 1) • z, by - have : 0 < (n + 1 : ℝ) := by linarith + have : 0 < (n + 1 : ℝ) := by positivity simpa [this] using z.2⟩ simp [← mul_assoc, ← h] at * /-- The product term in the eta function, defined as `∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. -/ -noncomputable abbrev etaProdTerm (z : ℂ) := ∏' (n : ℕ), (1 - eta_q n z) +noncomputable abbrev ModularForm.etaProdTerm (z : ℂ) := ∏' (n : ℕ), (1 - eta_q n z) local notation "ηₚ" => etaProdTerm @@ -65,35 +67,34 @@ local notation "η" => ModularForm.eta open ModularForm -theorem Summable_eta_q (z : ℍ) : Summable fun n ↦ ‖-eta_q n z‖ := by +theorem summable_eta_q (z : ℍ) : Summable fun n ↦ ‖-eta_q n z‖ := by simp [eta_q, eta_q_eq_pow, summable_nat_add_iff 1, norm_exp_two_pi_I_lt_one z] lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ηₚ ℍₒ:= by simp_rw [sub_eq_add_neg] - apply hasProdLocallyUniformlyOn_of_forall_compact complexUpperHalPlane_isOpen + apply hasProdLocallyUniformlyOn_of_forall_compact upperHalfPlaneSet_isOpen intro K hK hcK by_cases hN : K.Nonempty · have hc : ContinuousOn (fun x ↦ ‖cexp (2 * π * Complex.I * x)‖) K := by fun_prop obtain ⟨z, hz, hB, HB⟩ := hcK.exists_sSup_image_eq_and_ge hN hc - apply (Summable_eta_q ⟨z, by simpa using (hK hz)⟩).hasProdUniformlyOn_nat_one_add hcK + apply (summable_eta_q ⟨z, hK hz⟩).hasProdUniformlyOn_nat_one_add hcK · filter_upwards with n x hx - simpa only [eta_q, eta_q_eq_pow n x, norm_neg, norm_pow, coe_mk_subtype, - eta_q_eq_pow n (⟨z, hK hz⟩ : ℍ)] using + simpa [eta_q, eta_q_eq_pow n x, eta_q_eq_pow n (⟨z, hK hz⟩ : ℍₒ)] using pow_le_pow_left₀ (by simp [norm_nonneg]) (HB x hx) (n + 1) · simp_rw [eta_q, Periodic.qParam] fun_prop · rw [hasProdUniformlyOn_iff_tendstoUniformlyOn] simpa [not_nonempty_iff_eq_empty.mp hN] using tendstoUniformlyOn_empty -theorem etaProdTerm_ne_zero (z : ℍ) : ηₚ z ≠ 0 := by +theorem etaProdTerm_ne_zero (z : ℍₒ) : ηₚ z ≠ 0 := by simp only [etaProdTerm, eta_q, ne_eq] refine tprod_one_add_ne_zero_of_summable z (f := fun n x ↦ -eta_q n x) ?_ ?_ - · refine fun i x ↦ by simpa using one_add_eta_q_ne_zero i x + · refine fun i x ↦ by simpa using one_sub_eta_q_ne_zero i x · intro x - simpa [eta_q, ← summable_norm_iff] using Summable_eta_q x + simpa [eta_q, ← summable_norm_iff] using summable_eta_q x /-- Eta is non-vanishing on the upper half plane. -/ -lemma eta_ne_zero_on_UpperHalfPlane (z : ℍ) : η z ≠ 0 := by +lemma eta_ne_zero_on_UpperHalfPlane (z : ℍₒ) : η z ≠ 0 := by simpa [ModularForm.eta, Periodic.qParam] using etaProdTerm_ne_zero z lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = @@ -121,23 +122,23 @@ private theorem one_sub_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x simp lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - (2 * π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by + (2 * π * Complex.I) * ∑' n : ℕ, (n + 1) * (-eta_q n z) / (1 - eta_q n z) := by suffices ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by + ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by rw [this, ← tsum_mul_left] congr 1 ext i ring exact tsum_congr (fun i ↦ one_sub_eta_logDeriv_eq z i) -theorem etaProdTerm_differentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by +theorem etaProdTerm_differentiableAt (z : ℍₒ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ - complexUpperHalPlane_isOpen - · exact (hD z z.2).differentiableAt (complexUpperHalPlane_isOpen.mem_nhds z.2) + upperHalfPlaneSet_isOpen + · exact (hD z z.2).differentiableAt (upperHalfPlaneSet_isOpen.mem_nhds z.2) · filter_upwards with b y apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x ↦ 1 - eta_q i x) (by fun_prop)).congr simp -lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := +lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍₒ) : DifferentiableAt ℂ eta z := DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) From 4b99d295cebbe8cab4c9ed4557d3460f863b1bf8 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 17:55:50 +0100 Subject: [PATCH 114/128] typo --- Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index d1f50582955012..4952efdd22603a 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -205,7 +205,7 @@ theorem vadd_im : (x +ᵥ z).im = z.im := end RealAddAction section complexUpperHalfPlane -/-- The UpperHalfPlane as a subset of `ℂ`. This is convinient for takind derivatives of functions +/-- The UpperHalfPlane as a subset of `ℂ`. This is convinient for taking derivatives of functions on the upper half plane. -/ abbrev upperHalfPlaneSet := {z : ℂ | 0 < z.im} From 532866d0b479a003b95682534aecf84696c224a7 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 17:56:42 +0100 Subject: [PATCH 115/128] typo --- Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index 4952efdd22603a..69d6d543db0548 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -203,7 +203,7 @@ theorem vadd_im : (x +ᵥ z).im = z.im := zero_add _ end RealAddAction -section complexUpperHalfPlane +section upperHalfPlaneSet /-- The UpperHalfPlane as a subset of `ℂ`. This is convinient for taking derivatives of functions on the upper half plane. -/ @@ -213,6 +213,6 @@ local notation "ℍₒ" => upperHalfPlaneSet lemma upperHalfPlaneSet_isOpen : IsOpen ℍₒ := (isOpen_lt continuous_const Complex.continuous_im) -end complexUpperHalfPlane +end upperHalfPlaneSet end UpperHalfPlane From 434f0f6ded4f7c445b371f4adc3e78fc9904ba70 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 18:39:57 +0100 Subject: [PATCH 116/128] save --- .../Complex/UpperHalfPlane/Basic.lean | 10 +-- .../Trigonometric/Cotangent.lean | 65 +++++++++---------- .../EisensteinSeries/QExpansion.lean | 21 +++--- 3 files changed, 46 insertions(+), 50 deletions(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index f5c194a02ece9a..77b08088d7f5a1 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -203,16 +203,16 @@ theorem vadd_im : (x +ᵥ z).im = z.im := zero_add _ end RealAddAction -section complexUpperHalfPlane +section upperHalfPlaneSet /-- The UpperHalfPlane as a subset of `ℂ`. This is convinient for takind derivatives of functions on the upper half plane. -/ -abbrev complexUpperHalfPlane := {z : ℂ | 0 < z.im} +abbrev upperHalfPlaneSet := {z : ℂ | 0 < z.im} -local notation "ℍₒ" => complexUpperHalfPlane +local notation "ℍₒ" => upperHalfPlaneSet -lemma complexUpperHalPlane_isOpen : IsOpen ℍₒ := (isOpen_lt continuous_const Complex.continuous_im) +lemma upperHalfPlaneSet_isOpen : IsOpen ℍₒ := (isOpen_lt continuous_const Complex.continuous_im) -end complexUpperHalfPlane +end upperHalfPlaneSet end UpperHalfPlane diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index 1c670b7798a51b..c831dd7fad79ad 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -29,7 +29,7 @@ open scoped UpperHalfPlane local notation "ℂ_ℤ" => integerComplement -local notation "ℍₒ" => UpperHalfPlane.complexUpperHalfPlane +local notation "ℍₒ" => UpperHalfPlane.upperHalfPlaneSet lemma Complex.cot_eq_exp_ratio (z : ℂ) : cot z = (Complex.exp (2 * I * z) + 1) / (I * (1 - Complex.exp (2 * I * z))) := by @@ -280,7 +280,7 @@ lemma cotTerm_iteratedDerivWithin_eqOn_complexUpperHalfPlane (d : ℕ) : (z - (d + 1)) ^ (-1 - k : ℤ))) ℍₒ := by apply Set.EqOn.trans (upperHalfPlane_inter_integerComplement ▸ iteratedDerivWithin_congr_right_of_isOpen (fun (z : ℂ) ↦ cotTerm z d) k - complexUpperHalPlane_isOpen (Complex.isOpen_compl_range_intCast)) + upperHalfPlaneSet_isOpen (Complex.isOpen_compl_range_intCast)) intro z hz simpa using cotTerm_iteratedDerivWithin_eqOn_intergerCompliment k d (coe_mem_integerComplement ⟨z, hz⟩) @@ -309,37 +309,32 @@ private lemma iteratedDerivWithin_cotTerm_bounded_uniformly norm_pow, norm_neg,norm_one, one_pow, Complex.norm_natCast, one_mul, cotTermUpperBound, Int.reduceNeg, norm_zpow, Real.norm_eq_abs, two_mul, add_mul] gcongr - apply le_trans (norm_add_le _ _) (add_le_add ?_ ?_) - · have := summand_bound_of_mem_verticalStrip (k := (k + 1)) (by norm_cast; omega) ![1, n + 1] hB + have h1 := summand_bound_of_mem_verticalStrip (k := (k + 1)) (by norm_cast; omega) ![1, n + 1] hB (z := ⟨a, (hK ha)⟩) (A := A) (by aesop) - simp only [coe_setOf, image_univ, Fin.isValue, Matrix.cons_val_zero, Int.cast_one, + have h2 := abs_norm_eq_max_natAbs_neg n ▸ (summand_bound_of_mem_verticalStrip (k := k + 1) + (by norm_cast; omega) ![1, -(n + 1)] hB (z := ⟨a, (hK ha)⟩) (A := A) (by aesop)) + simp only [coe_setOf, image_univ, Fin.isValue, Matrix.cons_val_zero, Int.cast_one, coe_mk_subtype, one_mul, Matrix.cons_val_one, Matrix.cons_val_fin_one, Int.cast_add, - Int.cast_natCast, neg_add_rev, abs_norm_eq_max_natAbs, Int.reduceNeg, sub_eq_add_neg, - norm_zpow, ge_iff_le] at * + Int.cast_natCast, neg_add_rev, abs_norm_eq_max_natAbs, Int.reduceNeg, sub_eq_add_neg] at * + apply le_trans (norm_add_le _ _) (add_le_add ?_ ?_) + · simp only [Int.reduceNeg, norm_zpow] at * norm_cast at * - · have := summand_bound_of_mem_verticalStrip (k := k + 1) (by norm_cast; omega) ![1, -(n + 1)] hB - (z := ⟨a, (hK ha)⟩) (A := A) (by aesop) - rw [abs_norm_eq_max_natAbs_neg] at this - simp only [coe_setOf, image_univ, neg_add_rev, Int.reduceNeg, Fin.isValue, Matrix.cons_val_zero, - Int.cast_one, coe_mk_subtype, one_mul, Matrix.cons_val_one, Matrix.cons_val_fin_one, - Int.cast_add, Int.cast_neg, Int.cast_natCast, sub_eq_add_neg, norm_zpow, ge_iff_le] at * + · simp only [Int.cast_one, Int.cast_neg, Int.cast_natCast, norm_zpow] at * norm_cast at * lemma summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm {k : ℕ} (hk : 1 ≤ k) : SummableLocallyUniformlyOn (fun n : ℕ ↦ iteratedDerivWithin k (fun z ↦ cotTerm z n) ℍₒ) ℍₒ := by - apply SummableLocallyUniformlyOn_of_locally_bounded (complexUpperHalPlane_isOpen) + apply SummableLocallyUniformlyOn_of_locally_bounded (upperHalfPlaneSet_isOpen) intro K hK hKc - have hKK2 : IsCompact (Set.image (inclusion hK) univ) := by - exact (isCompact_iff_isCompact_univ.mp hKc).image_of_continuousOn - (continuous_inclusion hK |>.continuousOn) - obtain ⟨A, B, hB, HABK⟩ := subset_verticalStrip_of_isCompact hKK2 + obtain ⟨A, B, hB, HABK⟩ := subset_verticalStrip_of_isCompact + ((isCompact_iff_isCompact_univ.mp hKc).image_of_continuousOn + (continuous_inclusion hK |>.continuousOn)) exact ⟨cotTermUpperBound k A B hB, Summable_cotTermUpperBound A B hB hk, iteratedDerivWithin_cotTerm_bounded_uniformly hk hK A B hB HABK⟩ theorem DifferentiableOn_iteratedDerivWithin_cotTerm (n l : ℕ) : DifferentiableOn ℂ (iteratedDerivWithin l (fun z ↦ cotTerm z n) ℍₒ) ℍₒ := by - suffices DifferentiableOn ℂ - (fun z : ℂ ↦ (-1) ^ l * l ! * ((z + (n + 1)) ^ (-1 - l : ℤ) + + suffices DifferentiableOn ℂ (fun z : ℂ ↦ (-1) ^ l * l ! * ((z + (n + 1)) ^ (-1 - l : ℤ) + (z - (n + 1)) ^ (-1 - l : ℤ))) ℍₒ by apply this.congr intro z hz @@ -350,32 +345,32 @@ theorem DifferentiableOn_iteratedDerivWithin_cotTerm (n l : ℕ) : · simpa [add_eq_zero_iff_neg_eq'] using (UpperHalfPlane.ne_int ⟨x, hx⟩ (-(n+1))).symm · simpa [sub_eq_zero] using (UpperHalfPlane.ne_int ⟨x, hx⟩ ((n+1))) -private theorem aux_summable_add {k : ℕ} (hk : 1 ≤ k) (x : ℍ) : +private theorem aux_summable_add {k : ℕ} (hk : 1 ≤ k) (x : ℍₒ) : Summable fun (n : ℕ) ↦ ((x : ℂ) + (n + 1)) ^ (-1 - k : ℤ) := by apply ((summable_nat_add_iff 1).mpr (summable_int_iff_summable_nat_and_neg.mp (EisensteinSeries.linear_right_summable x 1 (k := k + 1) (by omega))).1).congr simp [← zpow_neg, sub_eq_add_neg] -private theorem aux_summable_neg {k : ℕ} (hk : 1 ≤ k) (x : ℍ) : +private theorem aux_summable_neg {k : ℕ} (hk : 1 ≤ k) (x : ℍₒ) : Summable fun (n : ℕ) ↦ ((x : ℂ) - (n + 1)) ^ (-1 - k : ℤ) := by apply ((summable_nat_add_iff 1).mpr (summable_int_iff_summable_nat_and_neg.mp (EisensteinSeries.linear_right_summable x 1 (k := k + 1) (by omega))).2).congr simp [← zpow_neg, sub_eq_add_neg] -- We have this auxilary ugly version on the lhs so the the rhs looks nicer. -private theorem aux_iteratedDeriv_tsum_cotTerm {k : ℕ} (hk : 1 ≤ k) (x : ℍ) : +private theorem aux_iteratedDeriv_tsum_cotTerm {k : ℕ} (hk : 1 ≤ k) (x : ℍₒ) : (-1) ^ k * (k !) * (x : ℂ) ^ (-1 - k : ℤ) + iteratedDerivWithin k (fun z : ℂ ↦ ∑' n : ℕ, cotTerm z n) ℍₒ x = (-1) ^ (k : ℕ) * (k : ℕ)! * ∑' n : ℤ, ((x : ℂ) + n) ^ (-1 - k : ℤ) := by - rw [iteratedDerivWithin_tsum k complexUpperHalPlane_isOpen - (by simpa using x.2) (fun t ht ↦ Summable_cotTerm (coe_mem_integerComplement ⟨t, ht⟩)) - (fun l hl hl2 ↦ summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm hl) - (fun n l z hl hz ↦ ((DifferentiableOn_iteratedDerivWithin_cotTerm n l)).differentiableAt - ((IsOpen.mem_nhds (complexUpperHalPlane_isOpen) hz)))] + rw [iteratedDerivWithin_tsum k upperHalfPlaneSet_isOpen x.2 + (fun t ht ↦ Summable_cotTerm (coe_mem_integerComplement ⟨t, ht⟩)) + (fun l hl hl2 ↦ summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm hl) + (fun n l z hl hz ↦ ((DifferentiableOn_iteratedDerivWithin_cotTerm n l)).differentiableAt + ((IsOpen.mem_nhds (upperHalfPlaneSet_isOpen) hz)))] conv => enter [1,2,1] ext n - rw [cotTerm_iteratedDerivWithin_eqOn_complexUpperHalfPlane k n (by simp [UpperHalfPlane.coe])] + rw [cotTerm_iteratedDerivWithin_eqOn_complexUpperHalfPlane k n (by simp)] rw [tsum_of_add_one_of_neg_add_one (by simpa using aux_summable_add hk x) (by simpa [sub_eq_add_neg] using aux_summable_neg hk x), tsum_mul_left, Summable.tsum_add (aux_summable_add hk x) (aux_summable_neg hk x )] @@ -383,7 +378,7 @@ private theorem aux_iteratedDeriv_tsum_cotTerm {k : ℕ} (hk : 1 ≤ k) (x : ℍ Int.cast_one, Int.cast_zero, add_zero, Int.cast_neg] ring -theorem iteratedDerivWithin_cot_sub_inv_eq_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : +theorem iteratedDerivWithin_cot_sub_inv_eq_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍₒ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x) - 1 / x) ℍₒ z = -(-1) ^ k * (k !) * ((z : ℂ) ^ (-1 - k : ℤ)) + (-1) ^ (k : ℕ) * (k : ℕ)! * ∑' n : ℤ, ((z : ℂ) + n) ^ (-1 - k : ℤ):= by @@ -393,20 +388,20 @@ theorem iteratedDerivWithin_cot_sub_inv_eq_series_rep {k : ℕ} (hk : 1 ≤ k) ( intro x hx simpa [cotTerm] using (cot_series_rep' (UpperHalfPlane.coe_mem_integerComplement ⟨x, hx⟩)) -theorem iteratedDerivWithin_cot_pi_z_sub_inv (z : ℍ) : +theorem iteratedDerivWithin_cot_pi_z_sub_inv (z : ℍₒ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x) - 1 / x) ℍₒ z = (iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z) - (-1) ^ k * k ! * ((z : ℂ) ^ (-1 - k : ℤ)) := by simp_rw [sub_eq_add_neg] - rw [iteratedDerivWithin_fun_add (by apply z.2) complexUpperHalPlane_isOpen.uniqueDiffOn] + rw [iteratedDerivWithin_fun_add (by apply z.2) upperHalfPlaneSet_isOpen.uniqueDiffOn] · simpa [iteratedDerivWithin_fun_neg] using iteratedDerivWithin_one_div k - complexUpperHalPlane_isOpen z.2 + upperHalfPlaneSet_isOpen z.2 · exact ContDiffWithinAt.smul (by fun_prop) (cot_pi_z_contDiffWithinAt k z) · simp only [one_div] apply ContDiffWithinAt.neg exact ContDiffWithinAt.inv (by fun_prop) (ne_zero z) -theorem iteratedDerivWithin_cot_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : +theorem iteratedDerivWithin_cot_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍₒ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z = (-1) ^ k * k ! * ∑' n : ℤ, ((z : ℂ) + n) ^ (-1 - k : ℤ):= by have h0 := iteratedDerivWithin_cot_pi_z_sub_inv k z @@ -414,7 +409,7 @@ theorem iteratedDerivWithin_cot_series_rep {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : rw [← add_left_inj (-(-1) ^ k * ↑k ! * (z : ℂ) ^ (-1 - k : ℤ)), h0] ring -theorem iteratedDerivWithin_cot_series_rep_one_div {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : +theorem iteratedDerivWithin_cot_series_rep_one_div {k : ℕ} (hk : 1 ≤ k) (z : ℍₒ) : iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z = (-1) ^ k * k ! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) := by simp only [iteratedDerivWithin_cot_series_rep hk z, Int.reduceNeg, one_div, mul_eq_mul_left_iff, diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index c1a5a80b674ae1..f6dda74e437931 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -27,7 +27,7 @@ open Set Metric TopologicalSpace Function Filter Complex UpperHalfPlane Arithmet open scoped Topology Real Nat Complex Pointwise -local notation "ℍₒ" => complexUpperHalfPlane +local notation "ℍₒ" => upperHalfPlaneSet lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (p : ℝ) {S : Set ℂ} (hs : IsOpen S) : EqOn (iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * Complex.I * m * s / p)) S) @@ -60,7 +60,7 @@ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f (hp : 0 < p) (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : SummableLocallyUniformlyOn (fun n ↦ (f n) • iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z / p) ^ n) ℍₒ) ℍₒ := by - apply SummableLocallyUniformlyOn_of_locally_bounded complexUpperHalPlane_isOpen + apply SummableLocallyUniformlyOn_of_locally_bounded upperHalfPlaneSet_isOpen intro K hK hKc haveI : CompactSpace K := isCompact_univ_iff.mp (isCompact_iff_isCompact_univ.mp hKc) let c : ContinuousMap K ℂ := ⟨fun r : K ↦ Complex.exp (2 * ↑π * Complex.I * r / p), by fun_prop⟩ @@ -79,7 +79,7 @@ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f have h0 := pow_le_pow_left₀ (by apply norm_nonneg _) (norm_coe_le_norm (mkOfCompact c) ⟨z, hz⟩) n simp only [norm_mkOfCompact, mkOfCompact_apply, ContinuousMap.coe_mk, ← exp_nsmul', Pi.smul_apply, - iteratedDerivWithin_cexp_mul_const k n p complexUpperHalPlane_isOpen (hK hz), smul_eq_mul, + iteratedDerivWithin_cexp_mul_const k n p upperHalfPlaneSet_isOpen (hK hz), smul_eq_mul, norm_mul, norm_pow, Complex.norm_div, norm_ofNat, norm_real, Real.norm_eq_abs, norm_I, mul_one, norm_natCast, abs_norm, ge_iff_le, r, c] at * rw [← mul_assoc] @@ -110,20 +110,20 @@ theorem differnetiableAt_iteratedDerivWithin_cexp (n a : ℕ) {s : Set ℂ} (hs lemma iteratedDerivWithin_tsum_exp_eq (k : ℕ) (z : ℍ) : iteratedDerivWithin k (fun z ↦ ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n) ℍₒ z = ∑' n : ℕ, iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * Complex.I * s) ^ n) ℍₒ z := by - rw [iteratedDerivWithin_tsum k complexUpperHalPlane_isOpen (by simpa using z.2)] + rw [iteratedDerivWithin_tsum k upperHalfPlaneSet_isOpen (by simpa using z.2)] · exact fun x hx => summable_geometric_iff_norm_lt_one.mpr (UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨x, hx⟩) · exact fun n _ _ => summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' n · exact fun n l z hl hz => differnetiableAt_iteratedDerivWithin_cexp n l - complexUpperHalPlane_isOpen hz + upperHalfPlaneSet_isOpen hz theorem contDiffOn_tsum_cexp (k : ℕ∞) : ContDiffOn ℂ k (fun z : ℂ ↦ ∑' n : ℕ, cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ := contDiffOn_of_differentiableOn_deriv fun m _ z hz ↦ - ((summableUniformlyOn_differentiableOn complexUpperHalPlane_isOpen + ((summableUniformlyOn_differentiableOn upperHalfPlaneSet_isOpen (summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' m) (fun n _ hz => differnetiableAt_iteratedDerivWithin_cexp n m - complexUpperHalPlane_isOpen hz)) z hz).congr (fun z hz ↦ + upperHalfPlaneSet_isOpen hz)) z hz).congr (fun z hz ↦ iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) (iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : @@ -150,11 +150,11 @@ private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ have := exp_nsmul' (p := 1) (a := 2 * π * Complex.I) (n := n) simp only [div_one] at this simpa [this, ofReal_one, div_one, one_mul, UpperHalfPlane.coe] using - iteratedDerivWithin_cexp_mul_const k n 1 complexUpperHalPlane_isOpen z.2 + iteratedDerivWithin_cexp_mul_const k n 1 upperHalfPlaneSet_isOpen z.2 rw [iteratedDerivWithin_const_sub hk, iteratedDerivWithin_fun_neg, iteratedDerivWithin_const_mul] · simp only [iteratedDerivWithin_tsum_exp_eq, neg_mul] · simpa using z.2 - · exact complexUpperHalPlane_isOpen.uniqueDiffOn + · exact upperHalfPlaneSet_isOpen.uniqueDiffOn · exact (contDiffOn_tsum_cexp k).contDiffWithinAt (by simpa using z.2) theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : @@ -173,7 +173,8 @@ theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) field_simp [h3] ring_nf simp [Nat.mul_two] - rw [← iteratedDerivWithin_tsum_exp_eq' hk z, ← iteratedDerivWithin_cot_series_rep_one_div hk z] + rw [← iteratedDerivWithin_tsum_exp_eq' hk z, + ← iteratedDerivWithin_cot_series_rep_one_div hk ⟨z, z.2⟩] apply iteratedDerivWithin_congr · intro x hx simpa using pi_mul_cot_pi_q_exp ⟨x, hx⟩ From 0a387e586e3b7d2303c7eab4db44a39707cddb04 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 18:50:21 +0100 Subject: [PATCH 117/128] update --- .../ModularForms/DedekindEta.lean | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index dbe0e82405770e..b9c12344c53c81 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -47,12 +47,12 @@ lemma eta_q_eq_cexp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * lemma eta_q_eq_pow (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * z) ^ (n + 1) := by simp [eta_q, Periodic.qParam] -lemma one_sub_eta_q_ne_zero (n : ℕ) (z : ℍ) : 1 - eta_q n z ≠ 0 := by +lemma one_sub_eta_q_ne_zero (n : ℕ) {z : ℂ} (hz : z ∈ ℍₒ) : 1 - eta_q n z ≠ 0 := by rw [eta_q_eq_cexp, sub_ne_zero] intro h have := norm_exp_two_pi_I_lt_one ⟨(n + 1) • z, by have : 0 < (n + 1 : ℝ) := by positivity - simpa [this] using z.2⟩ + simpa [this] using hz⟩ simp [← mul_assoc, ← h] at * /-- The product term in the eta function, defined as `∏' 1 - q ^ (n + 1)` for `q = e ^ 2 π i z`. -/ @@ -86,16 +86,16 @@ lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - · rw [hasProdUniformlyOn_iff_tendstoUniformlyOn] simpa [not_nonempty_iff_eq_empty.mp hN] using tendstoUniformlyOn_empty -theorem etaProdTerm_ne_zero (z : ℍₒ) : ηₚ z ≠ 0 := by +theorem etaProdTerm_ne_zero {z : ℂ} (hz : z ∈ ℍₒ) : ηₚ z ≠ 0 := by simp only [etaProdTerm, eta_q, ne_eq] - refine tprod_one_add_ne_zero_of_summable z (f := fun n x ↦ -eta_q n x) ?_ ?_ - · refine fun i x ↦ by simpa using one_sub_eta_q_ne_zero i x + refine tprod_one_add_ne_zero_of_summable ⟨z, hz⟩ (f := fun n x ↦ -eta_q n x) (α := ℍₒ) ?_ ?_ + · refine fun i x ↦ by simpa using one_sub_eta_q_ne_zero i x.2 · intro x simpa [eta_q, ← summable_norm_iff] using summable_eta_q x /-- Eta is non-vanishing on the upper half plane. -/ -lemma eta_ne_zero_on_UpperHalfPlane (z : ℍₒ) : η z ≠ 0 := by - simpa [ModularForm.eta, Periodic.qParam] using etaProdTerm_ne_zero z +lemma eta_ne_zero_on_UpperHalfPlane {z : ℂ} (hz : z ∈ ℍₒ) : η z ≠ 0 := by + simpa [ModularForm.eta, Periodic.qParam] using etaProdTerm_ne_zero hz lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = fun z ↦ -r * cexp z / (1 - r * cexp z) := by @@ -131,14 +131,14 @@ lemma tsum_log_deriv_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - e ring exact tsum_congr (fun i ↦ one_sub_eta_logDeriv_eq z i) -theorem etaProdTerm_differentiableAt (z : ℍₒ) : DifferentiableAt ℂ ηₚ z := by +theorem etaProdTerm_differentiableAt {z : ℂ} (hz : z ∈ ℍₒ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ upperHalfPlaneSet_isOpen - · exact (hD z z.2).differentiableAt (upperHalfPlaneSet_isOpen.mem_nhds z.2) + · exact (hD z hz).differentiableAt (upperHalfPlaneSet_isOpen.mem_nhds hz) · filter_upwards with b y apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x ↦ 1 - eta_q i x) (by fun_prop)).congr simp -lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍₒ) : DifferentiableAt ℂ eta z := - DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt z) +lemma eta_DifferentiableAt_UpperHalfPlane {z : ℂ} (hz : z ∈ ℍₒ) : DifferentiableAt ℂ eta z := + DifferentiableAt.mul (by fun_prop) (etaProdTerm_differentiableAt hz) From 55e3f1f82fd720d170f26a137a8d9f1ec706a498 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 18:52:08 +0100 Subject: [PATCH 118/128] save --- Mathlib/NumberTheory/ModularForms/DedekindEta.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 892f773c343a95..9cad4df60a6546 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -35,7 +35,7 @@ open scoped Interval Real NNReal ENNReal Topology BigOperators Nat local notation "𝕢" => Periodic.qParam -local notation "ℍₒ" => complexUpperHalfPlane +local notation "ℍₒ" => upperHalfPlaneSet /-- The q term inside the product defining the eta function. It is defined as `eta_q n z = e ^ (2 π i (n + 1) z)`. -/ @@ -73,7 +73,7 @@ theorem Summable_eta_q (z : ℍ) : Summable fun n ↦ ‖-eta_q n z‖ := by lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ηₚ ℍₒ:= by simp_rw [sub_eq_add_neg] - apply hasProdLocallyUniformlyOn_of_forall_compact complexUpperHalPlane_isOpen + apply hasProdLocallyUniformlyOn_of_forall_compact upperHalfPlaneSet_isOpen intro K hK hcK by_cases hN : K.Nonempty · have hc : ContinuousOn (fun x ↦ ‖cexp (2 * π * Complex.I * x)‖) K := by fun_prop @@ -160,8 +160,8 @@ lemma multipliableLocallyUniformlyOn_one_sub_eta_q : theorem etaProdTerm_DifferentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ - complexUpperHalPlane_isOpen - · exact (hD z z.2).differentiableAt (complexUpperHalPlane_isOpen.mem_nhds z.2) + upperHalfPlaneSet_isOpen + · exact (hD z z.2).differentiableAt (upperHalfPlaneSet_isOpen.mem_nhds z.2) · filter_upwards with b y apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x ↦ 1 - eta_q i x) (by fun_prop)).congr @@ -174,7 +174,7 @@ lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12 unfold ModularForm.eta etaProdTerm rw [logDeriv_mul (UpperHalfPlane.coe z) (by simp [ne_eq, exp_ne_zero, not_false_eq_true, Periodic.qParam]) (etaProdTerm_ne_zero z) (by fun_prop) (etaProdTerm_DifferentiableAt z)] - have HG := logDeriv_tprod_eq_tsum (complexUpperHalPlane_isOpen) (x := z) + have HG := logDeriv_tprod_eq_tsum (upperHalfPlaneSet_isOpen) (x := z) (f := fun n x => 1 - eta_q n x) (fun i ↦ one_add_eta_q_ne_zero i z) (by simp_rw [eta_q_eq_pow]; fun_prop) (summable_log_deriv_one_sub_eta_q z) (multipliableLocallyUniformlyOn_one_sub_eta_q) (etaProdTerm_ne_zero z) From 955c18d40944d2994b48e26b33d69b7f5f216479 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 20 Aug 2025 18:54:16 +0100 Subject: [PATCH 119/128] move --- .../ModularForms/DedekindEta.lean | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 9cad4df60a6546..da31d734630521 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -140,6 +140,18 @@ lemma tsum_log_deriv_one_sub_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ring exact tsum_congr (fun i ↦ one_sub_eta_logDeriv_eq z i) +theorem etaProdTerm_DifferentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by + have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ + upperHalfPlaneSet_isOpen + · exact (hD z z.2).differentiableAt (upperHalfPlaneSet_isOpen.mem_nhds z.2) + · filter_upwards with b y + apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x ↦ 1 - eta_q i x) + (by fun_prop)).congr + simp + +lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := + DifferentiableAt.mul (by fun_prop) (etaProdTerm_DifferentiableAt z) + lemma summable_log_deriv_one_sub_eta_q (z : ℍ) : Summable fun i ↦ logDeriv (fun x ↦ 1 - eta_q i x) z := by simp only [one_sub_eta_logDeriv_eq] @@ -158,18 +170,6 @@ lemma multipliableLocallyUniformlyOn_one_sub_eta_q : ⟨ηₚ, (hasProdLocallyUniformlyOn_eta).congr fun n x _ ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, (fun n a ↦ 1 - eta_q n a) i b) x)⟩ -theorem etaProdTerm_DifferentiableAt (z : ℍ) : DifferentiableAt ℂ ηₚ z := by - have hD := hasProdLocallyUniformlyOn_eta.tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_ - upperHalfPlaneSet_isOpen - · exact (hD z z.2).differentiableAt (upperHalfPlaneSet_isOpen.mem_nhds z.2) - · filter_upwards with b y - apply (DifferentiableOn.finset_prod (u := Finset.range b) (f := fun i x ↦ 1 - eta_q i x) - (by fun_prop)).congr - simp - -lemma eta_DifferentiableAt_UpperHalfPlane (z : ℍ) : DifferentiableAt ℂ eta z := - DifferentiableAt.mul (by fun_prop) (etaProdTerm_DifferentiableAt z) - lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E2 z := by unfold ModularForm.eta etaProdTerm rw [logDeriv_mul (UpperHalfPlane.coe z) (by simp [ne_eq, exp_ne_zero, not_false_eq_true, From 81baf95f02110eea6841788fbbd427067f4c40a7 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 21 Aug 2025 09:07:06 +0100 Subject: [PATCH 120/128] I cleanup --- .../EisensteinSeries/QExpansion.lean | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index f6dda74e437931..27c9a54303f013 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -22,20 +22,22 @@ Q-expansions. -/ -open Set Metric TopologicalSpace Function Filter Complex UpperHalfPlane ArithmeticFunction +open Set Metric TopologicalSpace Function Filter Complex ArithmeticFunction ModularForm EisensteinSeries +open _root_.UpperHalfPlane hiding I + open scoped Topology Real Nat Complex Pointwise local notation "ℍₒ" => upperHalfPlaneSet lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (p : ℝ) {S : Set ℂ} (hs : IsOpen S) : - EqOn (iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * Complex.I * m * s / p)) S) - (fun s ↦ (2 * ↑π * Complex.I * m / p) ^ k * cexp (2 * ↑π * Complex.I * m * s / p)) S := by + EqOn (iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * I * m * s / p)) S) + (fun s ↦ (2 * ↑π * I * m / p) ^ k * cexp (2 * ↑π * I * m * s / p)) S := by apply EqOn.trans (iteratedDerivWithin_of_isOpen hs) intro x hx - have : (fun s ↦ cexp (2 * ↑π * Complex.I * ↑m * s / ↑p)) = - (fun s ↦ cexp (((2 * ↑π * Complex.I * ↑m) / p) * s)) := by + have : (fun s ↦ cexp (2 * ↑π * I * ↑m * s / ↑p)) = + (fun s ↦ cexp (((2 * ↑π * I * ↑m) / p) * s)) := by ext z ring_nf simp only [this, iteratedDeriv_cexp_const_mul] @@ -43,33 +45,32 @@ lemma iteratedDerivWithin_cexp_mul_const (k m : ℕ) (p : ℝ) {S : Set ℂ} (hs private lemma aux_IsBigO_mul (k l : ℕ) (p : ℝ) {f : ℕ → ℂ} (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : - (fun n ↦ f n * (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] (fun n ↦ (↑(n ^ (l + k)) : ℝ)) := by - have h0 : (fun n : ℕ ↦ (2 * ↑π * Complex.I * ↑n / p) ^ k) =O[atTop] (fun n ↦ (↑(n ^ k) : ℝ)) := by - have h1 : (fun n : ℕ ↦ (2 * ↑π * Complex.I * ↑n / p) ^ k) = - (fun n : ℕ ↦ ((2 * ↑π * Complex.I / p) ^ k) * ↑n ^ k) := by + (fun n ↦ f n * (2 * ↑π * I * ↑n / p) ^ k) =O[atTop] (fun n ↦ (↑(n ^ (l + k)) : ℝ)) := by + have h0 : (fun n : ℕ ↦ (2 * ↑π * I * ↑n / p) ^ k) =O[atTop] (fun n ↦ (↑(n ^ k) : ℝ)) := by + have h1 : (fun n : ℕ ↦ (2 * ↑π * I * ↑n / p) ^ k) = + (fun n : ℕ ↦ ((2 * ↑π * I / p) ^ k) * ↑n ^ k) := by ext z ring simpa [h1] using (Complex.isBigO_ofReal_right.mp (Asymptotics.isBigO_const_mul_self - ((2 * ↑π * Complex.I / p) ^ k) (fun (n : ℕ) ↦ (↑(n ^ k) : ℝ)) atTop)) + ((2 * ↑π * I / p) ^ k) (fun (n : ℕ) ↦ (↑(n ^ k) : ℝ)) atTop)) simp only [Nat.cast_pow] at * convert hf.mul h0 ring open BoundedContinuousFunction in theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f : ℕ → ℂ} {p : ℝ} - (hp : 0 < p) (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : - SummableLocallyUniformlyOn (fun n ↦ (f n) • - iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * Complex.I * z / p) ^ n) ℍₒ) ℍₒ := by + (hp : 0 < p) (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : SummableLocallyUniformlyOn + (fun n ↦ (f n) • iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * I * z / p) ^ n) ℍₒ) ℍₒ := by apply SummableLocallyUniformlyOn_of_locally_bounded upperHalfPlaneSet_isOpen intro K hK hKc haveI : CompactSpace K := isCompact_univ_iff.mp (isCompact_iff_isCompact_univ.mp hKc) - let c : ContinuousMap K ℂ := ⟨fun r : K ↦ Complex.exp (2 * ↑π * Complex.I * r / p), by fun_prop⟩ + let c : ContinuousMap K ℂ := ⟨fun r : K ↦ Complex.exp (2 * ↑π * I * r / p), by fun_prop⟩ let r : ℝ := ‖mkOfCompact c‖ have hr : ‖r‖ < 1 := by simp only [norm_norm, r, norm_lt_iff_of_compact Real.zero_lt_one, mkOfCompact_apply, ContinuousMap.coe_mk, c] intro x - have h1 : cexp (2 * ↑π * Complex.I * (↑x / ↑p)) = cexp (2 * ↑π * Complex.I * ↑x / ↑p) := by + have h1 : cexp (2 * ↑π * I * (↑x / ↑p)) = cexp (2 * ↑π * I * ↑x / ↑p) := by congr 1 ring simpa using h1 ▸ UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨((x : ℂ) / p) , by aesop⟩ @@ -90,8 +91,8 @@ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f /-- This is a version of `summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion` for level one and q-expansion coefficients all `1`. -/ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' (k : ℕ) : - SummableLocallyUniformlyOn (fun n ↦ iteratedDerivWithin k - (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ) ℍₒ := by + SummableLocallyUniformlyOn + (fun n ↦ iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * I * z) ^ n) ℍₒ) ℍₒ := by have h0 : (fun n : ℕ ↦ (1 : ℂ)) =O[atTop] (fun n ↦ ((n ^ 1) : ℝ)) := by simp only [Asymptotics.isBigO_iff, norm_one, norm_pow, Real.norm_natCast, eventually_atTop, ge_iff_le] @@ -99,17 +100,17 @@ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' (k : ℕ) : simpa using summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion k 1 (p := 1) (by norm_num) h0 -theorem differnetiableAt_iteratedDerivWithin_cexp (n a : ℕ) {s : Set ℂ} (hs : IsOpen s) {r : ℂ} - (hr : r ∈ s) : - DifferentiableAt ℂ (iteratedDerivWithin a (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n) s) r := by +theorem differnetiableAt_iteratedDerivWithin_cexp (n a : ℕ) {s : Set ℂ} + (hs : IsOpen s) {r : ℂ} (hr : r ∈ s) : + DifferentiableAt ℂ (iteratedDerivWithin a (fun z ↦ cexp (2 * ↑π * I * z) ^ n) s) r := by apply DifferentiableOn.differentiableAt _ (hs.mem_nhds hr) - suffices DifferentiableOn ℂ (iteratedDeriv a (fun z ↦ cexp (2 * ↑π * Complex.I * z) ^ n)) s by + suffices DifferentiableOn ℂ (iteratedDeriv a (fun z ↦ cexp (2 * ↑π * I * z) ^ n)) s by apply this.congr (iteratedDerivWithin_of_isOpen hs) fun_prop lemma iteratedDerivWithin_tsum_exp_eq (k : ℕ) (z : ℍ) : iteratedDerivWithin k (fun z ↦ - ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n) ℍₒ z = - ∑' n : ℕ, iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * Complex.I * s) ^ n) ℍₒ z := by + ∑' n : ℕ, cexp (2 * π * I * z) ^ n) ℍₒ z = + ∑' n : ℕ, iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * I * s) ^ n) ℍₒ z := by rw [iteratedDerivWithin_tsum k upperHalfPlaneSet_isOpen (by simpa using z.2)] · exact fun x hx => summable_geometric_iff_norm_lt_one.mpr (UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨x, hx⟩) @@ -118,7 +119,7 @@ lemma iteratedDerivWithin_tsum_exp_eq (k : ℕ) (z : ℍ) : iteratedDerivWithin upperHalfPlaneSet_isOpen hz theorem contDiffOn_tsum_cexp (k : ℕ∞) : - ContDiffOn ℂ k (fun z : ℂ ↦ ∑' n : ℕ, cexp (2 * ↑π * Complex.I * z) ^ n) ℍₒ := + ContDiffOn ℂ k (fun z : ℂ ↦ ∑' n : ℕ, cexp (2 * ↑π * I * z) ^ n) ℍₒ := contDiffOn_of_differentiableOn_deriv fun m _ z hz ↦ ((summableUniformlyOn_differentiableOn upperHalfPlaneSet_isOpen (summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' m) @@ -127,17 +128,16 @@ theorem contDiffOn_tsum_cexp (k : ℕ∞) : iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) (iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : - iteratedDerivWithin k (fun z ↦ (((π : ℂ) * Complex.I) - - (2 * π * Complex.I) * ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n)) ℍₒ z = - -(2 * π * Complex.I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by + iteratedDerivWithin k (fun z ↦ (((π : ℂ) * I) - + (2 * π * I) * ∑' n : ℕ, cexp (2 * π * I * z) ^ n)) ℍₒ z = + -(2 * π * I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * I * z) ^ n := by suffices - iteratedDerivWithin k (fun z ↦ ((↑π * Complex.I) - - (2 * π * Complex.I) * ∑' n : ℕ, cexp (2 * π * Complex.I * z) ^ n)) ℍₒ z = - -(2 * π * Complex.I) * ∑' n : ℕ, iteratedDerivWithin k - (fun s : ℂ ↦ cexp (2 * ↑π * Complex.I * s) ^ n) ℍₒ z by - have h : -(2 * ↑π * Complex.I * (2 * ↑π * Complex.I) ^ k) * - ∑' (n : ℕ), ↑n ^ k * cexp (2 * ↑π * Complex.I * ↑z) ^ n = -(2 * π * Complex.I) * - ∑' n : ℕ, (2 * ↑π * Complex.I * n) ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by + iteratedDerivWithin k (fun z ↦ ((↑π * I) - + (2 * π * I) * ∑' n : ℕ, cexp (2 * π * I * z) ^ n)) ℍₒ z = + -(2 * π * I) * ∑' n : ℕ, iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * I * s) ^ n) ℍₒ z by + have h : -(2 * ↑π * I * (2 * ↑π * I) ^ k) * + ∑' (n : ℕ), ↑n ^ k * cexp (2 * ↑π * I * ↑z) ^ n = -(2 * π * I) * + ∑' n : ℕ, (2 * ↑π * I * n) ^ k * cexp (2 * ↑π * I * z) ^ n := by simp_rw [← tsum_mul_left] congr ext y @@ -147,7 +147,7 @@ private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ or_false, Real.pi_ne_zero] congr ext n - have := exp_nsmul' (p := 1) (a := 2 * π * Complex.I) (n := n) + have := exp_nsmul' (p := 1) (a := 2 * π * I) (n := n) simp only [div_one] at this simpa [this, ofReal_one, div_one, one_mul, UpperHalfPlane.coe] using iteratedDerivWithin_cexp_mul_const k n 1 upperHalfPlaneSet_isOpen z.2 @@ -158,17 +158,17 @@ private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ · exact (contDiffOn_tsum_cexp k).contDiffWithinAt (by simpa using z.2) theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : - ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = ((-2 * π * Complex.I) ^ (k + 1) / (k !)) * - ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n := by + ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = ((-2 * π * I) ^ (k + 1) / (k !)) * + ∑' n : ℕ, n ^ k * cexp (2 * ↑π * I * z) ^ n := by suffices (-1) ^ k * (k : ℕ)! * ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = - -(2 * π * Complex.I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ n by + -(2 * π * I) ^ (k + 1) * ∑' n : ℕ, n ^ k * cexp (2 * ↑π * I * z) ^ n by simp_rw [(eq_inv_mul_iff_mul_eq₀ (by simp [Nat.factorial_ne_zero])).mpr this, ← tsum_mul_left] congr ext n have h3 : (k ! : ℂ) ≠ 0 := by norm_cast apply Nat.factorial_ne_zero - rw [show (-2 * ↑π * Complex.I) ^ (k + 1) = (-1)^ (k + 1) * (2 * π * Complex.I) ^ (k + 1) by + rw [show (-2 * ↑π * I) ^ (k + 1) = (-1)^ (k + 1) * (2 * π * I) ^ (k + 1) by rw [← neg_pow]; ring] field_simp [h3] ring_nf @@ -181,7 +181,7 @@ theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) · simpa using z.2 theorem summable_pow_mul_cexp (k : ℕ) (e : ℕ+) (z : ℍ) : - Summable fun c : ℕ ↦ (c : ℂ) ^ k * cexp (2 * ↑π * Complex.I * e * ↑z) ^ c := by + Summable fun c : ℕ ↦ (c : ℂ) ^ k * cexp (2 * ↑π * I * e * ↑z) ^ c := by have he : 0 < (e * (z : ℂ)).im := by simpa using z.2 apply ((summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion 0 k (p := 1) @@ -194,8 +194,8 @@ theorem summable_pow_mul_cexp (k : ℕ) (e : ℕ+) (z : ℍ) : ring_nf theorem EisensteinSeries.qExpansion_identity_pnat {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : - ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = ((-2 * π * Complex.I) ^ (k + 1) / (k !)) * - ∑' n : ℕ+, n ^ k * cexp (2 * ↑π * Complex.I * z) ^ (n : ℕ) := by + ∑' n : ℤ, 1 / ((z : ℂ) + n) ^ (k + 1) = ((-2 * π * I) ^ (k + 1) / (k !)) * + ∑' n : ℕ+, n ^ k * cexp (2 * ↑π * I * z) ^ (n : ℕ) := by have hk0 : k ≠ 0 := by omega rw [EisensteinSeries.qExpansion_identity hk z, ← tsum_zero_pnat_eq_tsum_nat] · simp only [neg_mul, CharP.cast_eq_zero, ne_eq, hk0, not_false_eq_true, zero_pow, pow_zero, @@ -205,17 +205,17 @@ theorem EisensteinSeries.qExpansion_identity_pnat {k : ℕ} (hk : 1 ≤ k) (z : @[simp] lemma cexp_pow_aux (a b : ℕ) (z : ℍ) : - cexp (2 * ↑π * Complex.I * a * z) ^ b = Complex.exp (2 * ↑π * Complex.I * z) ^ (a * b) := by + cexp (2 * ↑π * I * a * z) ^ b = cexp (2 * ↑π * I * z) ^ (a * b) := by simp [← Complex.exp_nsmul] ring_nf -theorem summable_prod_aux (k : ℕ) (z : ℍ) : Summable fun c : ℕ+ × ℕ+ ↦ - (c.1 ^ k : ℂ) * Complex.exp (2 * ↑π * Complex.I * c.2 * z) ^ (c.1 : ℕ) := by +theorem summable_prod_aux (k : ℕ) (z : ℍ) : + Summable fun c : ℕ+ × ℕ+ ↦ (c.1 ^ k : ℂ) * cexp (2 * ↑π * I * c.2 * z) ^ (c.1 : ℕ) := by simpa using summable_prod_mul_pow k (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) theorem tsum_prod_pow_cexp_eq_tsum_sigma (k : ℕ) (z : ℍ) : - ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ) = - ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * Complex.I * z) ^ (e : ℕ) := by + ∑' d : ℕ+, ∑' (c : ℕ+), (c ^ k : ℂ) * cexp (2 * ↑π * I * d * z) ^ (c : ℕ) = + ∑' e : ℕ+, sigma k e * cexp (2 * ↑π * I * z) ^ (e : ℕ) := by simpa using tsum_prod_pow_eq_tsum_sigma k (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z) theorem summable_prod_eisSummand {k : ℕ} (hk : 3 ≤ k) (z : ℍ) : @@ -226,8 +226,8 @@ theorem summable_prod_eisSummand {k : ℕ} (hk : 3 ≤ k) (z : ℍ) : simp [EisensteinSeries.eisSummand] lemma tsum_eisSummand_eq_sigma_cexp {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : - ∑' x, eisSummand k x z = 2 * riemannZeta k + 2 * ((-2 * π * Complex.I) ^ k / (k - 1)!) * - ∑' (n : ℕ+), (σ (k - 1) n) * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by + ∑' x, eisSummand k x z = 2 * riemannZeta k + 2 * ((-2 * π * I) ^ k / (k - 1)!) * + ∑' (n : ℕ+), (σ (k - 1) n) * cexp (2 * π * I * z) ^ (n : ℕ) := by rw [← (piFinTwoEquiv fun _ ↦ ℤ).symm.tsum_eq, Summable.tsum_prod (by apply summable_prod_eisSummand hk), tsum_nat_eq_zero_two_pnat] · have (b : ℕ+) := EisensteinSeries.qExpansion_identity_pnat (k := k - 1) (by omega) @@ -254,8 +254,8 @@ lemma tsum_eisSummand_eq_sigma_cexp {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : · simpa using Summable.prod (f := fun x : ℤ × ℤ ↦ eisSummand k ![x.1, x.2] z) (by apply summable_prod_eisSummand hk) -lemma gammaSetN_eisSummand (k : ℤ) (z : ℍ) {n : ℕ} (v : gammaSetN n) : eisSummand k v z = - ((n : ℂ) ^ k)⁻¹ * eisSummand k (div_N_map n v) z := by +lemma gammaSetN_eisSummand (k : ℤ) (z : ℍ) {n : ℕ} (v : gammaSetN n) : + eisSummand k v z = ((n : ℂ) ^ k)⁻¹ * eisSummand k (div_N_map n v) z := by have := gammaSetN_map_eq v simp_rw [eisSummand] nth_rw 1 2 [this] @@ -293,8 +293,8 @@ lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ /-- The q-Expansion of normalised Eisenstein series of level one with `riemannZeta` term. -/ lemma EisensteinSeries.q_expansion_riemannZeta {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : - (E hk) z = 1 + (1 / (riemannZeta (k))) * ((-2 * π * Complex.I) ^ k / (k - 1)!) * - ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * π * Complex.I * z) ^ (n : ℤ) := by + (E hk) z = 1 + (1 / (riemannZeta (k))) * ((-2 * π * I) ^ k / (k - 1)!) * + ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * π * I * z) ^ (n : ℤ) := by have : (eisensteinSeries_MF (k := k) (by omega) standardcongruencecondition) z = (eisensteinSeries_SIF standardcongruencecondition k) z := rfl rw [E, ModularForm.smul_apply, this, eisensteinSeries_SIF_apply standardcongruencecondition k z, @@ -319,7 +319,7 @@ theorem even_div_two_ne_zero {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) : k / 2 refine (Int.two_le_iff_pos_of_even (m := k) (by simpa using hk2 )).mpr (by omega) lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) : - (1 / (riemannZeta (k))) * ((-2 * π * Complex.I) ^ k / (k - 1)!) = -((2 * k) / bernoulli k) := by + (1 / (riemannZeta (k))) * ((-2 * π * I) ^ k / (k - 1)!) = -((2 * k) / bernoulli k) := by have hk0 := even_div_two_ne_zero hk2 hkn0 have hk1 : 2 * (k / 2) = k := Nat.two_mul_div_two_of_even hk2 have hk11 : 2 * (((k / 2) : ℕ) : ℂ) = k := by norm_cast @@ -328,7 +328,7 @@ lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) have hkf : ((k - 1)! : ℂ) ≠ 0 := by norm_cast apply Nat.factorial_ne_zero - have h3 : (-2 * ↑π * Complex.I) ^ k = (-1) ^ k * 2 ^ k * π ^ k * (-1) ^ (k / 2) := by + have h3 : (-2 * ↑π * I) ^ k = (-1) ^ k * 2 ^ k * π ^ k * (-1) ^ (k / 2) := by simp_rw [mul_pow] nth_rw 3 [← hk1] rw [neg_pow, pow_mul, I_sq] @@ -349,7 +349,7 @@ lemma eisensteinSeries_coeff_identity {k : ℕ} (hk2 : Even k) (hkn0 : k ≠ 0) /-- The q-Expansion of normalised Eisenstein series of level one with `bernoulli` term. -/ lemma EisensteinSeries.q_expansion_bernoulli {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : (E hk) z = 1 + -((2 * k) / bernoulli k) * - ∑' n : ℕ+, σ (k - 1) n * cexp (2 * ↑π * Complex.I * z) ^ (n : ℤ) := by + ∑' n : ℕ+, σ (k - 1) n * cexp (2 * ↑π * I * z) ^ (n : ℤ) := by have h2 := EisensteinSeries.q_expansion_riemannZeta hk hk2 z rw [eisensteinSeries_coeff_identity hk2 (by omega)] at h2 apply h2 From 8354138322bccb81973e18f9cacf81514e276dc8 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 21 Aug 2025 09:08:29 +0100 Subject: [PATCH 121/128] I cleanup --- .../ModularForms/DedekindEta.lean | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 5a2e8bb6a2480c..b687a8e5f55627 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -28,9 +28,11 @@ differentiable on the upper half-plane. * [F. Diamond and J. Shurman, *A First Course in Modular Forms*][diamondshurman2005] -/ -open UpperHalfPlane TopologicalSpace Set MeasureTheory intervalIntegral +open TopologicalSpace Set MeasureTheory intervalIntegral Metric Filter Function Complex ArithmeticFunction +open _root_.UpperHalfPlane hiding I + open scoped Interval Real NNReal ENNReal Topology BigOperators Nat local notation "𝕢" => Periodic.qParam @@ -43,11 +45,11 @@ noncomputable abbrev ModularForm.eta_q (n : ℕ) (z : ℂ) := (𝕢 1 z) ^ (n + open ModularForm -lemma eta_q_eq_cexp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * (n + 1) * z) := by +lemma eta_q_eq_cexp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * I * (n + 1) * z) := by simp [eta_q, Periodic.qParam, ← Complex.exp_nsmul] ring_nf -lemma eta_q_eq_pow (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * Complex.I * z) ^ (n + 1) := by +lemma eta_q_eq_pow (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * I * z) ^ (n + 1) := by simp [eta_q, Periodic.qParam] lemma one_sub_eta_q_ne_zero (n : ℕ) {z : ℂ} (hz : z ∈ ℍₒ) : 1 - eta_q n z ≠ 0 := by @@ -78,7 +80,7 @@ lemma hasProdLocallyUniformlyOn_eta : HasProdLocallyUniformlyOn (fun n a ↦ 1 - apply hasProdLocallyUniformlyOn_of_forall_compact upperHalfPlaneSet_isOpen intro K hK hcK by_cases hN : K.Nonempty - · have hc : ContinuousOn (fun x ↦ ‖cexp (2 * π * Complex.I * x)‖) K := by fun_prop + · have hc : ContinuousOn (fun x ↦ ‖cexp (2 * π * I * x)‖) K := by fun_prop obtain ⟨z, hz, hB, HB⟩ := hcK.exists_sSup_image_eq_and_ge hN hc apply (summable_eta_q ⟨z, hK hz⟩).hasProdUniformlyOn_nat_one_add hcK · filter_upwards with n x hx @@ -105,8 +107,8 @@ lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = ext z simp [logDeriv] -lemma logDeriv_q_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * Complex.I / 24 := by - have : (𝕢 24) = (fun z ↦ cexp (z)) ∘ (fun z => (2 * ↑π * Complex.I / 24) * z) := by +lemma logDeriv_q_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * I / 24 := by + have : (𝕢 24) = (fun z ↦ cexp (z)) ∘ (fun z => (2 * ↑π * I / 24) * z) := by ext y simp only [Periodic.qParam, ofReal_ofNat, comp_apply] ring_nf @@ -121,20 +123,20 @@ lemma logDeriv_one_sub_mul_cexp_comp (r : ℂ) {g : ℂ → ℂ} (hg : Different ring private theorem one_sub_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ↦ 1 - eta_q i x) z = - 2 * π * Complex.I * (i + 1) * -eta_q i z / (1 - eta_q i z) := by - have h2 : (fun x ↦ 1 - cexp (2 * ↑π * Complex.I * (i + 1) * x)) = - ((fun z ↦ 1 - 1 * cexp z) ∘ fun x ↦ 2 * ↑π * Complex.I * (↑i + 1) * x) := by aesop - have h3 : deriv (fun x : ℂ ↦ (2 * π * Complex.I * (i + 1) * x)) = - fun _ ↦ 2 * π * Complex.I * (i + 1) := by + 2 * π * I * (i + 1) * -eta_q i z / (1 - eta_q i z) := by + have h2 : (fun x ↦ 1 - cexp (2 * ↑π * I * (i + 1) * x)) = + ((fun z ↦ 1 - 1 * cexp z) ∘ fun x ↦ 2 * ↑π * I * (↑i + 1) * x) := by aesop + have h3 : deriv (fun x : ℂ ↦ (2 * π * I * (i + 1) * x)) = + fun _ ↦ 2 * π * I * (i + 1) := by ext y - simpa using deriv_const_mul (2 * π * Complex.I * (i + 1)) (d := fun (x : ℂ) ↦ x) (x := y) + simpa using deriv_const_mul (2 * π * I * (i + 1)) (d := fun (x : ℂ) ↦ x) (x := y) simp_rw [eta_q_eq_cexp, h2, logDeriv_one_sub_mul_cexp_comp 1 - (g := fun x ↦ (2 * π * Complex.I * (i + 1) * x)) (by fun_prop), h3, neg_mul, one_mul, mul_neg] + (g := fun x ↦ (2 * π * I * (i + 1) * x)) (by fun_prop), h3, neg_mul, one_mul, mul_neg] lemma tsum_log_deriv_one_sub_eta_q (z : ℂ) : ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - -(2 * π * Complex.I) * ∑' n : ℕ, (n + 1) * (eta_q n z) / (1 - eta_q n z) := by + -(2 * π * I) * ∑' n : ℕ, (n + 1) * (eta_q n z) / (1 - eta_q n z) := by suffices ∑' (i : ℕ), logDeriv (fun x ↦ 1 - eta_q i x) z = - ∑' n : ℕ, (2 * ↑π * Complex.I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by + ∑' n : ℕ, (2 * ↑π * I * (n + 1)) * (-eta_q n z) / (1 - eta_q n z) by rw [this, ← tsum_mul_left] congr 1 ext i @@ -158,7 +160,7 @@ lemma summable_log_deriv_one_sub_eta_q {z : ℂ} (hz : z ∈ ℍₒ) : simp only [one_sub_eta_logDeriv_eq] apply ((summable_nat_add_iff 1).mpr ((summable_norm_pow_mul_geometric_div_one_sub (r := 𝕢 1 z) 1 (by simpa [Periodic.qParam] using UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨z, hz⟩)).mul_left - (-2 * π * Complex.I))).congr + (-2 * π * I))).congr intro b field_simp [one_sub_eta_q_ne_zero b hz] ring @@ -168,7 +170,7 @@ lemma multipliableLocallyUniformlyOn_one_sub_eta_q : ⟨ηₚ, (hasProdLocallyUniformlyOn_eta).congr fun n x _ ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, (fun n a ↦ 1 - eta_q n a) i b) x)⟩ -lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12) * E2 z := by +lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * I / 12) * E2 z := by unfold ModularForm.eta etaProdTerm rw [logDeriv_mul (UpperHalfPlane.coe z) (by simp [ne_eq, exp_ne_zero, not_false_eq_true, Periodic.qParam]) (etaProdTerm_ne_zero z.2) (by fun_prop) (etaProdTerm_differentiableAt z.2)] @@ -184,8 +186,8 @@ lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * Complex.I / 12 congr 1 · field_simp ring - · field_simp [tsum_pnat_eq_tsum_succ (f := fun n ↦ n * cexp (2 * π * Complex.I * z) ^ n - / (1 - cexp (2 * π * Complex.I * z) ^ n )), Periodic.qParam, eta_q_eq_pow] + · field_simp [tsum_pnat_eq_tsum_succ (f := fun n ↦ n * cexp (2 * π * I * z) ^ n + / (1 - cexp (2 * π * I * z) ^ n )), Periodic.qParam, eta_q_eq_pow] ring_nf congr ext n From 0e80d68721f27e613c646d0ad181afc76ba9f3bb Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 21 Aug 2025 09:12:29 +0100 Subject: [PATCH 122/128] I cleanup --- .../ModularForms/EisensteinSeries/E2.lean | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean index 596f2cd00920f3..df2599e281a2e6 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/E2.lean @@ -18,9 +18,11 @@ over non-symmetric intervals. -/ -open ModularForm EisensteinSeries UpperHalfPlane TopologicalSpace intervalIntegral +open ModularForm EisensteinSeries TopologicalSpace intervalIntegral Metric Filter Function Complex MatrixGroups Finset ArithmeticFunction +open _root_.UpperHalfPlane hiding I + open scoped Interval Real Topology BigOperators Nat noncomputable section @@ -47,8 +49,9 @@ def G2 : ℍ → ℂ := fun z => limUnder atTop (fun N : ℕ => ∑ m ∈ Icc (- def E2 : ℍ → ℂ := (1 / (2 * riemannZeta 2)) • G2 /-- This function measures the defect in `E2` being a modular form. -/ -def D2 (γ : SL(2, ℤ)) : ℍ → ℂ := fun z => (2 * π * Complex.I * γ 1 0) / (denom γ z) +def D2 (γ : SL(2, ℤ)) : ℍ → ℂ := fun z => (2 * π * I * γ 1 0) / (denom γ z) +--moves these two elsewhere lemma Icc_succ_succ (n : ℕ) : Finset.Icc (-(n + 1) : ℤ) (n + 1) = Finset.Icc (-n : ℤ) n ∪ {(-(n + 1) : ℤ), (n + 1 : ℤ)} := by refine Finset.ext_iff.mpr ?_ @@ -72,8 +75,8 @@ lemma sum_Icc_of_even_eq_range {α : Type*} [CommRing α] (f : ℤ → α) (hf : norm_cast lemma G2_partial_sum_eq (z : ℍ) (N : ℕ) : (∑ m ∈ Icc (-N : ℤ) N, e2Summand m z) = - (2 * riemannZeta 2) + (∑ m ∈ Finset.range N, 2 * (-2 * ↑π * Complex.I) ^ 2 * - ∑' n : ℕ+, n * cexp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) := by + (2 * riemannZeta 2) + (∑ m ∈ Finset.range N, 2 * (-2 * ↑π * I) ^ 2 * + ∑' n : ℕ+, n * cexp (2 * ↑π * I * (m + 1) * z) ^ (n : ℕ)) := by rw [sum_Icc_of_even_eq_range, Finset.sum_range_succ', mul_add] · nth_rw 2 [two_mul] ring_nf @@ -104,30 +107,28 @@ lemma G2_partial_sum_eq (z : ℍ) (N : ℕ) : (∑ m ∈ Icc (-N : ℤ) N, e2Sum ring_nf aesop -private lemma aux_tsum_identity (z : ℍ) : ∑' m : ℕ, (2 * (-2 * ↑π * Complex.I) ^ 2 * - ∑' n : ℕ+, n * cexp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) = - -8 * π ^ 2 * ∑' (n : ℕ+), (sigma 1 n) * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by +private lemma aux_tsum_identity (z : ℍ) : ∑' m : ℕ, (2 * (-2 * ↑π * I) ^ 2 * + ∑' n : ℕ+, n * cexp (2 * ↑π * I * (m + 1) * z) ^ (n : ℕ)) = + -8 * π ^ 2 * ∑' (n : ℕ+), (sigma 1 n) * cexp (2 * π * I * z) ^ (n : ℕ) := by have := tsum_prod_pow_cexp_eq_tsum_sigma 1 z rw [tsum_pnat_eq_tsum_succ (fun d => - ∑' (c : ℕ+), (c ^ 1 : ℂ) * cexp (2 * ↑π * Complex.I * d * z) ^ (c : ℕ))] at this + ∑' (c : ℕ+), (c ^ 1 : ℂ) * cexp (2 * ↑π * I * d * z) ^ (c : ℕ))] at this simp only [neg_mul, even_two, Even.neg_pow, ← tsum_mul_left, ← this, Nat.cast_add, Nat.cast_one] - apply tsum_congr - intro b - apply tsum_congr - intro c - simp only [mul_pow, I_sq, mul_neg, mul_one, neg_mul, neg_inj] + apply tsum_congr2 + intro b c + rw [mul_pow, I_sq, mul_neg, mul_one] ring -theorem G2_tendsto (z : ℍ) : Tendsto (fun N ↦ ∑ x ∈ range N, 2 * (2 * ↑π * Complex.I) ^ 2 * - ∑' (n : ℕ+), n * cexp (2 * ↑π * Complex.I * (↑x + 1) * ↑z) ^ (n : ℕ)) atTop - (𝓝 (-8 * ↑π ^ 2 * ∑' (n : ℕ+), ↑((σ 1) ↑n) * cexp (2 * ↑π * Complex.I * ↑z) ^ (n : ℕ))) := by +theorem G2_tendsto (z : ℍ) : Tendsto (fun N ↦ ∑ x ∈ range N, 2 * (2 * ↑π * I) ^ 2 * + ∑' (n : ℕ+), n * cexp (2 * ↑π * I * (↑x + 1) * ↑z) ^ (n : ℕ)) atTop + (𝓝 (-8 * ↑π ^ 2 * ∑' (n : ℕ+), ↑((σ 1) ↑n) * cexp (2 * ↑π * I * ↑z) ^ (n : ℕ))) := by rw [← aux_tsum_identity] - have hf : Summable fun m : ℕ => ( 2 * (-2 * ↑π * Complex.I) ^ 2 * - ∑' n : ℕ+, n ^ ((2 - 1)) * Complex.exp (2 * ↑π * Complex.I * (m + 1) * z) ^ (n : ℕ)) := by + have hf : Summable fun m : ℕ => ( 2 * (-2 * ↑π * I) ^ 2 * + ∑' n : ℕ+, n ^ ((2 - 1)) * Complex.exp (2 * ↑π * I * (m + 1) * z) ^ (n : ℕ)) := by apply Summable.mul_left have := (summable_prod_aux 1 z).prod_symm.prod have h0 := pnat_summable_iff_summable_succ - (f := fun b ↦ ∑' (c : ℕ+), c * cexp (2 * ↑π * Complex.I * ↑↑b * ↑z) ^ (c : ℕ)) + (f := fun b ↦ ∑' (c : ℕ+), c * cexp (2 * ↑π * I * ↑↑b * ↑z) ^ (c : ℕ)) simp at * rw [← h0] apply this @@ -139,21 +140,18 @@ lemma G2_cauchy (z : ℍ) : CauchySeq (fun N : ℕ => ∑ m ∈ Icc (-N : ℤ) N ext n rw [G2_partial_sum_eq] apply CauchySeq.const_add - apply Filter.Tendsto.cauchySeq (x := - -8 * π ^ 2 * ∑' (n : ℕ+), (σ 1 n) * cexp (2 * π * Complex.I * z) ^ (n : ℕ)) + apply Filter.Tendsto.cauchySeq (x := -8 * π ^ 2 * + ∑' (n : ℕ+), (σ 1 n) * cexp (2 * π * I * z) ^ (n : ℕ)) simpa using G2_tendsto z -lemma G2_q_exp (z : ℍ) : G2 z = (2 * riemannZeta 2) - 8 * π ^ 2 * - ∑' n : ℕ+, sigma 1 n * cexp (2 * π * Complex.I * z) ^ (n : ℕ) := by - rw [G2, Filter.Tendsto.limUnder_eq] +lemma G2_q_exp (z : ℍ) : G2 z = (2 * riemannZeta 2) - 8 * π ^ 2 * + ∑' n : ℕ+, sigma 1 n * cexp (2 * π * I * z) ^ (n : ℕ) := by + rw [G2, Filter.Tendsto.limUnder_eq, sub_eq_add_neg] conv => enter [1] ext N rw [G2_partial_sum_eq z N] - rw [sub_eq_add_neg] - apply Filter.Tendsto.add - · simp - · simpa using G2_tendsto z + exact Filter.Tendsto.add (by simp) (by simpa using G2_tendsto z) From e624e657f906b9ebb7f3d8f0061aa6134b863433 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Thu, 21 Aug 2025 10:08:36 +0100 Subject: [PATCH 123/128] updates --- .../NumberTheory/TsumDivsorsAntidiagonal.lean | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean b/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean index 0cac65cbc8d8cc..02f772d02f7012 100644 --- a/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean +++ b/Mathlib/NumberTheory/TsumDivsorsAntidiagonal.lean @@ -84,21 +84,21 @@ lemma summable_norm_pow_mul_geometric_div_one_sub [CompleteSpace 𝕜] (k : ℕ) variable [CompleteSpace 𝕜] [NormSMulClass ℤ 𝕜] -theorem summable_divisorsAntidiagonal_aux (k : ℕ) (r : 𝕜) (hr : ‖r‖ < 1) : +theorem summable_divisorsAntidiagonal_aux (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : Summable fun c : (n : ℕ+) × { x // x ∈ (n : ℕ).divisorsAntidiagonal} ↦ (c.2.1).1 ^ k * (r ^ (c.2.1.2 * c.2.1.1)) := by apply Summable.of_norm rw [summable_sigma_of_nonneg] constructor - · apply fun n => (hasSum_fintype _).summable + · apply fun n ↦ (hasSum_fintype _).summable · simp only [norm_mul, norm_pow, tsum_fintype, Finset.univ_eq_attach] · apply Summable.of_nonneg_of_le (f := fun c : ℕ+ ↦ ‖(c : 𝕜) ^ (k + 1) * r ^ (c : ℕ)‖) - (fun b => Finset.sum_nonneg (fun _ _ => by apply mul_nonneg (by simp) (by simp))) ?_ + (fun b ↦ Finset.sum_nonneg (fun _ _ ↦ by apply mul_nonneg (by simp) (by simp))) ?_ (by apply (summable_norm_pow_mul_geometric_of_norm_lt_one (k + 1) hr).subtype) intro b apply le_trans (b := ∑ _ ∈ (b : ℕ).divisors, ‖(b : 𝕜)‖ ^ k * ‖r ^ (b : ℕ)‖) · rw [Finset.sum_attach ((b : ℕ).divisorsAntidiagonal) (fun x ↦ - ‖(x.1 : 𝕜)‖ ^ (k : ℕ) * ‖r‖^ (x.2 * x.1)), Nat.sum_divisorsAntidiagonal + ‖(x.1 : 𝕜)‖ ^ (k : ℕ) * ‖r‖ ^ (x.2 * x.1)), Nat.sum_divisorsAntidiagonal ((fun x y ↦ ‖(x : 𝕜)‖ ^ k * ‖r‖ ^ (y * x))) (n := b)] gcongr <;> rename_i i hi <;> simp [natCast_norm] at * · exact Nat.le_of_dvd b.2 hi @@ -116,7 +116,7 @@ theorem summable_prod_mul_pow (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : Summable fun c : (ℕ+ × ℕ+) ↦ c.1 ^ k * (r ^ (c.2 * c.1 : ℕ)) := by rw [sigmaAntidiagonalEquivProd.summable_iff.symm] simp only [sigmaAntidiagonalEquivProd, divisorsAntidiagonalFactors, PNat.mk_coe, Equiv.coe_fn_mk] - apply summable_divisorsAntidiagonal_aux k r hr + apply summable_divisorsAntidiagonal_aux k hr theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : ∑' d : ℕ+, ∑' (c : ℕ+), c ^ k * (r ^ (d * c : ℕ)) = ∑' e : ℕ+, σ k e * r ^ (e : ℕ) := by @@ -128,7 +128,7 @@ theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : simp simp only [← sigmaAntidiagonalEquivProd.tsum_eq, sigmaAntidiagonalEquivProd, divisorsAntidiagonalFactors, PNat.mk_coe, Equiv.coe_fn_mk, sigma_eq_sum_div', cast_sum, - cast_pow, Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k r hr)] + cast_pow, Summable.tsum_sigma (summable_divisorsAntidiagonal_aux k hr)] apply tsum_congr intro n simp only [tsum_fintype, Finset.univ_eq_attach, Finset.sum_attach ((n : ℕ).divisorsAntidiagonal) @@ -145,7 +145,7 @@ theorem tsum_prod_pow_eq_tsum_sigma (k : ℕ) {r : 𝕜} (hr : ‖r‖ < 1) : lemma tsum_pow_div_one_sub_eq_tsum_sigma {r : 𝕜} (hr : ‖r‖ < 1) : ∑' n : ℕ+, n * r ^ (n : ℕ) / (1 - r ^ (n : ℕ)) = ∑' n : ℕ+, σ 1 n * r ^ (n : ℕ) := by - have := fun m : ℕ+ => tsum_choose_mul_geometric_of_norm_lt_one + have := fun m : ℕ+ ↦ tsum_choose_mul_geometric_of_norm_lt_one (r := r ^ (m : ℕ)) 0 (by simpa using (pow_lt_one₀ (by simp) hr (by apply PNat.ne_zero))) simp only [add_zero, Nat.choose_zero_right, Nat.cast_one, one_mul, zero_add, pow_one, one_div] at this @@ -157,7 +157,7 @@ lemma tsum_pow_div_one_sub_eq_tsum_sigma {r : 𝕜} (hr : ‖r‖ < 1) : enter [1] ext m rw [mul_assoc, ← pow_succ' (r ^ (n : ℕ)) m] - rw [← tsum_pnat_eq_tsum_succ (fun m => n * (r ^ (n : ℕ)) ^ (m : ℕ))] + rw [← tsum_pnat_eq_tsum_succ (fun m ↦ n * (r ^ (n : ℕ)) ^ (m : ℕ))] have h00 := (tsum_prod_pow_eq_tsum_sigma 1 hr) rw [Summable.tsum_comm (by apply summable_prod_mul_pow 1 hr)] at h00 rw [← h00] From c730baf0cc982b60a288586ca002cf3f729449e2 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 27 Aug 2025 15:46:08 +0100 Subject: [PATCH 124/128] fix --- Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean | 12 ------------ Mathlib/NumberTheory/ModularForms/DedekindEta.lean | 1 - 2 files changed, 13 deletions(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index 59b4fad7c455a8..69d6d543db0548 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -215,16 +215,4 @@ lemma upperHalfPlaneSet_isOpen : IsOpen ℍₒ := (isOpen_lt continuous_const Co end upperHalfPlaneSet -section upperHalfPlaneSet - -/-- The upper half plane as a subset of `ℂ`. This is convenient for taking derivatives of functions -on the upper half plane. -/ -abbrev upperHalfPlaneSet := {z : ℂ | 0 < z.im} - -local notation "ℍₒ" => upperHalfPlaneSet - -lemma isOpen_upperHalfPlaneSet : IsOpen ℍₒ := isOpen_lt continuous_const Complex.continuous_im - -end upperHalfPlaneSet - end UpperHalfPlane diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index d004cc0887b2e5..4c1a5da1b8cd29 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -9,7 +9,6 @@ import Mathlib.Analysis.CStarAlgebra.Classes import Mathlib.Analysis.Complex.LocallyUniformLimit import Mathlib.Analysis.Complex.UpperHalfPlane.Exp import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn -import Mathlib.Data.Complex.FiniteDimensional import Mathlib.Analysis.Calculus.LogDerivUniformlyOn import Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2 import Mathlib.NumberTheory.TsumDivsorsAntidiagonal From 2bb764f122a3f3658a2d0868ba8aaa9d55222c56 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 27 Aug 2025 15:46:45 +0100 Subject: [PATCH 125/128] fix --- Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index 69d6d543db0548..417c7da35232cb 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -203,15 +203,16 @@ theorem vadd_im : (x +ᵥ z).im = z.im := zero_add _ end RealAddAction + section upperHalfPlaneSet -/-- The UpperHalfPlane as a subset of `ℂ`. This is convinient for taking derivatives of functions +/-- The upper half plane as a subset of `ℂ`. This is convenient for taking derivatives of functions on the upper half plane. -/ abbrev upperHalfPlaneSet := {z : ℂ | 0 < z.im} local notation "ℍₒ" => upperHalfPlaneSet -lemma upperHalfPlaneSet_isOpen : IsOpen ℍₒ := (isOpen_lt continuous_const Complex.continuous_im) +lemma isOpen_upperHalfPlaneSet : IsOpen ℍₒ := isOpen_lt continuous_const Complex.continuous_im end upperHalfPlaneSet From 5a526e3b319e67f09832d52232bbc26905953337 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 27 Aug 2025 15:52:56 +0100 Subject: [PATCH 126/128] save --- Mathlib/Analysis/Complex/Periodic.lean | 11 ------- .../Trigonometric/Cotangent.lean | 12 ++++---- .../ModularForms/DedekindEta.lean | 2 +- .../EisensteinSeries/QExpansion.lean | 29 ++++++++++--------- 4 files changed, 22 insertions(+), 32 deletions(-) diff --git a/Mathlib/Analysis/Complex/Periodic.lean b/Mathlib/Analysis/Complex/Periodic.lean index 5e3303d9bf2e7c..a3453c8a5992d4 100644 --- a/Mathlib/Analysis/Complex/Periodic.lean +++ b/Mathlib/Analysis/Complex/Periodic.lean @@ -72,16 +72,6 @@ theorem norm_qParam_lt_iff (hh : 0 < h) (A : ℝ) (z : ℂ) : rw [norm_qParam, Real.exp_lt_exp, div_lt_div_iff_of_pos_right hh, mul_lt_mul_left_of_neg] simpa using Real.pi_pos -<<<<<<< HEAD -@[fun_prop] -lemma qParam_differentiable (n : ℝ) : Differentiable ℂ (𝕢 n) := by - rw [show 𝕢 n = fun x => exp (2 * π * Complex.I * x / n) by rfl] - fun_prop - -@[fun_prop] -lemma qParam_ContDiff (n : ℝ) (m : WithTop ℕ∞) : ContDiff ℂ m (𝕢 n) := by - rw [show 𝕢 n = fun x => exp (2 * π * Complex.I * x / n) by rfl] -======= lemma qParam_ne_zero (z : ℂ) : 𝕢 h z ≠ 0 := by simp [qParam, exp_ne_zero] @@ -93,7 +83,6 @@ lemma differentiable_qParam : Differentiable ℂ (𝕢 h) := by @[fun_prop] lemma contDiff_qParam (m : WithTop ℕ∞) : ContDiff ℂ m (𝕢 h) := by unfold qParam ->>>>>>> upstream/master fun_prop @[deprecated (since := "2025-02-17")] alias abs_qParam_lt_iff := norm_qParam_lt_iff diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index c5122e4fc599fd..4cbc2dff838b7d 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -280,7 +280,7 @@ lemma cotTerm_iteratedDerivWithin_eqOn_complexUpperHalfPlane (d : ℕ) : (z - (d + 1)) ^ (-1 - k : ℤ))) ℍₒ := by apply Set.EqOn.trans (upperHalfPlane_inter_integerComplement ▸ iteratedDerivWithin_congr_right_of_isOpen (fun (z : ℂ) ↦ cotTerm z d) k - upperHalfPlaneSet_isOpen (Complex.isOpen_compl_range_intCast)) + isOpen_upperHalfPlaneSet (Complex.isOpen_compl_range_intCast)) intro z hz simpa using cotTerm_iteratedDerivWithin_eqOn_intergerCompliment k d (coe_mem_integerComplement ⟨z, hz⟩) @@ -324,7 +324,7 @@ private lemma iteratedDerivWithin_cotTerm_bounded_uniformly lemma summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm {k : ℕ} (hk : 1 ≤ k) : SummableLocallyUniformlyOn (fun n : ℕ ↦ iteratedDerivWithin k (fun z ↦ cotTerm z n) ℍₒ) ℍₒ := by - apply SummableLocallyUniformlyOn_of_locally_bounded (upperHalfPlaneSet_isOpen) + apply SummableLocallyUniformlyOn_of_locally_bounded (isOpen_upperHalfPlaneSet) intro K hK hKc obtain ⟨A, B, hB, HABK⟩ := subset_verticalStrip_of_isCompact ((isCompact_iff_isCompact_univ.mp hKc).image_of_continuousOn @@ -362,11 +362,11 @@ private theorem aux_iteratedDeriv_tsum_cotTerm {k : ℕ} (hk : 1 ≤ k) (x : ℍ (-1) ^ k * (k !) * (x : ℂ) ^ (-1 - k : ℤ) + iteratedDerivWithin k (fun z : ℂ ↦ ∑' n : ℕ, cotTerm z n) ℍₒ x = (-1) ^ (k : ℕ) * (k : ℕ)! * ∑' n : ℤ, ((x : ℂ) + n) ^ (-1 - k : ℤ) := by - rw [iteratedDerivWithin_tsum k upperHalfPlaneSet_isOpen x.2 + rw [iteratedDerivWithin_tsum k isOpen_upperHalfPlaneSet x.2 (fun t ht ↦ Summable_cotTerm (coe_mem_integerComplement ⟨t, ht⟩)) (fun l hl hl2 ↦ summableLocallyUniformlyOn_iteratedDerivWithin_cotTerm hl) (fun n l z hl hz ↦ ((DifferentiableOn_iteratedDerivWithin_cotTerm n l)).differentiableAt - ((IsOpen.mem_nhds (upperHalfPlaneSet_isOpen) hz)))] + ((IsOpen.mem_nhds isOpen_upperHalfPlaneSet hz)))] conv => enter [1,2,1] ext n @@ -393,9 +393,9 @@ theorem iteratedDerivWithin_cot_pi_z_sub_inv (z : ℍₒ) : (iteratedDerivWithin k (fun x ↦ π * Complex.cot (π * x)) ℍₒ z) - (-1) ^ k * k ! * ((z : ℂ) ^ (-1 - k : ℤ)) := by simp_rw [sub_eq_add_neg] - rw [iteratedDerivWithin_fun_add (by apply z.2) upperHalfPlaneSet_isOpen.uniqueDiffOn] + rw [iteratedDerivWithin_fun_add (by apply z.2) isOpen_upperHalfPlaneSet.uniqueDiffOn] · simpa [iteratedDerivWithin_fun_neg] using iteratedDerivWithin_one_div k - upperHalfPlaneSet_isOpen z.2 + isOpen_upperHalfPlaneSet z.2 · exact ContDiffWithinAt.smul (by fun_prop) (cot_pi_z_contDiffWithinAt k z) · simp only [one_div] apply ContDiffWithinAt.neg diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 4c1a5da1b8cd29..1529364f82eeb1 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -30,7 +30,7 @@ differentiable on the upper half-plane. open TopologicalSpace Set MeasureTheory intervalIntegral Metric Filter Function Complex -open UpperHalfPlane hiding I +open _root_.UpperHalfPlane hiding I open scoped Interval Real NNReal ENNReal Topology BigOperators Nat diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean index 27c9a54303f013..4c613ec63196c2 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/QExpansion.lean @@ -61,7 +61,7 @@ open BoundedContinuousFunction in theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f : ℕ → ℂ} {p : ℝ} (hp : 0 < p) (hf : f =O[atTop] (fun n ↦ ((n ^ l) : ℝ))) : SummableLocallyUniformlyOn (fun n ↦ (f n) • iteratedDerivWithin k (fun z ↦ cexp (2 * ↑π * I * z / p) ^ n) ℍₒ) ℍₒ := by - apply SummableLocallyUniformlyOn_of_locally_bounded upperHalfPlaneSet_isOpen + apply SummableLocallyUniformlyOn_of_locally_bounded isOpen_upperHalfPlaneSet intro K hK hKc haveI : CompactSpace K := isCompact_univ_iff.mp (isCompact_iff_isCompact_univ.mp hKc) let c : ContinuousMap K ℂ := ⟨fun r : K ↦ Complex.exp (2 * ↑π * I * r / p), by fun_prop⟩ @@ -80,7 +80,7 @@ theorem summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion (k l : ℕ) {f have h0 := pow_le_pow_left₀ (by apply norm_nonneg _) (norm_coe_le_norm (mkOfCompact c) ⟨z, hz⟩) n simp only [norm_mkOfCompact, mkOfCompact_apply, ContinuousMap.coe_mk, ← exp_nsmul', Pi.smul_apply, - iteratedDerivWithin_cexp_mul_const k n p upperHalfPlaneSet_isOpen (hK hz), smul_eq_mul, + iteratedDerivWithin_cexp_mul_const k n p isOpen_upperHalfPlaneSet (hK hz), smul_eq_mul, norm_mul, norm_pow, Complex.norm_div, norm_ofNat, norm_real, Real.norm_eq_abs, norm_I, mul_one, norm_natCast, abs_norm, ge_iff_le, r, c] at * rw [← mul_assoc] @@ -111,20 +111,20 @@ theorem differnetiableAt_iteratedDerivWithin_cexp (n a : ℕ) {s : Set ℂ} lemma iteratedDerivWithin_tsum_exp_eq (k : ℕ) (z : ℍ) : iteratedDerivWithin k (fun z ↦ ∑' n : ℕ, cexp (2 * π * I * z) ^ n) ℍₒ z = ∑' n : ℕ, iteratedDerivWithin k (fun s : ℂ ↦ cexp (2 * ↑π * I * s) ^ n) ℍₒ z := by - rw [iteratedDerivWithin_tsum k upperHalfPlaneSet_isOpen (by simpa using z.2)] + rw [iteratedDerivWithin_tsum k isOpen_upperHalfPlaneSet (by simpa using z.2)] · exact fun x hx => summable_geometric_iff_norm_lt_one.mpr (UpperHalfPlane.norm_exp_two_pi_I_lt_one ⟨x, hx⟩) · exact fun n _ _ => summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' n · exact fun n l z hl hz => differnetiableAt_iteratedDerivWithin_cexp n l - upperHalfPlaneSet_isOpen hz + isOpen_upperHalfPlaneSet hz theorem contDiffOn_tsum_cexp (k : ℕ∞) : ContDiffOn ℂ k (fun z : ℂ ↦ ∑' n : ℕ, cexp (2 * ↑π * I * z) ^ n) ℍₒ := contDiffOn_of_differentiableOn_deriv fun m _ z hz ↦ - ((summableUniformlyOn_differentiableOn upperHalfPlaneSet_isOpen + ((summableUniformlyOn_differentiableOn isOpen_upperHalfPlaneSet (summableLocallyUniformlyOn_iteratedDerivWithin_qExpansion' m) (fun n _ hz => differnetiableAt_iteratedDerivWithin_cexp n m - upperHalfPlaneSet_isOpen hz)) z hz).congr (fun z hz ↦ + isOpen_upperHalfPlaneSet hz)) z hz).congr (fun z hz ↦ iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) (iteratedDerivWithin_tsum_exp_eq m ⟨z, hz⟩) private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : @@ -150,11 +150,11 @@ private lemma iteratedDerivWithin_tsum_exp_eq' {k : ℕ} (hk : 1 ≤ k) (z : ℍ have := exp_nsmul' (p := 1) (a := 2 * π * I) (n := n) simp only [div_one] at this simpa [this, ofReal_one, div_one, one_mul, UpperHalfPlane.coe] using - iteratedDerivWithin_cexp_mul_const k n 1 upperHalfPlaneSet_isOpen z.2 + iteratedDerivWithin_cexp_mul_const k n 1 isOpen_upperHalfPlaneSet z.2 rw [iteratedDerivWithin_const_sub hk, iteratedDerivWithin_fun_neg, iteratedDerivWithin_const_mul] · simp only [iteratedDerivWithin_tsum_exp_eq, neg_mul] · simpa using z.2 - · exact upperHalfPlaneSet_isOpen.uniqueDiffOn + · exact isOpen_upperHalfPlaneSet.uniqueDiffOn · exact (contDiffOn_tsum_cexp k).contDiffWithinAt (by simpa using z.2) theorem EisensteinSeries.qExpansion_identity {k : ℕ} (hk : 1 ≤ k) (z : ℍ) : @@ -264,7 +264,8 @@ lemma gammaSetN_eisSummand (k : ℤ) (z : ℍ) {n : ℕ} (v : gammaSetN n) : ring_nf lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ k) (z : ℍ) : - ∑' (x : Fin 2 → ℤ), eisSummand k x z = (riemannZeta (k)) * (eisensteinSeries 𝟙 k z) := by + ∑' (x : Fin 2 → ℤ), eisSummand k x z = + (riemannZeta (k)) * (eisensteinSeries (N := 1) 0 k z) := by rw [← GammaSet_top_Equiv.symm.tsum_eq] have hk1 : 1 < k := by omega conv => @@ -295,17 +296,17 @@ lemma tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries {k : ℕ} (hk : 3 ≤ lemma EisensteinSeries.q_expansion_riemannZeta {k : ℕ} (hk : 3 ≤ k) (hk2 : Even k) (z : ℍ) : (E hk) z = 1 + (1 / (riemannZeta (k))) * ((-2 * π * I) ^ k / (k - 1)!) * ∑' n : ℕ+, sigma (k - 1) n * cexp (2 * π * I * z) ^ (n : ℤ) := by - have : (eisensteinSeries_MF (k := k) (by omega) standardcongruencecondition) z = - (eisensteinSeries_SIF standardcongruencecondition k) z := rfl - rw [E, ModularForm.smul_apply, this, eisensteinSeries_SIF_apply standardcongruencecondition k z, - eisensteinSeries, standardcongruencecondition] + have : (eisensteinSeries_MF (k := k) (by omega) 0) z = + (eisensteinSeries_SIF (N := 1) 0 k) z := rfl + rw [E, ModularForm.smul_apply, this, eisensteinSeries_SIF_apply 0 k z, + eisensteinSeries] have HE1 := tsum_eisSummand_eq_sigma_cexp (by omega) hk2 z have HE2 := tsum_prod_eisSummand_eq_riemannZeta_eisensteinSeries (by omega) z have z2 : (riemannZeta (k)) ≠ 0 := by refine riemannZeta_ne_zero_of_one_lt_re ?_ simp only [natCast_re, Nat.one_lt_cast] omega - simp only [PNat.val_ofNat, standardcongruencecondition, eisSummand, Fin.isValue, + simp only [eisSummand, Fin.isValue, UpperHalfPlane.coe, zpow_neg, zpow_natCast, neg_mul, eisensteinSeries, ← inv_mul_eq_iff_eq_mul₀ z2, ne_eq, one_div, smul_eq_mul] at * simp_rw [← HE2, HE1, mul_add] From 10c9eced565ad5ae825c6f903348a5cb7d6a19ed Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 27 Aug 2025 16:24:26 +0100 Subject: [PATCH 127/128] fix --- .../ModularForms/DedekindEta.lean | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 1529364f82eeb1..430b40e826d287 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -82,13 +82,15 @@ lemma multipliableLocallyUniformlyOn_eta : · rw [hasProdUniformlyOn_iff_tendstoUniformlyOn] simpa [not_nonempty_iff_eq_empty.mp hN] using tendstoUniformlyOn_empty -/-- Eta is non-vanishing on the upper half plane. -/ -lemma eta_ne_zero {z : ℂ} (hz : z ∈ ℍₒ) : η z ≠ 0 := by - apply mul_ne_zero (Periodic.qParam_ne_zero z) - refine tprod_one_add_ne_zero_of_summable (f := fun n ↦ -eta_q n z) ?_ ?_ +lemma eta_tprod_ne_zero {z : ℂ} (hz : z ∈ ℍₒ) : (∏' n, (1 - eta_q n z)) ≠ 0 := by + refine tprod_one_add_ne_zero_of_summable (f := fun n ↦ -eta_q n z) ?_ ?_ · exact fun i ↦ by simpa using one_sub_eta_q_ne_zero i hz · simpa [eta_q, ← summable_norm_iff] using summable_eta_q ⟨z, hz⟩ +/-- Eta is non-vanishing on the upper half plane. -/ +lemma eta_ne_zero {z : ℂ} (hz : z ∈ ℍₒ) : η z ≠ 0 := by + apply mul_ne_zero (Periodic.qParam_ne_zero z) (eta_tprod_ne_zero hz) + lemma logDeriv_one_sub_cexp (r : ℂ) : logDeriv (fun z ↦ 1 - r * cexp z) = fun z ↦ -r * cexp z / (1 - r * cexp z) := by ext z @@ -118,14 +120,17 @@ lemma tsum_logDeriv_eta_q (z : ℂ) : ∑' n, logDeriv (fun x ↦ 1 - eta_q n x) rw [tsum_congr (one_sub_eta_logDeriv_eq z), ← tsum_mul_left] grind -theorem differentiableAt_eta_of_mem_upperHalfPlaneSet {z : ℂ} (hz : z ∈ ℍₒ) : - DifferentiableAt ℂ eta z := by - apply DifferentiableAt.mul (by fun_prop) - refine (multipliableLocallyUniformlyOn_eta.hasProdLocallyUniformlyOn.differentiableOn ?_ +lemma differentiableAt_eta_tprod {z : ℂ} (hz : z ∈ ℍₒ) : + DifferentiableAt ℂ (fun x ↦ ∏' n, (1 - eta_q n x)) z := by + apply (multipliableLocallyUniformlyOn_eta.hasProdLocallyUniformlyOn.differentiableOn ?_ isOpen_upperHalfPlaneSet z hz).differentiableAt (isOpen_upperHalfPlaneSet.mem_nhds hz) filter_upwards with b simpa [Finset.prod_fn] using DifferentiableOn.finset_prod (by fun_prop) +theorem differentiableAt_eta_of_mem_upperHalfPlaneSet {z : ℂ} (hz : z ∈ ℍₒ) : + DifferentiableAt ℂ eta z := by + apply DifferentiableAt.mul (by fun_prop) (differentiableAt_eta_tprod hz) + lemma summable_log_deriv_one_sub_eta_q {z : ℂ} (hz : z ∈ ℍₒ) : Summable fun i ↦ logDeriv (fun x ↦ 1 - eta_q i x) z := by simp only [one_sub_eta_logDeriv_eq] @@ -136,21 +141,24 @@ lemma summable_log_deriv_one_sub_eta_q {z : ℂ} (hz : z ∈ ℍₒ) : field_simp [one_sub_eta_q_ne_zero b hz] ring -lemma multipliableLocallyUniformlyOn_one_sub_eta_q : - MultipliableLocallyUniformlyOn (fun n x ↦ 1 - eta_q n x) ℍₒ := - ⟨ηₚ, (hasProdLocallyUniformlyOn_eta).congr fun n x _ ↦ Eq.refl ((fun b ↦ ∏ i ∈ n, - (fun n a ↦ 1 - eta_q n a) i b) x)⟩ +lemma logDeriv_q_term (z : ℍ) : logDeriv (𝕢 24) ↑z = 2 * ↑π * I / 24 := by + have : (𝕢 24) = (fun z ↦ cexp (z)) ∘ (fun z => (2 * ↑π * I / 24) * z) := by + ext y + simp only [Periodic.qParam, ofReal_ofNat, comp_apply] + ring_nf + rw [this, logDeriv_comp (by fun_prop) (by fun_prop), deriv_const_mul _ (by fun_prop)] + simp only [LogDeriv_exp, Pi.one_apply, deriv_id'', mul_one, one_mul] lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * I / 12) * E2 z := by - unfold ModularForm.eta etaProdTerm + unfold ModularForm.eta rw [logDeriv_mul (UpperHalfPlane.coe z) (by simp [ne_eq, exp_ne_zero, not_false_eq_true, - Periodic.qParam]) (etaProdTerm_ne_zero z.2) (by fun_prop) (etaProdTerm_differentiableAt z.2)] - have HG := logDeriv_tprod_eq_tsum (upperHalfPlaneSet_isOpen) (x := z) + Periodic.qParam]) (eta_tprod_ne_zero z.2) (by fun_prop) (differentiableAt_eta_tprod z.2)] + have HG := logDeriv_tprod_eq_tsum isOpen_upperHalfPlaneSet (x := z) (f := fun n x => 1 - eta_q n x) (fun i ↦ one_sub_eta_q_ne_zero i z.2) (by simp_rw [eta_q_eq_pow]; fun_prop) (summable_log_deriv_one_sub_eta_q z.2) - (multipliableLocallyUniformlyOn_one_sub_eta_q) (etaProdTerm_ne_zero z.2) + (multipliableLocallyUniformlyOn_eta ) (eta_tprod_ne_zero z.2) rw [show z.1 = UpperHalfPlane.coe z by rfl] at HG - simp only [logDeriv_q_term z, HG, tsum_log_deriv_one_sub_eta_q z, E2, one_div, + simp only [logDeriv_q_term z, HG, tsum_logDeriv_eta_q z, E2, one_div, mul_inv_rev, Pi.smul_apply, smul_eq_mul] rw [G2_q_exp, riemannZeta_two, ← tsum_pow_div_one_sub_eq_tsum_sigma (by apply UpperHalfPlane.norm_exp_two_pi_I_lt_one z), mul_sub, sub_eq_add_neg, mul_add] @@ -158,8 +166,10 @@ lemma eta_logDeriv (z : ℍ) : logDeriv ModularForm.eta z = (π * I / 12) * E2 z · field_simp ring · field_simp [tsum_pnat_eq_tsum_succ (f := fun n ↦ n * cexp (2 * π * I * z) ^ n - / (1 - cexp (2 * π * I * z) ^ n )), Periodic.qParam, eta_q_eq_pow] - ring_nf + / (1 - cexp (2 * π * I * z) ^ n )), eta_q_eq_pow] + simp_rw [← tsum_mul_left, ← tsum_mul_right, ← tsum_neg] congr ext n ring_nf + +end ModularForm From af28cc188a4965880dc35a42ead04d57e6f37af5 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Wed, 27 Aug 2025 16:27:39 +0100 Subject: [PATCH 128/128] merge fixes --- Mathlib/NumberTheory/ModularForms/DedekindEta.lean | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean index 430b40e826d287..19d24c9c9f03c9 100644 --- a/Mathlib/NumberTheory/ModularForms/DedekindEta.lean +++ b/Mathlib/NumberTheory/ModularForms/DedekindEta.lean @@ -4,14 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck, David Loeffler -/ -import Mathlib.Algebra.Order.Ring.Star -import Mathlib.Analysis.CStarAlgebra.Classes -import Mathlib.Analysis.Complex.LocallyUniformLimit -import Mathlib.Analysis.Complex.UpperHalfPlane.Exp -import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn import Mathlib.Analysis.Calculus.LogDerivUniformlyOn import Mathlib.NumberTheory.ModularForms.EisensteinSeries.E2 -import Mathlib.NumberTheory.TsumDivsorsAntidiagonal /-! # Dedekind eta function @@ -27,11 +21,11 @@ differentiable on the upper half-plane. * [F. Diamond and J. Shurman, *A First Course in Modular Forms*][diamondshurman2005], section 1.2 -/ +open UpperHalfPlane hiding I + open TopologicalSpace Set MeasureTheory intervalIntegral Metric Filter Function Complex -open _root_.UpperHalfPlane hiding I - open scoped Interval Real NNReal ENNReal Topology BigOperators Nat local notation "𝕢" => Periodic.qParam