Skip to content
Closed
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
ed2eb15
open
CBirkbeck Aug 14, 2025
dc50298
save
CBirkbeck Aug 14, 2025
d6c2526
Merge remote-tracking branch 'upstream/master' into Dedekind_eta
CBirkbeck Aug 14, 2025
64bf79f
update
CBirkbeck Aug 14, 2025
f80072a
save
CBirkbeck Aug 14, 2025
6c8f169
remove logderiv stuff
CBirkbeck Aug 14, 2025
d0416ab
remove logderiv stuff
CBirkbeck Aug 14, 2025
e7eed91
remove logderiv stuff
CBirkbeck Aug 14, 2025
46f2afa
remove stuff
CBirkbeck Aug 14, 2025
4ed6485
save
CBirkbeck Aug 14, 2025
07bb88d
update with complexupperhalfplane
CBirkbeck Aug 14, 2025
6ed01ba
clean
CBirkbeck Aug 14, 2025
0804f62
clean more
CBirkbeck Aug 14, 2025
7266763
clean more
CBirkbeck Aug 14, 2025
d310781
arrows
CBirkbeck Aug 14, 2025
eec7f0d
Merge remote-tracking branch 'upstream/master' into Dedekind_eta
CBirkbeck Aug 18, 2025
5e81cc0
golf
CBirkbeck Aug 18, 2025
a145d41
rev updates
CBirkbeck Aug 20, 2025
4b99d29
typo
CBirkbeck Aug 20, 2025
532866d
typo
CBirkbeck Aug 20, 2025
0a387e5
update
CBirkbeck Aug 20, 2025
ae4f93c
hide I
CBirkbeck Aug 21, 2025
dc72f90
remove etaProdTerm
CBirkbeck Aug 21, 2025
ce15717
first clean
CBirkbeck Aug 21, 2025
01efbda
rev fixes
CBirkbeck Aug 21, 2025
dfa9769
fix
CBirkbeck Aug 21, 2025
679f7dc
fix build
CBirkbeck Aug 21, 2025
dccbe95
save@
CBirkbeck Aug 22, 2025
e7738b5
merge
CBirkbeck Aug 22, 2025
b78fffd
fix and merge with other PR
CBirkbeck Aug 22, 2025
777000f
fix
CBirkbeck Aug 22, 2025
ab1d6f0
merge
CBirkbeck Aug 22, 2025
3589dfc
Update Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean
CBirkbeck Aug 25, 2025
15bdbb3
Apply suggestions from code review
CBirkbeck Aug 25, 2025
058d578
fix
CBirkbeck Aug 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Mathlib.lean
Original file line number Diff line number Diff line change
Expand Up @@ -4729,6 +4729,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
Expand Down
13 changes: 13 additions & 0 deletions Mathlib/Analysis/Complex/Periodic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ 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

lemma qParam_ne_zero (z : ℂ) : 𝕢 h z ≠ 0 := by
simp [qParam, exp_ne_zero]

@[fun_prop]
lemma differentiable_qParam : Differentiable ℂ (𝕢 h) := by
unfold qParam
fun_prop

@[fun_prop]
lemma contDiff_qParam (m : WithTop ℕ∞) : ContDiff ℂ m (𝕢 h) := by
unfold qParam
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
Expand Down
11 changes: 11 additions & 0 deletions Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -203,5 +203,16 @@ theorem vadd_im : (x +ᵥ z).im = z.im :=
zero_add _

end RealAddAction
section upperHalfPlaneSet
Comment thread
CBirkbeck marked this conversation as resolved.

/-- 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
2 changes: 1 addition & 1 deletion Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ lemma mdifferentiable_iff {f : ℍ → ℂ} :
MDifferentiable 𝓘(ℂ) 𝓘(ℂ) f ↔ DifferentiableOn ℂ (f ∘ ofComplex) {z | 0 < z.im} :=
fun h z hz ↦ (mdifferentiableAt_iff.mp (h ⟨z, hz⟩)).differentiableWithinAt,
fun h ⟨z, hz⟩ ↦ mdifferentiableAt_iff.mpr <| (h z hz).differentiableAt
<| (Complex.continuous_im.isOpen_preimage _ isOpen_Ioi).mem_nhds hz⟩
<| isOpen_upperHalfPlaneSet.mem_nhds hz⟩

lemma contMDiff_num (g : GL (Fin 2) ℝ) : ContMDiff 𝓘(ℂ) 𝓘(ℂ) n (fun τ : ℍ ↦ num g τ) :=
(contMDiff_const.smul contMDiff_coe).add contMDiff_const
Expand Down
4 changes: 2 additions & 2 deletions Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ instance : TopologicalSpace ℍ :=
instTopologicalSpaceSubtype

theorem isOpenEmbedding_coe : IsOpenEmbedding ((↑) : ℍ → ℂ) :=
IsOpen.isOpenEmbedding_subtypeVal <| isOpen_lt continuous_const Complex.continuous_im
IsOpen.isOpenEmbedding_subtypeVal <| isOpen_upperHalfPlaneSet

theorem isEmbedding_coe : IsEmbedding ((↑) : ℍ → ℂ) :=
IsEmbedding.subtypeVal
Expand Down Expand Up @@ -168,7 +168,7 @@ lemma comp_ofComplex_of_im_le_zero (f : ℍ → ℂ) (z z' : ℂ) (hz : z.im ≤

lemma eventuallyEq_coe_comp_ofComplex {z : ℂ} (hz : 0 < z.im) :
UpperHalfPlane.coe ∘ ofComplex =ᶠ[𝓝 z] id := by
filter_upwards [(Complex.continuous_im.isOpen_preimage _ isOpen_Ioi).mem_nhds hz] with x hx
filter_upwards [isOpen_upperHalfPlaneSet.mem_nhds hz] with x hx
simp only [Function.comp_apply, ofComplex_apply_of_im_pos hx, id_eq, coe_mk_subtype]

end ofComplex
Expand Down
25 changes: 25 additions & 0 deletions Mathlib/Analysis/SpecialFunctions/Log/Summable.lean
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,29 @@ lemma multipliable_one_add_of_summable [CompleteSpace R]
· intro x hx y hy
exact (dist_triangle_right _ _ (∏ i ∈ s, (1 + f i))).trans_lt (add_halves ε ▸ add_lt_add hx hy)

variable {𝕜 : Type*} [NontriviallyNormedField 𝕜]

lemma Real.summable_log_norm_of_summable_norm {f : ι → 𝕜} (hu : Summable fun n => ‖f n‖) :
Summable fun i ↦ Real.log ‖1 + f i‖ := by
let g (i : ι) := ‖1 + f i‖ - 1
have aux1 : Summable (g ·) := by
apply Summable.of_norm
apply hu.of_nonneg_of_le (fun i => by positivity)
intro i
simp_rw [g, Real.norm_eq_abs, abs_le]
constructor
· simpa [le_sub_iff_add_le, neg_add_eq_sub] using norm_add_le (1 + f i) (-f i)
· rw [sub_le_iff_le_add, ← norm_one (α := 𝕜), add_comm]
exact norm_add_le (f i) 1
apply (Real.summable_log_one_add_of_summable aux1).congr
simp [g]

lemma tprod_one_add_ne_zero_of_summable [CompleteSpace 𝕜] {f : ι → 𝕜} (hf : ∀ i, 1 + f i ≠ 0)
(hu : Summable fun n => ‖f n‖) : (∏' i : ι, (1 + f i)) ≠ 0 := by
rw [← norm_ne_zero_iff, Multipliable.norm_tprod]
· rw [ne_eq, ← Real.rexp_tsum_eq_tprod (f := fun n => (‖1 + f n‖)) (by intro i; simp [hf i])
(Real.summable_log_norm_of_summable_norm hu)]
simp [Real.exp_ne_zero]
· exact multipliable_one_add_of_summable hu
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated

end NormedRing
2 changes: 1 addition & 1 deletion Mathlib/NumberTheory/ModularForms/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private lemma MDifferentiable.slashJ {f : ℍ → ℂ} (hf : MDifferentiable
simp [ofComplex_apply_of_im_pos hz]
refine .congr (fun z hz ↦ DifferentiableAt.differentiableWithinAt ?_) this
have : 0 < (-conj z).im := by simpa using hz
have := hf.differentiableAt ((Complex.continuous_im.isOpen_preimage _ isOpen_Ioi).mem_nhds this)
have := hf.differentiableAt (isOpen_upperHalfPlaneSet.mem_nhds this)
simpa using (this.comp _ differentiable_neg.differentiableAt).star_star.neg

/-- The weight `k` slash action of `GL(2, ℝ)` preserves holomorphic functions. -/
Expand Down
140 changes: 140 additions & 0 deletions Mathlib/NumberTheory/ModularForms/DedekindEta.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/-
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
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
import Mathlib.Analysis.Complex.LocallyUniformLimit
import Mathlib.Analysis.Complex.UpperHalfPlane.Exp
import Mathlib.Analysis.NormedSpace.MultipliableUniformlyOn

/-!
# Dedekind eta function

## Main definitions

* We define the Dedekind eta function as the infinite product
`η(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]
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
-/

open TopologicalSpace Set MeasureTheory intervalIntegral
Metric Filter Function Complex

open UpperHalfPlane hiding I

open scoped Interval Real NNReal ENNReal Topology BigOperators Nat

local notation "𝕢" => Periodic.qParam

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 ModularForm.eta_q (n : ℕ) (z : ℂ) := (𝕢 1 z) ^ (n + 1)

open ModularForm

lemma eta_q_eq_cexp (n : ℕ) (z : ℂ) : eta_q n z = cexp (2 * π * I * (n + 1) * z) := by
Comment thread
CBirkbeck marked this conversation as resolved.
simp [eta_q, Periodic.qParam, ← Complex.exp_nsmul]
ring_nf

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
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 hz⟩
simp [← mul_assoc, ← h] at *
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated


Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
/-- 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 * ∏' (n : ℕ), (1 - eta_q n z)

local notation "η" => ModularForm.eta
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated

open ModularForm

Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
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 multipliableLocallyUniformlyOn_eta :
MultipliableLocallyUniformlyOn (fun n a ↦ 1 - eta_q n a) ℍₒ:= by
use fun z => ∏' (n : ℕ), (1 - eta_q n z)
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
simp_rw [sub_eq_add_neg]
apply hasProdLocallyUniformlyOn_of_forall_compact isOpen_upperHalfPlaneSet
intro K hK hcK
by_cases hN : K.Nonempty
· 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
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)
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
· simp_rw [eta_q, Periodic.qParam]
fun_prop
· rw [hasProdUniformlyOn_iff_tendstoUniformlyOn]
simpa [not_nonempty_iff_eq_empty.mp hN] using tendstoUniformlyOn_empty

-- Eta is non-vanishing on the upper half plane. -/
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
lemma eta_ne_zero_on_UpperHalfPlane {z : ℂ} (hz : z ∈ ℍₒ) : η z ≠ 0 := by
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
apply mul_ne_zero (Periodic.qParam_ne_zero z)
simp only [eta_q, ne_eq]
refine tprod_one_add_ne_zero_of_summable (f := fun n ↦ -eta_q n z) ?_ ?_
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
· refine fun i ↦ by simpa using one_sub_eta_q_ne_zero i hz
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
· simpa [eta_q, ← summable_norm_iff] using summable_eta_q ⟨z, 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
simp [logDeriv]

lemma logDeriv_one_sub_mul_cexp_comp (r : ℂ) {g : ℂ → ℂ} (hg : Differentiable ℂ g) :
Comment thread
CBirkbeck marked this conversation as resolved.
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

private theorem one_sub_eta_logDeriv_eq (z : ℂ) (i : ℕ) : logDeriv (fun x ↦ 1 - eta_q i x) z =
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
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 * π * 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 * π * 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 =
(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 * ↑π * 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)
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated

theorem differentiableAt_eta_of_mem_upperHalfPlaneSet {z : ℂ} (hz : z ∈ ℍₒ) :
DifferentiableAt ℂ eta z := by
apply DifferentiableAt.mul (by fun_prop)
have hD := (MultipliableLocallyUniformlyOn.hasProdLocallyUniformlyOn
multipliableLocallyUniformlyOn_eta).tendstoLocallyUniformlyOn_finsetRange.differentiableOn ?_
isOpen_upperHalfPlaneSet
· exact (hD z hz).differentiableAt (isOpen_upperHalfPlaneSet.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
Comment thread
CBirkbeck marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,9 @@ theorem eisensteinSeries_SIF_MDifferentiable {k : ℤ} {N : ℕ} (hk : 3 ≤ k)
suffices DifferentiableAt ℂ (↑ₕeisensteinSeries_SIF a k) τ.1 by
convert MDifferentiableAt.comp τ (DifferentiableAt.mdifferentiableAt this) τ.mdifferentiable_coe
exact funext fun z ↦ (comp_ofComplex (eisensteinSeries_SIF a k) z).symm
refine DifferentiableOn.differentiableAt ?_
((isOpen_lt continuous_const Complex.continuous_im).mem_nhds τ.2)
refine DifferentiableOn.differentiableAt ?_ (isOpen_upperHalfPlaneSet.mem_nhds τ.2)
exact (eisensteinSeries_tendstoLocallyUniformlyOn hk a).differentiableOn
(Eventually.of_forall fun s ↦ DifferentiableOn.fun_sum
fun _ _ ↦ eisSummand_extension_differentiableOn _ _)
(isOpen_lt continuous_const continuous_im)
fun _ _ ↦ eisSummand_extension_differentiableOn _ _) isOpen_upperHalfPlaneSet

end EisensteinSeries