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

Commit f06058e

Browse files
RuizheWanocfnasheric-wieser
committed
feat(analysis/complex/upper_half_plane/metric): prove that SL(2, ℝ) acts isometrically on upper half space with the hyperbolic metric (#18379)
A key part of the argument is to show that the element `modular_group.S` acts isometrically. We thus move the definition `modular_group.S` (and its partner `modular_group.T`) earlier in the import hierarchy to make it available without introducing a dependency on the theory of the modular group. Co-authored-by: Oliver Nash <github@olivernash.org> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: RuizheWan <115158055+RuizheWan@users.noreply.github.com>
1 parent 842328d commit f06058e

5 files changed

Lines changed: 147 additions & 35 deletions

File tree

src/analysis/complex/upper_half_plane/basic.lean

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import linear_algebra.matrix.special_linear_group
88
import analysis.complex.basic
99
import group_theory.group_action.defs
1010
import linear_algebra.matrix.general_linear_group
11-
11+
import tactic.linear_combination
1212

1313
/-!
1414
# The upper half plane and its automorphisms
@@ -30,11 +30,13 @@ open_locale classical big_operators matrix_groups
3030

3131
local attribute [instance] fintype.card_fin_even
3232

33-
/- Disable this instances as it is not the simp-normal form, and having them disabled ensures
33+
/- Disable these instances as they are not the simp-normal form, and having them disabled ensures
3434
we state lemmas in this file without spurious `coe_fn` terms. -/
3535
local attribute [-instance] matrix.special_linear_group.has_coe_to_fun
36+
local attribute [-instance] matrix.general_linear_group.has_coe_to_fun
3637

3738
local prefix `↑ₘ`:1024 := @coe _ (matrix (fin 2) (fin 2) _) _
39+
local notation `↑ₘ[`:1024 R `]` := @coe _ (matrix (fin 2) (fin 2) R) _
3840

3941
local notation `GL(` n `, ` R `)`⁺ := matrix.GL_pos (fin n) R
4042

@@ -84,6 +86,9 @@ by { rw complex.norm_sq_pos, exact z.ne_zero }
8486

8587
lemma norm_sq_ne_zero (z : ℍ) : complex.norm_sq (z : ℂ) ≠ 0 := (norm_sq_pos z).ne'
8688

89+
lemma im_inv_neg_coe_pos (z : ℍ) : 0 < ((-z : ℂ)⁻¹).im :=
90+
by simpa using div_pos z.property (norm_sq_pos z)
91+
8792
/-- Numerator of the formula for a fractional linear transformation -/
8893
@[simp] def num (g : GL(2, ℝ)⁺) (z : ℍ) : ℂ := (↑ₘg 0 0 : ℝ) * z + (↑ₘg 0 1 : ℝ)
8994

@@ -217,6 +222,11 @@ instance subgroup_to_SL_tower : is_scalar_tower Γ SL(2,ℤ) ℍ :=
217222

218223
end modular_scalar_towers
219224

225+
lemma special_linear_group_apply {R : Type*} [comm_ring R] [algebra R ℝ] (g : SL(2, R)) (z : ℍ) :
226+
g • z = mk ((((↑(↑ₘ[R] g 0 0) : ℝ) : ℂ) * z + ((↑(↑ₘ[R] g 0 1) : ℝ) : ℂ)) /
227+
(((↑(↑ₘ[R] g 1 0) : ℝ) : ℂ) * z + ((↑(↑ₘ[R] g 1 1) : ℝ) : ℂ))) (g • z).property :=
228+
rfl
229+
220230
@[simp] lemma coe_smul (g : GL(2, ℝ)⁺) (z : ℍ) : ↑(g • z) = num g z / denom g z := rfl
221231
@[simp] lemma re_smul (g : GL(2, ℝ)⁺) (z : ℍ) : (g • z).re = (num g z / denom g z).re := rfl
222232
lemma im_smul (g : GL(2, ℝ)⁺) (z : ℍ) : (g • z).im = (num g z / denom g z).im := rfl
@@ -299,4 +309,40 @@ variables (x : ℝ) (z : ℍ)
299309

300310
end real_add_action
301311

312+
@[simp] lemma modular_S_smul (z : ℍ) : modular_group.S • z = mk (-z : ℂ)⁻¹ z.im_inv_neg_coe_pos :=
313+
by { rw special_linear_group_apply, simp [modular_group.S, neg_div, inv_neg], }
314+
315+
lemma exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 = 0) :
316+
∃ (u : {x : ℝ // 0 < x}) (v : ℝ),
317+
((•) g : ℍ → ℍ) = (λ z, v +ᵥ z) ∘ (λ z, u • z) :=
318+
begin
319+
obtain ⟨a, b, ha, rfl⟩ := g.fin_two_exists_eq_mk_of_apply_zero_one_eq_zero hc,
320+
refine ⟨⟨_, mul_self_pos.mpr ha⟩, b * a, _⟩,
321+
ext1 ⟨z, hz⟩, ext1,
322+
suffices : ↑a * z * a + b * a = b * a + a * a * z,
323+
{ rw special_linear_group_apply, simpa [add_mul], },
324+
ring,
325+
end
326+
327+
lemma exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 00) :
328+
∃ (u : {x : ℝ // 0 < x}) (v w : ℝ),
329+
((•) g : ℍ → ℍ) = ((+ᵥ) w : ℍ → ℍ) ∘ ((•) modular_group.S : ℍ → ℍ)
330+
∘ ((+ᵥ) v : ℍ → ℍ) ∘ ((•) u : ℍ → ℍ) :=
331+
begin
332+
have h_denom := denom_ne_zero g,
333+
induction g using matrix.special_linear_group.fin_two_induction with a b c d h,
334+
replace hc : c ≠ 0, { simpa using hc, },
335+
refine ⟨⟨_, mul_self_pos.mpr hc⟩, c * d, a / c, _⟩,
336+
ext1 ⟨z, hz⟩, ext1,
337+
suffices : (↑a * z + b) / (↑c * z + d) = a / c - (c * d + ↑c * ↑c * z)⁻¹,
338+
{ rw special_linear_group_apply, simpa [-neg_add_rev, inv_neg, ← sub_eq_add_neg], },
339+
replace hc : (c : ℂ) ≠ 0, { norm_cast, assumption, },
340+
replace h_denom : ↑c * z + d ≠ 0, { simpa using h_denom ⟨z, hz⟩, },
341+
have h_aux : (c : ℂ) * d + ↑c * ↑c * z ≠ 0,
342+
{ rw [mul_assoc, ← mul_add, add_comm], exact mul_ne_zero hc h_denom, },
343+
replace h : (a * d - b * c : ℂ) = (1 : ℂ), { norm_cast, assumption, },
344+
field_simp,
345+
linear_combination (-(z * ↑c ^ 2) - ↑c * ↑d) * h,
346+
end
347+
302348
end upper_half_plane

src/analysis/complex/upper_half_plane/metric.lean

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ ball/sphere with another center and radius.
2424

2525
noncomputable theory
2626

27-
open_locale upper_half_plane complex_conjugate nnreal topology
27+
open_locale upper_half_plane complex_conjugate nnreal topology matrix_groups
2828
open set metric filter real
2929

3030
variables {z w : ℍ} {r R : ℝ}
@@ -349,4 +349,26 @@ begin
349349
exact mul_div_mul_left _ _ (mt _root_.abs_eq_zero.1 a.2.ne')
350350
end
351351

352+
/-- `SL(2, ℝ)` acts on the upper half plane as an isometry.-/
353+
instance : has_isometric_smul SL(2, ℝ) ℍ :=
354+
⟨λ g,
355+
begin
356+
have h₀ : isometry (λ z, modular_group.S • z : ℍ → ℍ) := isometry.of_dist_eq (λ y₁ y₂, by
357+
{ have h₁ : 0 ≤ im y₁ * im y₂ := mul_nonneg y₁.property.le y₂.property.le,
358+
have h₂ : complex.abs (y₁ * y₂) ≠ 0, { simp [y₁.ne_zero, y₂.ne_zero], },
359+
simp only [dist_eq, modular_S_smul, inv_neg, neg_div, div_mul_div_comm, coe_mk, mk_im, div_one,
360+
complex.inv_im, complex.neg_im, coe_im, neg_neg, complex.norm_sq_neg, mul_eq_mul_left_iff,
361+
real.arsinh_inj, bit0_eq_zero, one_ne_zero, or_false, dist_neg_neg, mul_neg, neg_mul,
362+
dist_inv_inv₀ y₁.ne_zero y₂.ne_zero, ← absolute_value.map_mul,
363+
← complex.norm_sq_mul, real.sqrt_div h₁, ← complex.abs_apply, mul_div (2 : ℝ),
364+
div_div_div_comm, div_self h₂, complex.norm_eq_abs], }),
365+
by_cases hc : g 1 0 = 0,
366+
{ obtain ⟨u, v, h⟩ := exists_SL2_smul_eq_of_apply_zero_one_eq_zero g hc,
367+
rw h,
368+
exact (isometry_real_vadd v).comp (isometry_pos_mul u), },
369+
{ obtain ⟨u, v, w, h⟩ := exists_SL2_smul_eq_of_apply_zero_one_ne_zero g hc,
370+
rw h,
371+
exact (isometry_real_vadd w).comp (h₀.comp $ (isometry_real_vadd v).comp $ isometry_pos_mul u) }
372+
end
373+
352374
end upper_half_plane

src/analysis/normed/field/basic.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,15 @@ nnreal.eq $ by simp
474474
@[simp] lemma nnnorm_zpow : ∀ (a : α) (n : ℤ), ‖a ^ n‖₊ = ‖a‖₊ ^ n :=
475475
map_zpow₀ (nnnorm_hom : α →*₀ ℝ≥0)
476476

477+
lemma dist_inv_inv₀ {z w : α} (hz : z ≠ 0) (hw : w ≠ 0) :
478+
dist z⁻¹ w⁻¹ = (dist z w) / (‖z‖ * ‖w‖) :=
479+
by rw [dist_eq_norm, inv_sub_inv' hz hw, norm_mul, norm_mul, norm_inv, norm_inv, mul_comm ‖z‖⁻¹,
480+
mul_assoc, dist_eq_norm', div_eq_mul_inv, mul_inv]
481+
482+
lemma nndist_inv_inv₀ {z w : α} (hz : z ≠ 0) (hw : w ≠ 0) :
483+
nndist z⁻¹ w⁻¹ = (nndist z w) / (‖z‖₊ * ‖w‖₊) :=
484+
by { rw ← nnreal.coe_eq, simp [-nnreal.coe_eq, dist_inv_inv₀ hz hw], }
485+
477486
/-- Multiplication on the left by a nonzero element of a normed division ring tends to infinity at
478487
infinity. TODO: use `bornology.cobounded` instead of `filter.comap has_norm.norm filter.at_top`. -/
479488
lemma filter.tendsto_mul_left_cobounded {a : α} (ha : a ≠ 0) :

src/linear_algebra/matrix/special_linear_group.lean

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,27 @@ begin
232232
refl,
233233
end
234234

235+
lemma fin_two_induction (P : SL(2, R) → Prop)
236+
(h : ∀ (a b c d : R) (hdet : a * d - b * c = 1), P ⟨!![a, b; c, d], by rwa [det_fin_two_of]⟩)
237+
(g : SL(2, R)) : P g :=
238+
begin
239+
obtain ⟨m, hm⟩ := g,
240+
convert h (m 0 0) (m 0 1) (m 1 0) (m 1 1) (by rwa det_fin_two at hm),
241+
ext i j, fin_cases i; fin_cases j; refl,
242+
end
243+
244+
lemma fin_two_exists_eq_mk_of_apply_zero_one_eq_zero {R : Type*} [field R]
245+
(g : SL(2, R)) (hg : (g : matrix (fin 2) (fin 2) R) 1 0 = 0) :
246+
∃ (a b : R) (h : a ≠ 0),
247+
g = (⟨!![a, b; 0, a⁻¹], by simp [h]⟩ : SL(2, R)) :=
248+
begin
249+
induction g using matrix.special_linear_group.fin_two_induction with a b c d h_det,
250+
replace hg : c = 0 := by simpa using hg,
251+
have had : a * d = 1 := by rwa [hg, mul_zero, sub_zero] at h_det,
252+
refine ⟨a, b, left_ne_zero_of_mul_eq_one had, _⟩,
253+
simp_rw [eq_inv_of_mul_eq_one_right had, hg],
254+
end
255+
235256
end special_cases
236257

237258
-- this section should be last to ensure we do not use it in lemmas
@@ -249,3 +270,49 @@ end coe_fn_instance
249270
end special_linear_group
250271

251272
end matrix
273+
274+
namespace modular_group
275+
276+
open_locale matrix_groups
277+
open matrix matrix.special_linear_group
278+
279+
local prefix `↑ₘ`:1024 := @coe _ (matrix (fin 2) (fin 2) ℤ) _
280+
281+
/-- The matrix `S = [[0, -1], [1, 0]]` as an element of `SL(2, ℤ)`.
282+
283+
This element acts naturally on the Euclidean plane as a rotation about the origin by `π / 2`.
284+
285+
This element also acts naturally on the hyperbolic plane as rotation about `i` by `π`. It
286+
represents the Mobiüs transformation `z ↦ -1/z` and is an involutive elliptic isometry. -/
287+
def S : SL(2, ℤ) := ⟨!![0, -1; 1, 0], by norm_num [matrix.det_fin_two_of]⟩
288+
289+
/-- The matrix `T = [[1, 1], [0, 1]]` as an element of `SL(2, ℤ)` -/
290+
def T : SL(2, ℤ) := ⟨!![1, 1; 0, 1], by norm_num [matrix.det_fin_two_of]⟩
291+
292+
lemma coe_S : ↑ₘS = !![0, -1; 1, 0] := rfl
293+
294+
lemma coe_T : ↑ₘT = !![1, 1; 0, 1] := rfl
295+
296+
lemma coe_T_inv : ↑ₘ(T⁻¹) = !![1, -1; 0, 1] := by simp [coe_inv, coe_T, adjugate_fin_two]
297+
298+
lemma coe_T_zpow (n : ℤ) : ↑ₘ(T ^ n) = !![1, n; 0, 1] :=
299+
begin
300+
induction n using int.induction_on with n h n h,
301+
{ rw [zpow_zero, coe_one, matrix.one_fin_two] },
302+
{ simp_rw [zpow_add, zpow_one, coe_mul, h, coe_T, matrix.mul_fin_two],
303+
congrm !![_, _; _, _],
304+
rw [mul_one, mul_one, add_comm] },
305+
{ simp_rw [zpow_sub, zpow_one, coe_mul, h, coe_T_inv, matrix.mul_fin_two],
306+
congrm !![_, _; _, _]; ring },
307+
end
308+
309+
@[simp] lemma T_pow_mul_apply_one (n : ℤ) (g : SL(2, ℤ)) : ↑ₘ(T ^ n * g) 1 = ↑ₘg 1 :=
310+
by simp [coe_T_zpow, matrix.mul, matrix.dot_product, fin.sum_univ_succ]
311+
312+
@[simp] lemma T_mul_apply_one (g : SL(2, ℤ)) : ↑ₘ(T * g) 1 = ↑ₘg 1 :=
313+
by simpa using T_pow_mul_apply_one 1 g
314+
315+
@[simp] lemma T_inv_mul_apply_one (g : SL(2, ℤ)) : ↑ₘ(T⁻¹ * g) 1 = ↑ₘg 1 :=
316+
by simpa using T_pow_mul_apply_one (-1) g
317+
318+
end modular_group

src/number_theory/modular.lean

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -314,38 +314,6 @@ begin
314314
exact hg ⟨g1, this⟩ },
315315
end
316316

317-
/-- The matrix `T = [[1,1],[0,1]]` as an element of `SL(2,ℤ)` -/
318-
def T : SL(2,ℤ) := ⟨!![1, 1; 0, 1], by norm_num [matrix.det_fin_two_of]⟩
319-
320-
/-- The matrix `S = [[0,-1],[1,0]]` as an element of `SL(2,ℤ)` -/
321-
def S : SL(2,ℤ) := ⟨!![0, -1; 1, 0], by norm_num [matrix.det_fin_two_of]⟩
322-
323-
lemma coe_S : ↑ₘS = !![0, -1; 1, 0] := rfl
324-
325-
lemma coe_T : ↑ₘT = !![1, 1; 0, 1] := rfl
326-
327-
lemma coe_T_inv : ↑ₘ(T⁻¹) = !![1, -1; 0, 1] := by simp [coe_inv, coe_T, adjugate_fin_two]
328-
329-
lemma coe_T_zpow (n : ℤ) : ↑ₘ(T ^ n) = !![1, n; 0, 1] :=
330-
begin
331-
induction n using int.induction_on with n h n h,
332-
{ rw [zpow_zero, coe_one, matrix.one_fin_two] },
333-
{ simp_rw [zpow_add, zpow_one, coe_mul, h, coe_T, matrix.mul_fin_two],
334-
congrm !![_, _; _, _],
335-
rw [mul_one, mul_one, add_comm] },
336-
{ simp_rw [zpow_sub, zpow_one, coe_mul, h, coe_T_inv, matrix.mul_fin_two],
337-
congrm !![_, _; _, _]; ring },
338-
end
339-
340-
@[simp] lemma T_pow_mul_apply_one (n : ℤ) (g : SL(2, ℤ)) : ↑ₘ(T ^ n * g) 1 = ↑ₘg 1 :=
341-
by simp [coe_T_zpow, matrix.mul, matrix.dot_product, fin.sum_univ_succ]
342-
343-
@[simp] lemma T_mul_apply_one (g : SL(2, ℤ)) : ↑ₘ(T * g) 1 = ↑ₘg 1 :=
344-
by simpa using T_pow_mul_apply_one 1 g
345-
346-
@[simp] lemma T_inv_mul_apply_one (g : SL(2, ℤ)) : ↑ₘ(T⁻¹ * g) 1 = ↑ₘg 1 :=
347-
by simpa using T_pow_mul_apply_one (-1) g
348-
349317
lemma coe_T_zpow_smul_eq {n : ℤ} : (↑((T^n) • z) : ℂ) = z + n :=
350318
by simp [coe_T_zpow]
351319

0 commit comments

Comments
 (0)